Merge "video: driver: avoid drain_last_flag to drc state transition"
Esse commit está contido em:

commit de
Gerrit - the friendly Code Review server

commit
34ca840018
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Referência em uma nova issue
Block a user