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:

committed by
Darshana Patil

parent
7c203e7bf5
commit
58cd1120ee
@@ -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_
|
@@ -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_
|
@@ -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_
|
||||
|
@@ -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,11 +235,30 @@ 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);
|
||||
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);
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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__
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
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,26 +318,10 @@ 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;
|
||||
if (!msm_vidc_allow_reqbufs(inst, b->type)) {
|
||||
rc = -EBUSY;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
port = v4l2_type_to_driver_port(inst, b->type, __func__);
|
||||
if (port < 0) {
|
||||
@@ -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;
|
||||
if (!msm_vidc_allow_streamon(inst, type)) {
|
||||
rc = -EBUSY;
|
||||
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;
|
||||
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,31 +441,7 @@ 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);
|
||||
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)
|
||||
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
if (!msm_vidc_allow_streamoff(inst, type)) {
|
||||
rc = -EBUSY;
|
||||
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;
|
||||
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,42 +482,7 @@ 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);
|
||||
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)
|
||||
msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
@@ -740,9 +623,11 @@ 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);
|
||||
if (!inst) {
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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,6 +537,8 @@ 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);
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
Reference in New Issue
Block a user