video: driver: release internal buffer as part of start/resume

Change-Id: I45469c0a569fbc282aa1dbd217654e49eb50f54f
Signed-off-by: Darshana Patil <quic_darshana@quicinc.com>
This commit is contained in:
Darshana Patil
2022-06-29 17:39:06 -07:00
parent 10794c2968
commit fb1ecb69d0
5 changed files with 173 additions and 95 deletions

View File

@@ -30,5 +30,9 @@ 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_handle_release_buffer(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *buf);
int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst);
int msm_vdec_create_input_internal_buffers(struct msm_vidc_inst *inst);
int msm_vdec_queue_input_internal_buffers(struct msm_vidc_inst *inst);
int msm_vdec_release_input_internal_buffers(struct msm_vidc_inst *inst);
#endif // _MSM_VDEC_H_

View File

@@ -523,7 +523,8 @@ int msm_vidc_state_change_drain_last_flag(struct msm_vidc_inst *inst);
int msm_vidc_state_change_psc_last_flag(struct msm_vidc_inst *inst);
int msm_vidc_process_drain(struct msm_vidc_inst *inst);
int msm_vidc_process_resume(struct msm_vidc_inst *inst);
int msm_vidc_process_streamon(struct msm_vidc_inst *inst, u32 type);
int msm_vidc_process_streamon_input(struct msm_vidc_inst *inst);
int msm_vidc_process_streamon_output(struct msm_vidc_inst *inst);
int msm_vidc_process_stop_done(struct msm_vidc_inst *inst,
enum signal_session_response signal_type);
int msm_vidc_process_drain_done(struct msm_vidc_inst *inst);
@@ -586,5 +587,6 @@ int msm_vidc_update_input_rate(struct msm_vidc_inst *inst, u64 time_us);
int msm_vidc_get_input_rate(struct msm_vidc_inst *inst);
int msm_vidc_get_frame_rate(struct msm_vidc_inst *inst);
int msm_vidc_get_operating_rate(struct msm_vidc_inst *inst);
int msm_vidc_alloc_and_queue_input_internal_buffers(struct msm_vidc_inst *inst);
#endif // _MSM_VIDC_DRIVER_H_

View File

@@ -755,7 +755,7 @@ static int msm_vdec_set_output_properties(struct msm_vidc_inst *inst)
return rc;
}
static int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst)
int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst)
{
int rc = 0;
u32 i = 0;
@@ -790,7 +790,7 @@ static int msm_vdec_get_output_internal_buffers(struct msm_vidc_inst *inst)
return rc;
}
static int msm_vdec_create_input_internal_buffers(struct msm_vidc_inst *inst)
int msm_vdec_create_input_internal_buffers(struct msm_vidc_inst *inst)
{
int rc = 0;
u32 i = 0;
@@ -815,7 +815,7 @@ static int msm_vdec_create_output_internal_buffers(struct msm_vidc_inst *inst)
return 0;
}
static int msm_vdec_queue_input_internal_buffers(struct msm_vidc_inst *inst)
int msm_vdec_queue_input_internal_buffers(struct msm_vidc_inst *inst)
{
int rc = 0;
u32 i = 0;
@@ -840,7 +840,7 @@ static int msm_vdec_queue_output_internal_buffers(struct msm_vidc_inst *inst)
return 0;
}
static int msm_vdec_release_input_internal_buffers(struct msm_vidc_inst *inst)
int msm_vdec_release_input_internal_buffers(struct msm_vidc_inst *inst)
{
int rc = 0;
u32 i = 0;
@@ -1371,30 +1371,6 @@ int msm_vdec_input_port_settings_change(struct msm_vidc_inst *inst)
event.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION;
v4l2_event_queue_fh(&inst->event_handler, &event);
rc = msm_vdec_get_input_internal_buffers(inst);
if (rc)
return rc;
rc = msm_vdec_release_input_internal_buffers(inst);
if (rc)
return rc;
rc = msm_vdec_create_input_internal_buffers(inst);
if (rc)
return rc;
rc = msm_vdec_queue_input_internal_buffers(inst);
if (rc)
return rc;
rc = msm_vidc_set_stage(inst, STAGE);
if (rc)
return rc;
rc = msm_vidc_set_pipe(inst, PIPE);
if (rc)
return rc;
return rc;
}
@@ -1489,7 +1465,7 @@ int msm_vdec_streamon_input(struct msm_vidc_inst *inst)
if (rc)
goto error;
rc = msm_vidc_process_streamon(inst, INPUT_PORT);
rc = msm_vidc_process_streamon_input(inst);
if (rc)
goto error;
@@ -1809,7 +1785,7 @@ int msm_vdec_streamon_output(struct msm_vidc_inst *inst)
if (rc)
goto error;
rc = msm_vidc_process_streamon(inst, OUTPUT_PORT);
rc = msm_vidc_process_streamon_output(inst);
if (rc)
goto error;
@@ -2206,6 +2182,27 @@ int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
msm_vidc_allow_dcvs(inst);
msm_vidc_power_data_reset(inst);
/*
* client is completing partial port reconfiguration,
* hence reallocate input internal buffers before input port
* is resumed.
*/
if (is_sub_state(inst, MSM_VIDC_DRC) &&
is_sub_state(inst, MSM_VIDC_DRC_LAST_BUFFER) &&
is_sub_state(inst, MSM_VIDC_INPUT_PAUSE)) {
rc = msm_vidc_alloc_and_queue_input_internal_buffers(inst);
if (rc)
return rc;
rc = msm_vidc_set_stage(inst, STAGE);
if (rc)
return rc;
rc = msm_vidc_set_pipe(inst, PIPE);
if (rc)
return rc;
}
/* allocate and queue extra dpb buffers */
rc = msm_vdec_alloc_and_queue_additional_dpb_buffers(inst);
if (rc)

