Merge "video: driver: avoid drain_last_flag to drc state transition"

Esse commit está contido em:
qctecmdr
2021-02-17 11:41:43 -08:00
commit de Gerrit - the friendly Code Review server
3 arquivos alterados com 87 adições e 121 exclusões

Ver arquivo

@@ -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;

Ver arquivo

@@ -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;
}

Ver arquivo

@@ -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;
}