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 <media/videobuf2-v4l2.h>
13 #include "hfi_helper.h"
15 #include "hfi_parser.h"
17 static void event_seq_changed(struct venus_core
*core
, struct venus_inst
*inst
,
18 struct hfi_msg_event_notify_pkt
*pkt
)
20 enum hfi_version ver
= core
->res
->hfi_version
;
21 struct hfi_event_data event
= {0};
22 int num_properties_changed
;
23 struct hfi_framesize
*frame_sz
;
24 struct hfi_profile_level
*profile_level
;
25 struct hfi_bit_depth
*pixel_depth
;
26 struct hfi_pic_struct
*pic_struct
;
27 struct hfi_colour_space
*colour_info
;
28 struct hfi_buffer_requirements
*bufreq
;
29 struct hfi_extradata_input_crop
*crop
;
33 inst
->error
= HFI_ERR_NONE
;
35 switch (pkt
->event_data1
) {
36 case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES
:
37 case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES
:
40 inst
->error
= HFI_ERR_SESSION_INVALID_PARAMETER
;
44 event
.event_type
= pkt
->event_data1
;
46 num_properties_changed
= pkt
->event_data2
;
47 if (!num_properties_changed
) {
48 inst
->error
= HFI_ERR_SESSION_INSUFFICIENT_RESOURCES
;
52 data_ptr
= (u8
*)&pkt
->ext_event_data
[0];
54 ptype
= *((u32
*)data_ptr
);
56 case HFI_PROPERTY_PARAM_FRAME_SIZE
:
57 data_ptr
+= sizeof(u32
);
58 frame_sz
= (struct hfi_framesize
*)data_ptr
;
59 event
.width
= frame_sz
->width
;
60 event
.height
= frame_sz
->height
;
61 data_ptr
+= sizeof(*frame_sz
);
63 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT
:
64 data_ptr
+= sizeof(u32
);
65 profile_level
= (struct hfi_profile_level
*)data_ptr
;
66 event
.profile
= profile_level
->profile
;
67 event
.level
= profile_level
->level
;
68 data_ptr
+= sizeof(*profile_level
);
70 case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH
:
71 data_ptr
+= sizeof(u32
);
72 pixel_depth
= (struct hfi_bit_depth
*)data_ptr
;
73 event
.bit_depth
= pixel_depth
->bit_depth
;
74 data_ptr
+= sizeof(*pixel_depth
);
76 case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT
:
77 data_ptr
+= sizeof(u32
);
78 pic_struct
= (struct hfi_pic_struct
*)data_ptr
;
79 event
.pic_struct
= pic_struct
->progressive_only
;
80 data_ptr
+= sizeof(*pic_struct
);
82 case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE
:
83 data_ptr
+= sizeof(u32
);
84 colour_info
= (struct hfi_colour_space
*)data_ptr
;
85 event
.colour_space
= colour_info
->colour_space
;
86 data_ptr
+= sizeof(*colour_info
);
88 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY
:
89 data_ptr
+= sizeof(u32
);
90 event
.entropy_mode
= *(u32
*)data_ptr
;
91 data_ptr
+= sizeof(u32
);
93 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS
:
94 data_ptr
+= sizeof(u32
);
95 bufreq
= (struct hfi_buffer_requirements
*)data_ptr
;
96 event
.buf_count
= HFI_BUFREQ_COUNT_MIN(bufreq
, ver
);
97 data_ptr
+= sizeof(*bufreq
);
99 case HFI_INDEX_EXTRADATA_INPUT_CROP
:
100 data_ptr
+= sizeof(u32
);
101 crop
= (struct hfi_extradata_input_crop
*)data_ptr
;
102 event
.input_crop
.left
= crop
->left
;
103 event
.input_crop
.top
= crop
->top
;
104 event
.input_crop
.width
= crop
->width
;
105 event
.input_crop
.height
= crop
->height
;
106 data_ptr
+= sizeof(*crop
);
111 num_properties_changed
--;
112 } while (num_properties_changed
> 0);
115 inst
->ops
->event_notify(inst
, EVT_SYS_EVENT_CHANGE
, &event
);
118 static void event_release_buffer_ref(struct venus_core
*core
,
119 struct venus_inst
*inst
,
120 struct hfi_msg_event_notify_pkt
*pkt
)
122 struct hfi_event_data event
= {0};
123 struct hfi_msg_event_release_buffer_ref_pkt
*data
;
125 data
= (struct hfi_msg_event_release_buffer_ref_pkt
*)
128 event
.event_type
= HFI_EVENT_RELEASE_BUFFER_REFERENCE
;
129 event
.packet_buffer
= data
->packet_buffer
;
130 event
.extradata_buffer
= data
->extradata_buffer
;
131 event
.tag
= data
->output_tag
;
133 inst
->error
= HFI_ERR_NONE
;
134 inst
->ops
->event_notify(inst
, EVT_SYS_EVENT_CHANGE
, &event
);
137 static void event_sys_error(struct venus_core
*core
, u32 event
,
138 struct hfi_msg_event_notify_pkt
*pkt
)
141 dev_dbg(core
->dev
, VDBGH
142 "sys error (session id:%x, data1:%x, data2:%x)\n",
143 pkt
->shdr
.session_id
, pkt
->event_data1
,
146 core
->core_ops
->event_notify(core
, event
);
150 event_session_error(struct venus_core
*core
, struct venus_inst
*inst
,
151 struct hfi_msg_event_notify_pkt
*pkt
)
153 struct device
*dev
= core
->dev
;
155 dev_dbg(dev
, VDBGH
"session error: event id:%x, session id:%x\n",
156 pkt
->event_data1
, pkt
->shdr
.session_id
);
161 switch (pkt
->event_data1
) {
162 /* non fatal session errors */
163 case HFI_ERR_SESSION_INVALID_SCALE_FACTOR
:
164 case HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE
:
165 case HFI_ERR_SESSION_UNSUPPORTED_SETTING
:
166 case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED
:
167 inst
->error
= HFI_ERR_NONE
;
170 dev_err(dev
, "session error: event id:%x (%x), session id:%x\n",
171 pkt
->event_data1
, pkt
->event_data2
,
172 pkt
->shdr
.session_id
);
174 inst
->error
= pkt
->event_data1
;
175 inst
->ops
->event_notify(inst
, EVT_SESSION_ERROR
, NULL
);
180 static void hfi_event_notify(struct venus_core
*core
, struct venus_inst
*inst
,
183 struct hfi_msg_event_notify_pkt
*pkt
= packet
;
188 switch (pkt
->event_id
) {
189 case HFI_EVENT_SYS_ERROR
:
190 event_sys_error(core
, EVT_SYS_ERROR
, pkt
);
192 case HFI_EVENT_SESSION_ERROR
:
193 event_session_error(core
, inst
, pkt
);
195 case HFI_EVENT_SESSION_SEQUENCE_CHANGED
:
196 event_seq_changed(core
, inst
, pkt
);
198 case HFI_EVENT_RELEASE_BUFFER_REFERENCE
:
199 event_release_buffer_ref(core
, inst
, pkt
);
201 case HFI_EVENT_SESSION_PROPERTY_CHANGED
:
208 static void hfi_sys_init_done(struct venus_core
*core
, struct venus_inst
*inst
,
211 struct hfi_msg_sys_init_done_pkt
*pkt
= packet
;
215 error
= pkt
->error_type
;
216 if (error
!= HFI_ERR_NONE
)
219 if (!pkt
->num_properties
) {
220 error
= HFI_ERR_SYS_INVALID_PARAMETER
;
224 rem_bytes
= pkt
->hdr
.size
- sizeof(*pkt
) + sizeof(u32
);
225 if (rem_bytes
<= 0) {
226 /* missing property data */
227 error
= HFI_ERR_SYS_INSUFFICIENT_RESOURCES
;
231 error
= hfi_parser(core
, inst
, pkt
->data
, rem_bytes
);
235 complete(&core
->done
);
239 sys_get_prop_image_version(struct device
*dev
,
240 struct hfi_msg_sys_property_info_pkt
*pkt
)
244 req_bytes
= pkt
->hdr
.size
- sizeof(*pkt
);
246 if (req_bytes
< 128 || !pkt
->data
[1] || pkt
->num_properties
> 1)
250 dev_dbg(dev
, VDBGL
"F/W version: %s\n", (u8
*)&pkt
->data
[1]);
253 static void hfi_sys_property_info(struct venus_core
*core
,
254 struct venus_inst
*inst
, void *packet
)
256 struct hfi_msg_sys_property_info_pkt
*pkt
= packet
;
257 struct device
*dev
= core
->dev
;
259 if (!pkt
->num_properties
) {
260 dev_dbg(dev
, VDBGL
"no properties\n");
264 switch (pkt
->data
[0]) {
265 case HFI_PROPERTY_SYS_IMAGE_VERSION
:
266 sys_get_prop_image_version(dev
, pkt
);
269 dev_dbg(dev
, VDBGL
"unknown property data\n");
274 static void hfi_sys_rel_resource_done(struct venus_core
*core
,
275 struct venus_inst
*inst
,
278 struct hfi_msg_sys_release_resource_done_pkt
*pkt
= packet
;
280 core
->error
= pkt
->error_type
;
281 complete(&core
->done
);
284 static void hfi_sys_ping_done(struct venus_core
*core
, struct venus_inst
*inst
,
287 struct hfi_msg_sys_ping_ack_pkt
*pkt
= packet
;
289 core
->error
= HFI_ERR_NONE
;
291 if (pkt
->client_data
!= 0xbeef)
292 core
->error
= HFI_ERR_SYS_FATAL
;
294 complete(&core
->done
);
297 static void hfi_sys_idle_done(struct venus_core
*core
, struct venus_inst
*inst
,
300 dev_dbg(core
->dev
, VDBGL
"sys idle\n");
303 static void hfi_sys_pc_prepare_done(struct venus_core
*core
,
304 struct venus_inst
*inst
, void *packet
)
306 struct hfi_msg_sys_pc_prep_done_pkt
*pkt
= packet
;
308 dev_dbg(core
->dev
, VDBGL
"pc prepare done (error %x)\n",
313 session_get_prop_profile_level(struct hfi_msg_session_property_info_pkt
*pkt
,
314 struct hfi_profile_level
*profile_level
)
316 struct hfi_profile_level
*hfi
;
319 req_bytes
= pkt
->shdr
.hdr
.size
- sizeof(*pkt
);
321 if (!req_bytes
|| req_bytes
% sizeof(struct hfi_profile_level
))
323 return HFI_ERR_SESSION_INVALID_PARAMETER
;
325 hfi
= (struct hfi_profile_level
*)&pkt
->data
[1];
326 profile_level
->profile
= hfi
->profile
;
327 profile_level
->level
= hfi
->level
;
333 session_get_prop_buf_req(struct hfi_msg_session_property_info_pkt
*pkt
,
334 struct hfi_buffer_requirements
*bufreq
)
336 struct hfi_buffer_requirements
*buf_req
;
338 unsigned int idx
= 0;
340 req_bytes
= pkt
->shdr
.hdr
.size
- sizeof(*pkt
);
342 if (!req_bytes
|| req_bytes
% sizeof(*buf_req
) || !pkt
->data
[1])
344 return HFI_ERR_SESSION_INVALID_PARAMETER
;
346 buf_req
= (struct hfi_buffer_requirements
*)&pkt
->data
[1];
348 return HFI_ERR_SESSION_INVALID_PARAMETER
;
351 memcpy(&bufreq
[idx
], buf_req
, sizeof(*bufreq
));
354 if (idx
> HFI_BUFFER_TYPE_MAX
)
355 return HFI_ERR_SESSION_INVALID_PARAMETER
;
357 req_bytes
-= sizeof(struct hfi_buffer_requirements
);
364 static void hfi_session_prop_info(struct venus_core
*core
,
365 struct venus_inst
*inst
, void *packet
)
367 struct hfi_msg_session_property_info_pkt
*pkt
= packet
;
368 struct device
*dev
= core
->dev
;
369 union hfi_get_property
*hprop
= &inst
->hprop
;
370 unsigned int error
= HFI_ERR_NONE
;
372 if (!pkt
->num_properties
) {
373 error
= HFI_ERR_SESSION_INVALID_PARAMETER
;
374 dev_err(dev
, "%s: no properties\n", __func__
);
378 switch (pkt
->data
[0]) {
379 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS
:
380 memset(hprop
->bufreq
, 0, sizeof(hprop
->bufreq
));
381 error
= session_get_prop_buf_req(pkt
, hprop
->bufreq
);
383 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT
:
384 memset(&hprop
->profile_level
, 0, sizeof(hprop
->profile_level
));
385 error
= session_get_prop_profile_level(pkt
,
386 &hprop
->profile_level
);
388 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY
:
391 dev_dbg(dev
, VDBGM
"unknown property id:%x\n", pkt
->data
[0]);
397 complete(&inst
->done
);
400 static void hfi_session_init_done(struct venus_core
*core
,
401 struct venus_inst
*inst
, void *packet
)
403 struct hfi_msg_session_init_done_pkt
*pkt
= packet
;
407 error
= pkt
->error_type
;
408 if (error
!= HFI_ERR_NONE
)
414 rem_bytes
= pkt
->shdr
.hdr
.size
- sizeof(*pkt
) + sizeof(u32
);
415 if (rem_bytes
<= 0) {
416 error
= HFI_ERR_SESSION_INSUFFICIENT_RESOURCES
;
420 error
= hfi_parser(core
, inst
, pkt
->data
, rem_bytes
);
423 complete(&inst
->done
);
426 static void hfi_session_load_res_done(struct venus_core
*core
,
427 struct venus_inst
*inst
, void *packet
)
429 struct hfi_msg_session_load_resources_done_pkt
*pkt
= packet
;
431 inst
->error
= pkt
->error_type
;
432 complete(&inst
->done
);
435 static void hfi_session_flush_done(struct venus_core
*core
,
436 struct venus_inst
*inst
, void *packet
)
438 struct hfi_msg_session_flush_done_pkt
*pkt
= packet
;
440 inst
->error
= pkt
->error_type
;
441 complete(&inst
->done
);
442 if (inst
->ops
->flush_done
)
443 inst
->ops
->flush_done(inst
);
446 static void hfi_session_etb_done(struct venus_core
*core
,
447 struct venus_inst
*inst
, void *packet
)
449 struct hfi_msg_session_empty_buffer_done_pkt
*pkt
= packet
;
451 inst
->error
= pkt
->error_type
;
452 inst
->ops
->buf_done(inst
, HFI_BUFFER_INPUT
, pkt
->input_tag
,
453 pkt
->filled_len
, pkt
->offset
, 0, 0, 0);
456 static void hfi_session_ftb_done(struct venus_core
*core
,
457 struct venus_inst
*inst
, void *packet
)
459 u32 session_type
= inst
->session_type
;
460 u64 timestamp_us
= 0;
461 u32 timestamp_hi
= 0, timestamp_lo
= 0;
463 u32 flags
= 0, hfi_flags
= 0, offset
= 0, filled_len
= 0;
464 u32 pic_type
= 0, buffer_type
= 0, output_tag
= -1;
466 if (session_type
== VIDC_SESSION_TYPE_ENC
) {
467 struct hfi_msg_session_fbd_compressed_pkt
*pkt
= packet
;
469 timestamp_hi
= pkt
->time_stamp_hi
;
470 timestamp_lo
= pkt
->time_stamp_lo
;
471 hfi_flags
= pkt
->flags
;
472 offset
= pkt
->offset
;
473 filled_len
= pkt
->filled_len
;
474 pic_type
= pkt
->picture_type
;
475 output_tag
= pkt
->output_tag
;
476 buffer_type
= HFI_BUFFER_OUTPUT
;
478 error
= pkt
->error_type
;
479 } else if (session_type
== VIDC_SESSION_TYPE_DEC
) {
480 struct hfi_msg_session_fbd_uncompressed_plane0_pkt
*pkt
=
483 timestamp_hi
= pkt
->time_stamp_hi
;
484 timestamp_lo
= pkt
->time_stamp_lo
;
485 hfi_flags
= pkt
->flags
;
486 offset
= pkt
->offset
;
487 filled_len
= pkt
->filled_len
;
488 pic_type
= pkt
->picture_type
;
489 output_tag
= pkt
->output_tag
;
491 if (pkt
->stream_id
== 0)
492 buffer_type
= HFI_BUFFER_OUTPUT
;
493 else if (pkt
->stream_id
== 1)
494 buffer_type
= HFI_BUFFER_OUTPUT2
;
496 error
= pkt
->error_type
;
498 error
= HFI_ERR_SESSION_INVALID_PARAMETER
;
501 if (buffer_type
!= HFI_BUFFER_OUTPUT
&&
502 buffer_type
!= HFI_BUFFER_OUTPUT2
)
505 if (hfi_flags
& HFI_BUFFERFLAG_EOS
)
506 flags
|= V4L2_BUF_FLAG_LAST
;
509 case HFI_PICTURE_IDR
:
511 flags
|= V4L2_BUF_FLAG_KEYFRAME
;
514 flags
|= V4L2_BUF_FLAG_PFRAME
;
517 flags
|= V4L2_BUF_FLAG_BFRAME
;
519 case HFI_FRAME_NOTCODED
:
520 case HFI_UNUSED_PICT
:
526 if (!(hfi_flags
& HFI_BUFFERFLAG_TIMESTAMPINVALID
) && filled_len
) {
527 timestamp_us
= timestamp_hi
;
528 timestamp_us
= (timestamp_us
<< 32) | timestamp_lo
;
533 inst
->ops
->buf_done(inst
, buffer_type
, output_tag
, filled_len
,
534 offset
, flags
, hfi_flags
, timestamp_us
);
537 static void hfi_session_start_done(struct venus_core
*core
,
538 struct venus_inst
*inst
, void *packet
)
540 struct hfi_msg_session_start_done_pkt
*pkt
= packet
;
542 inst
->error
= pkt
->error_type
;
543 complete(&inst
->done
);
546 static void hfi_session_stop_done(struct venus_core
*core
,
547 struct venus_inst
*inst
, void *packet
)
549 struct hfi_msg_session_stop_done_pkt
*pkt
= packet
;
551 inst
->error
= pkt
->error_type
;
552 complete(&inst
->done
);
555 static void hfi_session_rel_res_done(struct venus_core
*core
,
556 struct venus_inst
*inst
, void *packet
)
558 struct hfi_msg_session_release_resources_done_pkt
*pkt
= packet
;
560 inst
->error
= pkt
->error_type
;
561 complete(&inst
->done
);
564 static void hfi_session_rel_buf_done(struct venus_core
*core
,
565 struct venus_inst
*inst
, void *packet
)
567 struct hfi_msg_session_release_buffers_done_pkt
*pkt
= packet
;
569 inst
->error
= pkt
->error_type
;
570 complete(&inst
->done
);
573 static void hfi_session_end_done(struct venus_core
*core
,
574 struct venus_inst
*inst
, void *packet
)
576 struct hfi_msg_session_end_done_pkt
*pkt
= packet
;
578 inst
->error
= pkt
->error_type
;
579 complete(&inst
->done
);
582 static void hfi_session_abort_done(struct venus_core
*core
,
583 struct venus_inst
*inst
, void *packet
)
585 struct hfi_msg_sys_session_abort_done_pkt
*pkt
= packet
;
587 inst
->error
= pkt
->error_type
;
588 complete(&inst
->done
);
591 static void hfi_session_get_seq_hdr_done(struct venus_core
*core
,
592 struct venus_inst
*inst
, void *packet
)
594 struct hfi_msg_session_get_sequence_hdr_done_pkt
*pkt
= packet
;
596 inst
->error
= pkt
->error_type
;
597 complete(&inst
->done
);
600 struct hfi_done_handler
{
604 void (*done
)(struct venus_core
*, struct venus_inst
*, void *);
608 static const struct hfi_done_handler handlers
[] = {
609 {.pkt
= HFI_MSG_EVENT_NOTIFY
,
610 .pkt_sz
= sizeof(struct hfi_msg_event_notify_pkt
),
611 .done
= hfi_event_notify
,
613 {.pkt
= HFI_MSG_SYS_INIT
,
614 .pkt_sz
= sizeof(struct hfi_msg_sys_init_done_pkt
),
615 .done
= hfi_sys_init_done
,
618 {.pkt
= HFI_MSG_SYS_PROPERTY_INFO
,
619 .pkt_sz
= sizeof(struct hfi_msg_sys_property_info_pkt
),
620 .done
= hfi_sys_property_info
,
623 {.pkt
= HFI_MSG_SYS_RELEASE_RESOURCE
,
624 .pkt_sz
= sizeof(struct hfi_msg_sys_release_resource_done_pkt
),
625 .done
= hfi_sys_rel_resource_done
,
628 {.pkt
= HFI_MSG_SYS_PING_ACK
,
629 .pkt_sz
= sizeof(struct hfi_msg_sys_ping_ack_pkt
),
630 .done
= hfi_sys_ping_done
,
633 {.pkt
= HFI_MSG_SYS_IDLE
,
634 .pkt_sz
= sizeof(struct hfi_msg_sys_idle_pkt
),
635 .done
= hfi_sys_idle_done
,
638 {.pkt
= HFI_MSG_SYS_PC_PREP
,
639 .pkt_sz
= sizeof(struct hfi_msg_sys_pc_prep_done_pkt
),
640 .done
= hfi_sys_pc_prepare_done
,
643 {.pkt
= HFI_MSG_SYS_SESSION_INIT
,
644 .pkt_sz
= sizeof(struct hfi_msg_session_init_done_pkt
),
645 .done
= hfi_session_init_done
,
647 {.pkt
= HFI_MSG_SYS_SESSION_END
,
648 .pkt_sz
= sizeof(struct hfi_msg_session_end_done_pkt
),
649 .done
= hfi_session_end_done
,
651 {.pkt
= HFI_MSG_SESSION_LOAD_RESOURCES
,
652 .pkt_sz
= sizeof(struct hfi_msg_session_load_resources_done_pkt
),
653 .done
= hfi_session_load_res_done
,
655 {.pkt
= HFI_MSG_SESSION_START
,
656 .pkt_sz
= sizeof(struct hfi_msg_session_start_done_pkt
),
657 .done
= hfi_session_start_done
,
659 {.pkt
= HFI_MSG_SESSION_STOP
,
660 .pkt_sz
= sizeof(struct hfi_msg_session_stop_done_pkt
),
661 .done
= hfi_session_stop_done
,
663 {.pkt
= HFI_MSG_SYS_SESSION_ABORT
,
664 .pkt_sz
= sizeof(struct hfi_msg_sys_session_abort_done_pkt
),
665 .done
= hfi_session_abort_done
,
667 {.pkt
= HFI_MSG_SESSION_EMPTY_BUFFER
,
668 .pkt_sz
= sizeof(struct hfi_msg_session_empty_buffer_done_pkt
),
669 .done
= hfi_session_etb_done
,
671 {.pkt
= HFI_MSG_SESSION_FILL_BUFFER
,
672 .pkt_sz
= sizeof(struct hfi_msg_session_fbd_uncompressed_plane0_pkt
),
673 .pkt_sz2
= sizeof(struct hfi_msg_session_fbd_compressed_pkt
),
674 .done
= hfi_session_ftb_done
,
676 {.pkt
= HFI_MSG_SESSION_FLUSH
,
677 .pkt_sz
= sizeof(struct hfi_msg_session_flush_done_pkt
),
678 .done
= hfi_session_flush_done
,
680 {.pkt
= HFI_MSG_SESSION_PROPERTY_INFO
,
681 .pkt_sz
= sizeof(struct hfi_msg_session_property_info_pkt
),
682 .done
= hfi_session_prop_info
,
684 {.pkt
= HFI_MSG_SESSION_RELEASE_RESOURCES
,
685 .pkt_sz
= sizeof(struct hfi_msg_session_release_resources_done_pkt
),
686 .done
= hfi_session_rel_res_done
,
688 {.pkt
= HFI_MSG_SESSION_GET_SEQUENCE_HEADER
,
689 .pkt_sz
= sizeof(struct hfi_msg_session_get_sequence_hdr_done_pkt
),
690 .done
= hfi_session_get_seq_hdr_done
,
692 {.pkt
= HFI_MSG_SESSION_RELEASE_BUFFERS
,
693 .pkt_sz
= sizeof(struct hfi_msg_session_release_buffers_done_pkt
),
694 .done
= hfi_session_rel_buf_done
,
698 void hfi_process_watchdog_timeout(struct venus_core
*core
)
700 event_sys_error(core
, EVT_SYS_WATCHDOG_TIMEOUT
, NULL
);
703 static struct venus_inst
*to_instance(struct venus_core
*core
, u32 session_id
)
705 struct venus_inst
*inst
;
707 mutex_lock(&core
->lock
);
708 list_for_each_entry(inst
, &core
->instances
, list
)
709 if (hash32_ptr(inst
) == session_id
) {
710 mutex_unlock(&core
->lock
);
713 mutex_unlock(&core
->lock
);
718 u32
hfi_process_msg_packet(struct venus_core
*core
, struct hfi_pkt_hdr
*hdr
)
720 const struct hfi_done_handler
*handler
;
721 struct device
*dev
= core
->dev
;
722 struct venus_inst
*inst
;
726 for (i
= 0; i
< ARRAY_SIZE(handlers
); i
++) {
727 handler
= &handlers
[i
];
728 if (handler
->pkt
!= hdr
->pkt_type
)
735 return hdr
->pkt_type
;
737 if (hdr
->size
&& hdr
->size
< handler
->pkt_sz
&&
738 hdr
->size
< handler
->pkt_sz2
) {
739 dev_err(dev
, "bad packet size (%d should be %d, pkt type:%x)\n",
740 hdr
->size
, handler
->pkt_sz
, hdr
->pkt_type
);
742 return hdr
->pkt_type
;
745 if (handler
->is_sys_pkt
) {
748 struct hfi_session_pkt
*pkt
;
750 pkt
= (struct hfi_session_pkt
*)hdr
;
751 inst
= to_instance(core
, pkt
->shdr
.session_id
);
754 dev_warn(dev
, "no valid instance(pkt session_id:%x, pkt:%x)\n",
755 pkt
->shdr
.session_id
,
756 handler
? handler
->pkt
: 0);
759 * Event of type HFI_EVENT_SYS_ERROR will not have any session
762 if (!inst
&& hdr
->pkt_type
!= HFI_MSG_EVENT_NOTIFY
) {
763 dev_err(dev
, "got invalid session id:%x\n",
764 pkt
->shdr
.session_id
);
765 goto invalid_session
;
769 handler
->done(core
, inst
, hdr
);
772 return hdr
->pkt_type
;