blob: ffcbdd9bc62abe87dbbe5734cb09214e4ea455a3 [file] [log] [blame]
Srinu Gorlecf8c6752018-01-19 18:36:13 +05301/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/bitops.h>
15#include <linux/slab.h>
16#include <linux/list.h>
17#include <linux/interrupt.h>
18#include <linux/hash.h>
19#include <soc/qcom/smem.h>
20#include "vidc_hfi_helper.h"
21#include "vidc_hfi_io.h"
22#include "msm_vidc_debug.h"
23#include "vidc_hfi.h"
24
25static enum vidc_status hfi_parse_init_done_properties(
26 struct msm_vidc_capability *capability,
27 u32 num_sessions, u8 *data_ptr, u32 num_properties,
28 u32 rem_bytes, u32 codec, u32 domain);
29
30static enum vidc_status hfi_map_err_status(u32 hfi_err)
31{
32 enum vidc_status vidc_err;
33
34 switch (hfi_err) {
35 case HFI_ERR_NONE:
36 case HFI_ERR_SESSION_SAME_STATE_OPERATION:
37 vidc_err = VIDC_ERR_NONE;
38 break;
39 case HFI_ERR_SYS_FATAL:
40 vidc_err = VIDC_ERR_HW_FATAL;
41 break;
42 case HFI_ERR_SYS_VERSION_MISMATCH:
43 case HFI_ERR_SYS_INVALID_PARAMETER:
44 case HFI_ERR_SYS_SESSION_ID_OUT_OF_RANGE:
45 case HFI_ERR_SESSION_INVALID_PARAMETER:
46 case HFI_ERR_SESSION_INVALID_SESSION_ID:
47 case HFI_ERR_SESSION_INVALID_STREAM_ID:
48 vidc_err = VIDC_ERR_BAD_PARAM;
49 break;
50 case HFI_ERR_SYS_INSUFFICIENT_RESOURCES:
51 case HFI_ERR_SYS_UNSUPPORTED_DOMAIN:
52 case HFI_ERR_SYS_UNSUPPORTED_CODEC:
53 case HFI_ERR_SESSION_UNSUPPORTED_PROPERTY:
54 case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
55 case HFI_ERR_SESSION_INSUFFICIENT_RESOURCES:
56 case HFI_ERR_SESSION_UNSUPPORTED_STREAM:
57 vidc_err = VIDC_ERR_NOT_SUPPORTED;
58 break;
59 case HFI_ERR_SYS_MAX_SESSIONS_REACHED:
60 vidc_err = VIDC_ERR_MAX_CLIENTS;
61 break;
62 case HFI_ERR_SYS_SESSION_IN_USE:
63 vidc_err = VIDC_ERR_CLIENT_PRESENT;
64 break;
65 case HFI_ERR_SESSION_FATAL:
66 vidc_err = VIDC_ERR_CLIENT_FATAL;
67 break;
68 case HFI_ERR_SESSION_BAD_POINTER:
69 vidc_err = VIDC_ERR_BAD_PARAM;
70 break;
71 case HFI_ERR_SESSION_INCORRECT_STATE_OPERATION:
72 vidc_err = VIDC_ERR_BAD_STATE;
73 break;
74 case HFI_ERR_SESSION_STREAM_CORRUPT:
75 case HFI_ERR_SESSION_STREAM_CORRUPT_OUTPUT_STALLED:
76 vidc_err = VIDC_ERR_BITSTREAM_ERR;
77 break;
78 case HFI_ERR_SESSION_SYNC_FRAME_NOT_DETECTED:
79 vidc_err = VIDC_ERR_IFRAME_EXPECTED;
80 break;
81 case HFI_ERR_SESSION_START_CODE_NOT_FOUND:
82 vidc_err = VIDC_ERR_START_CODE_NOT_FOUND;
83 break;
84 case HFI_ERR_SESSION_EMPTY_BUFFER_DONE_OUTPUT_PENDING:
85 default:
86 vidc_err = VIDC_ERR_FAIL;
87 break;
88 }
89 return vidc_err;
90}
91
92static enum msm_vidc_pixel_depth get_hal_pixel_depth(u32 hfi_bit_depth)
93{
94 switch (hfi_bit_depth) {
95 case HFI_BITDEPTH_8: return MSM_VIDC_BIT_DEPTH_8;
96 case HFI_BITDEPTH_9:
97 case HFI_BITDEPTH_10: return MSM_VIDC_BIT_DEPTH_10;
98 }
99 dprintk(VIDC_ERR, "Unsupported bit depth: %d\n", hfi_bit_depth);
100 return MSM_VIDC_BIT_DEPTH_UNSUPPORTED;
101}
102
103static int hfi_process_sess_evt_seq_changed(u32 device_id,
104 struct hfi_msg_event_notify_packet *pkt,
105 struct msm_vidc_cb_info *info)
106{
107 struct msm_vidc_cb_event event_notify = {0};
108 int num_properties_changed;
109 struct hfi_frame_size *frame_sz;
110 struct hfi_profile_level *profile_level;
111 struct hfi_bit_depth *pixel_depth;
112 struct hfi_pic_struct *pic_struct;
113 u8 *data_ptr;
114 int prop_id;
115 enum msm_vidc_pixel_depth luma_bit_depth, chroma_bit_depth;
116 struct hfi_colour_space *colour_info;
117
118 /* Initialize pic_struct to unknown as default */
119 //event_notify.pic_struct = MSM_VIDC_PIC_STRUCT_UNKNOWN;
120
121 if (sizeof(struct hfi_msg_event_notify_packet) > pkt->size) {
122 dprintk(VIDC_ERR,
123 "hal_process_session_init_done: bad_pkt_size\n");
124 return -E2BIG;
125 }
126
127 event_notify.device_id = device_id;
128 event_notify.session_id = (void *)(uintptr_t)pkt->session_id;
129 event_notify.status = VIDC_ERR_NONE;
130 num_properties_changed = pkt->event_data2;
131 switch (pkt->event_data1) {
132 case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUFFER_RESOURCES:
133 event_notify.hal_event_type =
134 HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES;
135 break;
136 case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUFFER_RESOURCES:
137 event_notify.hal_event_type =
138 HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES;
139 break;
140 default:
141 break;
142 }
143
144 if (num_properties_changed) {
145 data_ptr = (u8 *) &pkt->rg_ext_event_data[0];
146 do {
147 prop_id = (int) *((u32 *)data_ptr);
148 switch (prop_id) {
149 case HFI_PROPERTY_PARAM_FRAME_SIZE:
150 data_ptr = data_ptr + sizeof(u32);
151 frame_sz =
152 (struct hfi_frame_size *) data_ptr;
153 event_notify.width = frame_sz->width;
154 event_notify.height = frame_sz->height;
155 dprintk(VIDC_DBG, "height: %d width: %d\n",
156 frame_sz->height, frame_sz->width);
157 data_ptr +=
158 sizeof(struct hfi_frame_size);
159 break;
160 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
161 data_ptr = data_ptr + sizeof(u32);
162 profile_level =
163 (struct hfi_profile_level *) data_ptr;
164 dprintk(VIDC_DBG, "profile: %d level: %d\n",
165 profile_level->profile,
166 profile_level->level);
167 data_ptr +=
168 sizeof(struct hfi_profile_level);
169 break;
170 case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
171 data_ptr = data_ptr + sizeof(u32);
172 pixel_depth = (struct hfi_bit_depth *) data_ptr;
173 /*
174 * Luma and chroma can have different bitdepths.
175 * Driver should rely on luma and chroma
176 * bitdepth for determining output bitdepth
177 * type.
178 *
179 * pixel_depth->bitdepth will include luma
180 * bitdepth info in bits 0..15 and chroma
181 * bitdept in bits 16..31.
182 */
183 luma_bit_depth = get_hal_pixel_depth(
184 pixel_depth->bit_depth &
185 GENMASK(15, 0));
186 chroma_bit_depth = get_hal_pixel_depth(
187 (pixel_depth->bit_depth &
188 GENMASK(31, 16)) >> 16);
189 if (luma_bit_depth == MSM_VIDC_BIT_DEPTH_10 ||
190 chroma_bit_depth ==
191 MSM_VIDC_BIT_DEPTH_10)
192 event_notify.bit_depth =
193 MSM_VIDC_BIT_DEPTH_10;
194 else
195 event_notify.bit_depth = luma_bit_depth;
196 dprintk(VIDC_DBG,
197 "bitdepth(%d), luma_bit_depth(%d), chroma_bit_depth(%d)\n",
198 event_notify.bit_depth, luma_bit_depth,
199 chroma_bit_depth);
200 data_ptr += sizeof(struct hfi_bit_depth);
201 break;
202 case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
203 data_ptr = data_ptr + sizeof(u32);
204 pic_struct = (struct hfi_pic_struct *) data_ptr;
205 event_notify.pic_struct =
206 pic_struct->progressive_only;
207 dprintk(VIDC_DBG,
208 "Progressive only flag: %d\n",
209 pic_struct->progressive_only);
210 data_ptr +=
211 sizeof(struct hfi_pic_struct);
212 break;
213 case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
214 data_ptr = data_ptr + sizeof(u32);
215 colour_info =
216 (struct hfi_colour_space *) data_ptr;
217 event_notify.colour_space =
218 colour_info->colour_space;
219 dprintk(VIDC_DBG,
220 "Colour space value is: %d\n",
221 colour_info->colour_space);
222 data_ptr +=
223 sizeof(struct hfi_colour_space);
224 break;
225 default:
226 dprintk(VIDC_ERR,
227 "%s cmd: %#x not supported\n",
228 __func__, prop_id);
229 break;
230 }
231 num_properties_changed--;
232 } while (num_properties_changed > 0);
233 }
234
235 *info = (struct msm_vidc_cb_info) {
236 .response_type = HAL_SESSION_EVENT_CHANGE,
237 .response.event = event_notify,
238 };
239
240 return 0;
241}
242
243static int hfi_process_evt_release_buffer_ref(u32 device_id,
244 struct hfi_msg_event_notify_packet *pkt,
245 struct msm_vidc_cb_info *info)
246{
247 struct msm_vidc_cb_event event_notify = {0};
248 struct hfi_msg_release_buffer_ref_event_packet *data;
249
250 dprintk(VIDC_DBG,
251 "RECEIVED: EVENT_NOTIFY - release_buffer_reference\n");
252 if (sizeof(struct hfi_msg_event_notify_packet)
253 > pkt->size) {
254 dprintk(VIDC_ERR,
255 "hal_process_session_init_done: bad_pkt_size\n");
256 return -E2BIG;
257 }
258
259 data = (struct hfi_msg_release_buffer_ref_event_packet *)
260 pkt->rg_ext_event_data;
261
262 event_notify.device_id = device_id;
263 event_notify.session_id = (void *)(uintptr_t)pkt->session_id;
264 event_notify.status = VIDC_ERR_NONE;
265 event_notify.hal_event_type = HAL_EVENT_RELEASE_BUFFER_REFERENCE;
266 event_notify.packet_buffer = data->packet_buffer;
267 event_notify.extra_data_buffer = data->extra_data_buffer;
268
269 *info = (struct msm_vidc_cb_info) {
270 .response_type = HAL_SESSION_EVENT_CHANGE,
271 .response.event = event_notify,
272 };
273
274 return 0;
275}
276
277static int hfi_process_sys_error(u32 device_id, struct msm_vidc_cb_info *info)
278{
279 struct msm_vidc_cb_cmd_done cmd_done = {0};
280
281 cmd_done.device_id = device_id;
282
283 *info = (struct msm_vidc_cb_info) {
284 .response_type = HAL_SYS_ERROR,
285 .response.cmd = cmd_done,
286 };
287
288 return 0;
289}
290
291static int hfi_process_session_error(u32 device_id,
292 struct hfi_msg_event_notify_packet *pkt,
293 struct msm_vidc_cb_info *info)
294{
295 struct msm_vidc_cb_cmd_done cmd_done = {0};
296
297 cmd_done.device_id = device_id;
298 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
299 cmd_done.status = hfi_map_err_status(pkt->event_data1);
300 dprintk(VIDC_INFO, "Received: SESSION_ERROR with event id : %d\n",
301 pkt->event_data1);
302 switch (pkt->event_data1) {
303 case HFI_ERR_SESSION_INVALID_SCALE_FACTOR:
304 case HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE:
305 case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
306 case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED:
307 cmd_done.status = VIDC_ERR_NONE;
308 dprintk(VIDC_INFO, "Non Fatal: HFI_EVENT_SESSION_ERROR\n");
309 *info = (struct msm_vidc_cb_info) {
310 .response_type = HAL_RESPONSE_UNUSED,
311 .response.cmd = cmd_done,
312 };
313 return 0;
314 default:
315 dprintk(VIDC_ERR, "HFI_EVENT_SESSION_ERROR\n");
316 *info = (struct msm_vidc_cb_info) {
317 .response_type = HAL_SESSION_ERROR,
318 .response.cmd = cmd_done,
319 };
320 return 0;
321 }
322}
323
324static int hfi_process_event_notify(u32 device_id,
325 struct hfi_msg_event_notify_packet *pkt,
326 struct msm_vidc_cb_info *info)
327{
328 dprintk(VIDC_DBG, "Received: EVENT_NOTIFY\n");
329
330 if (pkt->size < sizeof(struct hfi_msg_event_notify_packet)) {
331 dprintk(VIDC_ERR, "Invalid Params\n");
332 return -E2BIG;
333 }
334
335 switch (pkt->event_id) {
336 case HFI_EVENT_SYS_ERROR:
337 dprintk(VIDC_ERR, "HFI_EVENT_SYS_ERROR: %d, %#x\n",
338 pkt->event_data1, pkt->event_data2);
339 return hfi_process_sys_error(device_id, info);
340 case HFI_EVENT_SESSION_ERROR:
341 dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR[%#x]\n",
342 pkt->session_id);
343 return hfi_process_session_error(device_id, pkt, info);
344
345 case HFI_EVENT_SESSION_SEQUENCE_CHANGED:
346 dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%#x]\n",
347 pkt->session_id);
348 return hfi_process_sess_evt_seq_changed(device_id, pkt, info);
349
350 case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
351 dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%#x]\n",
352 pkt->session_id);
353 return hfi_process_evt_release_buffer_ref(device_id, pkt, info);
354
355 case HFI_EVENT_SESSION_PROPERTY_CHANGED:
356 default:
357 *info = (struct msm_vidc_cb_info) {
358 .response_type = HAL_RESPONSE_UNUSED,
359 };
360
361 return 0;
362 }
363}
364
365static int hfi_process_sys_init_done(u32 device_id,
366 struct hfi_msg_sys_init_done_packet *pkt,
367 struct msm_vidc_cb_info *info)
368{
369 struct msm_vidc_cb_cmd_done cmd_done = {0};
370 enum vidc_status status = VIDC_ERR_NONE;
371
372 dprintk(VIDC_DBG, "RECEIVED: SYS_INIT_DONE\n");
373 if (sizeof(struct hfi_msg_sys_init_done_packet) > pkt->size) {
374 dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", __func__,
375 pkt->size);
376 return -E2BIG;
377 }
378 if (!pkt->num_properties) {
379 dprintk(VIDC_ERR,
380 "hal_process_sys_init_done: no_properties\n");
381 status = VIDC_ERR_FAIL;
382 goto err_no_prop;
383 }
384
385 status = hfi_map_err_status(pkt->error_type);
386 if (status) {
387 dprintk(VIDC_ERR, "%s: status %#x\n",
388 __func__, status);
389 goto err_no_prop;
390 }
391
392err_no_prop:
393 cmd_done.device_id = device_id;
394 cmd_done.session_id = NULL;
395 cmd_done.status = (u32)status;
396 cmd_done.size = sizeof(struct vidc_hal_sys_init_done);
397 *info = (struct msm_vidc_cb_info) {
398 .response_type = HAL_SYS_INIT_DONE,
399 .response.cmd = cmd_done,
400 };
401 return 0;
402}
403
404static int hfi_process_sys_rel_resource_done(u32 device_id,
405 struct hfi_msg_sys_release_resource_done_packet *pkt,
406 struct msm_vidc_cb_info *info)
407{
408 struct msm_vidc_cb_cmd_done cmd_done = {0};
409 enum vidc_status status = VIDC_ERR_NONE;
410 u32 pkt_size;
411
412 dprintk(VIDC_DBG, "RECEIVED: SYS_RELEASE_RESOURCE_DONE\n");
413 pkt_size = sizeof(struct hfi_msg_sys_release_resource_done_packet);
414 if (pkt_size > pkt->size) {
415 dprintk(VIDC_ERR,
416 "hal_process_sys_rel_resource_done: bad size: %d\n",
417 pkt->size);
418 return -E2BIG;
419 }
420
421 status = hfi_map_err_status(pkt->error_type);
422 cmd_done.device_id = device_id;
423 cmd_done.session_id = NULL;
424 cmd_done.status = (u32) status;
425 cmd_done.size = 0;
426
427 *info = (struct msm_vidc_cb_info) {
428 .response_type = HAL_SYS_RELEASE_RESOURCE_DONE,
429 .response.cmd = cmd_done,
430 };
431
432 return 0;
433}
434
435enum hal_capability get_hal_cap_type(u32 capability_type)
436{
437 enum hal_capability hal_cap = 0;
438
439 switch (capability_type) {
440 case HFI_CAPABILITY_FRAME_WIDTH:
441 hal_cap = HAL_CAPABILITY_FRAME_WIDTH;
442 break;
443 case HFI_CAPABILITY_FRAME_HEIGHT:
444 hal_cap = HAL_CAPABILITY_FRAME_HEIGHT;
445 break;
446 case HFI_CAPABILITY_MBS_PER_FRAME:
447 hal_cap = HAL_CAPABILITY_MBS_PER_FRAME;
448 break;
449 case HFI_CAPABILITY_MBS_PER_SECOND:
450 hal_cap = HAL_CAPABILITY_MBS_PER_SECOND;
451 break;
452 case HFI_CAPABILITY_FRAMERATE:
453 hal_cap = HAL_CAPABILITY_FRAMERATE;
454 break;
455 case HFI_CAPABILITY_SCALE_X:
456 hal_cap = HAL_CAPABILITY_SCALE_X;
457 break;
458 case HFI_CAPABILITY_SCALE_Y:
459 hal_cap = HAL_CAPABILITY_SCALE_Y;
460 break;
461 case HFI_CAPABILITY_BITRATE:
462 hal_cap = HAL_CAPABILITY_BITRATE;
463 break;
464 case HFI_CAPABILITY_BFRAME:
465 hal_cap = HAL_CAPABILITY_BFRAME;
466 break;
467 case HFI_CAPABILITY_PEAKBITRATE:
468 hal_cap = HAL_CAPABILITY_PEAKBITRATE;
469 break;
470 case HFI_CAPABILITY_HIER_P_NUM_ENH_LAYERS:
471 hal_cap = HAL_CAPABILITY_HIER_P_NUM_ENH_LAYERS;
472 break;
473 case HFI_CAPABILITY_ENC_LTR_COUNT:
474 hal_cap = HAL_CAPABILITY_ENC_LTR_COUNT;
475 break;
476 case HFI_CAPABILITY_CP_OUTPUT2_THRESH:
477 hal_cap = HAL_CAPABILITY_SECURE_OUTPUT2_THRESHOLD;
478 break;
479 case HFI_CAPABILITY_HIER_B_NUM_ENH_LAYERS:
480 hal_cap = HAL_CAPABILITY_HIER_B_NUM_ENH_LAYERS;
481 break;
482 case HFI_CAPABILITY_LCU_SIZE:
483 hal_cap = HAL_CAPABILITY_LCU_SIZE;
484 break;
485 case HFI_CAPABILITY_HIER_P_HYBRID_NUM_ENH_LAYERS:
486 hal_cap = HAL_CAPABILITY_HIER_P_HYBRID_NUM_ENH_LAYERS;
487 break;
488 case HFI_CAPABILITY_MBS_PER_SECOND_POWERSAVE:
489 hal_cap = HAL_CAPABILITY_MBS_PER_SECOND_POWER_SAVE;
490 break;
491 default:
492 dprintk(VIDC_DBG, "%s: unknown capablity %#x\n",
493 __func__, capability_type);
494 break;
495 }
496
497 return hal_cap;
498}
499
500static inline void copy_cap_prop(
501 struct hfi_capability_supported *in,
502 struct msm_vidc_capability *capability)
503{
504 struct hal_capability_supported *out = NULL;
505
506 if (!in || !capability) {
507 dprintk(VIDC_ERR, "%s Invalid input parameters\n",
508 __func__);
509 return;
510 }
511
512 switch (in->capability_type) {
513 case HFI_CAPABILITY_FRAME_WIDTH:
514 out = &capability->width;
515 break;
516 case HFI_CAPABILITY_FRAME_HEIGHT:
517 out = &capability->height;
518 break;
519 case HFI_CAPABILITY_MBS_PER_FRAME:
520 out = &capability->mbs_per_frame;
521 break;
522 case HFI_CAPABILITY_MBS_PER_SECOND:
523 out = &capability->mbs_per_sec;
524 break;
525 case HFI_CAPABILITY_FRAMERATE:
526 out = &capability->frame_rate;
527 break;
528 case HFI_CAPABILITY_SCALE_X:
529 out = &capability->scale_x;
530 break;
531 case HFI_CAPABILITY_SCALE_Y:
532 out = &capability->scale_y;
533 break;
534 case HFI_CAPABILITY_BITRATE:
535 out = &capability->bitrate;
536 break;
537 case HFI_CAPABILITY_BFRAME:
538 out = &capability->bframe;
539 break;
540 case HFI_CAPABILITY_PEAKBITRATE:
541 out = &capability->peakbitrate;
542 break;
543 case HFI_CAPABILITY_HIER_P_NUM_ENH_LAYERS:
544 out = &capability->hier_p;
545 break;
546 case HFI_CAPABILITY_ENC_LTR_COUNT:
547 out = &capability->ltr_count;
548 break;
549 case HFI_CAPABILITY_CP_OUTPUT2_THRESH:
550 out = &capability->secure_output2_threshold;
551 break;
552 case HFI_CAPABILITY_HIER_B_NUM_ENH_LAYERS:
553 out = &capability->hier_b;
554 break;
555 case HFI_CAPABILITY_LCU_SIZE:
556 out = &capability->lcu_size;
557 break;
558 case HFI_CAPABILITY_HIER_P_HYBRID_NUM_ENH_LAYERS:
559 out = &capability->hier_p_hybrid;
560 break;
561 case HFI_CAPABILITY_MBS_PER_SECOND_POWERSAVE:
562 out = &capability->mbs_per_sec_power_save;
563 break;
564 default:
565 dprintk(VIDC_DBG, "%s: unknown capablity %#x\n",
566 __func__, in->capability_type);
567 break;
568 }
569
570 if (out) {
571 out->capability_type = get_hal_cap_type(in->capability_type);
572 out->min = in->min;
573 out->max = in->max;
574 out->step_size = in->step_size;
575 }
576}
577
578static int hfi_fill_codec_info(u8 *data_ptr,
579 struct vidc_hal_sys_init_done *sys_init_done) {
580 u32 i;
581 u32 codecs = 0, codec_count = 0, size = 0;
582 struct msm_vidc_capability *capability;
583 u32 prop_id = *((u32 *)data_ptr);
584 u8 *orig_data_ptr = data_ptr;
585
586 if (prop_id == HFI_PROPERTY_PARAM_CODEC_SUPPORTED) {
587 struct hfi_codec_supported *prop;
588
589 data_ptr = data_ptr + sizeof(u32);
590 prop = (struct hfi_codec_supported *) data_ptr;
591 sys_init_done->dec_codec_supported =
592 prop->decoder_codec_supported;
593 sys_init_done->enc_codec_supported =
594 prop->encoder_codec_supported;
595 size = sizeof(struct hfi_codec_supported) + sizeof(u32);
596 } else {
597 dprintk(VIDC_WARN,
598 "%s: prop_id %#x, expected codec_supported property\n",
599 __func__, prop_id);
600 }
601
602 codecs = sys_init_done->dec_codec_supported;
603 for (i = 0; i < 8 * sizeof(codecs); i++) {
604 if ((1 << i) & codecs) {
605 capability =
606 &sys_init_done->capabilities[codec_count++];
607 capability->codec =
608 vidc_get_hal_codec((1 << i) & codecs);
609 capability->domain =
610 vidc_get_hal_domain(HFI_VIDEO_DOMAIN_DECODER);
611 }
612 }
613 codecs = sys_init_done->enc_codec_supported;
614 for (i = 0; i < 8 * sizeof(codecs); i++) {
615 if ((1 << i) & codecs) {
616 capability =
617 &sys_init_done->capabilities[codec_count++];
618 capability->codec =
619 vidc_get_hal_codec((1 << i) & codecs);
620 capability->domain =
621 vidc_get_hal_domain(HFI_VIDEO_DOMAIN_ENCODER);
622 }
623 }
624 sys_init_done->codec_count = codec_count;
625
626 prop_id = *((u32 *)(orig_data_ptr + size));
627 if (prop_id == HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED) {
628 struct hfi_max_sessions_supported *prop =
629 (struct hfi_max_sessions_supported *)
630 (orig_data_ptr + size + sizeof(u32));
631
632 sys_init_done->max_sessions_supported = prop->max_sessions;
633 size += sizeof(struct hfi_max_sessions_supported) + sizeof(u32);
634 dprintk(VIDC_DBG, "max_sessions_supported %d\n",
635 prop->max_sessions);
636 }
637 return size;
638}
639
640enum vidc_status hfi_process_session_init_done_prop_read(
641 struct hfi_msg_sys_session_init_done_packet *pkt,
642 struct vidc_hal_session_init_done *session_init_done)
643{
644 enum vidc_status status = VIDC_ERR_NONE;
645 struct msm_vidc_capability *capability = NULL;
646 u32 rem_bytes, num_properties;
647 u8 *data_ptr;
648
649 rem_bytes = pkt->size - sizeof(struct
650 hfi_msg_sys_session_init_done_packet) + sizeof(u32);
651 if (!rem_bytes) {
652 dprintk(VIDC_ERR, "%s: invalid property info\n", __func__);
653 return VIDC_ERR_FAIL;
654 }
655
656 status = hfi_map_err_status(pkt->error_type);
657 if (status) {
658 dprintk(VIDC_ERR, "%s: error status 0x%x\n", __func__, status);
659 return status;
660 }
661
662 data_ptr = (u8 *)&pkt->rg_property_data[0];
663 num_properties = pkt->num_properties;
664
665 capability = &session_init_done->capability;
666 status = hfi_parse_init_done_properties(
667 capability, 1, data_ptr, num_properties, rem_bytes,
668 vidc_get_hfi_codec(capability->codec),
669 vidc_get_hfi_domain(capability->domain));
670 if (status) {
671 dprintk(VIDC_ERR, "%s: parse status 0x%x\n", __func__, status);
672 return status;
673 }
674
675 return status;
676}
677
678static int copy_caps_to_sessions(struct hfi_capability_supported *cap,
679 u32 num_caps, struct msm_vidc_capability *capabilities,
680 u32 num_sessions, u32 codecs, u32 domain)
681{
682 u32 i = 0, j = 0;
683 struct msm_vidc_capability *capability;
684 u32 sess_codec;
685 u32 sess_domain;
686
687 /*
688 * iterate over num_sessions and copy all the capabilities
689 * to matching sessions.
690 */
691 for (i = 0; i < num_sessions; i++) {
692 sess_codec = 0;
693 sess_domain = 0;
694 capability = &capabilities[i];
695
696 if (capability->codec)
697 sess_codec =
698 vidc_get_hfi_codec(capability->codec);
699 if (capability->domain)
700 sess_domain =
701 vidc_get_hfi_domain(capability->domain);
702
703 if (!(sess_codec & codecs && sess_domain & domain))
704 continue;
705
706 for (j = 0; j < num_caps; j++)
707 copy_cap_prop(&cap[j], capability);
708 }
709
710 return 0;
711}
712
713static int copy_alloc_mode_to_sessions(
714 struct hfi_buffer_alloc_mode_supported *prop,
715 struct msm_vidc_capability *capabilities,
716 u32 num_sessions, u32 codecs, u32 domain)
717{
718 u32 i = 0, j = 0;
719 struct msm_vidc_capability *capability;
720 u32 sess_codec;
721 u32 sess_domain;
722
723 /*
724 * iterate over num_sessions and copy all the entries
725 * to matching sessions.
726 */
727 for (i = 0; i < num_sessions; i++) {
728 sess_codec = 0;
729 sess_domain = 0;
730 capability = &capabilities[i];
731
732 if (capability->codec)
733 sess_codec =
734 vidc_get_hfi_codec(capability->codec);
735 if (capability->domain)
736 sess_domain =
737 vidc_get_hfi_domain(capability->domain);
738
739 if (!(sess_codec & codecs && sess_domain & domain))
740 continue;
741
742 for (j = 0; j < prop->num_entries; j++) {
743 if (prop->buffer_type == HFI_BUFFER_OUTPUT ||
744 prop->buffer_type == HFI_BUFFER_OUTPUT2) {
745 switch (prop->rg_data[j]) {
746 case HFI_BUFFER_MODE_STATIC:
747 capability->alloc_mode_out |=
748 HAL_BUFFER_MODE_STATIC;
749 break;
750 case HFI_BUFFER_MODE_RING:
751 capability->alloc_mode_out |=
752 HAL_BUFFER_MODE_RING;
753 break;
754 case HFI_BUFFER_MODE_DYNAMIC:
755 capability->alloc_mode_out |=
756 HAL_BUFFER_MODE_DYNAMIC;
757 break;
758 }
759 } else if (prop->buffer_type == HFI_BUFFER_INPUT) {
760 switch (prop->rg_data[j]) {
761 case HFI_BUFFER_MODE_STATIC:
762 capability->alloc_mode_in |=
763 HAL_BUFFER_MODE_STATIC;
764 break;
765 case HFI_BUFFER_MODE_RING:
766 capability->alloc_mode_in |=
767 HAL_BUFFER_MODE_RING;
768 break;
769 case HFI_BUFFER_MODE_DYNAMIC:
770 capability->alloc_mode_in |=
771 HAL_BUFFER_MODE_DYNAMIC;
772 break;
773 }
774 }
775 }
776 }
777
778 return 0;
779}
780
781static enum vidc_status hfi_parse_init_done_properties(
782 struct msm_vidc_capability *capabilities,
783 u32 num_sessions, u8 *data_ptr, u32 num_properties,
784 u32 rem_bytes, u32 codecs, u32 domain)
785{
786 enum vidc_status status = VIDC_ERR_NONE;
787 u32 prop_id, next_offset;
788
789 while (status == VIDC_ERR_NONE && num_properties &&
790 rem_bytes >= sizeof(u32)) {
791
792 prop_id = *((u32 *)data_ptr);
793 next_offset = sizeof(u32);
794
795 switch (prop_id) {
796 case HFI_PROPERTY_PARAM_CODEC_MASK_SUPPORTED:
797 {
798 struct hfi_codec_mask_supported *prop =
799 (struct hfi_codec_mask_supported *)
800 (data_ptr + next_offset);
801
802 codecs = prop->codecs;
803 domain = prop->video_domains;
804 next_offset += sizeof(struct hfi_codec_mask_supported);
805 num_properties--;
806 break;
807 }
808 case HFI_PROPERTY_PARAM_CAPABILITY_SUPPORTED:
809 {
810 struct hfi_capability_supported_info *prop =
811 (struct hfi_capability_supported_info *)
812 (data_ptr + next_offset);
813
814 if ((rem_bytes - next_offset) < prop->num_capabilities *
815 sizeof(struct hfi_capability_supported)) {
816 status = VIDC_ERR_BAD_PARAM;
817 break;
818 }
819 next_offset += sizeof(u32) +
820 prop->num_capabilities *
821 sizeof(struct hfi_capability_supported);
822
823 copy_caps_to_sessions(&prop->rg_data[0],
824 prop->num_capabilities,
825 capabilities, num_sessions,
826 codecs, domain);
827 num_properties--;
828 break;
829 }
830 case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED:
831 {
832 struct hfi_uncompressed_format_supported *prop =
833 (struct hfi_uncompressed_format_supported *)
834 (data_ptr + next_offset);
835 u32 num_format_entries;
836 char *fmt_ptr;
837 struct hfi_uncompressed_plane_info *plane_info;
838
839 if ((rem_bytes - next_offset) < sizeof(*prop)) {
840 status = VIDC_ERR_BAD_PARAM;
841 break;
842 }
843 num_format_entries = prop->format_entries;
844 next_offset = sizeof(*prop);
845 fmt_ptr = (char *)&prop->rg_format_info[0];
846
847 while (num_format_entries) {
848 u32 bytes_to_skip;
849
850 plane_info =
851 (struct hfi_uncompressed_plane_info *) fmt_ptr;
852
853 if ((rem_bytes - next_offset) <
854 sizeof(*plane_info)) {
855 status = VIDC_ERR_BAD_PARAM;
856 break;
857 }
858 bytes_to_skip = sizeof(*plane_info) -
859 sizeof(struct
860 hfi_uncompressed_plane_constraints) +
861 plane_info->num_planes *
862 sizeof(struct
863 hfi_uncompressed_plane_constraints);
864
865 fmt_ptr += bytes_to_skip;
866 next_offset += bytes_to_skip;
867 num_format_entries--;
868 }
869 num_properties--;
870 break;
871 }
872 case HFI_PROPERTY_PARAM_PROPERTIES_SUPPORTED:
873 {
874 struct hfi_properties_supported *prop =
875 (struct hfi_properties_supported *)
876 (data_ptr + next_offset);
877 next_offset += sizeof(*prop) - sizeof(u32)
878 + prop->num_properties * sizeof(u32);
879 num_properties--;
880 break;
881 }
882 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED:
883 {
884 struct msm_vidc_capability capability;
885 char *ptr = NULL;
886 u32 count = 0;
887 u32 prof_count = 0;
888 struct hfi_profile_level *prof_level;
889 struct hfi_profile_level_supported *prop =
890 (struct hfi_profile_level_supported *)
891 (data_ptr + next_offset);
892
893 ptr = (char *) &prop->rg_profile_level[0];
894 prof_count = prop->profile_count;
895 next_offset += sizeof(u32);
896
897 if (prof_count > MAX_PROFILE_COUNT) {
898 prof_count = MAX_PROFILE_COUNT;
899 dprintk(VIDC_WARN,
900 "prop count exceeds max profile count\n");
901 break;
902 }
903 while (prof_count) {
904 prof_level = (struct hfi_profile_level *)ptr;
905 capability.
906 profile_level.profile_level[count].profile
907 = prof_level->profile;
908 capability.
909 profile_level.profile_level[count].level
910 = prof_level->level;
911 prof_count--;
912 count++;
913 ptr += sizeof(struct hfi_profile_level);
914 next_offset += sizeof(struct hfi_profile_level);
915 }
916 num_properties--;
917 break;
918 }
919 case HFI_PROPERTY_PARAM_INTERLACE_FORMAT_SUPPORTED:
920 {
921 next_offset +=
922 sizeof(struct hfi_interlace_format_supported);
923 num_properties--;
924 break;
925 }
926 case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SUPPORTED:
927 {
928 next_offset +=
929 sizeof(struct hfi_nal_stream_format_supported);
930 num_properties--;
931 break;
932 }
933 case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT:
934 {
935 next_offset += sizeof(u32);
936 num_properties--;
937 break;
938 }
939 case HFI_PROPERTY_PARAM_MAX_SEQUENCE_HEADER_SIZE:
940 {
941 next_offset += sizeof(u32);
942 num_properties--;
943 break;
944 }
945 case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH:
946 {
947 next_offset +=
948 sizeof(struct hfi_intra_refresh);
949 num_properties--;
950 break;
951 }
952 case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE_SUPPORTED:
953 {
954 struct hfi_buffer_alloc_mode_supported *prop =
955 (struct hfi_buffer_alloc_mode_supported *)
956 (data_ptr + next_offset);
957
958 if (prop->num_entries >= 32) {
959 dprintk(VIDC_ERR,
960 "%s - num_entries: %d from f/w seems suspect\n",
961 __func__, prop->num_entries);
962 break;
963 }
964 next_offset +=
965 sizeof(struct hfi_buffer_alloc_mode_supported) -
966 sizeof(u32) + prop->num_entries * sizeof(u32);
967
968 copy_alloc_mode_to_sessions(prop,
969 capabilities, num_sessions,
970 codecs, domain);
971
972 num_properties--;
973 break;
974 }
975 default:
976 dprintk(VIDC_DBG,
977 "%s: default case - data_ptr %pK, prop_id 0x%x\n",
978 __func__, data_ptr, prop_id);
979 break;
980 }
981 rem_bytes -= next_offset;
982 data_ptr += next_offset;
983 }
984
985 return status;
986}
987
988enum vidc_status hfi_process_sys_init_done_prop_read(
989 struct hfi_msg_sys_init_done_packet *pkt,
990 struct vidc_hal_sys_init_done *sys_init_done)
991{
992 enum vidc_status status = VIDC_ERR_NONE;
993 u32 rem_bytes, bytes_read, num_properties;
994 u8 *data_ptr;
995 u32 codecs = 0, domain = 0;
996
997 if (!pkt || !sys_init_done) {
998 dprintk(VIDC_ERR,
999 "hfi_msg_sys_init_done: Invalid input\n");
1000 return VIDC_ERR_FAIL;
1001 }
1002
1003 rem_bytes = pkt->size - sizeof(struct
1004 hfi_msg_sys_init_done_packet) + sizeof(u32);
1005
1006 if (!rem_bytes) {
1007 dprintk(VIDC_ERR,
1008 "hfi_msg_sys_init_done: missing_prop_info\n");
1009 return VIDC_ERR_FAIL;
1010 }
1011
1012 status = hfi_map_err_status(pkt->error_type);
1013 if (status) {
1014 dprintk(VIDC_ERR, "%s: status %#x\n", __func__, status);
1015 return status;
1016 }
1017
1018 data_ptr = (u8 *) &pkt->rg_property_data[0];
1019 num_properties = pkt->num_properties;
1020 dprintk(VIDC_DBG,
1021 "%s: data_start %pK, num_properties %#x\n",
1022 __func__, data_ptr, num_properties);
1023 if (!num_properties) {
1024 sys_init_done->capabilities = NULL;
1025 dprintk(VIDC_DBG,
1026 "Venus didn't set any properties in SYS_INIT_DONE");
1027 return status;
1028 }
1029 bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done);
1030 data_ptr += bytes_read;
1031 rem_bytes -= bytes_read;
1032 num_properties--;
1033
1034 status = hfi_parse_init_done_properties(
1035 sys_init_done->capabilities,
1036 VIDC_MAX_SESSIONS, data_ptr, num_properties,
1037 rem_bytes, codecs, domain);
1038 if (status) {
1039 dprintk(VIDC_ERR, "%s: parse status %#x\n",
1040 __func__, status);
1041 return status;
1042 }
1043
1044 return status;
1045}
1046
1047static void hfi_process_sess_get_prop_dec_entropy(
1048 struct hfi_msg_session_property_info_packet *prop,
1049 enum hal_h264_entropy *entropy)
1050{
1051 u32 req_bytes, hfi_entropy;
1052
1053 req_bytes = prop->size - sizeof(
1054 struct hfi_msg_session_property_info_packet);
1055
1056 if (!req_bytes || req_bytes % sizeof(hfi_entropy)) {
1057 dprintk(VIDC_ERR, "%s: bad packet: %d\n", __func__, req_bytes);
1058 return;
1059 }
1060
1061 hfi_entropy = prop->rg_property_data[1];
1062 *entropy =
1063 hfi_entropy == HFI_H264_ENTROPY_CAVLC ? HAL_H264_ENTROPY_CAVLC :
1064 hfi_entropy == HFI_H264_ENTROPY_CABAC ? HAL_H264_ENTROPY_CABAC :
1065 HAL_UNUSED_ENTROPY;
1066}
1067
1068static void hfi_process_sess_get_prop_profile_level(
1069 struct hfi_msg_session_property_info_packet *prop,
1070 struct hfi_profile_level *profile_level)
1071{
1072 struct hfi_profile_level *hfi_profile_level;
1073 u32 req_bytes;
1074
1075 dprintk(VIDC_DBG, "Entered %s\n", __func__);
1076 if (!prop) {
1077 dprintk(VIDC_ERR,
1078 "hal_process_sess_get_profile_level: bad_prop: %pK\n",
1079 prop);
1080 return;
1081 }
1082 req_bytes = prop->size - sizeof(
1083 struct hfi_msg_session_property_info_packet);
1084
1085 if (!req_bytes || req_bytes % sizeof(struct hfi_profile_level)) {
1086 dprintk(VIDC_ERR,
1087 "hal_process_sess_get_profile_level: bad_pkt: %d\n",
1088 req_bytes);
1089 return;
1090 }
1091 hfi_profile_level = (struct hfi_profile_level *)
1092 &prop->rg_property_data[1];
1093 profile_level->profile = hfi_profile_level->profile;
1094 profile_level->level = hfi_profile_level->level;
1095 dprintk(VIDC_DBG, "%s profile: %d level: %d\n",
1096 __func__, profile_level->profile,
1097 profile_level->level);
1098}
1099
1100static void hfi_process_sess_get_prop_buf_req(
1101 struct hfi_msg_session_property_info_packet *prop,
1102 struct buffer_requirements *buffreq)
1103{
1104 struct hfi_buffer_requirements *hfi_buf_req;
1105 u32 req_bytes;
1106
1107 if (!prop) {
1108 dprintk(VIDC_ERR,
1109 "hal_process_sess_get_prop_buf_req: bad_prop: %pK\n",
1110 prop);
1111 return;
1112 }
1113
1114 req_bytes = prop->size - sizeof(
1115 struct hfi_msg_session_property_info_packet);
1116 if (!req_bytes || req_bytes % sizeof(struct hfi_buffer_requirements) ||
1117 !prop->rg_property_data[1]) {
1118 dprintk(VIDC_ERR,
1119 "hal_process_sess_get_prop_buf_req: bad_pkt: %d\n",
1120 req_bytes);
1121 return;
1122 }
1123
1124 hfi_buf_req = (struct hfi_buffer_requirements *)
1125 &prop->rg_property_data[1];
1126
1127 if (!hfi_buf_req) {
1128 dprintk(VIDC_ERR, "%s - invalid buffer req pointer\n",
1129 __func__);
1130 return;
1131 }
1132
1133 while (req_bytes) {
1134 if (hfi_buf_req->buffer_size &&
1135 hfi_buf_req->buffer_count_min > hfi_buf_req->
1136 buffer_count_actual)
1137 dprintk(VIDC_WARN,
1138 "Bad buffer requirements for %#x: min %d, actual %d\n",
1139 hfi_buf_req->buffer_type,
1140 hfi_buf_req->buffer_count_min,
1141 hfi_buf_req->buffer_count_actual);
1142
1143 dprintk(VIDC_DBG, "got buffer requirements for: %d\n",
1144 hfi_buf_req->buffer_type);
1145 switch (hfi_buf_req->buffer_type) {
1146 case HFI_BUFFER_INPUT:
1147 memcpy(&buffreq->buffer[0], hfi_buf_req,
1148 sizeof(struct hfi_buffer_requirements));
1149 buffreq->buffer[0].buffer_type = HAL_BUFFER_INPUT;
1150 break;
1151 case HFI_BUFFER_OUTPUT:
1152 memcpy(&buffreq->buffer[1], hfi_buf_req,
1153 sizeof(struct hfi_buffer_requirements));
1154 buffreq->buffer[1].buffer_type = HAL_BUFFER_OUTPUT;
1155 break;
1156 case HFI_BUFFER_OUTPUT2:
1157 memcpy(&buffreq->buffer[2], hfi_buf_req,
1158 sizeof(struct hfi_buffer_requirements));
1159 buffreq->buffer[2].buffer_type = HAL_BUFFER_OUTPUT2;
1160 break;
1161 case HFI_BUFFER_EXTRADATA_INPUT:
1162 memcpy(&buffreq->buffer[3], hfi_buf_req,
1163 sizeof(struct hfi_buffer_requirements));
1164 buffreq->buffer[3].buffer_type =
1165 HAL_BUFFER_EXTRADATA_INPUT;
1166 break;
1167 case HFI_BUFFER_EXTRADATA_OUTPUT:
1168 memcpy(&buffreq->buffer[4], hfi_buf_req,
1169 sizeof(struct hfi_buffer_requirements));
1170 buffreq->buffer[4].buffer_type =
1171 HAL_BUFFER_EXTRADATA_OUTPUT;
1172 break;
1173 case HFI_BUFFER_EXTRADATA_OUTPUT2:
1174 memcpy(&buffreq->buffer[5], hfi_buf_req,
1175 sizeof(struct hfi_buffer_requirements));
1176 buffreq->buffer[5].buffer_type =
1177 HAL_BUFFER_EXTRADATA_OUTPUT2;
1178 break;
1179 case HFI_BUFFER_INTERNAL_SCRATCH:
1180 memcpy(&buffreq->buffer[6], hfi_buf_req,
1181 sizeof(struct hfi_buffer_requirements));
1182 buffreq->buffer[6].buffer_type =
1183 HAL_BUFFER_INTERNAL_SCRATCH;
1184 break;
1185 case HFI_BUFFER_INTERNAL_SCRATCH_1:
1186 memcpy(&buffreq->buffer[7], hfi_buf_req,
1187 sizeof(struct hfi_buffer_requirements));
1188 buffreq->buffer[7].buffer_type =
1189 HAL_BUFFER_INTERNAL_SCRATCH_1;
1190 break;
1191 case HFI_BUFFER_INTERNAL_SCRATCH_2:
1192 memcpy(&buffreq->buffer[8], hfi_buf_req,
1193 sizeof(struct hfi_buffer_requirements));
1194 buffreq->buffer[8].buffer_type =
1195 HAL_BUFFER_INTERNAL_SCRATCH_2;
1196 break;
1197 case HFI_BUFFER_INTERNAL_PERSIST:
1198 memcpy(&buffreq->buffer[9], hfi_buf_req,
1199 sizeof(struct hfi_buffer_requirements));
1200 buffreq->buffer[9].buffer_type =
1201 HAL_BUFFER_INTERNAL_PERSIST;
1202 break;
1203 case HFI_BUFFER_INTERNAL_PERSIST_1:
1204 memcpy(&buffreq->buffer[10], hfi_buf_req,
1205 sizeof(struct hfi_buffer_requirements));
1206 buffreq->buffer[10].buffer_type =
1207 HAL_BUFFER_INTERNAL_PERSIST_1;
1208 break;
1209 default:
1210 dprintk(VIDC_ERR,
1211 "hal_process_sess_get_prop_buf_req: bad_buffer_type: %d\n",
1212 hfi_buf_req->buffer_type);
1213 break;
1214 }
1215 req_bytes -= sizeof(struct hfi_buffer_requirements);
1216 hfi_buf_req++;
1217 }
1218}
1219
1220static int hfi_process_session_prop_info(u32 device_id,
1221 struct hfi_msg_session_property_info_packet *pkt,
1222 struct msm_vidc_cb_info *info)
1223{
1224 struct msm_vidc_cb_cmd_done cmd_done = {0};
1225 struct hfi_profile_level profile_level = {0};
1226 enum hal_h264_entropy entropy = HAL_UNUSED_ENTROPY;
1227 struct buffer_requirements buff_req = { { {0} } };
1228
1229 dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO[%#x]\n",
1230 pkt->session_id);
1231
1232 if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) {
1233 dprintk(VIDC_ERR,
1234 "hal_process_session_prop_info: bad_pkt_size\n");
1235 return -E2BIG;
1236 } else if (!pkt->num_properties) {
1237 dprintk(VIDC_ERR,
1238 "hal_process_session_prop_info: no_properties\n");
1239 return -EINVAL;
1240 }
1241
1242 switch (pkt->rg_property_data[0]) {
1243 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
1244 hfi_process_sess_get_prop_buf_req(pkt, &buff_req);
1245 cmd_done.device_id = device_id;
1246 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1247 cmd_done.status = VIDC_ERR_NONE;
1248 cmd_done.data.property.buf_req = buff_req;
1249 cmd_done.size = sizeof(buff_req);
1250
1251 *info = (struct msm_vidc_cb_info) {
1252 .response_type = HAL_SESSION_PROPERTY_INFO,
1253 .response.cmd = cmd_done,
1254 };
1255
1256 return 0;
1257 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
1258 hfi_process_sess_get_prop_profile_level(pkt, &profile_level);
1259 cmd_done.device_id = device_id;
1260 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1261 cmd_done.status = VIDC_ERR_NONE;
1262 cmd_done.data.property.profile_level =
1263 (struct hal_profile_level) {
1264 .profile = profile_level.profile,
1265 .level = profile_level.level,
1266 };
1267 cmd_done.size = sizeof(struct hal_profile_level);
1268
1269 *info = (struct msm_vidc_cb_info) {
1270 .response_type = HAL_SESSION_PROPERTY_INFO,
1271 .response.cmd = cmd_done,
1272 };
1273 return 0;
1274 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
1275 hfi_process_sess_get_prop_dec_entropy(pkt, &entropy);
1276 cmd_done.device_id = device_id;
1277 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1278 cmd_done.status = VIDC_ERR_NONE;
1279 cmd_done.data.property.h264_entropy = entropy;
1280 cmd_done.size = sizeof(enum hal_h264_entropy);
1281
1282 *info = (struct msm_vidc_cb_info) {
1283 .response_type = HAL_SESSION_PROPERTY_INFO,
1284 .response.cmd = cmd_done,
1285 };
1286 return 0;
1287 default:
1288 dprintk(VIDC_DBG,
1289 "hal_process_session_prop_info: unknown_prop_id: %x\n",
1290 pkt->rg_property_data[0]);
1291 return -ENOTSUPP;
1292 }
1293}
1294
1295static int hfi_process_session_init_done(u32 device_id,
1296 struct hfi_msg_sys_session_init_done_packet *pkt,
1297 struct msm_vidc_cb_info *info)
1298{
1299 struct msm_vidc_cb_cmd_done cmd_done = {0};
1300 struct vidc_hal_session_init_done session_init_done = { {0} };
1301
1302 dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE[%x]\n", pkt->session_id);
1303
1304 if (sizeof(struct hfi_msg_sys_session_init_done_packet) > pkt->size) {
1305 dprintk(VIDC_ERR,
1306 "hal_process_session_init_done: bad_pkt_size\n");
1307 return -E2BIG;
1308 }
1309
1310 cmd_done.device_id = device_id;
1311 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1312 cmd_done.status = hfi_map_err_status(pkt->error_type);
1313 if (!cmd_done.status) {
1314 cmd_done.status = hfi_process_session_init_done_prop_read(
1315 pkt, &session_init_done);
1316 }
1317
1318 cmd_done.data.session_init_done = session_init_done;
1319 cmd_done.size = sizeof(struct vidc_hal_session_init_done);
1320
1321 *info = (struct msm_vidc_cb_info) {
1322 .response_type = HAL_SESSION_INIT_DONE,
1323 .response.cmd = cmd_done,
1324 };
1325
1326 return 0;
1327}
1328
1329static int hfi_process_session_load_res_done(u32 device_id,
1330 struct hfi_msg_session_load_resources_done_packet *pkt,
1331 struct msm_vidc_cb_info *info)
1332{
1333 struct msm_vidc_cb_cmd_done cmd_done = {0};
1334
1335 dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%#x]\n",
1336 pkt->session_id);
1337
1338 if (sizeof(struct hfi_msg_session_load_resources_done_packet) !=
1339 pkt->size) {
1340 dprintk(VIDC_ERR,
1341 "hal_process_session_load_res_done: bad packet size: %d\n",
1342 pkt->size);
1343 return -E2BIG;
1344 }
1345
1346 cmd_done.device_id = device_id;
1347 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1348 cmd_done.status = hfi_map_err_status(pkt->error_type);
1349 cmd_done.size = 0;
1350
1351 *info = (struct msm_vidc_cb_info) {
1352 .response_type = HAL_SESSION_LOAD_RESOURCE_DONE,
1353 .response.cmd = cmd_done,
1354 };
1355
1356 return 0;
1357}
1358
1359static int hfi_process_session_flush_done(u32 device_id,
1360 struct hfi_msg_session_flush_done_packet *pkt,
1361 struct msm_vidc_cb_info *info)
1362{
1363 struct msm_vidc_cb_cmd_done cmd_done = {0};
1364
1365 dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n",
1366 pkt->session_id);
1367
1368 if (sizeof(struct hfi_msg_session_flush_done_packet) != pkt->size) {
1369 dprintk(VIDC_ERR,
1370 "hal_process_session_flush_done: bad packet size: %d\n",
1371 pkt->size);
1372 return -E2BIG;
1373 }
1374
1375 cmd_done.device_id = device_id;
1376 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1377 cmd_done.status = hfi_map_err_status(pkt->error_type);
1378 cmd_done.size = sizeof(u32);
1379
1380 switch (pkt->flush_type) {
1381 case HFI_FLUSH_OUTPUT:
1382 cmd_done.data.flush_type = HAL_FLUSH_OUTPUT;
1383 break;
1384 case HFI_FLUSH_INPUT:
1385 cmd_done.data.flush_type = HAL_FLUSH_INPUT;
1386 break;
1387 case HFI_FLUSH_ALL:
1388 cmd_done.data.flush_type = HAL_FLUSH_ALL;
1389 break;
1390 default:
1391 dprintk(VIDC_ERR,
1392 "%s: invalid flush type!", __func__);
1393 return -EINVAL;
1394 }
1395
1396 *info = (struct msm_vidc_cb_info) {
1397 .response_type = HAL_SESSION_FLUSH_DONE,
1398 .response.cmd = cmd_done,
1399 };
1400
1401 return 0;
1402}
1403
1404static int hfi_process_session_etb_done(u32 device_id,
1405 struct hfi_msg_session_empty_buffer_done_packet *pkt,
1406 struct msm_vidc_cb_info *info)
1407{
1408 struct msm_vidc_cb_data_done data_done = {0};
1409 struct hfi_picture_type *hfi_picture_type = NULL;
1410
1411 dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id);
1412
1413 if (!pkt || pkt->size <
1414 sizeof(struct hfi_msg_session_empty_buffer_done_packet)) {
1415 dprintk(VIDC_ERR,
1416 "hal_process_session_etb_done: bad_pkt_size\n");
1417 return -E2BIG;
1418 }
1419
1420 data_done.device_id = device_id;
1421 data_done.session_id = (void *)(uintptr_t)pkt->session_id;
1422 data_done.status = hfi_map_err_status(pkt->error_type);
1423 data_done.size = sizeof(struct msm_vidc_cb_data_done);
1424 data_done.clnt_data = pkt->input_tag;
1425 data_done.input_done.offset = pkt->offset;
1426 data_done.input_done.filled_len = pkt->filled_len;
1427 data_done.input_done.packet_buffer =
1428 (ion_phys_addr_t)pkt->packet_buffer;
1429 data_done.input_done.extra_data_buffer =
1430 (ion_phys_addr_t)pkt->extra_data_buffer;
1431 data_done.input_done.status =
1432 hfi_map_err_status(pkt->error_type);
1433 hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[0];
1434 if (hfi_picture_type->is_sync_frame) {
1435 if (hfi_picture_type->picture_type)
1436 data_done.input_done.flags =
1437 hfi_picture_type->picture_type;
1438 else
1439 dprintk(VIDC_DBG,
1440 "Non-Sync frame sent for H264/HEVC\n");
1441 }
1442
1443 trace_msm_v4l2_vidc_buffer_event_end("ETB",
1444 (u32)pkt->packet_buffer, -1, -1,
1445 pkt->filled_len, pkt->offset);
1446
1447 *info = (struct msm_vidc_cb_info) {
1448 .response_type = HAL_SESSION_ETB_DONE,
1449 .response.data = data_done,
1450 };
1451
1452 return 0;
1453}
1454
1455static int hfi_process_session_ftb_done(
1456 u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr,
1457 struct msm_vidc_cb_info *info)
1458{
1459 struct msm_vidc_cb_data_done data_done = {0};
1460 bool is_decoder = false, is_encoder = false;
1461
1462 if (!msg_hdr) {
1463 dprintk(VIDC_ERR, "Invalid Params\n");
1464 return -EINVAL;
1465 }
1466
1467 is_encoder = msg_hdr->size == sizeof(struct
1468 hfi_msg_session_fill_buffer_done_compressed_packet) + 4;
1469 is_decoder = msg_hdr->size == sizeof(struct
1470 hfi_msg_session_fbd_uncompressed_plane0_packet) + 4;
1471
1472 if (!(is_encoder ^ is_decoder)) {
1473 dprintk(VIDC_ERR, "Ambiguous packet (%#x) received (size %d)\n",
1474 msg_hdr->packet, msg_hdr->size);
1475 return -EBADHANDLE;
1476 }
1477
1478 if (is_encoder) {
1479 struct hfi_msg_session_fill_buffer_done_compressed_packet *pkt =
1480 (struct hfi_msg_session_fill_buffer_done_compressed_packet *)
1481 msg_hdr;
1482 dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%#x]\n",
1483 pkt->session_id);
1484 if (sizeof(struct
1485 hfi_msg_session_fill_buffer_done_compressed_packet)
1486 > pkt->size) {
1487 dprintk(VIDC_ERR,
1488 "hal_process_session_ftb_done: bad_pkt_size\n");
1489 return -E2BIG;
1490 } else if (pkt->error_type != HFI_ERR_NONE) {
1491 dprintk(VIDC_ERR,
1492 "got buffer back with error %x\n",
1493 pkt->error_type);
1494 /* Proceed with the FBD */
1495 }
1496
1497 data_done.device_id = device_id;
1498 data_done.session_id = (void *)(uintptr_t)pkt->session_id;
1499 data_done.status = hfi_map_err_status(pkt->error_type);
1500 data_done.size = sizeof(struct msm_vidc_cb_data_done);
1501 data_done.clnt_data = 0;
1502
1503 data_done.output_done.timestamp_hi = pkt->time_stamp_hi;
1504 data_done.output_done.timestamp_lo = pkt->time_stamp_lo;
1505 data_done.output_done.flags1 = pkt->flags;
1506 data_done.output_done.mark_target = pkt->mark_target;
1507 data_done.output_done.mark_data = pkt->mark_data;
1508 data_done.output_done.stats = pkt->stats;
1509 data_done.output_done.offset1 = pkt->offset;
1510 data_done.output_done.alloc_len1 = pkt->alloc_len;
1511 data_done.output_done.filled_len1 = pkt->filled_len;
1512 data_done.output_done.picture_type = pkt->picture_type;
1513 data_done.output_done.packet_buffer1 =
1514 (ion_phys_addr_t)pkt->packet_buffer;
1515 data_done.output_done.extra_data_buffer =
1516 (ion_phys_addr_t)pkt->extra_data_buffer;
1517 data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT;
1518 } else /* if (is_decoder) */ {
1519 struct hfi_msg_session_fbd_uncompressed_plane0_packet *pkt =
1520 (struct hfi_msg_session_fbd_uncompressed_plane0_packet *)
1521 msg_hdr;
1522
1523 dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%#x]\n",
1524 pkt->session_id);
1525 if (sizeof(
1526 struct hfi_msg_session_fbd_uncompressed_plane0_packet) >
1527 pkt->size) {
1528 dprintk(VIDC_ERR,
1529 "hal_process_session_ftb_done: bad_pkt_size\n");
1530 return -E2BIG;
1531 }
1532
1533 data_done.device_id = device_id;
1534 data_done.session_id = (void *)(uintptr_t)pkt->session_id;
1535 data_done.status = hfi_map_err_status(pkt->error_type);
1536 data_done.size = sizeof(struct msm_vidc_cb_data_done);
1537 data_done.clnt_data = 0;
1538
1539 data_done.output_done.stream_id = pkt->stream_id;
1540 data_done.output_done.view_id = pkt->view_id;
1541 data_done.output_done.timestamp_hi = pkt->time_stamp_hi;
1542 data_done.output_done.timestamp_lo = pkt->time_stamp_lo;
1543 data_done.output_done.flags1 = pkt->flags;
1544 data_done.output_done.mark_target = pkt->mark_target;
1545 data_done.output_done.mark_data = pkt->mark_data;
1546 data_done.output_done.stats = pkt->stats;
1547 data_done.output_done.alloc_len1 = pkt->alloc_len;
1548 data_done.output_done.filled_len1 = pkt->filled_len;
1549 data_done.output_done.offset1 = pkt->offset;
1550 data_done.output_done.frame_width = pkt->frame_width;
1551 data_done.output_done.frame_height = pkt->frame_height;
1552 data_done.output_done.start_x_coord = pkt->start_x_coord;
1553 data_done.output_done.start_y_coord = pkt->start_y_coord;
1554 data_done.output_done.input_tag1 = pkt->input_tag;
1555 data_done.output_done.picture_type = pkt->picture_type;
1556 data_done.output_done.packet_buffer1 = pkt->packet_buffer;
1557 data_done.output_done.extra_data_buffer =
1558 pkt->extra_data_buffer;
1559
1560 if (!pkt->stream_id)
1561 data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT;
1562 else if (pkt->stream_id == 1)
1563 data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT2;
1564 }
1565
1566 trace_msm_v4l2_vidc_buffer_event_end("FTB",
1567 (u32)data_done.output_done.packet_buffer1,
1568 (((u64)data_done.output_done.timestamp_hi) << 32)
1569 + ((u64)data_done.output_done.timestamp_lo),
1570 data_done.output_done.alloc_len1,
1571 data_done.output_done.filled_len1,
1572 data_done.output_done.offset1);
1573
1574 *info = (struct msm_vidc_cb_info) {
1575 .response_type = HAL_SESSION_FTB_DONE,
1576 .response.data = data_done,
1577 };
1578
1579 return 0;
1580}
1581
1582static int hfi_process_session_start_done(u32 device_id,
1583 struct hfi_msg_session_start_done_packet *pkt,
1584 struct msm_vidc_cb_info *info)
1585{
1586 struct msm_vidc_cb_cmd_done cmd_done = {0};
1587
1588 dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%#x]\n",
1589 pkt->session_id);
1590
1591 if (!pkt || pkt->size !=
1592 sizeof(struct hfi_msg_session_start_done_packet)) {
1593 dprintk(VIDC_ERR, "%s: bad packet/packet size\n",
1594 __func__);
1595 return -E2BIG;
1596 }
1597
1598 cmd_done.device_id = device_id;
1599 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1600 cmd_done.status = hfi_map_err_status(pkt->error_type);
1601 cmd_done.size = 0;
1602
1603 *info = (struct msm_vidc_cb_info) {
1604 .response_type = HAL_SESSION_START_DONE,
1605 .response.cmd = cmd_done,
1606 };
1607 return 0;
1608}
1609
1610static int hfi_process_session_stop_done(u32 device_id,
1611 struct hfi_msg_session_stop_done_packet *pkt,
1612 struct msm_vidc_cb_info *info)
1613{
1614 struct msm_vidc_cb_cmd_done cmd_done = {0};
1615
1616 dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%#x]\n",
1617 pkt->session_id);
1618
1619 if (!pkt || pkt->size !=
1620 sizeof(struct hfi_msg_session_stop_done_packet)) {
1621 dprintk(VIDC_ERR, "%s: bad packet/packet size\n",
1622 __func__);
1623 return -E2BIG;
1624 }
1625
1626 cmd_done.device_id = device_id;
1627 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1628 cmd_done.status = hfi_map_err_status(pkt->error_type);
1629 cmd_done.size = 0;
1630
1631 *info = (struct msm_vidc_cb_info) {
1632 .response_type = HAL_SESSION_STOP_DONE,
1633 .response.cmd = cmd_done,
1634 };
1635
1636 return 0;
1637}
1638
1639static int hfi_process_session_rel_res_done(u32 device_id,
1640 struct hfi_msg_session_release_resources_done_packet *pkt,
1641 struct msm_vidc_cb_info *info)
1642{
1643 struct msm_vidc_cb_cmd_done cmd_done = {0};
1644
1645 dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%#x]\n",
1646 pkt->session_id);
1647
1648 if (!pkt || pkt->size !=
1649 sizeof(struct hfi_msg_session_release_resources_done_packet)) {
1650 dprintk(VIDC_ERR, "%s: bad packet/packet size\n",
1651 __func__);
1652 return -E2BIG;
1653 }
1654
1655 cmd_done.device_id = device_id;
1656 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1657 cmd_done.status = hfi_map_err_status(pkt->error_type);
1658 cmd_done.size = 0;
1659
1660 *info = (struct msm_vidc_cb_info) {
1661 .response_type = HAL_SESSION_RELEASE_RESOURCE_DONE,
1662 .response.cmd = cmd_done,
1663 };
1664
1665 return 0;
1666}
1667
1668static int hfi_process_session_rel_buf_done(u32 device_id,
1669 struct hfi_msg_session_release_buffers_done_packet *pkt,
1670 struct msm_vidc_cb_info *info)
1671{
1672 struct msm_vidc_cb_cmd_done cmd_done = {0};
1673
1674 if (!pkt || pkt->size <
1675 sizeof(struct hfi_msg_session_release_buffers_done_packet)) {
1676 dprintk(VIDC_ERR, "bad packet/packet size %d\n",
1677 pkt ? pkt->size : 0);
1678 return -E2BIG;
1679 }
1680 dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%#x]\n",
1681 pkt->session_id);
1682
1683 cmd_done.device_id = device_id;
1684 cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done);
1685 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1686 cmd_done.status = hfi_map_err_status(pkt->error_type);
1687 if (pkt->rg_buffer_info) {
1688 cmd_done.data.buffer_info =
1689 *(struct hal_buffer_info *)pkt->rg_buffer_info;
1690 cmd_done.size = sizeof(struct hal_buffer_info);
1691 } else {
1692 dprintk(VIDC_ERR, "invalid payload in rel_buff_done\n");
1693 }
1694
1695 *info = (struct msm_vidc_cb_info) {
1696 .response_type = HAL_SESSION_RELEASE_BUFFER_DONE,
1697 .response.cmd = cmd_done,
1698 };
1699
1700 return 0;
1701}
1702
1703static int hfi_process_session_end_done(u32 device_id,
1704 struct hfi_msg_sys_session_end_done_packet *pkt,
1705 struct msm_vidc_cb_info *info)
1706{
1707 struct msm_vidc_cb_cmd_done cmd_done = {0};
1708
1709 dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%#x]\n", pkt->session_id);
1710
1711 if (!pkt || pkt->size !=
1712 sizeof(struct hfi_msg_sys_session_end_done_packet)) {
1713 dprintk(VIDC_ERR, "%s: bad packet/packet size\n", __func__);
1714 return -E2BIG;
1715 }
1716
1717 cmd_done.device_id = device_id;
1718 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1719 cmd_done.status = hfi_map_err_status(pkt->error_type);
1720 cmd_done.size = 0;
1721
1722 *info = (struct msm_vidc_cb_info) {
1723 .response_type = HAL_SESSION_END_DONE,
1724 .response.cmd = cmd_done,
1725 };
1726
1727 return 0;
1728}
1729
1730static int hfi_process_session_abort_done(u32 device_id,
1731 struct hfi_msg_sys_session_abort_done_packet *pkt,
1732 struct msm_vidc_cb_info *info)
1733{
1734 struct msm_vidc_cb_cmd_done cmd_done = {0};
1735
1736 dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%#x]\n",
1737 pkt->session_id);
1738
1739 if (!pkt || pkt->size !=
1740 sizeof(struct hfi_msg_sys_session_abort_done_packet)) {
1741 dprintk(VIDC_ERR, "%s: bad packet/packet size: %d\n",
1742 __func__, pkt ? pkt->size : 0);
1743 return -E2BIG;
1744 }
1745 cmd_done.device_id = device_id;
1746 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1747 cmd_done.status = hfi_map_err_status(pkt->error_type);
1748 cmd_done.size = 0;
1749
1750 *info = (struct msm_vidc_cb_info) {
1751 .response_type = HAL_SESSION_ABORT_DONE,
1752 .response.cmd = cmd_done,
1753 };
1754
1755 return 0;
1756}
1757
1758static int hfi_process_session_get_seq_hdr_done(
1759 u32 device_id,
1760 struct hfi_msg_session_get_sequence_header_done_packet *pkt,
1761 struct msm_vidc_cb_info *info)
1762{
1763 struct msm_vidc_cb_data_done data_done = {0};
1764
1765 if (!pkt || pkt->size !=
1766 sizeof(struct
1767 hfi_msg_session_get_sequence_header_done_packet)) {
1768 dprintk(VIDC_ERR, "%s: bad packet/packet size\n",
1769 __func__);
1770 return -E2BIG;
1771 }
1772
1773 dprintk(VIDC_DBG, "RECEIVED:SESSION_GET_SEQ_HDR_DONE[%#x]\n",
1774 pkt->session_id);
1775
1776 data_done.device_id = device_id;
1777 data_done.size = sizeof(struct msm_vidc_cb_data_done);
1778 data_done.session_id = (void *)(uintptr_t)pkt->session_id;
1779 data_done.status = hfi_map_err_status(pkt->error_type);
1780 data_done.output_done.packet_buffer1 =
1781 (ion_phys_addr_t)pkt->sequence_header;
1782 data_done.output_done.filled_len1 = pkt->header_len;
1783 dprintk(VIDC_INFO, "seq_hdr: %#x, Length: %d\n",
1784 pkt->sequence_header, pkt->header_len);
1785
1786 *info = (struct msm_vidc_cb_info) {
1787 .response_type = HAL_SESSION_GET_SEQ_HDR_DONE,
1788 .response.data = data_done,
1789 };
1790
1791 return 0;
1792}
1793
1794static void hfi_process_sys_get_prop_image_version(
1795 struct hfi_msg_sys_property_info_packet *pkt)
1796{
1797 int i = 0;
1798 u32 smem_block_size = 0;
1799 u8 *smem_table_ptr;
1800 char version[256];
1801 const u32 version_string_size = 128;
1802 const u32 smem_image_index_venus = 14 * 128;
1803 u8 *str_image_version;
1804 int req_bytes;
1805
1806 req_bytes = pkt->size - sizeof(*pkt);
1807 if (req_bytes < version_string_size ||
1808 !pkt->rg_property_data[1] ||
1809 pkt->num_properties > 1) {
1810 dprintk(VIDC_ERR,
1811 "hfi_process_sys_get_prop_image_version: bad_pkt: %d\n",
1812 req_bytes);
1813 return;
1814 }
1815 str_image_version = (u8 *)&pkt->rg_property_data[1];
1816 /*
1817 * The version string returned by firmware includes null
1818 * characters at the start and in between. Replace the null
1819 * characters with space, to print the version info.
1820 */
1821 for (i = 0; i < version_string_size; i++) {
1822 if (str_image_version[i] != '\0')
1823 version[i] = str_image_version[i];
1824 else
1825 version[i] = ' ';
1826 }
1827 version[i] = '\0';
1828 dprintk(VIDC_DBG, "F/W version: %s\n", version);
1829
1830 smem_table_ptr = smem_get_entry(SMEM_IMAGE_VERSION_TABLE,
1831 &smem_block_size, 0, SMEM_ANY_HOST_FLAG);
1832 if ((smem_image_index_venus + version_string_size) <= smem_block_size &&
1833 smem_table_ptr)
1834 memcpy(smem_table_ptr + smem_image_index_venus,
1835 str_image_version, version_string_size);
1836}
1837
1838static int hfi_process_sys_property_info(u32 device_id,
1839 struct hfi_msg_sys_property_info_packet *pkt,
1840 struct msm_vidc_cb_info *info)
1841{
1842 if (!pkt) {
1843 dprintk(VIDC_ERR, "%s: invalid param\n", __func__);
1844 return -EINVAL;
1845 } else if (pkt->size < sizeof(*pkt)) {
1846 dprintk(VIDC_ERR,
1847 "hfi_process_sys_property_info: bad_pkt_size\n");
1848 return -E2BIG;
1849 } else if (!pkt->num_properties) {
1850 dprintk(VIDC_ERR,
1851 "hfi_process_sys_property_info: no_properties\n");
1852 return -EINVAL;
1853 }
1854
1855 switch (pkt->rg_property_data[0]) {
1856 case HFI_PROPERTY_SYS_IMAGE_VERSION:
1857 hfi_process_sys_get_prop_image_version(pkt);
1858
1859 *info = (struct msm_vidc_cb_info) {
1860 .response_type = HAL_RESPONSE_UNUSED,
1861 };
1862 return 0;
1863 default:
1864 dprintk(VIDC_DBG,
1865 "hfi_process_sys_property_info: unknown_prop_id: %x\n",
1866 pkt->rg_property_data[0]);
1867 return -ENOTSUPP;
1868 }
1869
1870}
1871
1872static int hfi_process_ignore(u32 device_id,
1873 struct vidc_hal_msg_pkt_hdr *msg_hdr,
1874 struct msm_vidc_cb_info *info)
1875{
1876 *info = (struct msm_vidc_cb_info) {
1877 .response_type = HAL_RESPONSE_UNUSED,
1878 };
1879
1880 return 0;
1881}
1882
1883int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr,
1884 struct msm_vidc_cb_info *info)
1885{
1886 typedef int (*pkt_func_def)(u32, void *, struct msm_vidc_cb_info *info);
1887 pkt_func_def pkt_func = NULL;
1888
1889 if (!info || !msg_hdr || msg_hdr->size < VIDC_IFACEQ_MIN_PKT_SIZE) {
1890 dprintk(VIDC_ERR, "%s: bad packet/packet size\n",
1891 __func__);
1892 return -EINVAL;
1893 }
1894
1895 dprintk(VIDC_DBG, "Parse response %#x\n", msg_hdr->packet);
1896 switch (msg_hdr->packet) {
1897 case HFI_MSG_EVENT_NOTIFY:
1898 pkt_func = (pkt_func_def)hfi_process_event_notify;
1899 break;
1900 case HFI_MSG_SYS_INIT_DONE:
1901 pkt_func = (pkt_func_def)hfi_process_sys_init_done;
1902 break;
1903 case HFI_MSG_SYS_SESSION_INIT_DONE:
1904 pkt_func = (pkt_func_def)hfi_process_session_init_done;
1905 break;
1906 case HFI_MSG_SYS_PROPERTY_INFO:
1907 pkt_func = (pkt_func_def)hfi_process_sys_property_info;
1908 break;
1909 case HFI_MSG_SYS_SESSION_END_DONE:
1910 pkt_func = (pkt_func_def)hfi_process_session_end_done;
1911 break;
1912 case HFI_MSG_SESSION_LOAD_RESOURCES_DONE:
1913 pkt_func = (pkt_func_def)hfi_process_session_load_res_done;
1914 break;
1915 case HFI_MSG_SESSION_START_DONE:
1916 pkt_func = (pkt_func_def)hfi_process_session_start_done;
1917 break;
1918 case HFI_MSG_SESSION_STOP_DONE:
1919 pkt_func = (pkt_func_def)hfi_process_session_stop_done;
1920 break;
1921 case HFI_MSG_SESSION_EMPTY_BUFFER_DONE:
1922 pkt_func = (pkt_func_def)hfi_process_session_etb_done;
1923 break;
1924 case HFI_MSG_SESSION_FILL_BUFFER_DONE:
1925 pkt_func = (pkt_func_def)hfi_process_session_ftb_done;
1926 break;
1927 case HFI_MSG_SESSION_FLUSH_DONE:
1928 pkt_func = (pkt_func_def)hfi_process_session_flush_done;
1929 break;
1930 case HFI_MSG_SESSION_PROPERTY_INFO:
1931 pkt_func = (pkt_func_def)hfi_process_session_prop_info;
1932 break;
1933 case HFI_MSG_SESSION_RELEASE_RESOURCES_DONE:
1934 pkt_func = (pkt_func_def)hfi_process_session_rel_res_done;
1935 break;
1936 case HFI_MSG_SYS_RELEASE_RESOURCE:
1937 pkt_func = (pkt_func_def)hfi_process_sys_rel_resource_done;
1938 break;
1939 case HFI_MSG_SESSION_GET_SEQUENCE_HEADER_DONE:
1940 pkt_func = (pkt_func_def) hfi_process_session_get_seq_hdr_done;
1941 break;
1942 case HFI_MSG_SESSION_RELEASE_BUFFERS_DONE:
1943 pkt_func = (pkt_func_def)hfi_process_session_rel_buf_done;
1944 break;
1945 case HFI_MSG_SYS_SESSION_ABORT_DONE:
1946 pkt_func = (pkt_func_def)hfi_process_session_abort_done;
1947 break;
1948 case HFI_MSG_SESSION_SYNC_DONE:
1949 pkt_func = (pkt_func_def)hfi_process_ignore;
1950 break;
1951 default:
1952 dprintk(VIDC_DBG, "Unable to parse message: %#x\n",
1953 msg_hdr->packet);
1954 break;
1955 }
1956
1957 return pkt_func ? pkt_func(device_id, msg_hdr, info) : -ENOTSUPP;
1958}