video: driver: add support for instance states

Add support for all the required instance states and
move the states accordingly.

Change-Id: Iac1046ab8c7a0116df6ed3069d566c7a1b65e61c
Signed-off-by: Maheshwar Ajja <majja@codeaurora.org>
This commit is contained in:
Maheshwar Ajja
2020-12-30 08:30:11 -08:00
committed by Darshana Patil
parent 7c203e7bf5
commit 58cd1120ee
18 changed files with 1119 additions and 461 deletions

View File

@@ -9,19 +9,18 @@
#include "msm_vidc_core.h"
#include "msm_vidc_inst.h"
int msm_vdec_stop_input(struct msm_vidc_inst *inst);
int msm_vdec_start_input(struct msm_vidc_inst *inst);
int msm_vdec_stop_output(struct msm_vidc_inst *inst);
int msm_vdec_start_output(struct msm_vidc_inst *inst);
int msm_vdec_streamoff_input(struct msm_vidc_inst *inst);
int msm_vdec_streamon_input(struct msm_vidc_inst *inst);
int msm_vdec_streamoff_output(struct msm_vidc_inst *inst);
int msm_vdec_streamon_output(struct msm_vidc_inst *inst);
int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb2);
int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f);
int msm_vdec_inst_init(struct msm_vidc_inst *inst);
int msm_vdec_inst_deinit(struct msm_vidc_inst *inst);
int msm_vdec_input_port_settings_change(struct msm_vidc_inst *inst);
int msm_vdec_output_port_settings_change(struct msm_vidc_inst *inst);
int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd);
int msm_vdec_subscribe_port_settings_change(struct msm_vidc_inst *inst,
enum msm_vidc_port_type port);
#endif // _MSM_VDEC_H_

View File

@@ -9,14 +9,15 @@
#include "msm_vidc_core.h"
#include "msm_vidc_inst.h"
int msm_venc_stop_input(struct msm_vidc_inst *inst);
int msm_venc_start_input(struct msm_vidc_inst *inst);
int msm_venc_stop_output(struct msm_vidc_inst *inst);
int msm_venc_start_output(struct msm_vidc_inst *inst);
int msm_venc_streamoff_input(struct msm_vidc_inst *inst);
int msm_venc_streamon_input(struct msm_vidc_inst *inst);
int msm_venc_streamoff_output(struct msm_vidc_inst *inst);
int msm_venc_streamon_output(struct msm_vidc_inst *inst);
int msm_venc_process_cmd(struct msm_vidc_inst *inst, u32 cmd);
int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f);
int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f);
int msm_venc_inst_init(struct msm_vidc_inst *inst);
int msm_venc_inst_deinit(struct msm_vidc_inst *inst);
#endif // _MSM_VENC_H_

View File

@@ -60,18 +60,6 @@ enum msm_vidc_core_state {
MSM_VIDC_CORE_ERROR = 2,
};
enum work_type {
MSM_VIDC_INST_WORK_PSC = 1,
};
struct work_header {
void *data;
struct list_head list;
enum work_type type;
u32 session_id;
u32 data_size;
};
struct msm_vidc_core {
struct platform_device *pdev;
struct msm_video_device vdev[2];
@@ -120,9 +108,6 @@ struct msm_vidc_core {
u32 header_id;
u32 packet_id;
struct completion init_done;
struct list_head inst_works; /* list of struct work_header */
struct delayed_work inst_work;
struct workqueue_struct *inst_workq;
};
#endif // _MSM_VIDC_CORE_H_

View File

@@ -177,6 +177,7 @@ u32 v4l2_colorformat_from_driver(enum msm_vidc_colorformat_type colorformat,
const char *func);
int v4l2_type_to_driver_port(struct msm_vidc_inst *inst, u32 type,
const char *func);
const char *state_name(enum msm_vidc_inst_state state);
int msm_vidc_change_inst_state(struct msm_vidc_inst *inst,
enum msm_vidc_inst_state state, const char *func);
int msm_vidc_get_input_internal_buffers(struct msm_vidc_inst *inst,
@@ -193,13 +194,14 @@ int msm_vidc_remove_session(struct msm_vidc_inst *inst);
int msm_vidc_add_session(struct msm_vidc_inst *inst);
int msm_vidc_session_open(struct msm_vidc_inst *inst);
int msm_vidc_session_set_codec(struct msm_vidc_inst *inst);
int msm_vidc_session_start(struct msm_vidc_inst* inst,
int msm_vidc_session_streamon(struct msm_vidc_inst *inst,
enum msm_vidc_port_type port);
int msm_vidc_session_stop(struct msm_vidc_inst *inst,
int msm_vidc_session_streamoff(struct msm_vidc_inst *inst,
enum msm_vidc_port_type port);
int msm_vidc_session_close(struct msm_vidc_inst *inst);
int msm_vidc_get_inst_capability(struct msm_vidc_inst *inst);
int msm_vidc_core_init(struct msm_vidc_core *core);
int msm_vidc_core_deinit(struct msm_vidc_core *core);
int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
struct device *dev, unsigned long iova, int flags, void *data);
int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
@@ -208,8 +210,10 @@ void msm_vidc_ssr_handler(struct work_struct *work);
void msm_vidc_pm_work_handler(struct work_struct *work);
void msm_vidc_fw_unload_handler(struct work_struct *work);
void msm_vidc_batch_handler(struct work_struct *work);
int msm_vidc_setup_event_queue(struct msm_vidc_inst *inst);
int msm_vidc_event_queue_init(struct msm_vidc_inst *inst);
int msm_vidc_event_queue_deinit(struct msm_vidc_inst *inst);
int msm_vidc_vb2_queue_init(struct msm_vidc_inst *inst);
int msm_vidc_vb2_queue_deinit(struct msm_vidc_inst *inst);
int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl);
u32 msm_vidc_get_buffer_region(struct msm_vidc_inst *inst,
enum msm_vidc_buffer_type buffer_type, const char *func);
@@ -231,14 +235,33 @@ int msm_vidc_put_driver_buf(struct msm_vidc_inst *inst,
int msm_vidc_queue_buffer(struct msm_vidc_inst *inst, struct vb2_buffer *vb2);
int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *buffer);
void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst);
struct msm_vidc_buffer *get_meta_buffer(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *vbuf);
struct msm_vidc_inst *get_inst_ref(struct msm_vidc_core *core,
struct msm_vidc_inst *instance);
struct msm_vidc_inst *get_inst(struct msm_vidc_core *core,
u32 session_id);
void put_inst(struct msm_vidc_inst *inst);
int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst* inst);
int msm_vidc_get_fps(struct msm_vidc_inst* inst);
int msm_vidc_num_queued_bufs(struct msm_vidc_inst* inst, u32 type);
bool msm_vidc_allow_s_fmt(struct msm_vidc_inst *inst, u32 type);
bool msm_vidc_allow_s_ctrl(struct msm_vidc_inst *inst, u32 id);
bool msm_vidc_allow_reqbufs(struct msm_vidc_inst *inst, u32 type);
bool msm_vidc_allow_stop(struct msm_vidc_inst *inst);
bool msm_vidc_allow_start(struct msm_vidc_inst *inst);
bool msm_vidc_allow_streamon(struct msm_vidc_inst *inst, u32 type);
bool msm_vidc_allow_streamoff(struct msm_vidc_inst *inst, u32 type);
bool msm_vidc_allow_qbuf(struct msm_vidc_inst *inst);
int msm_vidc_allow_input_psc(struct msm_vidc_inst *inst);
bool msm_vidc_allow_last_flag(struct msm_vidc_inst *inst);
int msm_vidc_state_change_streamon(struct msm_vidc_inst *inst, u32 type);
int msm_vidc_state_change_streamoff(struct msm_vidc_inst *inst, u32 type);
int msm_vidc_state_change_stop(struct msm_vidc_inst *inst);
int msm_vidc_state_change_start(struct msm_vidc_inst *inst);
int msm_vidc_state_change_input_psc(struct msm_vidc_inst *inst);
int msm_vidc_state_change_last_flag(struct msm_vidc_inst *inst);
int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst);
int msm_vidc_get_fps(struct msm_vidc_inst *inst);
int msm_vidc_num_queued_bufs(struct msm_vidc_inst *inst, u32 type);
void core_lock(struct msm_vidc_core *core, const char *function);
void core_unlock(struct msm_vidc_core *core, const char *function);
void inst_lock(struct msm_vidc_inst *inst, const char *function);

View File

