summaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c')
-rw-r--r--drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c79
1 files changed, 76 insertions, 3 deletions
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
index 78fefa4176f9..18ba5f67dd36 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c
@@ -13,13 +13,54 @@ iris_hfi_gen1_sys_event_notify(struct iris_core *core, void *packet)
struct hfi_msg_event_notify_pkt *pkt = packet;
if (pkt->event_id == HFI_EVENT_SYS_ERROR)
- dev_err(core->dev, "sys error (type: %x, data1:%x, data2:%x)\n",
- pkt->event_id, pkt->event_data1, pkt->event_data2);
+ dev_err(core->dev, "sys error (type: %x, session id:%x, data1:%x, data2:%x)\n",
+ pkt->event_id, pkt->shdr.session_id, pkt->event_data1,
+ pkt->event_data2);
core->state = IRIS_CORE_ERROR;
schedule_delayed_work(&core->sys_error_handler, msecs_to_jiffies(10));
}
+static void
+iris_hfi_gen1_event_session_error(struct iris_inst *inst, struct hfi_msg_event_notify_pkt *pkt)
+{
+ switch (pkt->event_data1) {
+ /* non fatal session errors */
+ case HFI_ERR_SESSION_INVALID_SCALE_FACTOR:
+ case HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE:
+ case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
+ case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED:
+ dev_dbg(inst->core->dev, "session error: event id:%x, session id:%x\n",
+ pkt->event_data1, pkt->shdr.session_id);
+ break;
+ /* fatal session errors */
+ default:
+ /*
+ * firmware fills event_data2 as an additional information about the
+ * hfi command for which session error has ouccured.
+ */
+ dev_err(inst->core->dev,
+ "session error for command: %x, event id:%x, session id:%x\n",
+ pkt->event_data2, pkt->event_data1,
+ pkt->shdr.session_id);
+ iris_vb2_queue_error(inst);
+ break;
+ }
+}
+
+static void iris_hfi_gen1_session_event_notify(struct iris_inst *inst, void *packet)
+{
+ struct hfi_msg_event_notify_pkt *pkt = packet;
+
+ switch (pkt->event_id) {
+ case HFI_EVENT_SESSION_ERROR:
+ iris_hfi_gen1_event_session_error(inst, pkt);
+ break;
+ default:
+ break;
+ }
+}
+
static void iris_hfi_gen1_sys_init_done(struct iris_core *core, void *packet)
{
struct hfi_msg_sys_init_done_pkt *pkt = packet;
@@ -99,6 +140,14 @@ static const struct iris_hfi_gen1_response_pkt_info pkt_infos[] = {
.pkt = HFI_MSG_SYS_PROPERTY_INFO,
.pkt_sz = sizeof(struct hfi_msg_sys_property_info_pkt),
},
+ {
+ .pkt = HFI_MSG_SYS_SESSION_INIT,
+ .pkt_sz = sizeof(struct hfi_msg_session_init_done_pkt),
+ },
+ {
+ .pkt = HFI_MSG_SYS_SESSION_END,
+ .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt),
+ },
};
static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response)
@@ -106,6 +155,8 @@ static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response
struct hfi_pkt_hdr *hdr = (struct hfi_pkt_hdr *)response;
const struct iris_hfi_gen1_response_pkt_info *pkt_info;
struct device *dev = core->dev;
+ struct hfi_session_pkt *pkt;
+ struct iris_inst *inst;
bool found = false;
u32 i;
@@ -132,9 +183,31 @@ static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response
iris_hfi_gen1_sys_property_info(core, hdr);
break;
case HFI_MSG_EVENT_NOTIFY:
- iris_hfi_gen1_sys_event_notify(core, hdr);
+ pkt = (struct hfi_session_pkt *)hdr;
+ inst = iris_get_instance(core, pkt->shdr.session_id);
+ if (inst) {
+ mutex_lock(&inst->lock);
+ iris_hfi_gen1_session_event_notify(inst, hdr);
+ mutex_unlock(&inst->lock);
+ } else {
+ iris_hfi_gen1_sys_event_notify(core, hdr);
+ }
+
break;
default:
+ pkt = (struct hfi_session_pkt *)hdr;
+ inst = iris_get_instance(core, pkt->shdr.session_id);
+ if (!inst) {
+ dev_warn(dev, "no valid instance(pkt session_id:%x, pkt:%x)\n",
+ pkt->shdr.session_id,
+ pkt_info ? pkt_info->pkt : 0);
+ return;
+ }
+
+ mutex_lock(&inst->lock);
+ complete(&inst->completion);
+ mutex_unlock(&inst->lock);
+
break;
}
}