|
@@ -178,14 +178,6 @@ bool is_valid_hfi_buffer_type(struct msm_vidc_inst *inst,
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-static int signal_session_msg_receipt(struct msm_vidc_inst *inst,
|
|
|
- enum signal_session_response cmd)
|
|
|
-{
|
|
|
- if (cmd < MAX_SIGNAL)
|
|
|
- complete(&inst->completions[cmd]);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
int validate_packet(u8 *response_pkt, u8 *core_resp_pkt,
|
|
|
u32 core_resp_pkt_size, const char *func)
|
|
|
{
|
|
@@ -304,29 +296,35 @@ static bool check_for_packet_payload(struct msm_vidc_inst *inst,
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-static bool check_last_flag(struct msm_vidc_inst *inst,
|
|
|
- struct hfi_packet *pkt)
|
|
|
+static int handle_session_last_flag_info(struct msm_vidc_inst *inst,
|
|
|
+ struct hfi_packet *pkt)
|
|
|
{
|
|
|
- struct hfi_buffer *buffer;
|
|
|
+ int rc = 0;
|
|
|
|
|
|
- if (!inst || !pkt) {
|
|
|
- d_vpr_e("%s: invalid params\n", __func__);
|
|
|
- return false;
|
|
|
+ if (pkt->type == HFI_INFO_HFI_FLAG_PSC_LAST) {
|
|
|
+ if (msm_vidc_allow_psc_last_flag(inst))
|
|
|
+ rc = msm_vidc_process_psc_last_flag(inst);
|
|
|
+ else
|
|
|
+ rc = -EINVAL;
|
|
|
+ } else if (pkt->type == HFI_INFO_HFI_FLAG_DRAIN_LAST) {
|
|
|
+ if (msm_vidc_allow_drain_last_flag(inst))
|
|
|
+ rc = msm_vidc_process_drain_last_flag(inst);
|
|
|
+ else
|
|
|
+ rc = -EINVAL;
|
|
|
+ } else {
|
|
|
+ i_vpr_e(inst, "%s: invalid packet type %#x\n", __func__,
|
|
|
+ pkt->type);
|
|
|
}
|
|
|
|
|
|
- buffer = (struct hfi_buffer *)((u8 *)pkt + sizeof(struct hfi_packet));
|
|
|
- if (buffer->flags & HFI_BUF_FW_FLAG_LAST) {
|
|
|
- i_vpr_h(inst, "%s: received last flag on FBD, index: %d\n",
|
|
|
- __func__, buffer->index);
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
+ if (rc)
|
|
|
+ msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
+
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
static int handle_session_info(struct msm_vidc_inst *inst,
|
|
|
struct hfi_packet *pkt)
|
|
|
{
|
|
|
-
|
|
|
int rc = 0;
|
|
|
char *info;
|
|
|
|
|
@@ -342,12 +340,20 @@ static int handle_session_info(struct msm_vidc_inst *inst,
|
|
|
info = "buffer overflow";
|
|
|
inst->hfi_frame_info.overflow = 1;
|
|
|
break;
|
|
|
+ case HFI_INFO_HFI_FLAG_DRAIN_LAST:
|
|
|
+ info = "drain last flag";
|
|
|
+ rc = handle_session_last_flag_info(inst, pkt);
|
|
|
+ break;
|
|
|
+ case HFI_INFO_HFI_FLAG_PSC_LAST:
|
|
|
+ info = "drc last flag";
|
|
|
+ rc = handle_session_last_flag_info(inst, pkt);
|
|
|
+ break;
|
|
|
default:
|
|
|
info = "unknown";
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- i_vpr_e(inst, "session info (%#x): %s\n", pkt->type, info);
|
|
|
+ i_vpr_h(inst, "session info (%#x): %s\n", pkt->type, info);
|
|
|
|
|
|
return rc;
|
|
|
}
|
|
@@ -385,7 +391,7 @@ static int handle_session_error(struct msm_vidc_inst *inst,
|
|
|
i_vpr_e(inst, "%s: session error received %#x: %s\n",
|
|
|
__func__, pkt->type, error);
|
|
|
|
|
|
- rc = msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
+ rc = msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
@@ -537,7 +543,8 @@ static int handle_session_start(struct msm_vidc_inst *inst,
|
|
|
static int handle_session_stop(struct msm_vidc_inst *inst,
|
|
|
struct hfi_packet *pkt)
|
|
|
{
|
|
|
- int signal_type = -1;
|
|
|
+ int rc = 0;
|
|
|
+ enum signal_session_response signal_type = -1;
|
|
|
|
|
|
if (pkt->flags & HFI_FW_FLAGS_SUCCESS)
|
|
|
i_vpr_h(inst, "%s: successful for port %d\n",
|
|
@@ -568,17 +575,28 @@ static int handle_session_stop(struct msm_vidc_inst *inst,
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
- if (signal_type != -1)
|
|
|
- signal_session_msg_receipt(inst, signal_type);
|
|
|
+ if (signal_type != -1) {
|
|
|
+ rc = msm_vidc_process_stop_done(inst, signal_type);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static int handle_session_drain(struct msm_vidc_inst *inst,
|
|
|
struct hfi_packet *pkt)
|
|
|
{
|
|
|
+ int rc = 0;
|
|
|
+
|
|
|
if (pkt->flags & HFI_FW_FLAGS_SUCCESS)
|
|
|
i_vpr_h(inst, "%s: successful\n", __func__);
|
|
|
- return 0;
|
|
|
+
|
|
|
+ rc = msm_vidc_process_drain_done(inst);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
static int get_driver_buffer_flags(struct msm_vidc_inst *inst, u32 hfi_flags)
|
|
@@ -618,7 +636,18 @@ static int get_driver_buffer_flags(struct msm_vidc_inst *inst, u32 hfi_flags)
|
|
|
if (hfi_flags & HFI_BUF_FW_FLAG_CODEC_CONFIG)
|
|
|
driver_flags |= MSM_VIDC_BUF_FLAG_CODECCONFIG;
|
|
|
|
|
|
- if (hfi_flags & HFI_BUF_FW_FLAG_LAST)
|
|
|
+ /*
|
|
|
+ * attach last flag to the buffer for encode session.
|
|
|
+ * For decode session attach only if control(LAST_FLAG_EVENT_ENABLE)
|
|
|
+ * is not set by client. If this control is enabled, last flag
|
|
|
+ * info will be sent via event(V4L2_EVENT_VIDC_LAST_FLAG) to client.
|
|
|
+ */
|
|
|
+ if ((is_encode_session(inst) &&
|
|
|
+ (hfi_flags & HFI_BUF_FW_FLAG_LAST)) ||
|
|
|
+ (is_decode_session(inst) &&
|
|
|
+ !inst->capabilities->cap[LAST_FLAG_EVENT_ENABLE].value &&
|
|
|
+ ((hfi_flags & HFI_BUF_FW_FLAG_LAST) ||
|
|
|
+ (hfi_flags & HFI_BUF_FW_FLAG_PSC_LAST))))
|
|
|
driver_flags |= MSM_VIDC_BUF_FLAG_LAST;
|
|
|
|
|
|
return driver_flags;
|
|
@@ -714,6 +743,48 @@ static int handle_non_read_only_buffer(struct msm_vidc_inst *inst,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int handle_psc_last_flag_buffer(struct msm_vidc_inst *inst,
|
|
|
+ struct hfi_buffer *buffer)
|
|
|
+{
|
|
|
+ int rc = 0;
|
|
|
+
|
|
|
+ if (!(buffer->flags & HFI_BUF_FW_FLAG_PSC_LAST))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (!msm_vidc_allow_psc_last_flag(inst))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ rc = msm_vidc_process_psc_last_flag(inst);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
+static int handle_drain_last_flag_buffer(struct msm_vidc_inst *inst,
|
|
|
+ struct hfi_buffer *buffer)
|
|
|
+{
|
|
|
+ int rc = 0;
|
|
|
+
|
|
|
+ if (!(buffer->flags & HFI_BUF_FW_FLAG_LAST))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (!msm_vidc_allow_drain_last_flag(inst))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (is_decode_session(inst)) {
|
|
|
+ rc = msm_vidc_process_drain_last_flag(inst);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+ } else if (is_encode_session(inst)) {
|
|
|
+ rc = msm_vidc_state_change_drain_last_flag(inst);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
static int handle_input_buffer(struct msm_vidc_inst *inst,
|
|
|
struct hfi_buffer *buffer)
|
|
|
{
|
|
@@ -801,11 +872,25 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+ /* handle drain last flag buffer */
|
|
|
+ if (buffer->flags & HFI_BUF_FW_FLAG_LAST) {
|
|
|
+ rc = handle_drain_last_flag_buffer(inst, buffer);
|
|
|
+ if (rc)
|
|
|
+ msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
+ }
|
|
|
+
|
|
|
if (is_decode_session(inst)) {
|
|
|
+ /* handle psc last flag buffer */
|
|
|
+ if (buffer->flags & HFI_BUF_FW_FLAG_PSC_LAST) {
|
|
|
+ rc = handle_psc_last_flag_buffer(inst, buffer);
|
|
|
+ if (rc)
|
|
|
+ msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
+ }
|
|
|
+ /* handle non-read only buffer */
|
|
|
if (!(buffer->flags & HFI_BUF_FW_FLAG_READONLY)) {
|
|
|
rc = handle_non_read_only_buffer(inst, buffer);
|
|
|
if (rc)
|
|
|
- msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
+ msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -861,14 +946,15 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
|
|
|
}
|
|
|
}
|
|
|
if (fatal)
|
|
|
- msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
+ msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* reset data size to zero for last flag buffer.
|
|
|
* reset RO flag for last flag buffer.
|
|
|
*/
|
|
|
- if (buffer->flags & HFI_BUF_FW_FLAG_LAST) {
|
|
|
+ if ((buffer->flags & HFI_BUF_FW_FLAG_LAST) ||
|
|
|
+ (buffer->flags & HFI_BUF_FW_FLAG_PSC_LAST)) {
|
|
|
if (buffer->data_size) {
|
|
|
i_vpr_e(inst, "%s: reset data size to zero for last flag buffer\n",
|
|
|
__func__);
|
|
@@ -894,7 +980,7 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
|
|
|
buf->attr |= MSM_VIDC_ATTR_READ_ONLY;
|
|
|
rc = handle_read_only_buffer(inst, buf);
|
|
|
if (rc)
|
|
|
- msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
+ msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
} else {
|
|
|
buf->attr &= ~MSM_VIDC_ATTR_READ_ONLY;
|
|
|
}
|
|
@@ -993,7 +1079,12 @@ static int handle_input_metadata_buffer(struct msm_vidc_inst *inst,
|
|
|
buf->attr &= ~MSM_VIDC_ATTR_QUEUED;
|
|
|
buf->attr |= MSM_VIDC_ATTR_DEQUEUED;
|
|
|
buf->flags = 0;
|
|
|
- if (buffer->flags & HFI_BUF_FW_FLAG_LAST)
|
|
|
+ if ((is_encode_session(inst) &&
|
|
|
+ (buffer->flags & HFI_BUF_FW_FLAG_LAST)) ||
|
|
|
+ (is_decode_session(inst) &&
|
|
|
+ !inst->capabilities->cap[LAST_FLAG_EVENT_ENABLE].value &&
|
|
|
+ ((buffer->flags & HFI_BUF_FW_FLAG_LAST) ||
|
|
|
+ (buffer->flags & HFI_BUF_FW_FLAG_PSC_LAST))))
|
|
|
buf->flags |= MSM_VIDC_BUF_FLAG_LAST;
|
|
|
|
|
|
print_vidc_buffer(VIDC_LOW, "low ", "dqbuf", inst, buf);
|
|
@@ -1008,6 +1099,11 @@ static int handle_output_metadata_buffer(struct msm_vidc_inst *inst,
|
|
|
struct msm_vidc_buffer *buf;
|
|
|
bool found;
|
|
|
|
|
|
+ if (!inst || !inst->capabilities) {
|
|
|
+ d_vpr_e("%s: Invalid params\n", __func__);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
buffers = msm_vidc_get_buffers(inst, MSM_VIDC_BUF_OUTPUT_META, __func__);
|
|
|
if (!buffers)
|
|
|
return -EINVAL;
|
|
@@ -1035,7 +1131,12 @@ static int handle_output_metadata_buffer(struct msm_vidc_inst *inst,
|
|
|
buf->attr &= ~MSM_VIDC_ATTR_QUEUED;
|
|
|
buf->attr |= MSM_VIDC_ATTR_DEQUEUED;
|
|
|
buf->flags = 0;
|
|
|
- if (buffer->flags & HFI_BUF_FW_FLAG_LAST)
|
|
|
+ if ((is_encode_session(inst) &&
|
|
|
+ (buffer->flags & HFI_BUF_FW_FLAG_LAST)) ||
|
|
|
+ (is_decode_session(inst) &&
|
|
|
+ !inst->capabilities->cap[LAST_FLAG_EVENT_ENABLE].value &&
|
|
|
+ ((buffer->flags & HFI_BUF_FW_FLAG_LAST) ||
|
|
|
+ (buffer->flags & HFI_BUF_FW_FLAG_PSC_LAST))))
|
|
|
buf->flags |= MSM_VIDC_BUF_FLAG_LAST;
|
|
|
|
|
|
print_vidc_buffer(VIDC_LOW, "low ", "dqbuf", inst, buf);
|
|
@@ -1267,18 +1368,18 @@ static int handle_session_buffer(struct msm_vidc_inst *inst,
|
|
|
}
|
|
|
|
|
|
if (!check_for_packet_payload(inst, pkt, __func__)) {
|
|
|
- msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
+ msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
buffer = (struct hfi_buffer *)((u8 *)pkt + sizeof(struct hfi_packet));
|
|
|
if (!is_valid_hfi_buffer_type(inst, buffer->type, __func__)) {
|
|
|
- msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
+ msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
if (!is_valid_hfi_port(inst, pkt->port, buffer->type, __func__)) {
|
|
|
- msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
+ msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
return 0;
|
|
|
}
|
|
|
if (is_decode_session(inst) && buffer->type == HFI_BUFFER_RAW &&
|
|
@@ -1329,6 +1430,39 @@ static int handle_session_buffer(struct msm_vidc_inst *inst,
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
+static int handle_input_port_settings_change(struct msm_vidc_inst *inst)
|
|
|
+{
|
|
|
+ int rc = 0;
|
|
|
+ enum msm_vidc_allow allow = MSM_VIDC_DISALLOW;
|
|
|
+
|
|
|
+ allow = msm_vidc_allow_input_psc(inst);
|
|
|
+ if (allow == MSM_VIDC_DISALLOW) {
|
|
|
+ return -EINVAL;
|
|
|
+ } else if (allow == MSM_VIDC_ALLOW) {
|
|
|
+ rc = msm_vidc_state_change_input_psc(inst);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+ print_psc_properties("INPUT_PSC", inst, inst->subcr_params[INPUT_PORT]);
|
|
|
+ rc = msm_vdec_input_port_settings_change(inst);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
+static int handle_output_port_settings_change(struct msm_vidc_inst *inst)
|
|
|
+{
|
|
|
+ int rc = 0;
|
|
|
+
|
|
|
+ print_psc_properties("OUTPUT_PSC", inst, inst->subcr_params[OUTPUT_PORT]);
|
|
|
+ rc = msm_vdec_output_port_settings_change(inst);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
static int handle_port_settings_change(struct msm_vidc_inst *inst,
|
|
|
struct hfi_packet *pkt)
|
|
|
{
|
|
@@ -1338,17 +1472,23 @@ static int handle_port_settings_change(struct msm_vidc_inst *inst,
|
|
|
__func__, pkt->port);
|
|
|
|
|
|
if (pkt->port == HFI_PORT_RAW) {
|
|
|
- print_psc_properties("OUTPUT_PSC", inst, inst->subcr_params[OUTPUT_PORT]);
|
|
|
- rc = msm_vdec_output_port_settings_change(inst);
|
|
|
+ rc = handle_output_port_settings_change(inst);
|
|
|
+ if (rc)
|
|
|
+ goto exit;
|
|
|
} else if (pkt->port == HFI_PORT_BITSTREAM) {
|
|
|
- print_psc_properties("INPUT_PSC", inst, inst->subcr_params[INPUT_PORT]);
|
|
|
- rc = msm_vdec_input_port_settings_change(inst);
|
|
|
+ rc = handle_input_port_settings_change(inst);
|
|
|
+ if (rc)
|
|
|
+ goto exit;
|
|
|
} else {
|
|
|
i_vpr_e(inst, "%s: invalid port type: %#x\n",
|
|
|
__func__, pkt->port);
|
|
|
rc = -EINVAL;
|
|
|
+ goto exit;
|
|
|
}
|
|
|
|
|
|
+exit:
|
|
|
+ if (rc)
|
|
|
+ msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
@@ -1368,6 +1508,14 @@ static int handle_session_delivery_mode(struct msm_vidc_inst *inst,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int handle_session_pause(struct msm_vidc_inst *inst,
|
|
|
+ struct hfi_packet *pkt)
|
|
|
+{
|
|
|
+ if (pkt->flags & HFI_FW_FLAGS_SUCCESS)
|
|
|
+ i_vpr_h(inst, "%s: successful\n", __func__);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int handle_session_resume(struct msm_vidc_inst *inst,
|
|
|
struct hfi_packet *pkt)
|
|
|
{
|
|
@@ -1398,6 +1546,7 @@ static int handle_session_command(struct msm_vidc_inst *inst,
|
|
|
{HFI_CMD_SETTINGS_CHANGE, handle_port_settings_change },
|
|
|
{HFI_CMD_SUBSCRIBE_MODE, handle_session_subscribe_mode },
|
|
|
{HFI_CMD_DELIVERY_MODE, handle_session_delivery_mode },
|
|
|
+ {HFI_CMD_PAUSE, handle_session_pause },
|
|
|
{HFI_CMD_RESUME, handle_session_resume },
|
|
|
{HFI_CMD_STABILITY, handle_session_stability },
|
|
|
};
|
|
@@ -1437,7 +1586,7 @@ static int handle_dpb_list_property(struct msm_vidc_inst *inst,
|
|
|
i_vpr_e(inst,
|
|
|
"%s: dpb list payload size %d exceeds expected max size %d\n",
|
|
|
__func__, payload_size, MAX_DPB_LIST_PAYLOAD_SIZE);
|
|
|
- msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
+ msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
}
|
|
|
memcpy(inst->dpb_list_payload, payload_start, payload_size);
|
|
|
|
|
@@ -1764,7 +1913,7 @@ static int __handle_session_response(struct msm_vidc_inst *inst,
|
|
|
dequeue |= (packet->type == HFI_CMD_BUFFER);
|
|
|
rc = be[i].handle(inst, packet);
|
|
|
if (rc)
|
|
|
- msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
+ msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
}
|
|
|
pkt += packet->size;
|
|
|
}
|
|
@@ -1780,163 +1929,14 @@ static int __handle_session_response(struct msm_vidc_inst *inst,
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-int handle_session_response_work(struct msm_vidc_inst *inst,
|
|
|
- struct response_work *resp_work)
|
|
|
-{
|
|
|
- int rc = 0;
|
|
|
- struct hfi_header *hdr = NULL;
|
|
|
-
|
|
|
- if (!inst || !inst->core || !resp_work) {
|
|
|
- d_vpr_e("%s: invalid params\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
- hdr = (struct hfi_header *)resp_work->data;
|
|
|
- if (!hdr) {
|
|
|
- i_vpr_e(inst, "%s: invalid params\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- if (resp_work->type == RESP_WORK_INPUT_PSC)
|
|
|
- msm_vdec_init_input_subcr_params(inst);
|
|
|
-
|
|
|
- rc = __handle_session_response(inst, hdr);
|
|
|
- if (rc)
|
|
|
- return rc;
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-void handle_session_response_work_handler(struct work_struct *work)
|
|
|
-{
|
|
|
- int rc = 0;
|
|
|
- struct msm_vidc_inst *inst;
|
|
|
- struct response_work *resp_work, *dummy = NULL;
|
|
|
-
|
|
|
- inst = container_of(work, struct msm_vidc_inst, response_work.work);
|
|
|
- inst = get_inst_ref(g_core, inst);
|
|
|
- if (!inst) {
|
|
|
- d_vpr_e("%s: invalid params\n", __func__);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- inst_lock(inst, __func__);
|
|
|
- list_for_each_entry_safe(resp_work, dummy, &inst->response_works, list) {
|
|
|
- switch (resp_work->type) {
|
|
|
- case RESP_WORK_INPUT_PSC:
|
|
|
- {
|
|
|
- enum msm_vidc_allow allow = MSM_VIDC_DISALLOW;
|
|
|
-
|
|
|
- allow = msm_vidc_allow_input_psc(inst);
|
|
|
- if (allow == MSM_VIDC_DISALLOW) {
|
|
|
- msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
- break;
|
|
|
- } else if (allow == MSM_VIDC_DEFER) {
|
|
|
- /* continue to next entry processing */
|
|
|
- continue;
|
|
|
- } else if (allow == MSM_VIDC_DISCARD) {
|
|
|
- /* if ipsc is discarded then override the psc properties again */
|
|
|
- inst->ipsc_properties_set = false;
|
|
|
- /* discard current entry processing */
|
|
|
- break;
|
|
|
- } else if (allow == MSM_VIDC_ALLOW) {
|
|
|
- rc = handle_session_response_work(inst, resp_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__);
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- case RESP_WORK_OUTPUT_PSC:
|
|
|
- rc = handle_session_response_work(inst, resp_work);
|
|
|
- if (rc)
|
|
|
- msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
- break;
|
|
|
- case RESP_WORK_LAST_FLAG:
|
|
|
- rc = handle_session_response_work(inst, resp_work);
|
|
|
- if (rc) {
|
|
|
- msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
- break;
|
|
|
- }
|
|
|
- if (msm_vidc_allow_last_flag(inst)) {
|
|
|
- rc = msm_vidc_state_change_last_flag(inst);
|
|
|
- if (rc)
|
|
|
- msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
|
|
|
- }
|
|
|
- break;
|
|
|
- default:
|
|
|
- i_vpr_e(inst, "%s: invalid response work type %d\n", __func__,
|
|
|
- resp_work->type);
|
|
|
- break;
|
|
|
- }
|
|
|
- list_del(&resp_work->list);
|
|
|
- msm_vidc_vmem_free((void **)&resp_work->data);
|
|
|
- msm_vidc_vmem_free((void **)&resp_work);
|
|
|
- }
|
|
|
- inst_unlock(inst, __func__);
|
|
|
-
|
|
|
- put_inst(inst);
|
|
|
-}
|
|
|
-
|
|
|
-static int queue_response_work(struct msm_vidc_inst *inst,
|
|
|
- enum response_work_type type, void *hdr, u32 hdr_size)
|
|
|
-{
|
|
|
- struct response_work *work = NULL;
|
|
|
-
|
|
|
- if (msm_vidc_vmem_alloc(sizeof(struct response_work), (void **)&work, __func__))
|
|
|
- return -ENOMEM;
|
|
|
- INIT_LIST_HEAD(&work->list);
|
|
|
- work->type = type;
|
|
|
- work->data_size = hdr_size;
|
|
|
- if (msm_vidc_vmem_alloc(hdr_size, (void **)&work->data, "Work data"))
|
|
|
- return -ENOMEM;
|
|
|
- memcpy(work->data, hdr, hdr_size);
|
|
|
- list_add_tail(&work->list, &inst->response_works);
|
|
|
- queue_delayed_work(inst->response_workq,
|
|
|
- &inst->response_work, msecs_to_jiffies(0));
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int cancel_response_work(struct msm_vidc_inst *inst)
|
|
|
-{
|
|
|
- struct response_work *work, *dummy_work = NULL;
|
|
|
-
|
|
|
- if (!inst) {
|
|
|
- d_vpr_e("%s: Invalid arguments\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- cancel_delayed_work(&inst->response_work);
|
|
|
-
|
|
|
- list_for_each_entry_safe(work, dummy_work, &inst->response_works, list) {
|
|
|
- list_del(&work->list);
|
|
|
- msm_vidc_vmem_free((void **)&work->data);
|
|
|
- msm_vidc_vmem_free((void **)&work);
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int cancel_response_work_sync(struct msm_vidc_inst *inst)
|
|
|
-{
|
|
|
- if (!inst || !inst->response_workq) {
|
|
|
- d_vpr_e("%s: Invalid arguments\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- cancel_delayed_work_sync(&inst->response_work);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
static int handle_session_response(struct msm_vidc_core *core,
|
|
|
struct hfi_header *hdr)
|
|
|
{
|
|
|
struct msm_vidc_inst *inst;
|
|
|
struct hfi_packet *packet;
|
|
|
u8 *pkt;
|
|
|
- enum response_work_type type;
|
|
|
int i, rc = 0;
|
|
|
- bool offload = false;
|
|
|
+ bool found_ipsc = false;
|
|
|
|
|
|
if (!core || !hdr) {
|
|
|
d_vpr_e("%s: Invalid params\n", __func__);
|
|
@@ -1950,42 +1950,22 @@ static int handle_session_response(struct msm_vidc_core *core,
|
|
|
}
|
|
|
|
|
|
inst_lock(inst, __func__);
|
|
|
- /* search for special pkt */
|
|
|
+ /* search for cmd settings change pkt */
|
|
|
pkt = (u8 *)((u8 *)hdr + sizeof(struct hfi_header));
|
|
|
for (i = 0; i < hdr->num_packets; i++) {
|
|
|
packet = (struct hfi_packet *)pkt;
|
|
|
-
|
|
|
if (packet->type == HFI_CMD_SETTINGS_CHANGE) {
|
|
|
if (packet->port == HFI_PORT_BITSTREAM) {
|
|
|
- offload = true;
|
|
|
- type = RESP_WORK_INPUT_PSC;
|
|
|
- } else if (packet->port == HFI_PORT_RAW) {
|
|
|
- offload = true;
|
|
|
- type = RESP_WORK_OUTPUT_PSC;
|
|
|
- }
|
|
|
- } else if (packet->type == HFI_CMD_BUFFER &&
|
|
|
- vidc_port_from_hfi(inst, packet->port) ==
|
|
|
- OUTPUT_PORT) {
|
|
|
- if (check_last_flag(inst, packet)) {
|
|
|
- offload = true;
|
|
|
- type = RESP_WORK_LAST_FLAG;
|
|
|
+ found_ipsc = true;
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- if (offload)
|
|
|
- break;
|
|
|
-
|
|
|
pkt += packet->size;
|
|
|
}
|
|
|
|
|
|
- if (offload) {
|
|
|
- i_vpr_h(inst, "%s: queue response work %#x\n", __func__, type);
|
|
|
- rc = queue_response_work(inst, type, (void *)hdr, hdr->size);
|
|
|
- if (rc)
|
|
|
- i_vpr_e(inst, "%s: Offload response work failed\n", __func__);
|
|
|
-
|
|
|
- goto exit;
|
|
|
- }
|
|
|
+ /* if ipsc packet is found, initialise subsc_params */
|
|
|
+ if (found_ipsc)
|
|
|
+ msm_vdec_init_input_subcr_params(inst);
|
|
|
|
|
|
rc = __handle_session_response(inst, hdr);
|
|
|
if (rc)
|