f81232: switch to ->get_serial()
[linux/fpc-iii.git] / drivers / media / platform / qcom / venus / hfi_msgs.c
blob0ecdaa15c296971f0a2968f81af97ec1c1101d25
1 /*
2 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
3 * Copyright (C) 2017 Linaro Ltd.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 and
7 * only version 2 as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <linux/hash.h>
16 #include <linux/list.h>
17 #include <linux/slab.h>
18 #include <media/videobuf2-v4l2.h>
20 #include "core.h"
21 #include "hfi.h"
22 #include "hfi_helper.h"
23 #include "hfi_msgs.h"
24 #include "hfi_parser.h"
26 static void event_seq_changed(struct venus_core *core, struct venus_inst *inst,
27 struct hfi_msg_event_notify_pkt *pkt)
29 enum hfi_version ver = core->res->hfi_version;
30 struct hfi_event_data event = {0};
31 int num_properties_changed;
32 struct hfi_framesize *frame_sz;
33 struct hfi_profile_level *profile_level;
34 struct hfi_bit_depth *pixel_depth;
35 struct hfi_pic_struct *pic_struct;
36 struct hfi_colour_space *colour_info;
37 struct hfi_buffer_requirements *bufreq;
38 struct hfi_extradata_input_crop *crop;
39 u8 *data_ptr;
40 u32 ptype;
42 inst->error = HFI_ERR_NONE;
44 switch (pkt->event_data1) {
45 case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES:
46 case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES:
47 break;
48 default:
49 inst->error = HFI_ERR_SESSION_INVALID_PARAMETER;
50 goto done;
53 event.event_type = pkt->event_data1;
55 num_properties_changed = pkt->event_data2;
56 if (!num_properties_changed) {
57 inst->error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;
58 goto done;
61 data_ptr = (u8 *)&pkt->ext_event_data[0];
62 do {
63 ptype = *((u32 *)data_ptr);
64 switch (ptype) {
65 case HFI_PROPERTY_PARAM_FRAME_SIZE:
66 data_ptr += sizeof(u32);
67 frame_sz = (struct hfi_framesize *)data_ptr;
68 event.width = frame_sz->width;
69 event.height = frame_sz->height;
70 data_ptr += sizeof(*frame_sz);
71 break;
72 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
73 data_ptr += sizeof(u32);
74 profile_level = (struct hfi_profile_level *)data_ptr;
75 event.profile = profile_level->profile;
76 event.level = profile_level->level;
77 data_ptr += sizeof(*profile_level);
78 break;
79 case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
80 data_ptr += sizeof(u32);
81 pixel_depth = (struct hfi_bit_depth *)data_ptr;
82 event.bit_depth = pixel_depth->bit_depth;
83 data_ptr += sizeof(*pixel_depth);
84 break;
85 case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
86 data_ptr += sizeof(u32);
87 pic_struct = (struct hfi_pic_struct *)data_ptr;
88 event.pic_struct = pic_struct->progressive_only;
89 data_ptr += sizeof(*pic_struct);
90 break;
91 case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
92 data_ptr += sizeof(u32);
93 colour_info = (struct hfi_colour_space *)data_ptr;
94 event.colour_space = colour_info->colour_space;
95 data_ptr += sizeof(*colour_info);
96 break;
97 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
98 data_ptr += sizeof(u32);
99 event.entropy_mode = *(u32 *)data_ptr;
100 data_ptr += sizeof(u32);
101 break;
102 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
103 data_ptr += sizeof(u32);
104 bufreq = (struct hfi_buffer_requirements *)data_ptr;
105 event.buf_count = HFI_BUFREQ_COUNT_MIN(bufreq, ver);
106 data_ptr += sizeof(*bufreq);
107 break;
108 case HFI_INDEX_EXTRADATA_INPUT_CROP:
109 data_ptr += sizeof(u32);
110 crop = (struct hfi_extradata_input_crop *)data_ptr;
111 event.input_crop.left = crop->left;
112 event.input_crop.top = crop->top;
113 event.input_crop.width = crop->width;
114 event.input_crop.height = crop->height;
115 data_ptr += sizeof(*crop);
116 break;
117 default:
118 break;
120 num_properties_changed--;
121 } while (num_properties_changed > 0);
123 done:
124 inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
127 static void event_release_buffer_ref(struct venus_core *core,
128 struct venus_inst *inst,
129 struct hfi_msg_event_notify_pkt *pkt)
131 struct hfi_event_data event = {0};
132 struct hfi_msg_event_release_buffer_ref_pkt *data;
134 data = (struct hfi_msg_event_release_buffer_ref_pkt *)
135 pkt->ext_event_data;
137 event.event_type = HFI_EVENT_RELEASE_BUFFER_REFERENCE;
138 event.packet_buffer = data->packet_buffer;
139 event.extradata_buffer = data->extradata_buffer;
140 event.tag = data->output_tag;
142 inst->error = HFI_ERR_NONE;
143 inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
146 static void event_sys_error(struct venus_core *core, u32 event,
147 struct hfi_msg_event_notify_pkt *pkt)
149 if (pkt)
150 dev_dbg(core->dev,
151 "sys error (session id:%x, data1:%x, data2:%x)\n",
152 pkt->shdr.session_id, pkt->event_data1,
153 pkt->event_data2);
155 core->core_ops->event_notify(core, event);
158 static void
159 event_session_error(struct venus_core *core, struct venus_inst *inst,
160 struct hfi_msg_event_notify_pkt *pkt)
162 struct device *dev = core->dev;
164 dev_dbg(dev, "session error: event id:%x, session id:%x\n",
165 pkt->event_data1, pkt->shdr.session_id);
167 if (!inst)
168 return;
170 switch (pkt->event_data1) {
171 /* non fatal session errors */
172 case HFI_ERR_SESSION_INVALID_SCALE_FACTOR:
173 case HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE:
174 case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
175 case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED:
176 inst->error = HFI_ERR_NONE;
177 break;
178 default:
179 dev_err(dev, "session error: event id:%x (%x), session id:%x\n",
180 pkt->event_data1, pkt->event_data2,
181 pkt->shdr.session_id);
183 inst->error = pkt->event_data1;
184 inst->ops->event_notify(inst, EVT_SESSION_ERROR, NULL);
185 break;
189 static void hfi_event_notify(struct venus_core *core, struct venus_inst *inst,
190 void *packet)
192 struct hfi_msg_event_notify_pkt *pkt = packet;
194 if (!packet)
195 return;
197 switch (pkt->event_id) {
198 case HFI_EVENT_SYS_ERROR:
199 event_sys_error(core, EVT_SYS_ERROR, pkt);
200 break;
201 case HFI_EVENT_SESSION_ERROR:
202 event_session_error(core, inst, pkt);
203 break;
204 case HFI_EVENT_SESSION_SEQUENCE_CHANGED:
205 event_seq_changed(core, inst, pkt);
206 break;
207 case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
208 event_release_buffer_ref(core, inst, pkt);
209 break;
210 case HFI_EVENT_SESSION_PROPERTY_CHANGED:
211 break;
212 default:
213 break;
217 static void hfi_sys_init_done(struct venus_core *core, struct venus_inst *inst,
218 void *packet)
220 struct hfi_msg_sys_init_done_pkt *pkt = packet;
221 int rem_bytes;
222 u32 error;
224 error = pkt->error_type;
225 if (error != HFI_ERR_NONE)
226 goto done;
228 if (!pkt->num_properties) {
229 error = HFI_ERR_SYS_INVALID_PARAMETER;
230 goto done;
233 rem_bytes = pkt->hdr.size - sizeof(*pkt) + sizeof(u32);
234 if (rem_bytes <= 0) {
235 /* missing property data */
236 error = HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
237 goto done;
240 error = hfi_parser(core, inst, pkt->data, rem_bytes);
242 done:
243 core->error = error;
244 complete(&core->done);
247 static void
248 sys_get_prop_image_version(struct device *dev,
249 struct hfi_msg_sys_property_info_pkt *pkt)
251 int req_bytes;
253 req_bytes = pkt->hdr.size - sizeof(*pkt);
255 if (req_bytes < 128 || !pkt->data[1] || pkt->num_properties > 1)
256 /* bad packet */
257 return;
259 dev_dbg(dev, "F/W version: %s\n", (u8 *)&pkt->data[1]);
262 static void hfi_sys_property_info(struct venus_core *core,
263 struct venus_inst *inst, void *packet)
265 struct hfi_msg_sys_property_info_pkt *pkt = packet;
266 struct device *dev = core->dev;
268 if (!pkt->num_properties) {
269 dev_dbg(dev, "%s: no properties\n", __func__);
270 return;
273 switch (pkt->data[0]) {
274 case HFI_PROPERTY_SYS_IMAGE_VERSION:
275 sys_get_prop_image_version(dev, pkt);
276 break;
277 default:
278 dev_dbg(dev, "%s: unknown property data\n", __func__);
279 break;
283 static void hfi_sys_rel_resource_done(struct venus_core *core,
284 struct venus_inst *inst,
285 void *packet)
287 struct hfi_msg_sys_release_resource_done_pkt *pkt = packet;
289 core->error = pkt->error_type;
290 complete(&core->done);
293 static void hfi_sys_ping_done(struct venus_core *core, struct venus_inst *inst,
294 void *packet)
296 struct hfi_msg_sys_ping_ack_pkt *pkt = packet;
298 core->error = HFI_ERR_NONE;
300 if (pkt->client_data != 0xbeef)
301 core->error = HFI_ERR_SYS_FATAL;
303 complete(&core->done);
306 static void hfi_sys_idle_done(struct venus_core *core, struct venus_inst *inst,
307 void *packet)
309 dev_dbg(core->dev, "sys idle\n");
312 static void hfi_sys_pc_prepare_done(struct venus_core *core,
313 struct venus_inst *inst, void *packet)
315 struct hfi_msg_sys_pc_prep_done_pkt *pkt = packet;
317 dev_dbg(core->dev, "pc prepare done (error %x)\n", pkt->error_type);
320 static unsigned int
321 session_get_prop_profile_level(struct hfi_msg_session_property_info_pkt *pkt,
322 struct hfi_profile_level *profile_level)
324 struct hfi_profile_level *hfi;
325 u32 req_bytes;
327 req_bytes = pkt->shdr.hdr.size - sizeof(*pkt);
329 if (!req_bytes || req_bytes % sizeof(struct hfi_profile_level))
330 /* bad packet */
331 return HFI_ERR_SESSION_INVALID_PARAMETER;
333 hfi = (struct hfi_profile_level *)&pkt->data[1];
334 profile_level->profile = hfi->profile;
335 profile_level->level = hfi->level;
337 return HFI_ERR_NONE;
340 static unsigned int
341 session_get_prop_buf_req(struct hfi_msg_session_property_info_pkt *pkt,
342 struct hfi_buffer_requirements *bufreq)
344 struct hfi_buffer_requirements *buf_req;
345 u32 req_bytes;
346 unsigned int idx = 0;
348 req_bytes = pkt->shdr.hdr.size - sizeof(*pkt);
350 if (!req_bytes || req_bytes % sizeof(*buf_req) || !pkt->data[1])
351 /* bad packet */
352 return HFI_ERR_SESSION_INVALID_PARAMETER;
354 buf_req = (struct hfi_buffer_requirements *)&pkt->data[1];
355 if (!buf_req)
356 return HFI_ERR_SESSION_INVALID_PARAMETER;
358 while (req_bytes) {
359 memcpy(&bufreq[idx], buf_req, sizeof(*bufreq));
360 idx++;
362 if (idx > HFI_BUFFER_TYPE_MAX)
363 return HFI_ERR_SESSION_INVALID_PARAMETER;
365 req_bytes -= sizeof(struct hfi_buffer_requirements);
366 buf_req++;
369 return HFI_ERR_NONE;
372 static void hfi_session_prop_info(struct venus_core *core,
373 struct venus_inst *inst, void *packet)
375 struct hfi_msg_session_property_info_pkt *pkt = packet;
376 struct device *dev = core->dev;
377 union hfi_get_property *hprop = &inst->hprop;
378 unsigned int error = HFI_ERR_NONE;
380 if (!pkt->num_properties) {
381 error = HFI_ERR_SESSION_INVALID_PARAMETER;
382 dev_err(dev, "%s: no properties\n", __func__);
383 goto done;
386 switch (pkt->data[0]) {
387 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
388 memset(hprop->bufreq, 0, sizeof(hprop->bufreq));
389 error = session_get_prop_buf_req(pkt, hprop->bufreq);
390 break;
391 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
392 memset(&hprop->profile_level, 0, sizeof(hprop->profile_level));
393 error = session_get_prop_profile_level(pkt,
394 &hprop->profile_level);
395 break;
396 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
397 break;
398 default:
399 dev_dbg(dev, "%s: unknown property id:%x\n", __func__,
400 pkt->data[0]);
401 return;
404 done:
405 inst->error = error;
406 complete(&inst->done);
409 static void hfi_session_init_done(struct venus_core *core,
410 struct venus_inst *inst, void *packet)
412 struct hfi_msg_session_init_done_pkt *pkt = packet;
413 int rem_bytes;
414 u32 error;
416 error = pkt->error_type;
417 if (error != HFI_ERR_NONE)
418 goto done;
420 if (!IS_V1(core))
421 goto done;
423 rem_bytes = pkt->shdr.hdr.size - sizeof(*pkt) + sizeof(u32);
424 if (rem_bytes <= 0) {
425 error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;
426 goto done;
429 error = hfi_parser(core, inst, pkt->data, rem_bytes);
430 done:
431 inst->error = error;
432 complete(&inst->done);
435 static void hfi_session_load_res_done(struct venus_core *core,
436 struct venus_inst *inst, void *packet)
438 struct hfi_msg_session_load_resources_done_pkt *pkt = packet;
440 inst->error = pkt->error_type;
441 complete(&inst->done);
444 static void hfi_session_flush_done(struct venus_core *core,
445 struct venus_inst *inst, void *packet)
447 struct hfi_msg_session_flush_done_pkt *pkt = packet;
449 inst->error = pkt->error_type;
450 complete(&inst->done);
453 static void hfi_session_etb_done(struct venus_core *core,
454 struct venus_inst *inst, void *packet)
456 struct hfi_msg_session_empty_buffer_done_pkt *pkt = packet;
458 inst->error = pkt->error_type;
459 inst->ops->buf_done(inst, HFI_BUFFER_INPUT, pkt->input_tag,
460 pkt->filled_len, pkt->offset, 0, 0, 0);
463 static void hfi_session_ftb_done(struct venus_core *core,
464 struct venus_inst *inst, void *packet)
466 u32 session_type = inst->session_type;
467 u64 timestamp_us = 0;
468 u32 timestamp_hi = 0, timestamp_lo = 0;
469 unsigned int error;
470 u32 flags = 0, hfi_flags = 0, offset = 0, filled_len = 0;
471 u32 pic_type = 0, buffer_type = 0, output_tag = -1;
473 if (session_type == VIDC_SESSION_TYPE_ENC) {
474 struct hfi_msg_session_fbd_compressed_pkt *pkt = packet;
476 timestamp_hi = pkt->time_stamp_hi;
477 timestamp_lo = pkt->time_stamp_lo;
478 hfi_flags = pkt->flags;
479 offset = pkt->offset;
480 filled_len = pkt->filled_len;
481 pic_type = pkt->picture_type;
482 output_tag = pkt->output_tag;
483 buffer_type = HFI_BUFFER_OUTPUT;
485 error = pkt->error_type;
486 } else if (session_type == VIDC_SESSION_TYPE_DEC) {
487 struct hfi_msg_session_fbd_uncompressed_plane0_pkt *pkt =
488 packet;
490 timestamp_hi = pkt->time_stamp_hi;
491 timestamp_lo = pkt->time_stamp_lo;
492 hfi_flags = pkt->flags;
493 offset = pkt->offset;
494 filled_len = pkt->filled_len;
495 pic_type = pkt->picture_type;
496 output_tag = pkt->output_tag;
498 if (pkt->stream_id == 0)
499 buffer_type = HFI_BUFFER_OUTPUT;
500 else if (pkt->stream_id == 1)
501 buffer_type = HFI_BUFFER_OUTPUT2;
503 error = pkt->error_type;
504 } else {
505 error = HFI_ERR_SESSION_INVALID_PARAMETER;
508 if (buffer_type != HFI_BUFFER_OUTPUT &&
509 buffer_type != HFI_BUFFER_OUTPUT2)
510 goto done;
512 if (hfi_flags & HFI_BUFFERFLAG_EOS)
513 flags |= V4L2_BUF_FLAG_LAST;
515 switch (pic_type) {
516 case HFI_PICTURE_IDR:
517 case HFI_PICTURE_I:
518 flags |= V4L2_BUF_FLAG_KEYFRAME;
519 break;
520 case HFI_PICTURE_P:
521 flags |= V4L2_BUF_FLAG_PFRAME;
522 break;
523 case HFI_PICTURE_B:
524 flags |= V4L2_BUF_FLAG_BFRAME;
525 break;
526 case HFI_FRAME_NOTCODED:
527 case HFI_UNUSED_PICT:
528 case HFI_FRAME_YUV:
529 default:
530 break;
533 if (!(hfi_flags & HFI_BUFFERFLAG_TIMESTAMPINVALID) && filled_len) {
534 timestamp_us = timestamp_hi;
535 timestamp_us = (timestamp_us << 32) | timestamp_lo;
538 done:
539 inst->error = error;
540 inst->ops->buf_done(inst, buffer_type, output_tag, filled_len,
541 offset, flags, hfi_flags, timestamp_us);
544 static void hfi_session_start_done(struct venus_core *core,
545 struct venus_inst *inst, void *packet)
547 struct hfi_msg_session_start_done_pkt *pkt = packet;
549 inst->error = pkt->error_type;
550 complete(&inst->done);
553 static void hfi_session_stop_done(struct venus_core *core,
554 struct venus_inst *inst, void *packet)
556 struct hfi_msg_session_stop_done_pkt *pkt = packet;
558 inst->error = pkt->error_type;
559 complete(&inst->done);
562 static void hfi_session_rel_res_done(struct venus_core *core,
563 struct venus_inst *inst, void *packet)
565 struct hfi_msg_session_release_resources_done_pkt *pkt = packet;
567 inst->error = pkt->error_type;
568 complete(&inst->done);
571 static void hfi_session_rel_buf_done(struct venus_core *core,
572 struct venus_inst *inst, void *packet)
574 struct hfi_msg_session_release_buffers_done_pkt *pkt = packet;
576 inst->error = pkt->error_type;
577 complete(&inst->done);
580 static void hfi_session_end_done(struct venus_core *core,
581 struct venus_inst *inst, void *packet)
583 struct hfi_msg_session_end_done_pkt *pkt = packet;
585 inst->error = pkt->error_type;
586 complete(&inst->done);
589 static void hfi_session_abort_done(struct venus_core *core,
590 struct venus_inst *inst, void *packet)
592 struct hfi_msg_sys_session_abort_done_pkt *pkt = packet;
594 inst->error = pkt->error_type;
595 complete(&inst->done);
598 static void hfi_session_get_seq_hdr_done(struct venus_core *core,
599 struct venus_inst *inst, void *packet)
601 struct hfi_msg_session_get_sequence_hdr_done_pkt *pkt = packet;
603 inst->error = pkt->error_type;
604 complete(&inst->done);
607 struct hfi_done_handler {
608 u32 pkt;
609 u32 pkt_sz;
610 u32 pkt_sz2;
611 void (*done)(struct venus_core *, struct venus_inst *, void *);
612 bool is_sys_pkt;
615 static const struct hfi_done_handler handlers[] = {
616 {.pkt = HFI_MSG_EVENT_NOTIFY,
617 .pkt_sz = sizeof(struct hfi_msg_event_notify_pkt),
618 .done = hfi_event_notify,
620 {.pkt = HFI_MSG_SYS_INIT,
621 .pkt_sz = sizeof(struct hfi_msg_sys_init_done_pkt),
622 .done = hfi_sys_init_done,
623 .is_sys_pkt = true,
625 {.pkt = HFI_MSG_SYS_PROPERTY_INFO,
626 .pkt_sz = sizeof(struct hfi_msg_sys_property_info_pkt),
627 .done = hfi_sys_property_info,
628 .is_sys_pkt = true,
630 {.pkt = HFI_MSG_SYS_RELEASE_RESOURCE,
631 .pkt_sz = sizeof(struct hfi_msg_sys_release_resource_done_pkt),
632 .done = hfi_sys_rel_resource_done,
633 .is_sys_pkt = true,
635 {.pkt = HFI_MSG_SYS_PING_ACK,
636 .pkt_sz = sizeof(struct hfi_msg_sys_ping_ack_pkt),
637 .done = hfi_sys_ping_done,
638 .is_sys_pkt = true,
640 {.pkt = HFI_MSG_SYS_IDLE,
641 .pkt_sz = sizeof(struct hfi_msg_sys_idle_pkt),
642 .done = hfi_sys_idle_done,
643 .is_sys_pkt = true,
645 {.pkt = HFI_MSG_SYS_PC_PREP,
646 .pkt_sz = sizeof(struct hfi_msg_sys_pc_prep_done_pkt),
647 .done = hfi_sys_pc_prepare_done,
648 .is_sys_pkt = true,
650 {.pkt = HFI_MSG_SYS_SESSION_INIT,
651 .pkt_sz = sizeof(struct hfi_msg_session_init_done_pkt),
652 .done = hfi_session_init_done,
654 {.pkt = HFI_MSG_SYS_SESSION_END,
655 .pkt_sz = sizeof(struct hfi_msg_session_end_done_pkt),
656 .done = hfi_session_end_done,
658 {.pkt = HFI_MSG_SESSION_LOAD_RESOURCES,
659 .pkt_sz = sizeof(struct hfi_msg_session_load_resources_done_pkt),
660 .done = hfi_session_load_res_done,
662 {.pkt = HFI_MSG_SESSION_START,
663 .pkt_sz = sizeof(struct hfi_msg_session_start_done_pkt),
664 .done = hfi_session_start_done,
666 {.pkt = HFI_MSG_SESSION_STOP,
667 .pkt_sz = sizeof(struct hfi_msg_session_stop_done_pkt),
668 .done = hfi_session_stop_done,
670 {.pkt = HFI_MSG_SYS_SESSION_ABORT,
671 .pkt_sz = sizeof(struct hfi_msg_sys_session_abort_done_pkt),
672 .done = hfi_session_abort_done,
674 {.pkt = HFI_MSG_SESSION_EMPTY_BUFFER,
675 .pkt_sz = sizeof(struct hfi_msg_session_empty_buffer_done_pkt),
676 .done = hfi_session_etb_done,
678 {.pkt = HFI_MSG_SESSION_FILL_BUFFER,
679 .pkt_sz = sizeof(struct hfi_msg_session_fbd_uncompressed_plane0_pkt),
680 .pkt_sz2 = sizeof(struct hfi_msg_session_fbd_compressed_pkt),
681 .done = hfi_session_ftb_done,
683 {.pkt = HFI_MSG_SESSION_FLUSH,
684 .pkt_sz = sizeof(struct hfi_msg_session_flush_done_pkt),
685 .done = hfi_session_flush_done,
687 {.pkt = HFI_MSG_SESSION_PROPERTY_INFO,
688 .pkt_sz = sizeof(struct hfi_msg_session_property_info_pkt),
689 .done = hfi_session_prop_info,
691 {.pkt = HFI_MSG_SESSION_RELEASE_RESOURCES,
692 .pkt_sz = sizeof(struct hfi_msg_session_release_resources_done_pkt),
693 .done = hfi_session_rel_res_done,
695 {.pkt = HFI_MSG_SESSION_GET_SEQUENCE_HEADER,
696 .pkt_sz = sizeof(struct hfi_msg_session_get_sequence_hdr_done_pkt),
697 .done = hfi_session_get_seq_hdr_done,
699 {.pkt = HFI_MSG_SESSION_RELEASE_BUFFERS,
700 .pkt_sz = sizeof(struct hfi_msg_session_release_buffers_done_pkt),
701 .done = hfi_session_rel_buf_done,
705 void hfi_process_watchdog_timeout(struct venus_core *core)
707 event_sys_error(core, EVT_SYS_WATCHDOG_TIMEOUT, NULL);
710 static struct venus_inst *to_instance(struct venus_core *core, u32 session_id)
712 struct venus_inst *inst;
714 mutex_lock(&core->lock);
715 list_for_each_entry(inst, &core->instances, list)
716 if (hash32_ptr(inst) == session_id) {
717 mutex_unlock(&core->lock);
718 return inst;
720 mutex_unlock(&core->lock);
722 return NULL;
725 u32 hfi_process_msg_packet(struct venus_core *core, struct hfi_pkt_hdr *hdr)
727 const struct hfi_done_handler *handler;
728 struct device *dev = core->dev;
729 struct venus_inst *inst;
730 bool found = false;
731 unsigned int i;
733 for (i = 0; i < ARRAY_SIZE(handlers); i++) {
734 handler = &handlers[i];
735 if (handler->pkt != hdr->pkt_type)
736 continue;
737 found = true;
738 break;
741 if (!found)
742 return hdr->pkt_type;
744 if (hdr->size && hdr->size < handler->pkt_sz &&
745 hdr->size < handler->pkt_sz2) {
746 dev_err(dev, "bad packet size (%d should be %d, pkt type:%x)\n",
747 hdr->size, handler->pkt_sz, hdr->pkt_type);
749 return hdr->pkt_type;
752 if (handler->is_sys_pkt) {
753 inst = NULL;
754 } else {
755 struct hfi_session_pkt *pkt;
757 pkt = (struct hfi_session_pkt *)hdr;
758 inst = to_instance(core, pkt->shdr.session_id);
760 if (!inst)
761 dev_warn(dev, "no valid instance(pkt session_id:%x, pkt:%x)\n",
762 pkt->shdr.session_id,
763 handler ? handler->pkt : 0);
766 * Event of type HFI_EVENT_SYS_ERROR will not have any session
767 * associated with it
769 if (!inst && hdr->pkt_type != HFI_MSG_EVENT_NOTIFY) {
770 dev_err(dev, "got invalid session id:%x\n",
771 pkt->shdr.session_id);
772 goto invalid_session;
776 handler->done(core, inst, hdr);
778 invalid_session:
779 return hdr->pkt_type;