diff --git a/driver/vidc/inc/msm_vidc_internal.h b/driver/vidc/inc/msm_vidc_internal.h index b94818b738..4cde4f524e 100644 --- a/driver/vidc/inc/msm_vidc_internal.h +++ b/driver/vidc/inc/msm_vidc_internal.h @@ -607,11 +607,6 @@ struct msm_vidc_hfi_frame_info { u32 data_corrupt; }; -struct msm_vidc_cmd_range { - u32 begin; - u32 end; -}; - struct msm_vidc_decode_vpp_delay { bool enable; u32 size; diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index d7053d5cd9..90200132c3 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -807,11 +807,50 @@ bool msm_vidc_allow_last_flag(struct msm_vidc_inst *inst) return false; } +static int msm_vidc_process_pending_ipsc(struct msm_vidc_inst *inst, + enum msm_vidc_inst_state *new_state) +{ + struct response_work *resp_work, *dummy = NULL; + int rc = 0; + + if (!inst || !new_state) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + if (list_empty(&inst->response_works)) + return 0; + + i_vpr_h(inst, "%s: state %s, ipsc pending\n", __func__, state_name(inst->state)); + list_for_each_entry_safe(resp_work, dummy, &inst->response_works, list) { + if (resp_work->type == RESP_WORK_INPUT_PSC) { + rc = handle_session_response_work(inst, resp_work); + if (rc) { + i_vpr_e(inst, "%s: handle ipsc failed\n", __func__); + *new_state = MSM_VIDC_ERROR; + } else { + if (inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG || + inst->state == MSM_VIDC_DRAIN_START_INPUT) { + *new_state = MSM_VIDC_DRC_DRAIN; + } else if (inst->state == MSM_VIDC_DRC_LAST_FLAG) { + *new_state = MSM_VIDC_DRC; + } + } + list_del(&resp_work->list); + kfree(resp_work->data); + kfree(resp_work); + /* list contains max only one ipsc at anytime */ + break; + } + } + + return rc; +} + 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 response_work *resp_work; if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); @@ -832,35 +871,19 @@ int msm_vidc_state_change_streamon(struct msm_vidc_inst *inst, u32 type) } else if (inst->state == MSM_VIDC_START_INPUT) { new_state = MSM_VIDC_START; } else if (inst->state == MSM_VIDC_DRAIN_START_INPUT) { - i_vpr_h(inst, - "%s: streamon(output) in DRAIN_START_INPUT state\n", - __func__); + i_vpr_h(inst, "%s: streamon(output) in %s state\n", + __func__, state_name(inst->state)); new_state = MSM_VIDC_DRAIN; - if (!list_empty(&inst->response_works)) { - resp_work = list_first_entry(&inst->response_works, - struct response_work, list); - if (resp_work->type == RESP_WORK_INPUT_PSC) { - i_vpr_h(inst, - "%s: streamon(output) in DRAIN_START_INPUT state, input psc pending\n", - __func__); - rc = handle_session_response_work(inst, resp_work); - if (rc) { - i_vpr_e(inst, - "%s: handle input psc failed\n", __func__); - new_state = MSM_VIDC_ERROR; - } else { - new_state = MSM_VIDC_DRC_DRAIN; - } - list_del(&resp_work->list); - kfree(resp_work->data); - kfree(resp_work); - } + rc = msm_vidc_process_pending_ipsc(inst, &new_state); + if (rc) { + i_vpr_e(inst, "%s: process pending ipsc failed\n", __func__); + goto state_change; } } } - rc = msm_vidc_change_inst_state(inst, new_state, __func__); - if (rc) - return rc; + +state_change: + msm_vidc_change_inst_state(inst, new_state, __func__); return rc; } @@ -960,7 +983,6 @@ 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 response_work *resp_work; if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); @@ -969,57 +991,28 @@ int msm_vidc_state_change_start(struct msm_vidc_inst *inst) if (inst->state == MSM_VIDC_DRAIN_LAST_FLAG || inst->state == MSM_VIDC_DRC_LAST_FLAG) { - new_state = MSM_VIDC_START; - if (!list_empty(&inst->response_works)) { - resp_work = list_first_entry(&inst->response_works, - struct response_work, list); - if (resp_work->type == RESP_WORK_INPUT_PSC) { - i_vpr_h(inst, - "%s: start in DRC(DRAIN)_LAST_FLAG state, input psc pending\n", - __func__); - rc = handle_session_response_work(inst, resp_work); - if (rc) { - i_vpr_e(inst, - "%s: handle input psc failed\n", __func__); - new_state = MSM_VIDC_ERROR; - } else { - new_state = MSM_VIDC_DRC; - } - list_del(&resp_work->list); - kfree(resp_work->data); - kfree(resp_work); - } + new_state = MSM_VIDC_START; + rc = msm_vidc_process_pending_ipsc(inst, &new_state); + if (rc) { + i_vpr_e(inst, "%s: process pending ipsc failed\n", __func__); + goto state_change; } } else if (inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG) { - new_state = MSM_VIDC_DRAIN; - if (!list_empty(&inst->response_works)) { - resp_work = list_first_entry(&inst->response_works, - struct response_work, list); - if (resp_work->type == RESP_WORK_INPUT_PSC) { - i_vpr_h(inst, - "%s: start in DRC_DRAIN_LAST_FLAG state, input psc pending\n"); - rc = handle_session_response_work(inst, resp_work); - if (rc) { - i_vpr_e(inst, - "%s: handle input psc failed\n", __func__); - new_state = MSM_VIDC_ERROR; - } else { - new_state = MSM_VIDC_DRC_DRAIN; - } - list_del(&resp_work->list); - kfree(resp_work->data); - kfree(resp_work); - } + new_state = MSM_VIDC_DRAIN; + rc = msm_vidc_process_pending_ipsc(inst, &new_state); + if (rc) { + i_vpr_e(inst, "%s: process pending ipsc failed\n", __func__); + goto state_change; } } else { - i_vpr_e(inst, "%s: wrong state %s\n", - __func__, state_name(inst->state)); - msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__); - return -EINVAL; + i_vpr_e(inst, "%s: wrong state %s\n", __func__, state_name(inst->state)); + new_state = MSM_VIDC_ERROR; + rc = -EINVAL; + goto state_change; } - rc = msm_vidc_change_inst_state(inst, new_state, __func__); - if (rc) - return rc; + +state_change: + msm_vidc_change_inst_state(inst, new_state, __func__); return rc; } diff --git a/driver/vidc/src/venus_hfi_response.c b/driver/vidc/src/venus_hfi_response.c index 135dd9871c..f4a0a1689e 100644 --- a/driver/vidc/src/venus_hfi_response.c +++ b/driver/vidc/src/venus_hfi_response.c @@ -10,7 +10,14 @@ #include "msm_vidc_driver.h" #include "msm_vdec.h" +#define in_range(range, val) (((range.begin) < (val)) && ((range.end) > (val))) + extern struct msm_vidc_core *g_core; +struct msm_vidc_hfi_range { + u32 begin; + u32 end; + int (*handle)(struct msm_vidc_inst *inst, struct hfi_packet *pkt); +}; void print_psc_properties(u32 tag, const char *str, struct msm_vidc_inst *inst, struct msm_vidc_subscription_params subsc_params) @@ -1198,32 +1205,6 @@ exit: return rc; } -static int process_response_packet(struct msm_vidc_inst *inst, - struct hfi_packet *packet) -{ - int rc = 0; - - if (packet->type > HFI_CMD_BEGIN && - packet->type < HFI_CMD_END) { - rc = handle_session_command(inst, packet); - } else if (packet->type > HFI_PROP_BEGIN && - packet->type < HFI_PROP_END) { - rc = handle_session_property(inst, packet); - } else if (packet->type > HFI_SESSION_ERROR_BEGIN && - packet->type < HFI_SESSION_ERROR_END) { - rc = handle_session_error(inst, packet); - } else if (packet->type > HFI_INFORMATION_BEGIN && - packet->type < HFI_INFORMATION_END) { - rc = handle_session_info(inst, packet); - } else { - i_vpr_e(inst, "%s: Unknown packet type: %#x\n", - __func__, packet->type); - rc = -EINVAL; - } - - return rc; -} - int handle_session_response_work(struct msm_vidc_inst *inst, struct response_work *resp_work) { @@ -1233,12 +1214,11 @@ int handle_session_response_work(struct msm_vidc_inst *inst, u8 *pkt, *start_pkt; u32 hfi_cmd_type = 0; int i, j; - struct msm_vidc_cmd_range be[5] = { - {HFI_SYSTEM_ERROR_BEGIN, HFI_SYSTEM_ERROR_END}, - {HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END}, - {HFI_INFORMATION_BEGIN, HFI_INFORMATION_END}, - {HFI_PROP_BEGIN, HFI_PROP_END}, - {HFI_CMD_BEGIN, HFI_CMD_END}, + struct msm_vidc_hfi_range be[] = { + {HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END, handle_session_error}, + {HFI_INFORMATION_BEGIN, HFI_INFORMATION_END, handle_session_info}, + {HFI_PROP_BEGIN, HFI_PROP_END, handle_session_property}, + {HFI_CMD_BEGIN, HFI_CMD_END, handle_session_command}, }; if (!inst || !resp_work) { @@ -1273,8 +1253,7 @@ int handle_session_response_work(struct msm_vidc_inst *inst, pkt = start_pkt; for (j = 0; j < hdr->num_packets; j++) { packet = (struct hfi_packet * ) pkt; - if (packet->type > be[i].begin - && packet->type < be[i].end) { + if (in_range(be[i], packet->type)) { if (hfi_cmd_type == HFI_CMD_SETTINGS_CHANGE) { i_vpr_e(inst, "%s: invalid packet type %d in port settings change\n", @@ -1282,7 +1261,7 @@ int handle_session_response_work(struct msm_vidc_inst *inst, rc = -EINVAL; } hfi_cmd_type = packet->type; - rc = process_response_packet(inst, packet); + rc = be[i].handle(inst, packet); if (rc) goto exit; } @@ -1400,12 +1379,11 @@ static int handle_session_response(struct msm_vidc_core *core, u32 hfi_cmd_type = 0; u32 hfi_port = 0; int i, j; - struct msm_vidc_cmd_range be[5] = { - {HFI_SYSTEM_ERROR_BEGIN, HFI_SYSTEM_ERROR_END}, - {HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END}, - {HFI_INFORMATION_BEGIN, HFI_INFORMATION_END}, - {HFI_PROP_BEGIN, HFI_PROP_END}, - {HFI_CMD_BEGIN, HFI_CMD_END}, + struct msm_vidc_hfi_range be[] = { + {HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END, handle_session_error}, + {HFI_INFORMATION_BEGIN, HFI_INFORMATION_END, handle_session_info}, + {HFI_PROP_BEGIN, HFI_PROP_END, handle_session_property}, + {HFI_CMD_BEGIN, HFI_CMD_END, handle_session_command}, }; inst = get_inst(core, hdr->session_id); @@ -1460,9 +1438,9 @@ static int handle_session_response(struct msm_vidc_core *core, pkt = start_pkt; for (j = 0; j < hdr->num_packets; j++) { packet = (struct hfi_packet * ) pkt; - if (packet->type > be[i].begin && packet->type < be[i].end) { + if (in_range(be[i], packet->type)) { hfi_cmd_type = packet->type; - rc = process_response_packet(inst, packet); + rc = be[i].handle(inst, packet); if (rc) goto exit; }