@@ -34,6 +34,7 @@ struct msm_vidc_allocations_info {
struct msm_vidc_allocations line;
struct msm_vidc_allocations dpb;
struct msm_vidc_allocations persist;
struct msm_vidc_allocations vpss;
};
struct msm_vidc_mappings_info {
@@ -48,6 +49,7 @@ struct msm_vidc_mappings_info {
struct msm_vidc_mappings line;
struct msm_vidc_mappings dpb;
struct msm_vidc_mappings persist;
struct msm_vidc_mappings vpss;
};
struct msm_vidc_buffers_info {
@@ -62,6 +64,7 @@ struct msm_vidc_buffers_info {
struct msm_vidc_buffers line;
struct msm_vidc_buffers dpb;
struct msm_vidc_buffers persist;
struct msm_vidc_buffers vpss;
};
enum msm_vidc_inst_state {
@@ -119,6 +122,9 @@ struct msm_vidc_inst {
struct msm_vidc_decode_batch decode_batch;
struct msm_vidc_decode_vpp_delay decode_vpp_delay;
struct msm_vidc_session_idle session_idle;
struct delayed_work input_psc_work;
struct workqueue_struct *input_psc_workq;
struct list_head input_psc_works; /* list of struct input_psc_work */
struct list_head input_ts;
struct list_head enc_input_crs;
struct list_head decode_bitrate_data;

View File

@@ -708,6 +708,12 @@ struct msm_vidc_buffers {
bool reuse;
};
struct input_psc_work {
struct list_head list;
void *data;
u32 data_size;
};
struct msm_vidc_ssr {
bool trigger;
enum msm_vidc_ssr_trigger_type ssr_type;

View File

@@ -8,6 +8,10 @@
#include <media/videobuf2-core.h>
#include <media/videobuf2-v4l2.h>
#include "msm_vidc_inst.h"
struct vb2_queue *msm_vidc_get_vb2q(struct msm_vidc_inst *inst,
u32 type, const char *func);
/* vb2_mem_ops */
void *msm_vb2_get_userptr(struct device *dev, unsigned long vaddr,

View File

@@ -64,14 +64,13 @@ int venus_hfi_session_close(struct msm_vidc_inst *inst);
int venus_hfi_session_open(struct msm_vidc_inst *inst);
int venus_hfi_session_set_codec(struct msm_vidc_inst *inst);
int venus_hfi_core_init(struct msm_vidc_core *core);
int venus_hfi_core_release(struct msm_vidc_core *core);
int venus_hfi_core_deinit(struct msm_vidc_core *core);
int venus_hfi_suspend(struct msm_vidc_core *core);
int venus_hfi_scale_clocks(struct msm_vidc_inst* inst, u64 freq);
int venus_hfi_scale_buses(struct msm_vidc_inst* inst, u64 bw_ddr, u64 bw_llcc);
void venus_hfi_work_handler(struct work_struct *work);
void venus_hfi_pm_work_handler(struct work_struct *work);
void venus_hfi_inst_work_handler(struct work_struct *work);
irqreturn_t venus_hfi_isr(int irq, void *data);
void __write_register(struct msm_vidc_core *core,

View File

@@ -14,5 +14,8 @@ bool is_valid_port(struct msm_vidc_inst *inst, u32 port,
const char *func);
bool is_valid_hfi_buffer_type(struct msm_vidc_inst *inst,
u32 buffer_type, const char *func);
void handle_session_input_psc_work_handler(struct work_struct *work);
int handle_session_input_psc(struct msm_vidc_inst *inst,
struct input_psc_work *psc_work);
#endif // __VENUS_HFI_RESPONSE_H__

View File

@@ -1158,7 +1158,7 @@ int msm_vdec_output_port_settings_change(struct msm_vidc_inst *inst)
return 0;
}
int msm_vdec_stop_input(struct msm_vidc_inst *inst)
int msm_vdec_streamoff_input(struct msm_vidc_inst *inst)
{
int rc = 0;
@@ -1167,31 +1167,28 @@ int msm_vdec_stop_input(struct msm_vidc_inst *inst)
return -EINVAL;
}
rc = msm_vidc_session_stop(inst, INPUT_PORT);
rc = msm_vidc_session_streamoff(inst, INPUT_PORT);
if (rc)
return rc;
return 0;
}
int msm_vdec_start_input(struct msm_vidc_inst *inst)
int msm_vdec_streamon_input(struct msm_vidc_inst *inst)
{
int rc = 0;
struct msm_vidc_core *core;
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
s_vpr_h(inst->sid, "%s()\n", __func__);
if (is_input_meta_enabled(inst) &&
!inst->vb2q[INPUT_META_PORT].streaming) {
s_vpr_e(inst->sid,
"%s: Meta port must be streamed on before data port\n",
__func__);
goto error;
return -EINVAL;
}
//rc = msm_vidc_check_session_supported(inst);
@@ -1244,20 +1241,19 @@ int msm_vdec_start_input(struct msm_vidc_inst *inst)
if (rc)
return rc;
rc = msm_vidc_session_start(inst, INPUT_PORT);
rc = msm_vidc_session_streamon(inst, INPUT_PORT);
if (rc)
goto error;
s_vpr_h(inst->sid, "%s: done\n", __func__);
return 0;
error:
s_vpr_e(inst->sid, "%s: failed\n", __func__);
msm_vdec_stop_input(inst);
msm_vdec_streamoff_input(inst);
return rc;
}
int msm_vdec_stop_output(struct msm_vidc_inst *inst)
int msm_vdec_streamoff_output(struct msm_vidc_inst *inst)
{
int rc = 0;
@@ -1266,7 +1262,7 @@ int msm_vdec_stop_output(struct msm_vidc_inst *inst)
return -EINVAL;
}
rc = msm_vidc_session_stop(inst, OUTPUT_PORT);
rc = msm_vidc_session_streamoff(inst, OUTPUT_PORT);
if (rc)
return rc;
@@ -1385,11 +1381,10 @@ static int msm_vdec_subscribe_output_port_settings_change(struct msm_vidc_inst *
return rc;
}
int msm_vdec_start_output(struct msm_vidc_inst *inst)
int msm_vdec_streamon_output(struct msm_vidc_inst *inst)
{
int rc = 0;
d_vpr_h("%s()\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
@@ -1400,7 +1395,7 @@ int msm_vdec_start_output(struct msm_vidc_inst *inst)
s_vpr_e(inst->sid,
"%s: Meta port must be streamed on before data port\n",
__func__);
goto error;
return -EINVAL;
}
rc = msm_vdec_set_output_properties(inst);
@@ -1409,26 +1404,27 @@ int msm_vdec_start_output(struct msm_vidc_inst *inst)
if (!inst->opsc_properties_set) {
memcpy(&inst->subcr_params[OUTPUT_PORT],
&inst->subcr_params[INPUT_PORT], sizeof(inst->subcr_params[INPUT_PORT]));
&inst->subcr_params[INPUT_PORT],
sizeof(inst->subcr_params[INPUT_PORT]));
rc = msm_vdec_subscribe_output_port_settings_change(inst, OUTPUT_PORT);
if (rc)
return rc;
goto error;
inst->opsc_properties_set = true;
}
rc = msm_vdec_subscribe_metadata(inst, OUTPUT_PORT);
if (rc)
return rc;
goto error;
rc = msm_vidc_session_start(inst, OUTPUT_PORT);
rc = msm_vidc_session_streamon(inst, OUTPUT_PORT);
if (rc)
goto error;
d_vpr_h("%s: done\n", __func__);
return 0;
error:
msm_vdec_stop_output(inst);
s_vpr_e(inst->sid, "%s: failed\n", __func__);
msm_vdec_streamoff_output(inst);
return rc;
}
@@ -1468,6 +1464,8 @@ int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
}
if (cmd == V4L2_DEC_CMD_STOP) {
if (!msm_vidc_allow_stop(inst))
return -EBUSY;
rc = venus_hfi_session_command(inst,
HFI_CMD_DRAIN,
INPUT_PORT,
@@ -1476,6 +1474,23 @@ int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
0);
if (rc)
return rc;
rc = msm_vidc_state_change_stop(inst);
if (rc)
return rc;
} else if (cmd == V4L2_DEC_CMD_START) {
if (!msm_vidc_allow_start(inst))
return -EBUSY;
rc = msm_vidc_state_change_start(inst);
if (rc)
return rc;
rc = venus_hfi_session_command(inst,
HFI_CMD_RESUME,
OUTPUT_PORT,
HFI_PAYLOAD_NONE,
NULL,
0);
if (rc)
return rc;
} else {
d_vpr_e("%s: unknown cmd %d\n", __func__, cmd);
return -EINVAL;
@@ -1490,23 +1505,13 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
struct msm_vidc_core *core;
struct v4l2_format *fmt;
d_vpr_h("%s()\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
if (inst->state == MSM_VIDC_START) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
if (f->type == INPUT_MPLANE) {
if (inst->state == MSM_VIDC_START_INPUT) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
if (inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat !=
f->fmt.pix_mp.pixelformat) {
s_vpr_e(inst->sid,
@@ -1562,10 +1567,6 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
//msm_vidc_update_batching(inst);
} else if (f->type == INPUT_META_PLANE) {
if (inst->state == MSM_VIDC_START_INPUT) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
fmt = &inst->fmts[INPUT_META_PORT];
fmt->type = INPUT_META_PLANE;
fmt->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
@@ -1592,10 +1593,6 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
inst->buffers.input_meta.min_count,
inst->buffers.input_meta.extra_count);
} else if (f->type == OUTPUT_MPLANE) {
if (inst->state == MSM_VIDC_START_OUTPUT) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
fmt = &inst->fmts[OUTPUT_PORT];
fmt->type = OUTPUT_MPLANE;
fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
@@ -1637,10 +1634,6 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
inst->buffers.output.min_count,
inst->buffers.output.extra_count);
} else if (f->type == OUTPUT_META_PLANE) {
if (inst->state == MSM_VIDC_START_OUTPUT) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
fmt = &inst->fmts[OUTPUT_META_PORT];
fmt->type = OUTPUT_META_PLANE;
fmt->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
@@ -1681,7 +1674,6 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
int rc = 0;
int port;
d_vpr_h("%s()\n", __func__);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
@@ -1767,7 +1759,6 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
struct msm_vidc_core *core;
struct v4l2_format *f;
d_vpr_h("%s()\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
@@ -1850,3 +1841,16 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
return rc;
}
int msm_vdec_inst_deinit(struct msm_vidc_inst *inst)
{
int rc = 0;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
rc = msm_vidc_ctrl_deinit(inst);
return rc;
}

View File

@@ -701,7 +701,7 @@ static int msm_venc_metadata_subscription(struct msm_vidc_inst *inst,
return rc;
}
int msm_venc_stop_input(struct msm_vidc_inst *inst)
int msm_venc_streamoff_input(struct msm_vidc_inst *inst)
{
int rc = 0;
@@ -710,31 +710,28 @@ int msm_venc_stop_input(struct msm_vidc_inst *inst)
return -EINVAL;
}
rc = msm_vidc_session_stop(inst, INPUT_PORT);
rc = msm_vidc_session_streamoff(inst, INPUT_PORT);
if (rc)
return rc;
return 0;
}
int msm_venc_start_input(struct msm_vidc_inst *inst)
int msm_venc_streamon_input(struct msm_vidc_inst *inst)
{
int rc = 0;
struct msm_vidc_core *core;
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
s_vpr_h(inst->sid, "%s()\n", __func__);
if (is_input_meta_enabled(inst) &&
!inst->vb2q[INPUT_META_PORT].streaming) {
s_vpr_e(inst->sid,
"%s: Meta port must be streamed on before data port\n",
__func__);
goto error;
return -EINVAL;
}
//rc = msm_vidc_check_session_supported(inst);
@@ -780,16 +777,15 @@ int msm_venc_start_input(struct msm_vidc_inst *inst)
if (rc)
return rc;
rc = msm_vidc_session_start(inst, INPUT_PORT);
rc = msm_vidc_session_streamon(inst, INPUT_PORT);
if (rc)
goto error;
s_vpr_h(inst->sid, "%s: done\n", __func__);
return 0;
error:
s_vpr_e(inst->sid, "%s: failed\n", __func__);
msm_venc_stop_input(inst);
msm_venc_streamoff_input(inst);
return rc;
}
@@ -803,6 +799,8 @@ int msm_venc_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
}
if (cmd == V4L2_ENC_CMD_STOP) {
if (!msm_vidc_allow_stop(inst))
return -EBUSY;
rc = venus_hfi_session_command(inst,
HFI_CMD_DRAIN,
INPUT_PORT,
@@ -811,6 +809,17 @@ int msm_venc_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
0);
if (rc)
return rc;
} else if (cmd == V4L2_ENC_CMD_START) {
if (!msm_vidc_allow_start(inst))
return -EBUSY;
rc = venus_hfi_session_command(inst,
HFI_CMD_RESUME,
INPUT_PORT,
HFI_PAYLOAD_NONE,
NULL,
0);
if (rc)
return rc;
} else {
d_vpr_e("%s: unknown cmd %d\n", __func__, cmd);
return -EINVAL;
@@ -818,7 +827,7 @@ int msm_venc_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
return 0;
}
int msm_venc_stop_output(struct msm_vidc_inst *inst)
int msm_venc_streamoff_output(struct msm_vidc_inst *inst)
{
int rc = 0;
@@ -827,18 +836,17 @@ int msm_venc_stop_output(struct msm_vidc_inst *inst)
return -EINVAL;
}
rc = msm_vidc_session_stop(inst, OUTPUT_PORT);
rc = msm_vidc_session_streamoff(inst, OUTPUT_PORT);
if (rc)
return rc;
return 0;
}
int msm_venc_start_output(struct msm_vidc_inst *inst)
int msm_venc_streamon_output(struct msm_vidc_inst *inst)
{
int rc = 0;
d_vpr_h("%s()\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
@@ -849,7 +857,7 @@ int msm_venc_start_output(struct msm_vidc_inst *inst)
s_vpr_e(inst->sid,
"%s: Meta port must be streamed on before data port\n",
__func__);
goto error;
return -EINVAL;
}
rc = msm_venc_set_output_properties(inst);
@@ -858,11 +866,11 @@ int msm_venc_start_output(struct msm_vidc_inst *inst)
rc = msm_vidc_adjust_v4l2_properties(inst);
if (rc)
return -EINVAL;
goto error;
rc = msm_vidc_set_v4l2_properties(inst);
if (rc)
return -EINVAL;
goto error;
rc = msm_venc_set_internal_properties(inst);
if (rc)
@@ -870,21 +878,21 @@ int msm_venc_start_output(struct msm_vidc_inst *inst)
rc = msm_venc_property_subscription(inst, OUTPUT_PORT);
if (rc)
return rc;
goto error;
rc = msm_venc_metadata_subscription(inst, OUTPUT_PORT);
if (rc)
return rc;
goto error;
rc = msm_vidc_session_start(inst, OUTPUT_PORT);
rc = msm_vidc_session_streamon(inst, OUTPUT_PORT);
if (rc)
goto error;
d_vpr_h("%s: done\n", __func__);
return 0;
error:
msm_venc_stop_output(inst);
s_vpr_e(inst->sid, "%s: failed\n", __func__);
msm_venc_streamoff_output(inst);
return rc;
}
@@ -894,23 +902,13 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
struct msm_vidc_core *core;
struct v4l2_format *fmt;
d_vpr_h("%s()\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
if (inst->state == MSM_VIDC_START) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
if (f->type == INPUT_MPLANE) {
if (inst->state == MSM_VIDC_START_INPUT) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
fmt = &inst->fmts[INPUT_PORT];
fmt->type = INPUT_MPLANE;
fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
@@ -959,10 +957,6 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
//msm_vidc_update_batching(inst);
} else if (f->type == INPUT_META_PLANE) {
if (inst->state == MSM_VIDC_START_INPUT) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
fmt = &inst->fmts[INPUT_META_PORT];
fmt->type = INPUT_META_PLANE;
fmt->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
@@ -989,10 +983,6 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
inst->buffers.input_meta.min_count,
inst->buffers.input_meta.extra_count);
} else if (f->type == OUTPUT_MPLANE) {
if (inst->state == MSM_VIDC_START_OUTPUT) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
fmt = &inst->fmts[OUTPUT_PORT];
if (fmt->fmt.pix_mp.pixelformat != f->fmt.pix_mp.pixelformat) {
s_vpr_e(inst->sid,
@@ -1053,10 +1043,6 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
inst->buffers.output.min_count,
inst->buffers.output.extra_count);
} else if (f->type == OUTPUT_META_PLANE) {
if (inst->state == MSM_VIDC_START_OUTPUT) {
d_vpr_e("%s: invalid state %d\n", __func__, inst->state);
return -EINVAL;
}
fmt = &inst->fmts[OUTPUT_META_PORT];
fmt->type = OUTPUT_META_PLANE;
fmt->fmt.meta.dataformat = V4L2_META_FMT_VIDC;
@@ -1097,7 +1083,6 @@ int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
int rc = 0;
int port;
d_vpr_h("%s()\n", __func__);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
@@ -1265,3 +1250,16 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
return rc;
}
int msm_venc_inst_deinit(struct msm_vidc_inst *inst)
{
int rc = 0;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
rc = msm_vidc_ctrl_deinit(inst);
return rc;
}

View File

@@ -15,6 +15,7 @@
#include "msm_vidc_debug.h"
#include "msm_vidc_control.h"
#include "msm_vidc_power.h"
#include "venus_hfi_response.h"
#define MSM_VIDC_DRV_NAME "msm_vidc_driver"
/* kernel/msm-4.19 */
@@ -68,6 +69,10 @@ int msm_vidc_poll(void *instance, struct file *filp,
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
if (inst->state == MSM_VIDC_ERROR) {
s_vpr_e(inst->sid, "%s: inst in error state\n", __func__);
return -EINVAL;
}
poll_wait(filp, &inst->event_handler.wait, wait);
poll_wait(filp, &inst->vb2q[INPUT_META_PORT].done_wq, wait);
@@ -216,24 +221,8 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
return -EINVAL;
}
if (f->type == INPUT_MPLANE) {
if (inst->state != MSM_VIDC_OPEN &&
inst->state != MSM_VIDC_START_OUTPUT) {
s_vpr_e(inst->sid,
"%s: s_fmt(%d) not allowed in %d state\n",
__func__, f->type, inst->state);
return -EINVAL;
}
} else if (f->type == OUTPUT_MPLANE) {
if (inst->state != MSM_VIDC_OPEN &&
inst->state != MSM_VIDC_START_INPUT &&
inst->state != MSM_VIDC_DRAIN_START_INPUT) {
s_vpr_e(inst->sid,
"%s: s_fmt(%d) not allowed in %d state\n",
__func__, f->type, inst->state);
return -EINVAL;
}
}
if (!msm_vidc_allow_s_fmt(inst, f->type))
return -EBUSY;
if (inst->domain == MSM_VIDC_DECODER)
rc = msm_vdec_s_fmt(inst, f);
@@ -261,8 +250,18 @@ int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
rc = msm_vdec_g_fmt(inst, f);
if (inst->domain == MSM_VIDC_ENCODER)
rc = msm_venc_g_fmt(inst, f);
if (rc)
return rc;
return rc;
if (f->type == INPUT_MPLANE || f->type == OUTPUT_MPLANE)
s_vpr_h(inst->sid,
"%s: type %d format %#x width %d height %d size %d\n",
__func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width,
f->fmt.pix_mp.height, f->fmt.pix_mp.plane_fmt[0].sizeimage);
else if (f->type == INPUT_META_PLANE || f->type == OUTPUT_META_PLANE)
s_vpr_h(inst->sid, "%s: meta type %d size %d\n",
__func__, f->type, f->fmt.meta.buffersize);
return 0;
}
EXPORT_SYMBOL(msm_vidc_g_fmt);
@@ -273,6 +272,9 @@ int msm_vidc_s_ctrl(void *instance, struct v4l2_control *control)
if (!inst || !control)
return -EINVAL;
if (!msm_vidc_allow_s_ctrl(inst, control->id))
return -EBUSY;
return v4l2_s_ctrl(NULL, &inst->ctrl_handler, control);
}
EXPORT_SYMBOL(msm_vidc_s_ctrl);
@@ -316,25 +318,9 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
mutex_lock(&inst->lock);
if (b->type == INPUT_MPLANE) {
if (inst->state != MSM_VIDC_OPEN &&
inst->state != MSM_VIDC_START_OUTPUT) {
s_vpr_e(inst->sid,
"%s: reqbufs(%d) not allowed in %d state\n",
__func__, b->type, inst->state);
rc = -EINVAL;
goto unlock;
}
} else if (b->type == OUTPUT_MPLANE) {
if (inst->state != MSM_VIDC_OPEN &&
inst->state != MSM_VIDC_START_INPUT &&
inst->state != MSM_VIDC_DRAIN_START_INPUT) {
s_vpr_e(inst->sid,
"%s: reqbufs(%d) not allowed in %d state\n",
__func__, b->type, inst->state);
rc = -EINVAL;
goto unlock;
}
if (!msm_vidc_allow_reqbufs(inst, b->type)) {
rc = -EBUSY;
goto unlock;
}
port = v4l2_type_to_driver_port(inst, b->type, __func__);
@@ -370,22 +356,13 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev,
mutex_lock(&inst->lock);
if (inst->state == MSM_VIDC_ERROR) {
s_vpr_e(inst->sid, "%s: error state\n", __func__);
rc = -EINVAL;
if (!msm_vidc_allow_qbuf(inst)) {
rc = -EBUSY;
goto unlock;
}
if (b->type == INPUT_MPLANE) {
q = &inst->vb2q[INPUT_PORT];
} else if (b->type == OUTPUT_MPLANE) {
q = &inst->vb2q[OUTPUT_PORT];
} else if (b->type == INPUT_META_PLANE) {
q = &inst->vb2q[INPUT_META_PORT];
} else if (b->type == OUTPUT_META_PLANE) {
q = &inst->vb2q[OUTPUT_META_PORT];
} else {
s_vpr_e(inst->sid, "%s: invalid buffer type %d\n",
__func__, b->type);
q = msm_vidc_get_vb2q(inst, b->type, __func__);
if (!q) {
rc = -EINVAL;
goto unlock;
}
@@ -412,17 +389,9 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
}
mutex_lock(&inst->lock);
if (b->type == INPUT_MPLANE) {
q = &inst->vb2q[INPUT_PORT];
} else if (b->type == OUTPUT_MPLANE) {
q = &inst->vb2q[OUTPUT_PORT];
} else if (b->type == INPUT_META_PLANE) {
q = &inst->vb2q[INPUT_META_PORT];
} else if (b->type == OUTPUT_META_PLANE) {
q = &inst->vb2q[OUTPUT_META_PORT];
} else {
s_vpr_e(inst->sid, "%s: invalid buffer type %d\n",
__func__, b->type);
q = msm_vidc_get_vb2q(inst, b->type, __func__);
if (!q) {
rc = -EINVAL;
goto unlock;
}
@@ -445,7 +414,6 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type)
{
int rc = 0;
struct msm_vidc_inst *inst = instance;
enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR;
int port;
if (!inst) {
@@ -455,26 +423,13 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type)
mutex_lock(&inst->lock);
if (type == INPUT_MPLANE) {
if (inst->state != MSM_VIDC_OPEN &&
inst->state != MSM_VIDC_START_OUTPUT) {
s_vpr_e(inst->sid,
"%s: streamon(%d) not allowed in %d state\n",
__func__, type, inst->state);
rc = -EINVAL;
goto unlock;
}
} else if (type == OUTPUT_MPLANE) {
if (inst->state != MSM_VIDC_OPEN &&
inst->state != MSM_VIDC_START_INPUT &&
inst->state != MSM_VIDC_DRAIN_START_INPUT) {
s_vpr_e(inst->sid,
"%s: streamon(%d) not allowed in %d state\n",
__func__, type, inst->state);
rc = -EINVAL;
goto unlock;
}
if (!msm_vidc_allow_streamon(inst, type)) {
rc = -EBUSY;
goto unlock;
}
rc = msm_vidc_state_change_streamon(inst, type);
if (rc)
goto unlock;
port = v4l2_type_to_driver_port(inst, type, __func__);
if (port < 0) {
@@ -486,34 +441,10 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type)
if (rc) {
s_vpr_e(inst->sid, "%s: vb2_streamon(%d) failed, %d\n",
__func__, type, rc);
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
goto unlock;
}
if (type == INPUT_MPLANE) {
if (inst->state == MSM_VIDC_OPEN) {
new_state = MSM_VIDC_START_INPUT;
} else if (inst->state == MSM_VIDC_START_OUTPUT) {
new_state = MSM_VIDC_START;
}
rc = msm_vidc_change_inst_state(inst, new_state, __func__);
if (rc)
goto unlock;
} else if (type == OUTPUT_MPLANE) {
if (inst->state == MSM_VIDC_OPEN) {
new_state = MSM_VIDC_START_OUTPUT;
} else if (inst->state == MSM_VIDC_START_INPUT) {
new_state = MSM_VIDC_START;
} else if (inst->state == MSM_VIDC_DRAIN_START_INPUT) {
if (0 /* check if input port settings change pending */)
new_state = MSM_VIDC_DRC_DRAIN;
else
new_state = MSM_VIDC_DRAIN;
}
rc = msm_vidc_change_inst_state(inst, new_state, __func__);
if (rc)
goto unlock;
}
unlock:
mutex_unlock(&inst->lock);
return rc;
@@ -524,7 +455,6 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type)
{
int rc = 0;
struct msm_vidc_inst *inst = instance;
enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR;
int port;
if (!inst) {
@@ -534,25 +464,13 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type)
mutex_lock(&inst->lock);
if (type == INPUT_MPLANE) {
if (inst->state == MSM_VIDC_OPEN ||
inst->state == MSM_VIDC_START_OUTPUT) {
s_vpr_e(inst->sid,
"%s: streamoff(%d) not allowed in %d state\n",
__func__, type, inst->state);
rc = -EINVAL;
goto unlock;
}
} else if (type == OUTPUT_MPLANE) {
if (inst->state == MSM_VIDC_OPEN ||
inst->state == MSM_VIDC_START_INPUT) {
s_vpr_e(inst->sid,
"%s: streamoff(%d) not allowed in %d state\n",
__func__, type, inst->state);
rc = -EINVAL;
goto unlock;
}
if (!msm_vidc_allow_streamoff(inst, type)) {
rc = -EBUSY;
goto unlock;
}
rc = msm_vidc_state_change_streamoff(inst, type);
if (rc)
goto unlock;
port = v4l2_type_to_driver_port(inst, type, __func__);
if (port < 0) {
@@ -564,45 +482,10 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type)
if (rc) {
s_vpr_e(inst->sid, "%s: vb2_streamoff(%d) failed, %d\n",
__func__, type, rc);
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
goto unlock;
}
if (type == INPUT_MPLANE) {
if (inst->state == MSM_VIDC_START_INPUT) {
new_state = MSM_VIDC_OPEN;
} else if (inst->state == MSM_VIDC_START) {
new_state = MSM_VIDC_START_OUTPUT;
} else if (inst->state == MSM_VIDC_DRC ||
inst->state == MSM_VIDC_DRC_LAST_FLAG ||
inst->state == MSM_VIDC_DRAIN ||
inst->state == MSM_VIDC_DRAIN_LAST_FLAG ||
inst->state == MSM_VIDC_DRC_DRAIN ||
inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG ||
inst->state == MSM_VIDC_DRAIN_START_INPUT) {
new_state = MSM_VIDC_START_OUTPUT;
/* discard pending port settings change if any */
}
rc = msm_vidc_change_inst_state(inst, new_state, __func__);
if (rc)
goto unlock;
} else if (type == OUTPUT_MPLANE) {
if (inst->state == MSM_VIDC_START_OUTPUT) {
new_state = MSM_VIDC_OPEN;
} else if (inst->state == MSM_VIDC_START ||
inst->state == MSM_VIDC_DRAIN ||
inst->state == MSM_VIDC_DRAIN_LAST_FLAG ||
inst->state == MSM_VIDC_DRC ||
inst->state == MSM_VIDC_DRC_LAST_FLAG ||
inst->state == MSM_VIDC_DRC_DRAIN) {
new_state = MSM_VIDC_START_INPUT;
} else if (inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG) {
new_state = MSM_VIDC_DRAIN_START_INPUT;
}
rc = msm_vidc_change_inst_state(inst, new_state, __func__);
if (rc)
goto unlock;
}
unlock:
mutex_unlock(&inst->lock);
return rc;
@@ -740,8 +623,10 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
if (core->state == MSM_VIDC_CORE_DEINIT) {
rc = msm_vidc_core_init(core);
if (rc)
if (rc) {
msm_vidc_core_deinit(core);
return NULL;
}
}
inst = kzalloc(sizeof(*inst), GFP_KERNEL);
@@ -750,25 +635,34 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
return NULL;
}
inst->core = core;
kref_init(&inst->kref);
mutex_init(&inst->lock);
rc = msm_vidc_add_session(inst);
if (rc) {
d_vpr_e("%s: failed to get session id\n", __func__);
goto error;
}
s_vpr_i(inst->sid, "Opening video instance: %d\n", session_type);
inst->input_psc_workq = create_singlethread_workqueue("input_psc_workq");
if (!inst->input_psc_workq) {
d_vpr_e("%s: create input_psc_workq failed\n", __func__);
goto error;
}
inst->capabilities = kzalloc(
sizeof(struct msm_vidc_inst_capability), GFP_KERNEL);
if (!inst->capabilities) {
s_vpr_e(inst->sid,
"%s: inst capability allocation failed\n", __func__);
return NULL;
goto error;
}
rc = msm_vidc_add_session(inst);
if (rc) {
d_vpr_e("%s: failed to get session id\n", __func__);
return NULL;
}
INIT_DELAYED_WORK(&inst->input_psc_work,
handle_session_input_psc_work_handler);
s_vpr_i(inst->sid, "Opening video instance: %d\n", session_type);
kref_init(&inst->kref);
mutex_init(&inst->lock);
INIT_LIST_HEAD(&inst->input_psc_works);
INIT_LIST_HEAD(&inst->buffers.input.list);
INIT_LIST_HEAD(&inst->buffers.input_meta.list);
INIT_LIST_HEAD(&inst->buffers.output.list);
@@ -780,6 +674,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
INIT_LIST_HEAD(&inst->buffers.line.list);
INIT_LIST_HEAD(&inst->buffers.dpb.list);
INIT_LIST_HEAD(&inst->buffers.persist.list);
INIT_LIST_HEAD(&inst->buffers.vpss.list);
INIT_LIST_HEAD(&inst->allocations.bin.list);
INIT_LIST_HEAD(&inst->allocations.arp.list);
INIT_LIST_HEAD(&inst->allocations.comv.list);
@@ -787,6 +682,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
INIT_LIST_HEAD(&inst->allocations.line.list);
INIT_LIST_HEAD(&inst->allocations.dpb.list);
INIT_LIST_HEAD(&inst->allocations.persist.list);
INIT_LIST_HEAD(&inst->allocations.vpss.list);
INIT_LIST_HEAD(&inst->mappings.input.list);
INIT_LIST_HEAD(&inst->mappings.input_meta.list);
INIT_LIST_HEAD(&inst->mappings.output.list);
@@ -798,6 +694,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
INIT_LIST_HEAD(&inst->mappings.line.list);
INIT_LIST_HEAD(&inst->mappings.dpb.list);
INIT_LIST_HEAD(&inst->mappings.persist.list);
INIT_LIST_HEAD(&inst->mappings.vpss.list);
INIT_LIST_HEAD(&inst->children.list);
INIT_LIST_HEAD(&inst->firmware.list);
inst->domain = session_type;
@@ -812,21 +709,18 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
//inst->debugfs_root =
// msm_vidc_debugfs_init_inst(inst, core->debugfs_root);
if (is_decode_session(inst)) {
if (is_decode_session(inst))
rc = msm_vdec_inst_init(inst);
if (rc)
goto error;
} else if (is_encode_session(inst)) {
else if (is_encode_session(inst))
rc = msm_venc_inst_init(inst);
if (rc)
goto error;
}
if (rc)
goto error;
rc = msm_vidc_vb2_queue_init(inst);
if (rc)
goto error;
rc = msm_vidc_setup_event_queue(inst);
rc = msm_vidc_event_queue_init(inst);
if (rc)
goto error;
@@ -854,9 +748,12 @@ int msm_vidc_close(void *instance)
return -EINVAL;
}
s_vpr_h(inst->sid, "%s()\n", __func__);
mutex_lock(&inst->lock);
msm_vidc_session_close(inst);
msm_vidc_remove_session(inst);
msm_vidc_destroy_buffers(inst);
mutex_unlock(&inst->lock);
put_inst(inst);
return rc;
}
EXPORT_SYMBOL(msm_vidc_close);

View File

@@ -346,7 +346,7 @@ int msm_vidc_ctrl_deinit(struct msm_vidc_inst *inst)
d_vpr_e("%s: invalid parameters\n", __func__);
return -EINVAL;
}
s_vpr_h(inst->sid, "%s(): num ctrls %d\n", __func__, inst->num_ctrls);
v4l2_ctrl_handler_free(&inst->ctrl_handler);
kfree(inst->ctrls);
@@ -362,7 +362,6 @@ int msm_vidc_ctrl_init(struct msm_vidc_inst *inst)
struct v4l2_ctrl_config ctrl_cfg = {0};
int num_ctrls = 0, ctrl_idx = 0;
d_vpr_h("%s()\n", __func__);
if (!inst || !inst->core || !inst->capabilities) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
@@ -497,6 +496,7 @@ int msm_vidc_ctrl_init(struct msm_vidc_inst *inst)
ctrl_idx++;
}
inst->num_ctrls = num_ctrls;
s_vpr_h(inst->sid, "%s(): num ctrls %d\n", __func__, inst->num_ctrls);
return rc;
}

View File

@@ -14,8 +14,11 @@
#include "msm_vidc_memory.h"
#include "msm_vidc_debug.h"
#include "msm_vidc_power.h"
#include "venus_hfi.h"
#include "msm_vidc.h"
#include "msm_vdec.h"
#include "msm_venc.h"
#include "venus_hfi.h"
#include "venus_hfi_response.h"
#define COUNT_BITS(a, out) { \
while ((a) >= 1) { \
@@ -345,6 +348,8 @@ struct msm_vidc_buffers *msm_vidc_get_buffers(
return &inst->buffers.dpb;
case MSM_VIDC_BUF_PERSIST:
return &inst->buffers.persist;
case MSM_VIDC_BUF_VPSS:
return &inst->buffers.vpss;
default:
s_vpr_e(inst->sid, "%s: invalid driver buffer type %d\n",
func, buffer_type);
@@ -379,6 +384,8 @@ struct msm_vidc_mappings *msm_vidc_get_mappings(
return &inst->mappings.dpb;
case MSM_VIDC_BUF_PERSIST:
return &inst->mappings.persist;
case MSM_VIDC_BUF_VPSS:
return &inst->mappings.vpss;
default:
s_vpr_e(inst->sid, "%s: invalid driver buffer type %d\n",
func, buffer_type);
@@ -405,6 +412,8 @@ struct msm_vidc_allocations *msm_vidc_get_allocations(
return &inst->allocations.dpb;
case MSM_VIDC_BUF_PERSIST:
return &inst->allocations.persist;
case MSM_VIDC_BUF_VPSS:
return &inst->allocations.vpss;
default:
s_vpr_e(inst->sid, "%s: invalid driver buffer type %d\n",
func, buffer_type);
@@ -412,6 +421,55 @@ struct msm_vidc_allocations *msm_vidc_get_allocations(
}
}
const char *state_name(enum msm_vidc_inst_state state)
{
const char *name = "UNKNOWN";
switch (state) {
case MSM_VIDC_OPEN:
name = "OPEN";
break;
case MSM_VIDC_START_INPUT:
name = "START_INPUT";
break;
case MSM_VIDC_START_OUTPUT:
name = "START_OUTPUT";
break;
case MSM_VIDC_START:
name = "START";
break;
case MSM_VIDC_DRC:
name = "DRC";
break;
case MSM_VIDC_DRC_LAST_FLAG:
name = "DRC_LAST_FLAG";
break;
case MSM_VIDC_DRAIN:
name = "DRAIN";
break;
case MSM_VIDC_DRAIN_LAST_FLAG:
name = "DRAIN_LAST_FLAG";
break;
case MSM_VIDC_DRC_DRAIN:
name = "DRC_DRAIN";
break;
case MSM_VIDC_DRC_DRAIN_LAST_FLAG:
name = "DRC_DRAIN_LAST_FLAG";
break;
case MSM_VIDC_DRAIN_START_INPUT:
name = "DRAIN_START_INPUT";
break;
case MSM_VIDC_ERROR:
name = "ERROR";
break;
default:
name = "UNKNOWN";
break;
}
return name;
}
int msm_vidc_change_inst_state(struct msm_vidc_inst *inst,
enum msm_vidc_inst_state request_state, const char *func)
{
@@ -427,17 +485,531 @@ int msm_vidc_change_inst_state(struct msm_vidc_inst *inst,
if (inst->state == MSM_VIDC_ERROR) {
s_vpr_h(inst->sid,
"%s: inst is in bad state, can not change state to %d\n",
func, request_state);
"%s: inst is in bad state, can not change state to %s\n",
func, state_name(request_state));
return 0;
}
s_vpr_h(inst->sid, "%s: state changed from %d to %d\n",
func, inst->state, request_state);
s_vpr_h(inst->sid, "%s: state changed from %s to %s\n",
func, state_name(inst->state), state_name(request_state));
inst->state = request_state;
return 0;
}
bool msm_vidc_allow_s_fmt(struct msm_vidc_inst *inst, u32 type)
{
bool allow = false;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return false;
}
if (inst->state == MSM_VIDC_OPEN) {
allow = true;
goto exit;
}
if (inst->state == MSM_VIDC_START_INPUT) {
if (type == OUTPUT_MPLANE || type == OUTPUT_META_PLANE) {
allow = true;
goto exit;
}
}
if (inst->state == MSM_VIDC_START_OUTPUT) {
if (type == INPUT_MPLANE || type == INPUT_META_PLANE) {
allow = true;
goto exit;
}
}
exit:
if (!allow)
s_vpr_e(inst->sid, "%s: type %d not allowed in state %s\n",
__func__, type, state_name(inst->state));
return allow;
}
bool msm_vidc_allow_s_ctrl(struct msm_vidc_inst *inst, u32 id)
{
bool allow = false;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return false;
}
if (inst->state == MSM_VIDC_OPEN) {
allow = true;
goto exit;
}
if (inst->state == MSM_VIDC_START || inst->state == MSM_VIDC_START_OUTPUT) {
switch (id) {
case V4L2_CID_MPEG_VIDEO_BITRATE:
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
case V4L2_CID_HFLIP:
case V4L2_CID_VFLIP:
case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:
case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER:
case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR:
case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR:
case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR:
case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR:
case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR:
case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR:
case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR:
case V4L2_CID_MPEG_VIDC_BASELAYER_PRIORITY:
case V4L2_CID_MPEG_VIDC_USELTRFRAME:
case V4L2_CID_MPEG_VIDC_MARKLTRFRAME:
case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_TYPES:
case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_RESOLUTION:
allow = true;
break;
default:
allow = false;
break;
}
}
exit:
if (!allow)
s_vpr_e(inst->sid, "%s: id %d not allowed in state %s\n",
__func__, id, state_name(inst->state));
return allow;
}
bool msm_vidc_allow_reqbufs(struct msm_vidc_inst *inst, u32 type)
{
bool allow = false;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return false;
}
if (inst->state == MSM_VIDC_OPEN) {
allow = true;
goto exit;
}
if (inst->state == MSM_VIDC_START_INPUT) {
if (type == OUTPUT_MPLANE || type == OUTPUT_META_PLANE) {
allow = true;
goto exit;
}
}
if (inst->state == MSM_VIDC_START_OUTPUT) {
if (type == INPUT_MPLANE || type == INPUT_META_PLANE) {
allow = true;
goto exit;
}
}
exit:
if (!allow)
s_vpr_e(inst->sid, "%s: type %d not allowed in state %s\n",
__func__, type, state_name(inst->state));
return allow;
}
bool msm_vidc_allow_stop(struct msm_vidc_inst *inst)
{
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return false;
}
if (inst->state == MSM_VIDC_START ||
inst->state == MSM_VIDC_DRC ||
inst->state == MSM_VIDC_DRC_LAST_FLAG ||
inst->state == MSM_VIDC_DRC_DRAIN)
return true;
s_vpr_e(inst->sid, "%s: not allowed in state %s\n",
__func__, state_name(inst->state));
return false;
}
bool msm_vidc_allow_start(struct msm_vidc_inst *inst)
{
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return false;
}
if (inst->state == MSM_VIDC_DRAIN_LAST_FLAG ||
inst->state == MSM_VIDC_DRC_LAST_FLAG ||
inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG)
return true;
s_vpr_e(inst->sid, "%s: not allowed in state %s\n",
__func__, state_name(inst->state));
return false;
}
bool msm_vidc_allow_streamon(struct msm_vidc_inst *inst, u32 type)
{
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return false;
}
if (type == INPUT_MPLANE || type == INPUT_META_PLANE) {
if (inst->state == MSM_VIDC_OPEN ||
inst->state == MSM_VIDC_START_OUTPUT)
return true;
} else if (type == OUTPUT_MPLANE || type == OUTPUT_META_PLANE) {
if (inst->state == MSM_VIDC_OPEN ||
inst->state == MSM_VIDC_START_INPUT ||
inst->state == MSM_VIDC_DRAIN_START_INPUT)
return true;
}
s_vpr_e(inst->sid, "%s: type %d not allowed in state %s\n",
__func__, type, state_name(inst->state));
return false;
}
bool msm_vidc_allow_streamoff(struct msm_vidc_inst *inst, u32 type)
{
bool allow = true;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return false;
}
if (type == INPUT_MPLANE || type == INPUT_META_PLANE) {
if (inst->state == MSM_VIDC_OPEN ||
inst->state == MSM_VIDC_START_OUTPUT)
allow = false;
} else if (type == OUTPUT_MPLANE || type == OUTPUT_META_PLANE) {
if (inst->state == MSM_VIDC_OPEN ||
inst->state == MSM_VIDC_START_INPUT)
allow = false;
}
if (!allow)
s_vpr_e(inst->sid, "%s: type %d not allowed in state %s\n",
__func__, type, state_name(inst->state));
return allow;
}
bool msm_vidc_allow_qbuf(struct msm_vidc_inst *inst)
{
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return false;
}
if (inst->state == MSM_VIDC_ERROR) {
s_vpr_e(inst->sid, "%s: inst in error state\n", __func__);
return false;
} else {
return true;
}
}
int msm_vidc_allow_input_psc(struct msm_vidc_inst *inst)
{
int rc = 0;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
if (inst->state == MSM_VIDC_START ||
inst->state == MSM_VIDC_START_INPUT ||
inst->state == MSM_VIDC_DRAIN) {
rc = 0;
} else if (inst->state == MSM_VIDC_DRC ||
inst->state == MSM_VIDC_DRC_LAST_FLAG ||
inst->state == MSM_VIDC_DRC_DRAIN ||
inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG ||
inst->state == MSM_VIDC_DRAIN_START_INPUT) {
s_vpr_h(inst->sid, "%s: input psc postponed, inst state %s\n",
__func__, state_name(inst->state));
rc = -EAGAIN;
} else {
s_vpr_e(inst->sid, "%s: input psc in wrong state %s\n",
__func__, state_name(inst->state));
rc = -EINVAL;
}
return rc;
}
bool msm_vidc_allow_last_flag(struct msm_vidc_inst *inst)
{
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return false;
}
if (inst->state == MSM_VIDC_DRC ||
inst->state == MSM_VIDC_DRAIN ||
inst->state == MSM_VIDC_DRC_DRAIN)
return true;
s_vpr_e(inst->sid, "%s: not allowed in state %s\n",
__func__, state_name(inst->state));
return false;
}
int msm_vidc_state_change_streamon(struct msm_vidc_inst *inst, u32 type)
{
int rc = 0;
enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR;
struct input_psc_work *psc_work;
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
if (type == INPUT_MPLANE) {
if (inst->state == MSM_VIDC_OPEN)
new_state = MSM_VIDC_START_INPUT;
else if (inst->state == MSM_VIDC_START_OUTPUT)
new_state = MSM_VIDC_START;
} else if (type == OUTPUT_MPLANE) {
if (inst->state == MSM_VIDC_OPEN) {
new_state = MSM_VIDC_START_OUTPUT;
} else if (inst->state == MSM_VIDC_START_INPUT) {
new_state = MSM_VIDC_START;
} else if (inst->state == MSM_VIDC_DRAIN_START_INPUT) {
s_vpr_h(inst->sid,
"%s: streamon(output) in DRAIN_START_INPUT state\n",
__func__);
if (list_empty(&inst->input_psc_works)) {
new_state = MSM_VIDC_DRAIN;
} else {
s_vpr_h(inst->sid,
"%s: streamon(output) in DRAIN_START_INPUT state, input psc pending\n",
__func__);
psc_work = list_first_entry(&inst->input_psc_works,
struct input_psc_work, list);
rc = handle_session_input_psc(inst, psc_work);
if (rc) {
s_vpr_e(inst->sid,
"%s: handle input psc failed\n", __func__);
new_state = MSM_VIDC_ERROR;
} else {
new_state = MSM_VIDC_DRC_DRAIN;
}
list_del(&psc_work->list);
kfree(psc_work->data);
kfree(psc_work);
}
}
}
rc = msm_vidc_change_inst_state(inst, new_state, __func__);
if (rc)
return rc;
return rc;
}
int msm_vidc_state_change_streamoff(struct msm_vidc_inst *inst, u32 type)
{
int rc = 0;
enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR;
struct input_psc_work *psc_work, *dummy;
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
if (type == INPUT_MPLANE) {
if (inst->state == MSM_VIDC_START_INPUT) {
new_state = MSM_VIDC_OPEN;
} else if (inst->state == MSM_VIDC_START) {
new_state = MSM_VIDC_START_OUTPUT;
} else if (inst->state == MSM_VIDC_DRC ||
inst->state == MSM_VIDC_DRC_LAST_FLAG ||
inst->state == MSM_VIDC_DRAIN ||
inst->state == MSM_VIDC_DRAIN_LAST_FLAG ||
inst->state == MSM_VIDC_DRC_DRAIN ||
inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG ||
inst->state == MSM_VIDC_DRAIN_START_INPUT) {
new_state = MSM_VIDC_START_OUTPUT;
/* discard pending port settings change if any */
list_for_each_entry_safe(psc_work, dummy,
&inst->input_psc_works, list) {
s_vpr_h(inst->sid,
"%s: discard pending input psc\n", __func__);
list_del(&psc_work->list);
kfree(psc_work->data);
kfree(psc_work);
}
}
} else if (type == OUTPUT_MPLANE) {
if (inst->state == MSM_VIDC_START_OUTPUT) {
new_state = MSM_VIDC_OPEN;
} else if (inst->state == MSM_VIDC_START ||
inst->state == MSM_VIDC_DRAIN ||
inst->state == MSM_VIDC_DRAIN_LAST_FLAG ||
inst->state == MSM_VIDC_DRC ||
inst->state == MSM_VIDC_DRC_LAST_FLAG ||
inst->state == MSM_VIDC_DRC_DRAIN) {
new_state = MSM_VIDC_START_INPUT;
} else if (inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG) {
new_state = MSM_VIDC_DRAIN_START_INPUT;
}
}
rc = msm_vidc_change_inst_state(inst, new_state, __func__);
if (rc)
goto exit;
exit:
return rc;
}
int msm_vidc_state_change_stop(struct msm_vidc_inst *inst)
{
int rc = 0;
enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR;
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
if (inst->state == MSM_VIDC_START) {
new_state = MSM_VIDC_DRAIN;
} else if (inst->state == MSM_VIDC_DRC) {
new_state = MSM_VIDC_DRC_DRAIN;
} else if (inst->state == MSM_VIDC_DRC_DRAIN ||
inst->state == MSM_VIDC_DRC_LAST_FLAG) {
new_state = MSM_VIDC_DRC_DRAIN_LAST_FLAG;
} else {
s_vpr_e(inst->sid, "%s: wrong state %s\n",
__func__, state_name(inst->state));
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
return -EINVAL;
}
rc = msm_vidc_change_inst_state(inst, new_state, __func__);
if (rc)
return rc;
return rc;
}
int msm_vidc_state_change_start(struct msm_vidc_inst *inst)
{
int rc = 0;
enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR;
struct input_psc_work *psc_work;
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
if (inst->state == MSM_VIDC_DRAIN_LAST_FLAG ||
inst->state == MSM_VIDC_DRC_LAST_FLAG) {
if (list_empty(&inst->input_psc_works)) {
new_state = MSM_VIDC_START;
} else {
s_vpr_h(inst->sid,
"%s: start in DRC(DRAIN)_LAST_FLAG state, input psc pending\n",
__func__);
psc_work = list_first_entry(&inst->input_psc_works,
struct input_psc_work, list);
rc = handle_session_input_psc(inst, psc_work);
if (rc) {
s_vpr_e(inst->sid,
"%s: handle input psc failed\n", __func__);
new_state = MSM_VIDC_ERROR;
} else {
new_state = MSM_VIDC_DRC;
}
list_del(&psc_work->list);
kfree(psc_work->data);
kfree(psc_work);
}
} else if (inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG) {
if (list_empty(&inst->input_psc_works)) {
new_state = MSM_VIDC_DRAIN;
} else {
s_vpr_h(inst->sid,
"%s: start in DRC_DRAIN_LAST_FLAG state, input psc pending\n");
psc_work = list_first_entry(&inst->input_psc_works,
struct input_psc_work, list);
rc = handle_session_input_psc(inst, psc_work);
if (rc) {
s_vpr_e(inst->sid,
"%s: handle input psc failed\n", __func__);
new_state = MSM_VIDC_ERROR;
} else {
new_state = MSM_VIDC_DRC_DRAIN;
}
list_del(&psc_work->list);
kfree(psc_work->data);
kfree(psc_work);
}
} else {
s_vpr_e(inst->sid, "%s: wrong state %s\n",
__func__, state_name(inst->state));
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
return -EINVAL;
}
rc = msm_vidc_change_inst_state(inst, new_state, __func__);
if (rc)
return rc;
return rc;
}
int msm_vidc_state_change_input_psc(struct msm_vidc_inst *inst)
{
int rc = 0;
enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR;
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
/* don't change state as output port is not started yet */
if (inst->state == MSM_VIDC_START_INPUT)
return 0;
if (inst->state == MSM_VIDC_START) {
new_state = MSM_VIDC_DRC;
} else if (inst->state == MSM_VIDC_DRAIN) {
new_state = MSM_VIDC_DRC_DRAIN;
} else {
s_vpr_e(inst->sid, "%s: wrong state %s\n",
__func__, state_name(inst->state));
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
return -EINVAL;
}
rc = msm_vidc_change_inst_state(inst, new_state, __func__);
if (rc)
return rc;
return rc;
}
int msm_vidc_state_change_last_flag(struct msm_vidc_inst *inst)
{
int rc = 0;
enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR;
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
if (inst->state == MSM_VIDC_DRC) {
new_state = MSM_VIDC_DRC_LAST_FLAG;
} else if (inst->state == MSM_VIDC_DRAIN) {
new_state = MSM_VIDC_DRAIN_LAST_FLAG;
} else if (inst->state == MSM_VIDC_DRC_DRAIN) {
new_state = MSM_VIDC_DRC_DRAIN_LAST_FLAG;
} else {
s_vpr_e(inst->sid, "%s: wrong state %s\n",
__func__, state_name(inst->state));
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
return -EINVAL;
}
rc = msm_vidc_change_inst_state(inst, new_state, __func__);
if (rc)
return rc;
return rc;
}
int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
{
int rc = 0;
@@ -602,10 +1174,6 @@ int msm_vidc_put_driver_buf(struct msm_vidc_inst *inst,
return -EINVAL;
}
/* do not unmap / delete read only buffer */
if (buf->attr & MSM_VIDC_ATTR_READ_ONLY)
return 0;
rc = msm_vidc_unmap_driver_buf(inst, buf);
if (rc)
return rc;
@@ -1218,20 +1786,18 @@ int msm_vidc_vb2_buffer_done(struct msm_vidc_inst *inst,
return 0;
}
int msm_vidc_setup_event_queue(struct msm_vidc_inst *inst)
int msm_vidc_event_queue_init(struct msm_vidc_inst *inst)
{
int rc = 0;
int index;
struct msm_vidc_core *core;
d_vpr_h("%s()\n", __func__);
if (!inst || !inst->core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
core = inst->core;
// TODO: check decode is index = 0 and encode is index 1
if (is_decode_session(inst))
index = 0;
else if (is_encode_session(inst))
@@ -1245,9 +1811,25 @@ int msm_vidc_setup_event_queue(struct msm_vidc_inst *inst)
return rc;
}
int msm_vidc_event_queue_deinit(struct msm_vidc_inst *inst)
{
int rc = 0;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
v4l2_fh_del(&inst->event_handler);
v4l2_fh_exit(&inst->event_handler);
return rc;
}
static int vb2q_init(struct msm_vidc_inst *inst,
struct vb2_queue *q, enum v4l2_buf_type type)
{
int rc = 0;
struct msm_vidc_core *core;
if (!inst || !q || !inst->core) {
@@ -1264,14 +1846,17 @@ static int vb2q_init(struct msm_vidc_inst *inst,
q->drv_priv = inst;
q->allow_zero_bytesused = 1;
q->copy_timestamp = 1;
return vb2_queue_init(q);
rc = vb2_queue_init(q);
if (rc)
s_vpr_e(inst->sid, "%s: vb2_queue_init failed for type %d\n",
__func__, type);
return rc;
}
int msm_vidc_vb2_queue_init(struct msm_vidc_inst *inst)
{
int rc = 0;
d_vpr_h("%s()\n", __func__);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
@@ -1296,6 +1881,22 @@ int msm_vidc_vb2_queue_init(struct msm_vidc_inst *inst)
return rc;
}
int msm_vidc_vb2_queue_deinit(struct msm_vidc_inst *inst)
{
int rc = 0;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
vb2_queue_release(&inst->vb2q[OUTPUT_META_PORT]);
vb2_queue_release(&inst->vb2q[INPUT_META_PORT]);
vb2_queue_release(&inst->vb2q[OUTPUT_PORT]);
vb2_queue_release(&inst->vb2q[INPUT_PORT]);
return rc;
}
int msm_vidc_add_session(struct msm_vidc_inst *inst)
{
int rc = 0;
@@ -1388,7 +1989,7 @@ int msm_vidc_session_set_codec(struct msm_vidc_inst *inst)
return 0;
}
int msm_vidc_session_start(struct msm_vidc_inst* inst,
int msm_vidc_session_streamon(struct msm_vidc_inst *inst,
enum msm_vidc_port_type port)
{
int rc = 0;
@@ -1407,7 +2008,7 @@ int msm_vidc_session_start(struct msm_vidc_inst* inst,
return rc;
}
int msm_vidc_session_stop(struct msm_vidc_inst *inst,
int msm_vidc_session_streamoff(struct msm_vidc_inst *inst,
enum msm_vidc_port_type port)
{
int rc = 0;
@@ -1433,9 +2034,9 @@ int msm_vidc_session_stop(struct msm_vidc_inst *inst,
return rc;
core = inst->core;
mutex_unlock(&inst->lock);
s_vpr_h(inst->sid, "%s: wait on port: %d for time: %d ms\n",
__func__, port, core->capabilities[HW_RESPONSE_TIMEOUT].value);
mutex_unlock(&inst->lock);
rc = wait_for_completion_timeout(
&inst->completions[signal_type],
msecs_to_jiffies(
@@ -1472,10 +2073,12 @@ int msm_vidc_session_close(struct msm_vidc_inst *inst)
core = inst->core;
s_vpr_h(inst->sid, "%s: wait on close for time: %d ms\n",
__func__, core->capabilities[HW_RESPONSE_TIMEOUT].value);
mutex_unlock(&inst->lock);
rc = wait_for_completion_timeout(
&inst->completions[SIGNAL_CMD_CLOSE],
msecs_to_jiffies(
core->capabilities[HW_RESPONSE_TIMEOUT].value));
mutex_lock(&inst->lock);
if (!rc) {
s_vpr_e(inst->sid, "%s: session close timed out\n", __func__);
//msm_comm_kill_session(inst);
@@ -1519,6 +2122,20 @@ int msm_vidc_get_inst_capability(struct msm_vidc_inst *inst)
return rc;
}
static int msm_vidc_deinit_core_caps(struct msm_vidc_core *core)
{
int rc = 0;
if (!core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
kfree(core->capabilities);
core->capabilities = NULL;
return rc;
}
static int msm_vidc_init_core_caps(struct msm_vidc_core *core)
{
int rc = 0;
@@ -1563,6 +2180,8 @@ static int msm_vidc_init_core_caps(struct msm_vidc_core *core)
}
exit:
if (rc)
msm_vidc_deinit_core_caps(core);
return rc;
}
@@ -1595,6 +2214,20 @@ static void update_inst_capability(struct msm_platform_inst_capability *in,
}
}
static int msm_vidc_deinit_instance_caps(struct msm_vidc_core *core)
{
int rc = 0;
if (!core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
kfree(core->inst_caps);
core->inst_caps = NULL;
return rc;
}
static int msm_vidc_init_instance_caps(struct msm_vidc_core *core)
{
int rc = 0;
@@ -1607,7 +2240,7 @@ static int msm_vidc_init_instance_caps(struct msm_vidc_core *core)
if (!core || !core->platform || !core->capabilities) {
d_vpr_e("%s: invalid params\n", __func__);
rc = -EINVAL;
goto exit;
goto error;
}
platform_data = core->platform->data.instance_data;
@@ -1615,7 +2248,7 @@ static int msm_vidc_init_instance_caps(struct msm_vidc_core *core)
d_vpr_e("%s: platform instance data is NULL\n",
__func__);
rc = -EINVAL;
goto exit;
goto error;
}
enc_valid_codecs = core->capabilities[ENC_CODECS].value;
@@ -1637,7 +2270,7 @@ static int msm_vidc_init_instance_caps(struct msm_vidc_core *core)
d_vpr_e("%s: failed to allocate core capabilities\n",
__func__);
rc = -ENOMEM;
goto exit;
goto error;
}
} else {
d_vpr_e("%s: capabilities memory is expected to be freed\n",
@@ -1692,7 +2325,28 @@ static int msm_vidc_init_instance_caps(struct msm_vidc_core *core)
}
}
}
exit:
return 0;
error:
if (rc)
msm_vidc_deinit_instance_caps(core);
return rc;
}
int msm_vidc_core_deinit(struct msm_vidc_core *core)
{
int rc = 0;
d_vpr_h("%s()\n", __func__);
if (!core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
mutex_lock(&core->lock);
venus_hfi_core_deinit(core);
msm_vidc_deinit_instance_caps(core);
msm_vidc_deinit_core_caps(core);
mutex_unlock(&core->lock);
return rc;
}
@@ -1736,16 +2390,14 @@ int msm_vidc_core_init(struct msm_vidc_core *core)
goto unlock;
}
mutex_unlock(&core->lock);
/*TODO: acquire lock or not */
d_vpr_h("%s(): waiting for sys init done, %d ms\n", __func__,
core->capabilities[HW_RESPONSE_TIMEOUT].value);
mutex_unlock(&core->lock);
rc = wait_for_completion_timeout(&core->init_done, msecs_to_jiffies(
core->capabilities[HW_RESPONSE_TIMEOUT].value));
if (!rc) {
d_vpr_e("%s: system init timed out\n", __func__);
//msm_comm_kill_session(inst);
//rc = -EIO;
rc = -ETIMEDOUT;
} else {
d_vpr_h("%s: system init wait completed\n", __func__);
rc = 0;
@@ -1785,6 +2437,82 @@ void msm_vidc_batch_handler(struct work_struct *work)
{
}
void msm_vidc_destroy_buffers(struct msm_vidc_inst *inst)
{
struct msm_vidc_buffers *buffers;
struct msm_vidc_buffer *buf, *dummy;
enum msm_vidc_buffer_type buf_types[] = {
MSM_VIDC_BUF_INPUT,
MSM_VIDC_BUF_OUTPUT,
MSM_VIDC_BUF_INPUT_META,
MSM_VIDC_BUF_OUTPUT_META,
MSM_VIDC_BUF_BIN,
MSM_VIDC_BUF_ARP,
MSM_VIDC_BUF_COMV,
MSM_VIDC_BUF_NON_COMV,
MSM_VIDC_BUF_LINE,
MSM_VIDC_BUF_DPB,
MSM_VIDC_BUF_PERSIST,
MSM_VIDC_BUF_VPSS,
};
int i;
for (i = 0; i < ARRAY_SIZE(buf_types); i++) {
buffers = msm_vidc_get_buffers(inst, buf_types[i], __func__);
if (!buffers)
continue;
list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
s_vpr_e(inst->sid,
"destroying buffer: type %d idx %d fd %d addr %#x size %d\n",
buf->type, buf->index, buf->fd, buf->device_addr, buf->buffer_size);
if (is_internal_buffer(buf->type))
msm_vidc_destroy_internal_buffer(inst, buf);
else
msm_vidc_put_driver_buf(inst, buf);
}
}
}
static void msm_vidc_close_helper(struct kref *kref)
{
struct msm_vidc_inst *inst = container_of(kref,
struct msm_vidc_inst, kref);
s_vpr_h(inst->sid, "%s()\n", __func__);
msm_vidc_event_queue_deinit(inst);
msm_vidc_vb2_queue_deinit(inst);
if (is_decode_session(inst))
msm_vdec_inst_deinit(inst);
else if (is_encode_session(inst))
msm_venc_inst_deinit(inst);
kfree(inst->capabilities);
if (inst->input_psc_workq)
destroy_workqueue(inst->input_psc_workq);
}
struct msm_vidc_inst *get_inst_ref(struct msm_vidc_core *core,
struct msm_vidc_inst *instance)
{
struct msm_vidc_inst *inst = NULL;
bool matches = false;
if (!core) {
d_vpr_e("%s: invalid params\n", __func__);
return NULL;
}
mutex_lock(&core->lock);
list_for_each_entry(inst, &core->instances, list) {
if (inst == instance) {
matches = true;
break;
}
}
inst = (matches && kref_get_unless_zero(&inst->kref)) ? inst : NULL;
mutex_unlock(&core->lock);
return inst;
}
struct msm_vidc_inst *get_inst(struct msm_vidc_core *core,
u32 session_id)
{
@@ -1808,14 +2536,6 @@ struct msm_vidc_inst *get_inst(struct msm_vidc_core *core,
return inst;
}
static void put_inst_helper(struct kref *kref)
{
struct msm_vidc_inst *inst = container_of(kref,
struct msm_vidc_inst, kref);
msm_vidc_close(inst);
}
void put_inst(struct msm_vidc_inst *inst)
{
if (!inst) {
@@ -1823,7 +2543,7 @@ void put_inst(struct msm_vidc_inst *inst)
return;
}
kref_put(&inst->kref, put_inst_helper);
kref_put(&inst->kref, msm_vidc_close_helper);
}
void core_lock(struct msm_vidc_core *core, const char *function)

View File

@@ -20,6 +20,8 @@
#define BASE_DEVICE_NUMBER 32
struct msm_vidc_core *g_core;
static int msm_vidc_deinit_irq(struct msm_vidc_core *core)
{
struct msm_vidc_dt *dt;
@@ -214,25 +216,15 @@ static int msm_vidc_initialize_core(struct msm_vidc_core *core)
goto exit;
}
core->inst_workq = create_singlethread_workqueue("inst_workq");
if (!core->inst_workq) {
d_vpr_e("%s: create workq failed\n", __func__);
destroy_workqueue(core->inst_workq);
rc = -EINVAL;
goto exit;
}
mutex_init(&core->lock);
INIT_LIST_HEAD(&core->instances);
INIT_LIST_HEAD(&core->dangling_instances);
INIT_LIST_HEAD(&core->inst_works);
INIT_WORK(&core->device_work, venus_hfi_work_handler);
INIT_DELAYED_WORK(&core->pm_work, venus_hfi_pm_work_handler);
INIT_DELAYED_WORK(&core->fw_unload_work, msm_vidc_fw_unload_handler);
INIT_DELAYED_WORK(&core->batch_work, msm_vidc_batch_handler);
INIT_WORK(&core->ssr_work, msm_vidc_ssr_handler);
INIT_DELAYED_WORK(&core->inst_work, venus_hfi_inst_work_handler);
exit:
return rc;
@@ -249,6 +241,7 @@ static int msm_vidc_probe_video_device(struct platform_device *pdev)
core = kzalloc(sizeof(*core), GFP_KERNEL);
if (!core)
return -ENOMEM;
g_core = core;
core->pdev = pdev;
dev_set_drvdata(&pdev->dev, core);
@@ -379,6 +372,7 @@ static int msm_vidc_remove(struct platform_device *pdev)
msm_vidc_deinitialize_core(core);
dev_set_drvdata(&pdev->dev, NULL);
kfree(core);
g_core = NULL;
return 0;
}

View File

@@ -13,6 +13,30 @@
#include "msm_vidc_debug.h"
#include "msm_vidc_control.h"
struct vb2_queue *msm_vidc_get_vb2q(struct msm_vidc_inst *inst,
u32 type, const char *func)
{
struct vb2_queue *q = NULL;
if (!inst) {
d_vpr_e("%s: invalid buffer type %d\n", func);
return NULL;
}
if (type == INPUT_MPLANE) {
q = &inst->vb2q[INPUT_PORT];
} else if (type == OUTPUT_MPLANE) {
q = &inst->vb2q[OUTPUT_PORT];
} else if (type == INPUT_META_PLANE) {
q = &inst->vb2q[INPUT_META_PORT];
} else if (type == OUTPUT_META_PLANE) {
q = &inst->vb2q[OUTPUT_META_PORT];
} else {
s_vpr_e(inst->sid, "%s: invalid buffer type %d\n",
__func__, type);
}
return q;
}
void *msm_vb2_get_userptr(struct device *dev, unsigned long vaddr,
unsigned long size, enum dma_data_direction dma_dir)
{
@@ -72,12 +96,6 @@ int msm_vidc_queue_setup(struct vb2_queue *q,
return -EINVAL;
if (port == INPUT_PORT) {
if (inst->state == MSM_VIDC_START_INPUT) {
d_vpr_e("%s: input invalid state %d\n",
__func__, inst->state);
return -EINVAL;
}
*num_planes = 1;
if (*num_buffers < inst->buffers.input.min_count +
inst->buffers.input.extra_count)
@@ -86,12 +104,6 @@ int msm_vidc_queue_setup(struct vb2_queue *q,
inst->buffers.input.actual_count = *num_buffers;
} else if (port == INPUT_META_PORT) {
if (inst->state == MSM_VIDC_START_INPUT) {
d_vpr_e("%s: input_meta invalid state %d\n",
__func__, inst->state);
return -EINVAL;
}
*num_planes = 1;
if (*num_buffers < inst->buffers.input_meta.min_count +
inst->buffers.input_meta.extra_count)
@@ -100,12 +112,6 @@ int msm_vidc_queue_setup(struct vb2_queue *q,
inst->buffers.input_meta.actual_count = *num_buffers;
} else if (port == OUTPUT_PORT) {
if (inst->state == MSM_VIDC_START_OUTPUT) {
d_vpr_e("%s: output invalid state %d\n",
__func__, inst->state);
return -EINVAL;
}
*num_planes = 1;
if (*num_buffers < inst->buffers.output.min_count +
inst->buffers.output.extra_count)
@@ -114,12 +120,6 @@ int msm_vidc_queue_setup(struct vb2_queue *q,
inst->buffers.output.actual_count = *num_buffers;
} else if (port == OUTPUT_META_PORT) {
if (inst->state == MSM_VIDC_START_OUTPUT) {
d_vpr_e("%s: output_meta invalid state %d\n",
__func__, inst->state);
return -EINVAL;
}
*num_planes = 1;
if (*num_buffers < inst->buffers.output_meta.min_count +
inst->buffers.output_meta.extra_count)
@@ -174,26 +174,29 @@ int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count)
if (q->type == INPUT_MPLANE) {
if (is_decode_session(inst))
rc = msm_vdec_start_input(inst);
rc = msm_vdec_streamon_input(inst);
else if (is_encode_session(inst))
rc = msm_venc_start_input(inst);
rc = msm_venc_streamon_input(inst);
else
goto error;
} else if (q->type == OUTPUT_MPLANE) {
if (is_decode_session(inst))
rc = msm_vdec_start_output(inst);
rc = msm_vdec_streamon_output(inst);
else if (is_encode_session(inst))
rc = msm_venc_start_output(inst);
rc = msm_venc_streamon_output(inst);
else
goto error;
} else {
s_vpr_e(inst->sid, "%s: invalid type %d\n", q->type);
goto error;
}
if (!rc)
s_vpr_h(inst->sid, "Streamon: %d successful\n", q->type);
return rc;
error:
s_vpr_e(inst->sid, "%s: invalid session/qtype, qtype %d\n", __func__, q->type);
s_vpr_h(inst->sid, "Streamon: %d failed\n", q->type);
return -EINVAL;
}
@@ -225,30 +228,29 @@ void msm_vidc_stop_streaming(struct vb2_queue *q)
if (q->type == INPUT_MPLANE) {
if (is_decode_session(inst))
rc = msm_vdec_stop_input(inst);
rc = msm_vdec_streamoff_input(inst);
else if (is_encode_session(inst))
rc = msm_venc_stop_input(inst);
rc = msm_venc_streamoff_input(inst);
else
goto error;
} else if (q->type == OUTPUT_MPLANE) {
if (is_decode_session(inst))
rc = msm_vdec_stop_output(inst);
rc = msm_vdec_streamoff_output(inst);
else if (is_encode_session(inst))
rc = msm_venc_stop_output(inst);
rc = msm_venc_streamoff_output(inst);
else
goto error;
} else {
s_vpr_e(inst->sid, "%s: invalid type %d\n", q->type);
goto error;
}
if (rc)
s_vpr_e(inst->sid, "%s: stop failed for qtype: %d\n",
__func__, q->type);
if (!rc)
s_vpr_h(inst->sid, "Streamoff: %d successful\n", q->type);
return;
error:
s_vpr_e(inst->sid, "%s: invalid session/qtype, qtype: %d\n",
__func__, q->type);
s_vpr_e(inst->sid, "Streamoff: %d failed\n", q->type);
return;
}

View File

@@ -2080,7 +2080,7 @@ static void __set_queue_hdr_defaults(struct hfi_queue_header *q_hdr)
q_hdr->qhdr_write_idx = 0x0;
}
static void __interface_queues_release(struct msm_vidc_core *core)
static void __interface_queues_deinit(struct msm_vidc_core *core)
{
int i;
@@ -2394,7 +2394,7 @@ static void __unload_fw(struct msm_vidc_core *core)
qcom_scm_pas_shutdown(core->dt->fw_cookie);
core->dt->fw_cookie = 0;
__interface_queues_release(core);
__interface_queues_deinit(core);
call_venus_op(core, power_off, core);
__deinit_resources(core);
@@ -2425,7 +2425,7 @@ irqreturn_t venus_hfi_isr(int irq, void *data)
{
struct msm_vidc_core *core = data;
d_vpr_e("%s()\n", __func__);
d_vpr_l("%s()\n", __func__);
disable_irq_nosync(irq);
queue_work(core->device_workq, &core->device_work);
@@ -2443,7 +2443,6 @@ void venus_hfi_work_handler(struct work_struct *work)
d_vpr_e("%s: invalid params\n", __func__);
return;
}
d_vpr_e("%s(): core %pK\n", __func__, core);
mutex_lock(&core->lock);
if (__resume(core)) {
@@ -2546,12 +2545,11 @@ int venus_hfi_core_init(struct msm_vidc_core *core)
{
int rc = 0;
d_vpr_h("%s(): core %p\n", __func__, core);
if (!core) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
d_vpr_h("%s(): core %pK\n", __func__, core);
core->packet_size = 4096;
core->packet = kzalloc(core->packet_size, GFP_KERNEL);
@@ -2580,27 +2578,49 @@ int venus_hfi_core_init(struct msm_vidc_core *core)
if (rc)
goto error;
__sys_init(core);
__sys_image_version(core);
__sys_set_debug(core, (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT);
__enable_subcaches(core);
__set_subcaches(core);
rc = __enable_subcaches(core);
if (rc)
goto error;
rc = __sys_init(core);
if (rc)
goto error;
rc = __sys_image_version(core);
if (rc)
goto error;
rc = __sys_set_debug(core, (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT);
if (rc)
goto error;
rc = __set_subcaches(core);
if (rc)
goto error;
d_vpr_h("%s(): successful\n", __func__);
return 0;
error:
d_vpr_h("%s(): failed\n", __func__);
__unload_fw(core);
kfree(core->response_packet);
kfree(core->packet);
venus_hfi_core_deinit(core);
return rc;
}
int venus_hfi_core_release(struct msm_vidc_core *core)
int venus_hfi_core_deinit(struct msm_vidc_core *core)
{
d_vpr_h("%s(): core %p\n", __func__, core);
if (!core) {
d_vpr_h("%s(): invalid params\n", __func__);
return -EINVAL;
}
d_vpr_h("%s(): core %pK\n", __func__, core);
__disable_subcaches(core);
__interface_queues_deinit(core);
__unload_fw(core);
kfree(core->response_packet);
core->response_packet = NULL;
kfree(core->packet);
core->packet = NULL;
return 0;
}
@@ -2867,7 +2887,6 @@ int venus_hfi_queue_buffer(struct msm_vidc_inst *inst,
struct msm_vidc_core *core;
struct hfi_buffer hfi_buffer;
d_vpr_h("%s(): inst %p\n", __func__, inst);
if (!inst || !inst->core || !inst->packet) {
d_vpr_e("%s: Invalid params\n", __func__);
return -EINVAL;
@@ -2927,7 +2946,6 @@ int venus_hfi_release_buffer(struct msm_vidc_inst *inst,
struct msm_vidc_core *core;
struct hfi_buffer hfi_buffer;
d_vpr_h("%s(): inst %p\n", __func__, inst);
if (!inst || !buffer) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;

View File

@@ -10,6 +10,8 @@
#include "msm_vidc_driver.h"
#include "msm_vdec.h"
extern struct msm_vidc_core *g_core;
void print_psc_properties(u32 tag, const char *str, struct msm_vidc_inst *inst,
struct msm_vidc_subscription_params subsc_params)
{
@@ -421,8 +423,6 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
//todo: moved to HFI_PROP_PICTURE_TYPE
/*if (buffer->flags & HFI_BUF_FW_FLAG_KEYFRAME)
buf->flags |= MSM_VIDC_BUF_FLAG_KEYFRAME;*/
if (buffer->flags & HFI_BUF_FW_FLAG_LAST)
buf->flags |= MSM_VIDC_BUF_FLAG_LAST;
//moved to HFI_INFO_DATA_CORRUPT
/*if (buffer->flags & HFI_BUF_FW_FLAG_CORRUPT)
buf->flags |= MSM_VIDC_BUF_FLAG_ERROR;*/
@@ -432,6 +432,12 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
/*if (buffer->flags & HFI_BUF_FW_FLAG_SUBFRAME)
buf->flags |= MSM_VIDC_BUF_FLAG_SUBFRAME;*/
if (buffer->flags & HFI_BUF_FW_FLAG_LAST) {
if (msm_vidc_allow_last_flag(inst)) {
buf->flags |= MSM_VIDC_BUF_FLAG_LAST;
msm_vidc_state_change_last_flag(inst);
}
}
print_vidc_buffer(VIDC_HIGH, "FBD", inst, buf);
return rc;
@@ -531,7 +537,9 @@ static int handle_dequeue_buffers(struct msm_vidc_inst* inst)
if (buf->attr & MSM_VIDC_ATTR_DEQUEUED) {
buf->attr &= ~MSM_VIDC_ATTR_DEQUEUED;
msm_vidc_vb2_buffer_done(inst, buf);
msm_vidc_put_driver_buf(inst, buf);
/* do not unmap / delete read only buffer */
if (!(buf->attr & MSM_VIDC_ATTR_READ_ONLY))
msm_vidc_put_driver_buf(inst, buf);
}
}
}
@@ -962,11 +970,10 @@ exit:
return rc;
}
static int venus_hfi_input_psc(struct msm_vidc_core *core,
struct work_header *work_hdr)
int handle_session_input_psc(struct msm_vidc_inst *inst,
struct input_psc_work *psc_work)
{
int rc = 0;
struct msm_vidc_inst *inst;
struct hfi_header *hdr = NULL;
struct hfi_packet *packet;
u8 *pkt, *temp_pkt;
@@ -974,32 +981,25 @@ static int venus_hfi_input_psc(struct msm_vidc_core *core,
u32 hfi_port = 0;
int i;
if (!work_hdr) {
if (!inst || !psc_work) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
hdr = (struct hfi_header *)work_hdr->data;
hdr = (struct hfi_header *)psc_work->data;
if (!hdr) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
inst = get_inst(core, hdr->session_id);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
mutex_lock(&inst->lock);
hfi_cmd_type = 0;
hfi_port = 0;
pkt = (u8 *)((u8 *)hdr + sizeof(struct hfi_header));
temp_pkt = pkt;
for (i = 0; i < hdr->num_packets; i++) {
if (validate_packet(pkt, work_hdr->data,
work_hdr->data_size, __func__)) {
if (validate_packet(pkt, psc_work->data,
psc_work->data_size, __func__)) {
rc = -EINVAL;
goto exit;
}
@@ -1034,47 +1034,48 @@ static int venus_hfi_input_psc(struct msm_vidc_core *core,
pkt += packet->size;
}
if (hfi_cmd_type == HFI_CMD_SETTINGS_CHANGE) {
if (hfi_port == HFI_PORT_BITSTREAM) {
print_psc_properties(VIDC_HIGH, "INPUT_PSC", inst,
inst->subcr_params[INPUT_PORT]);
rc = msm_vdec_input_port_settings_change(inst);
if (rc)
goto exit;
}
}
print_psc_properties(VIDC_HIGH, "INPUT_PSC", inst,
inst->subcr_params[INPUT_PORT]);
rc = msm_vdec_input_port_settings_change(inst);
if (rc)
goto exit;
exit:
mutex_unlock(&inst->lock);
put_inst(inst);
return rc;
}
void venus_hfi_inst_work_handler(struct work_struct *work)
void handle_session_input_psc_work_handler(struct work_struct *work)
{
struct msm_vidc_core *core;
struct work_header *work_hdr, *dummy = NULL;
int rc = 0;
struct msm_vidc_inst *inst;
struct input_psc_work *psc_work, *dummy = NULL;
core = container_of(work, struct msm_vidc_core, inst_work.work);
if (!core) {
inst = container_of(work, struct msm_vidc_inst, input_psc_work.work);
inst = get_inst_ref(g_core, inst);
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return;
}
list_for_each_entry_safe(work_hdr, dummy, &core->inst_works, list) {
switch (work_hdr->type) {
case MSM_VIDC_INST_WORK_PSC:
venus_hfi_input_psc(core, work_hdr);
break;
default:
d_vpr_e("%s(): invalid work type: %d\n", __func__,
work_hdr->type);
break;
mutex_lock(&inst->lock);
list_for_each_entry_safe(psc_work, dummy, &inst->input_psc_works, list) {
rc = msm_vidc_allow_input_psc(inst);
if (!rc) {
rc = handle_session_input_psc(inst, psc_work);
if (!rc)
rc = msm_vidc_state_change_input_psc(inst);
/* either handle input psc or state change failed */
if (rc)
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
}
list_del(&work_hdr->list);
kfree(work_hdr->data);
kfree(work_hdr);
list_del(&psc_work->list);
kfree(psc_work->data);
kfree(psc_work);
}
mutex_unlock(&inst->lock);
put_inst(inst);
}
static int handle_session_response(struct msm_vidc_core *core,
@@ -1110,12 +1111,10 @@ static int handle_session_response(struct msm_vidc_core *core,
packet->type < HFI_CMD_END) {
if (packet->type == HFI_CMD_SETTINGS_CHANGE &&
packet->port == HFI_PORT_BITSTREAM) {
struct work_header *work;
struct input_psc_work *work;
work = kzalloc(sizeof(struct work_header), GFP_KERNEL);
work = kzalloc(sizeof(struct input_psc_work), GFP_KERNEL);
INIT_LIST_HEAD(&work->list);
work->type = MSM_VIDC_INST_WORK_PSC;
work->session_id = hdr->session_id;
work->data_size = hdr->size;
work->data = kzalloc(hdr->size, GFP_KERNEL);
if (!work->data) {
@@ -1123,9 +1122,9 @@ static int handle_session_response(struct msm_vidc_core *core,
goto exit;
}
memcpy(work->data, (void *)hdr, hdr->size);
list_add_tail(&work->list, &core->inst_works);
queue_delayed_work(core->inst_workq,
&core->inst_work, msecs_to_jiffies(0));
list_add_tail(&work->list, &inst->input_psc_works);
queue_delayed_work(inst->input_psc_workq,
&inst->input_psc_work, msecs_to_jiffies(0));
goto exit;
}
if (hfi_cmd_type == HFI_CMD_SETTINGS_CHANGE) {