View File

@@ -863,7 +863,7 @@ int msm_venc_streamon_input(struct msm_vidc_inst *inst)
if (rc)
goto error;
rc = msm_vidc_process_streamon(inst, INPUT_PORT);
rc = msm_vidc_process_streamon_input(inst);
if (rc)
goto error;
@@ -1013,7 +1013,7 @@ int msm_venc_streamon_output(struct msm_vidc_inst *inst)
if (rc)
goto error;
rc = msm_vidc_process_streamon(inst, OUTPUT_PORT);
rc = msm_vidc_process_streamon_output(inst);
if (rc)
goto error;

View File

@@ -1664,12 +1664,15 @@ bool msm_vidc_allow_start(struct msm_vidc_inst *inst)
}
/* client would call start (resume) to complete DRC/drain sequence */
if (inst->state == MSM_VIDC_INPUT_STREAMING ||
inst->state == MSM_VIDC_OUTPUT_STREAMING ||
inst->state == MSM_VIDC_STREAMING) {
if ((is_sub_state(inst, MSM_VIDC_DRC) &&
is_sub_state(inst, MSM_VIDC_DRC_LAST_BUFFER)) ||
(is_sub_state(inst, MSM_VIDC_DRAIN) &&
is_sub_state(inst, MSM_VIDC_DRAIN_LAST_BUFFER)))
allow = true;
}
if (!allow)
i_vpr_e(inst, "%s: not allowed in state %s, sub state %s\n",
__func__, state_name(inst->state), inst->sub_state_name);
@@ -1984,40 +1987,30 @@ int msm_vidc_process_resume(struct msm_vidc_inst *inst)
return rc;
}
int msm_vidc_process_streamon(struct msm_vidc_inst *inst,
enum msm_vidc_port_type port)
int msm_vidc_process_streamon_input(struct msm_vidc_inst *inst)
{
int rc = 0;
enum msm_vidc_sub_state clear_sub_state = MSM_VIDC_SUB_STATE_NONE;
enum msm_vidc_sub_state set_sub_state = MSM_VIDC_SUB_STATE_NONE;
bool drain_pending = false;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
if (port == INPUT_META_PORT || port == OUTPUT_META_PORT)
return 0;
msm_vidc_scale_power(inst, true);
rc = venus_hfi_start(inst, port);
rc = venus_hfi_start(inst, INPUT_PORT);
if (rc)
return rc;
/* clear input/output pause substate immediately */
if (port == INPUT_PORT && is_sub_state(inst, MSM_VIDC_INPUT_PAUSE)) {
/* clear input pause substate immediately */
if (is_sub_state(inst, MSM_VIDC_INPUT_PAUSE)) {
rc = msm_vidc_change_sub_state(inst, MSM_VIDC_INPUT_PAUSE, 0, __func__);
if (rc)
return rc;
} else if (port == OUTPUT_PORT && is_sub_state(inst, MSM_VIDC_OUTPUT_PAUSE)) {
rc = msm_vidc_change_sub_state(inst, MSM_VIDC_OUTPUT_PAUSE, 0, __func__);
if (rc)
return rc;
}
if (port == INPUT_PORT) {
/*
* if DRC sequence is not completed by the client then PAUSE
* firmware input port to avoid firmware raising IPSC again.
@@ -2033,7 +2026,32 @@ int msm_vidc_process_streamon(struct msm_vidc_inst *inst,
set_sub_state = MSM_VIDC_INPUT_PAUSE;
}
}
} else if (port == OUTPUT_PORT) {
rc = msm_vidc_state_change_streamon(inst, INPUT_PORT);
if (rc)
return rc;
rc = msm_vidc_change_sub_state(inst, clear_sub_state, set_sub_state, __func__);
if (rc)
return rc;
return rc;
}
int msm_vidc_process_streamon_output(struct msm_vidc_inst *inst)
{
int rc = 0;
enum msm_vidc_sub_state clear_sub_state = MSM_VIDC_SUB_STATE_NONE;
enum msm_vidc_sub_state set_sub_state = MSM_VIDC_SUB_STATE_NONE;
bool drain_pending = false;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
msm_vidc_scale_power(inst, true);
/*
* client completed drc sequence, reset DRC and
* MSM_VIDC_DRC_LAST_BUFFER substates
@@ -2042,6 +2060,25 @@ int msm_vidc_process_streamon(struct msm_vidc_inst *inst,
is_sub_state(inst, MSM_VIDC_DRC_LAST_BUFFER)) {
clear_sub_state = MSM_VIDC_DRC | MSM_VIDC_DRC_LAST_BUFFER;
}
/*
* Client is completing port reconfiguration, hence reallocate
* input internal buffers before input port is resumed.
* Drc sub-state cannot be checked because DRC sub-state will
* not be set during initial port reconfiguration.
*/
if (is_decode_session(inst) &&
is_sub_state(inst, MSM_VIDC_INPUT_PAUSE)) {
rc = msm_vidc_alloc_and_queue_input_internal_buffers(inst);
if (rc)
return rc;
rc = msm_vidc_set_stage(inst, STAGE);
if (rc)
return rc;
rc = msm_vidc_set_pipe(inst, PIPE);
if (rc)
return rc;
}
/*
* fw input port is paused due to ipsc. now that client
* completed drc sequence, resume fw input port provided
@@ -2058,9 +2095,19 @@ int msm_vidc_process_streamon(struct msm_vidc_inst *inst,
clear_sub_state |= MSM_VIDC_INPUT_PAUSE;
}
}
rc = venus_hfi_start(inst, OUTPUT_PORT);
if (rc)
return rc;
/* clear output pause substate immediately */
if (is_sub_state(inst, MSM_VIDC_OUTPUT_PAUSE)) {
rc = msm_vidc_change_sub_state(inst, MSM_VIDC_OUTPUT_PAUSE, 0, __func__);
if (rc)
return rc;
}
rc = msm_vidc_state_change_streamon(inst, port);
rc = msm_vidc_state_change_streamon(inst, OUTPUT_PORT);
if (rc)
return rc;
@@ -3587,6 +3634,34 @@ static int msm_vidc_queue_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buf
return 0;
}
int msm_vidc_alloc_and_queue_input_internal_buffers(struct msm_vidc_inst *inst)
{
int rc = 0;
if (!inst) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
rc = msm_vdec_get_input_internal_buffers(inst);
if (rc)
return rc;
rc = msm_vdec_release_input_internal_buffers(inst);
if (rc)
return rc;
rc = msm_vdec_create_input_internal_buffers(inst);
if (rc)
return rc;
rc = msm_vdec_queue_input_internal_buffers(inst);
if (rc)
return rc;
return rc;
}
int msm_vidc_queue_deferred_buffers(struct msm_vidc_inst *inst, enum msm_vidc_buffer_type buf_type)
{
struct msm_vidc_buffers *buffers;