1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
4 * Copyright (C) 2017 Linaro Ltd.
6 #include <linux/hash.h>
7 #include <linux/list.h>
8 #include <linux/slab.h>
9 #include <linux/soc/qcom/smem.h>
10 #include <media/videobuf2-v4l2.h>
14 #include "hfi_helper.h"
16 #include "hfi_parser.h"
18 #define SMEM_IMG_VER_TBL 469
19 #define VER_STR_SZ 128
20 #define SMEM_IMG_OFFSET_VENUS (14 * 128)
22 static void event_seq_changed(struct venus_core *core, struct venus_inst *inst,
23 struct hfi_msg_event_notify_pkt *pkt)
25 enum hfi_version ver = core->res->hfi_version;
26 struct hfi_event_data event = {0};
27 int num_properties_changed;
28 struct hfi_framesize *frame_sz;
29 struct hfi_profile_level *profile_level;
30 struct hfi_bit_depth *pixel_depth;
31 struct hfi_pic_struct *pic_struct;
32 struct hfi_colour_space *colour_info;
33 struct hfi_buffer_requirements *bufreq;
34 struct hfi_extradata_input_crop *crop;
35 struct hfi_dpb_counts *dpb_count;
39 inst->error = HFI_ERR_NONE;
41 switch (pkt->event_data1) {
42 case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES:
43 case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES:
46 inst->error = HFI_ERR_SESSION_INVALID_PARAMETER;
50 event.event_type = pkt->event_data1;
52 num_properties_changed = pkt->event_data2;
53 if (!num_properties_changed) {
54 inst->error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;
58 data_ptr = (u8 *)&pkt->ext_event_data[0];
60 ptype = *((u32 *)data_ptr);
62 case HFI_PROPERTY_PARAM_FRAME_SIZE:
63 data_ptr += sizeof(u32);
64 frame_sz = (struct hfi_framesize *)data_ptr;
65 event.width = frame_sz->width;
66 event.height = frame_sz->height;
67 data_ptr += sizeof(*frame_sz);
69 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
70 data_ptr += sizeof(u32);
71 profile_level = (struct hfi_profile_level *)data_ptr;
72 event.profile = profile_level->profile;
73 event.level = profile_level->level;
74 data_ptr += sizeof(*profile_level);
76 case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
77 data_ptr += sizeof(u32);
78 pixel_depth = (struct hfi_bit_depth *)data_ptr;
79 event.bit_depth = pixel_depth->bit_depth;
80 data_ptr += sizeof(*pixel_depth);
82 case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
83 data_ptr += sizeof(u32);
84 pic_struct = (struct hfi_pic_struct *)data_ptr;
85 event.pic_struct = pic_struct->progressive_only;
86 data_ptr += sizeof(*pic_struct);
88 case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
89 data_ptr += sizeof(u32);
90 colour_info = (struct hfi_colour_space *)data_ptr;
91 event.colour_space = colour_info->colour_space;
92 data_ptr += sizeof(*colour_info);
94 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
95 data_ptr += sizeof(u32);
96 event.entropy_mode = *(u32 *)data_ptr;
97 data_ptr += sizeof(u32);
99 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
100 data_ptr += sizeof(u32);
101 bufreq = (struct hfi_buffer_requirements *)data_ptr;
102 event.buf_count = hfi_bufreq_get_count_min(bufreq, ver);
103 data_ptr += sizeof(*bufreq);
105 case HFI_INDEX_EXTRADATA_INPUT_CROP:
106 data_ptr += sizeof(u32);
107 crop = (struct hfi_extradata_input_crop *)data_ptr;
108 event.input_crop.left = crop->left;
109 event.input_crop.top = crop->top;
110 event.input_crop.width = crop->width;
111 event.input_crop.height = crop->height;
112 data_ptr += sizeof(*crop);
114 case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS:
115 data_ptr += sizeof(u32);
116 dpb_count = (struct hfi_dpb_counts *)data_ptr;
117 event.buf_count = dpb_count->fw_min_cnt;
118 data_ptr += sizeof(*dpb_count);
123 num_properties_changed--;
124 } while (num_properties_changed > 0);
127 inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
130 static void event_release_buffer_ref(struct venus_core *core,
131 struct venus_inst *inst,
132 struct hfi_msg_event_notify_pkt *pkt)
134 struct hfi_event_data event = {0};
135 struct hfi_msg_event_release_buffer_ref_pkt *data;
137 data = (struct hfi_msg_event_release_buffer_ref_pkt *)
140 event.event_type = HFI_EVENT_RELEASE_BUFFER_REFERENCE;
141 event.packet_buffer = data->packet_buffer;
142 event.extradata_buffer = data->extradata_buffer;
143 event.tag = data->output_tag;
145 inst->error = HFI_ERR_NONE;
146 inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
149 static void event_sys_error(struct venus_core *core, u32 event,
150 struct hfi_msg_event_notify_pkt *pkt)
153 dev_dbg(core->dev, VDBGH
154 "sys error (session id:%x, data1:%x, data2:%x)\n",
155 pkt->shdr.session_id, pkt->event_data1,
158 core->core_ops->event_notify(core, event);
162 event_session_error(struct venus_core *core, struct venus_inst *inst,
163 struct hfi_msg_event_notify_pkt *pkt)
165 struct device *dev = core->dev;
167 dev_dbg(dev, VDBGH "session error: event id:%x, session id:%x\n",
168 pkt->event_data1, pkt->shdr.session_id);
173 switch (pkt->event_data1) {
174 /* non fatal session errors */
175 case HFI_ERR_SESSION_INVALID_SCALE_FACTOR:
176 case HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE:
177 case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
178 case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED:
179 inst->error = HFI_ERR_NONE;
182 dev_err(dev, "session error: event id:%x (%x), session id:%x\n",
183 pkt->event_data1, pkt->event_data2,
184 pkt->shdr.session_id);
186 inst->error = pkt->event_data1;
187 inst->ops->event_notify(inst, EVT_SESSION_ERROR, NULL);
192 static void hfi_event_notify(struct venus_core *core, struct venus_inst *inst,
195 struct hfi_msg_event_notify_pkt *pkt = packet;
200 switch (pkt->event_id) {
201 case HFI_EVENT_SYS_ERROR:
202 event_sys_error(core, EVT_SYS_ERROR, pkt);
204 case HFI_EVENT_SESSION_ERROR:
205 event_session_error(core, inst, pkt);
207 case HFI_EVENT_SESSION_SEQUENCE_CHANGED:
208 event_seq_changed(core, inst, pkt);
210 case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
211 event_release_buffer_ref(core, inst, pkt);
213 case HFI_EVENT_SESSION_PROPERTY_CHANGED:
220 static void hfi_sys_init_done(struct venus_core *core, struct venus_inst *inst,
223 struct hfi_msg_sys_init_done_pkt *pkt = packet;
227 error = pkt->error_type;
228 if (error != HFI_ERR_NONE)
231 if (!pkt->num_properties) {
232 error = HFI_ERR_SYS_INVALID_PARAMETER;
236 rem_bytes = pkt->hdr.size - sizeof(*pkt);
237 if (rem_bytes <= 0) {
238 /* missing property data */
239 error = HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
243 error = hfi_parser(core, inst, pkt->data, rem_bytes);
247 complete(&core->done);
251 sys_get_prop_image_version(struct venus_core *core,
252 struct hfi_msg_sys_property_info_pkt *pkt)
254 struct device *dev = core->dev;
261 req_bytes = pkt->hdr.size - sizeof(*pkt);
263 if (req_bytes < VER_STR_SZ || !pkt->data[0] || pkt->num_properties > 1)
271 ret = sscanf(img_ver, "14:video-firmware.%u.%u-%u",
272 &core->venus_ver.major, &core->venus_ver.minor, &core->venus_ver.rev);
276 ret = sscanf(img_ver, "14:VIDEO.VPU.%u.%u-%u",
277 &core->venus_ver.major, &core->venus_ver.minor, &core->venus_ver.rev);
281 ret = sscanf(img_ver, "14:VIDEO.VE.%u.%u-%u",
282 &core->venus_ver.major, &core->venus_ver.minor, &core->venus_ver.rev);
286 dev_err(dev, VDBGL "error reading F/W version\n");
290 dev_dbg(dev, VDBGL "F/W version: %s, major %u, minor %u, revision %u\n",
291 img_ver, core->venus_ver.major, core->venus_ver.minor, core->venus_ver.rev);
293 smem_tbl_ptr = qcom_smem_get(QCOM_SMEM_HOST_ANY,
294 SMEM_IMG_VER_TBL, &smem_blk_sz);
295 if (!IS_ERR(smem_tbl_ptr) && smem_blk_sz >= SMEM_IMG_OFFSET_VENUS + VER_STR_SZ)
296 memcpy(smem_tbl_ptr + SMEM_IMG_OFFSET_VENUS,
297 img_ver, VER_STR_SZ);
300 static void hfi_sys_property_info(struct venus_core *core,
301 struct venus_inst *inst, void *packet)
303 struct hfi_msg_sys_property_info_pkt *pkt = packet;
304 struct device *dev = core->dev;
306 if (!pkt->num_properties) {
307 dev_dbg(dev, VDBGL "no properties\n");
311 switch (pkt->property) {
312 case HFI_PROPERTY_SYS_IMAGE_VERSION:
313 sys_get_prop_image_version(core, pkt);
316 dev_dbg(dev, VDBGL "unknown property data\n");
321 static void hfi_sys_rel_resource_done(struct venus_core *core,
322 struct venus_inst *inst,
325 struct hfi_msg_sys_release_resource_done_pkt *pkt = packet;
327 core->error = pkt->error_type;
328 complete(&core->done);
331 static void hfi_sys_ping_done(struct venus_core *core, struct venus_inst *inst,
334 struct hfi_msg_sys_ping_ack_pkt *pkt = packet;
336 core->error = HFI_ERR_NONE;
338 if (pkt->client_data != 0xbeef)
339 core->error = HFI_ERR_SYS_FATAL;
341 complete(&core->done);
344 static void hfi_sys_idle_done(struct venus_core *core, struct venus_inst *inst,
347 dev_dbg(core->dev, VDBGL "sys idle\n");
350 static void hfi_sys_pc_prepare_done(struct venus_core *core,
351 struct venus_inst *inst, void *packet)
353 struct hfi_msg_sys_pc_prep_done_pkt *pkt = packet;
355 dev_dbg(core->dev, VDBGL "pc prepare done (error %x)\n",
360 session_get_prop_profile_level(struct hfi_msg_session_property_info_pkt *pkt,
361 struct hfi_profile_level *profile_level)
363 struct hfi_profile_level *hfi;
366 req_bytes = pkt->shdr.hdr.size - sizeof(*pkt);
368 if (!req_bytes || req_bytes % sizeof(struct hfi_profile_level))
370 return HFI_ERR_SESSION_INVALID_PARAMETER;
372 hfi = (struct hfi_profile_level *)&pkt->data[0];
373 profile_level->profile = hfi->profile;
374 profile_level->level = hfi->level;
380 session_get_prop_buf_req(struct hfi_msg_session_property_info_pkt *pkt,
381 struct hfi_buffer_requirements *bufreq)
383 struct hfi_buffer_requirements *buf_req;
385 unsigned int idx = 0;
387 req_bytes = pkt->shdr.hdr.size - sizeof(*pkt);
389 if (!req_bytes || req_bytes % sizeof(*buf_req) || !pkt->data[0])
391 return HFI_ERR_SESSION_INVALID_PARAMETER;
393 buf_req = (struct hfi_buffer_requirements *)&pkt->data[0];
395 return HFI_ERR_SESSION_INVALID_PARAMETER;
398 memcpy(&bufreq[idx], buf_req, sizeof(*bufreq));
401 if (idx >= HFI_BUFFER_TYPE_MAX)
402 return HFI_ERR_SESSION_INVALID_PARAMETER;
404 req_bytes -= sizeof(struct hfi_buffer_requirements);
411 static void hfi_session_prop_info(struct venus_core *core,
412 struct venus_inst *inst, void *packet)
414 struct hfi_msg_session_property_info_pkt *pkt = packet;
415 struct device *dev = core->dev;
416 union hfi_get_property *hprop = &inst->hprop;
417 unsigned int error = HFI_ERR_NONE;
419 if (!pkt->num_properties) {
420 error = HFI_ERR_SESSION_INVALID_PARAMETER;
421 dev_err(dev, "%s: no properties\n", __func__);
425 switch (pkt->property) {
426 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
427 memset(hprop->bufreq, 0, sizeof(hprop->bufreq));
428 error = session_get_prop_buf_req(pkt, hprop->bufreq);
430 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
431 memset(&hprop->profile_level, 0, sizeof(hprop->profile_level));
432 error = session_get_prop_profile_level(pkt,
433 &hprop->profile_level);
435 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
438 dev_dbg(dev, VDBGM "unknown property id:%x\n", pkt->property);
444 complete(&inst->done);
447 static void hfi_session_init_done(struct venus_core *core,
448 struct venus_inst *inst, void *packet)
450 struct hfi_msg_session_init_done_pkt *pkt = packet;
454 error = pkt->error_type;
455 if (error != HFI_ERR_NONE)
461 rem_bytes = pkt->shdr.hdr.size - sizeof(*pkt);
462 if (rem_bytes <= 0) {
463 error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;
467 error = hfi_parser(core, inst, pkt->data, rem_bytes);
470 complete(&inst->done);
473 static void hfi_session_load_res_done(struct venus_core *core,
474 struct venus_inst *inst, void *packet)
476 struct hfi_msg_session_load_resources_done_pkt *pkt = packet;
478 inst->error = pkt->error_type;
479 complete(&inst->done);
482 static void hfi_session_flush_done(struct venus_core *core,
483 struct venus_inst *inst, void *packet)
485 struct hfi_msg_session_flush_done_pkt *pkt = packet;
487 inst->error = pkt->error_type;
488 complete(&inst->done);
489 if (inst->ops->flush_done)
490 inst->ops->flush_done(inst);
493 static void hfi_session_etb_done(struct venus_core *core,
494 struct venus_inst *inst, void *packet)
496 struct hfi_msg_session_empty_buffer_done_pkt *pkt = packet;
498 inst->error = pkt->error_type;
499 inst->ops->buf_done(inst, HFI_BUFFER_INPUT, pkt->input_tag,
500 pkt->filled_len, pkt->offset, 0, 0, 0);
503 static void hfi_session_ftb_done(struct venus_core *core,
504 struct venus_inst *inst, void *packet)
506 u32 session_type = inst->session_type;
507 u64 timestamp_us = 0;
508 u32 timestamp_hi = 0, timestamp_lo = 0;
510 u32 flags = 0, hfi_flags = 0, offset = 0, filled_len = 0;
511 u32 pic_type = 0, buffer_type = 0, output_tag = -1;
513 if (session_type == VIDC_SESSION_TYPE_ENC) {
514 struct hfi_msg_session_fbd_compressed_pkt *pkt = packet;
516 timestamp_hi = pkt->time_stamp_hi;
517 timestamp_lo = pkt->time_stamp_lo;
518 hfi_flags = pkt->flags;
519 offset = pkt->offset;
520 filled_len = pkt->filled_len;
521 pic_type = pkt->picture_type;
522 output_tag = pkt->output_tag;
523 buffer_type = HFI_BUFFER_OUTPUT;
525 error = pkt->error_type;
526 } else if (session_type == VIDC_SESSION_TYPE_DEC) {
527 struct hfi_msg_session_fbd_uncompressed_plane0_pkt *pkt =
530 timestamp_hi = pkt->time_stamp_hi;
531 timestamp_lo = pkt->time_stamp_lo;
532 hfi_flags = pkt->flags;
533 offset = pkt->offset;
534 filled_len = pkt->filled_len;
535 pic_type = pkt->picture_type;
536 output_tag = pkt->output_tag;
538 if (pkt->stream_id == 0)
539 buffer_type = HFI_BUFFER_OUTPUT;
540 else if (pkt->stream_id == 1)
541 buffer_type = HFI_BUFFER_OUTPUT2;
543 error = pkt->error_type;
545 error = HFI_ERR_SESSION_INVALID_PARAMETER;
548 if (buffer_type != HFI_BUFFER_OUTPUT &&
549 buffer_type != HFI_BUFFER_OUTPUT2)
552 if (hfi_flags & HFI_BUFFERFLAG_EOS)
553 flags |= V4L2_BUF_FLAG_LAST;
556 case HFI_PICTURE_IDR:
558 flags |= V4L2_BUF_FLAG_KEYFRAME;
561 flags |= V4L2_BUF_FLAG_PFRAME;
564 flags |= V4L2_BUF_FLAG_BFRAME;
566 case HFI_FRAME_NOTCODED:
567 case HFI_UNUSED_PICT:
573 if (!(hfi_flags & HFI_BUFFERFLAG_TIMESTAMPINVALID) && filled_len) {
574 timestamp_us = timestamp_hi;
575 timestamp_us = (timestamp_us << 32) | timestamp_lo;
580 inst->ops->buf_done(inst, buffer_type, output_tag, filled_len,
581 offset, flags, hfi_flags, timestamp_us);
584 static void hfi_session_start_done(struct venus_core *core,
585 struct venus_inst *inst, void *packet)
587 struct hfi_msg_session_start_done_pkt *pkt = packet;
589 inst->error = pkt->error_type;
590 complete(&inst->done);
593 static void hfi_session_stop_done(struct venus_core *core,
594 struct venus_inst *inst, void *packet)
596 struct hfi_msg_session_stop_done_pkt *pkt = packet;
598 inst->error = pkt->error_type;
599 complete(&inst->done);
602 static void hfi_session_rel_res_done(struct venus_core *core,
603 struct venus_inst *inst, void *packet)
605 struct hfi_msg_session_release_resources_done_pkt *pkt = packet;
607 inst->error = pkt->error_type;
608 complete(&inst->done);
611 static void hfi_session_rel_buf_done(struct venus_core *core,
612 struct venus_inst *inst, void *packet)
614 struct hfi_msg_session_release_buffers_done_pkt *pkt = packet;
616 inst->error = pkt->error_type;
617 complete(&inst->done);
620 static void hfi_session_end_done(struct venus_core *core,
621 struct venus_inst *inst, void *packet)
623 struct hfi_msg_session_end_done_pkt *pkt = packet;
625 inst->error = pkt->error_type;
626 complete(&inst->done);
629 static void hfi_session_abort_done(struct venus_core *core,
630 struct venus_inst *inst, void *packet)
632 struct hfi_msg_sys_session_abort_done_pkt *pkt = packet;
634 inst->error = pkt->error_type;
635 complete(&inst->done);
638 static void hfi_session_get_seq_hdr_done(struct venus_core *core,
639 struct venus_inst *inst, void *packet)
641 struct hfi_msg_session_get_sequence_hdr_done_pkt *pkt = packet;
643 inst->error = pkt->error_type;
644 complete(&inst->done);
647 struct hfi_done_handler {
651 void (*done)(struct venus_core *, struct venus_inst *, void *);
655 static const struct hfi_done_handler handlers[] = {
656 {.pkt = HFI_MSG_EVENT_NOTIFY,
657 .pkt_sz = sizeof(struct hfi_msg_event_notify_pkt),
658 .done = hfi_event_notify,
660 {.pkt = HFI_MSG_SYS_INIT,
661 .pkt_sz = sizeof(struct hfi_msg_sys_init_done_pkt),
662 .done = hfi_sys_init_done,
665 {.pkt = HFI_MSG_SYS_PROPERTY_INFO,
666 .pkt_sz = sizeof(struct hfi_msg_sys_property_info_pkt),
667 .done = hfi_sys_property_info,
670 {.pkt = HFI_MSG_SYS_RELEASE_RESOURCE,
671 .pkt_sz = sizeof(struct hfi_msg_sys_release_resource_done_pkt),
672 .done = hfi_sys_rel_resource_done,
675 {.pkt = HFI_MSG_SYS_PING_ACK,
676 .pkt_sz = sizeof(struct hfi_msg_sys_ping_ack_pkt),
677 .done = hfi_sys_ping_done,
680 {.pkt = HFI_MSG_SYS_IDLE,
681 .pkt_sz = sizeof(struct hfi_msg_sys_idle_pkt),
682 .done = hfi_sys_idle_done,
685 {.pkt = HFI_MSG_SYS_PC_PREP,
686 .pkt_sz = sizeof(struct hfi_msg_sys_pc_prep_done_pkt),
687 .done = hfi_sys_pc_prepare_done,
690 {.pkt = HFI_MSG_SYS_SESSION_INIT,
691 .pkt_sz = sizeof(struct hfi_msg_session_init_done_pkt),
692 .done = hfi_session_init_done,
694 {.pkt = HFI_MSG_SYS_SESSION_END,
695 .pkt_sz = sizeof(struct hfi_msg_session_end_done_pkt),
696 .done = hfi_session_end_done,
698 {.pkt = HFI_MSG_SESSION_LOAD_RESOURCES,
699 .pkt_sz = sizeof(struct hfi_msg_session_load_resources_done_pkt),
700 .done = hfi_session_load_res_done,
702 {.pkt = HFI_MSG_SESSION_START,
703 .pkt_sz = sizeof(struct hfi_msg_session_start_done_pkt),
704 .done = hfi_session_start_done,
706 {.pkt = HFI_MSG_SESSION_STOP,
707 .pkt_sz = sizeof(struct hfi_msg_session_stop_done_pkt),
708 .done = hfi_session_stop_done,
710 {.pkt = HFI_MSG_SYS_SESSION_ABORT,
711 .pkt_sz = sizeof(struct hfi_msg_sys_session_abort_done_pkt),
712 .done = hfi_session_abort_done,
714 {.pkt = HFI_MSG_SESSION_EMPTY_BUFFER,
715 .pkt_sz = sizeof(struct hfi_msg_session_empty_buffer_done_pkt),
716 .done = hfi_session_etb_done,
718 {.pkt = HFI_MSG_SESSION_FILL_BUFFER,
719 .pkt_sz = sizeof(struct hfi_msg_session_fbd_uncompressed_plane0_pkt),
720 .pkt_sz2 = sizeof(struct hfi_msg_session_fbd_compressed_pkt),
721 .done = hfi_session_ftb_done,
723 {.pkt = HFI_MSG_SESSION_FLUSH,
724 .pkt_sz = sizeof(struct hfi_msg_session_flush_done_pkt),
725 .done = hfi_session_flush_done,
727 {.pkt = HFI_MSG_SESSION_PROPERTY_INFO,
728 .pkt_sz = sizeof(struct hfi_msg_session_property_info_pkt),
729 .done = hfi_session_prop_info,
731 {.pkt = HFI_MSG_SESSION_RELEASE_RESOURCES,
732 .pkt_sz = sizeof(struct hfi_msg_session_release_resources_done_pkt),
733 .done = hfi_session_rel_res_done,
735 {.pkt = HFI_MSG_SESSION_GET_SEQUENCE_HEADER,
736 .pkt_sz = sizeof(struct hfi_msg_session_get_sequence_hdr_done_pkt),
737 .done = hfi_session_get_seq_hdr_done,
739 {.pkt = HFI_MSG_SESSION_RELEASE_BUFFERS,
740 .pkt_sz = sizeof(struct hfi_msg_session_release_buffers_done_pkt),
741 .done = hfi_session_rel_buf_done,
745 void hfi_process_watchdog_timeout(struct venus_core *core)
747 event_sys_error(core, EVT_SYS_WATCHDOG_TIMEOUT, NULL);
750 static struct venus_inst *to_instance(struct venus_core *core, u32 session_id)
752 struct venus_inst *inst;
754 mutex_lock(&core->lock);
755 list_for_each_entry(inst, &core->instances, list)
756 if (hash32_ptr(inst) == session_id) {
757 mutex_unlock(&core->lock);
760 mutex_unlock(&core->lock);
765 u32 hfi_process_msg_packet(struct venus_core *core, struct hfi_pkt_hdr *hdr)
767 const struct hfi_done_handler *handler;
768 struct device *dev = core->dev;
769 struct venus_inst *inst;
773 for (i = 0; i < ARRAY_SIZE(handlers); i++) {
774 handler = &handlers[i];
775 if (handler->pkt != hdr->pkt_type)
782 return hdr->pkt_type;
784 if (hdr->size && hdr->size < handler->pkt_sz &&
785 hdr->size < handler->pkt_sz2) {
786 dev_err(dev, "bad packet size (%d should be %d, pkt type:%x)\n",
787 hdr->size, handler->pkt_sz, hdr->pkt_type);
789 return hdr->pkt_type;
792 if (handler->is_sys_pkt) {
795 struct hfi_session_pkt *pkt;
797 pkt = (struct hfi_session_pkt *)hdr;
798 inst = to_instance(core, pkt->shdr.session_id);
801 dev_warn(dev, "no valid instance(pkt session_id:%x, pkt:%x)\n",
802 pkt->shdr.session_id,
803 handler ? handler->pkt : 0);
806 * Event of type HFI_EVENT_SYS_ERROR will not have any session
809 if (!inst && hdr->pkt_type != HFI_MSG_EVENT_NOTIFY) {
810 dev_err(dev, "got invalid session id:%x\n",
811 pkt->shdr.session_id);
812 goto invalid_session;
816 handler->done(core, inst, hdr);
819 return hdr->pkt_type;