blob: e5d1576f90c140271f4f8df104dd26330df1fc0a [file] [log] [blame]
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001/* Copyright (c) 2012-2017, 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,
Praneeth Paladugu520c7592017-01-26 13:53:14 -080028 u32 rem_bytes);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -080029
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;
Praneeth Paladugu520e9b22017-05-31 13:25:18 -0700113 struct hfi_buffer_requirements *buf_req;
114 struct hfi_index_extradata_input_crop_payload *crop_info;
Chinmay Sawarkarb3c6ccb2017-02-23 18:01:32 -0800115 u32 entropy_mode = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800116 u8 *data_ptr;
117 int prop_id;
118 enum msm_vidc_pixel_depth luma_bit_depth, chroma_bit_depth;
119 struct hfi_colour_space *colour_info;
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;
Chinmay Sawarkarb3c6ccb2017-02-23 18:01:32 -0800164 event_notify.profile = profile_level->profile;
165 event_notify.level = profile_level->level;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800166 dprintk(VIDC_DBG, "profile: %d level: %d\n",
167 profile_level->profile,
168 profile_level->level);
169 data_ptr +=
170 sizeof(struct hfi_profile_level);
171 break;
172 case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
173 data_ptr = data_ptr + sizeof(u32);
174 pixel_depth = (struct hfi_bit_depth *) data_ptr;
175 /*
176 * Luma and chroma can have different bitdepths.
177 * Driver should rely on luma and chroma
178 * bitdepth for determining output bitdepth
179 * type.
180 *
181 * pixel_depth->bitdepth will include luma
182 * bitdepth info in bits 0..15 and chroma
183 * bitdept in bits 16..31.
184 */
185 luma_bit_depth = get_hal_pixel_depth(
186 pixel_depth->bit_depth &
187 GENMASK(15, 0));
188 chroma_bit_depth = get_hal_pixel_depth(
189 (pixel_depth->bit_depth &
190 GENMASK(31, 16)) >> 16);
191 if (luma_bit_depth == MSM_VIDC_BIT_DEPTH_10 ||
192 chroma_bit_depth ==
193 MSM_VIDC_BIT_DEPTH_10)
194 event_notify.bit_depth =
195 MSM_VIDC_BIT_DEPTH_10;
196 else
197 event_notify.bit_depth = luma_bit_depth;
198 dprintk(VIDC_DBG,
199 "bitdepth(%d), luma_bit_depth(%d), chroma_bit_depth(%d)\n",
200 event_notify.bit_depth, luma_bit_depth,
201 chroma_bit_depth);
202 data_ptr += sizeof(struct hfi_bit_depth);
203 break;
204 case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
205 data_ptr = data_ptr + sizeof(u32);
206 pic_struct = (struct hfi_pic_struct *) data_ptr;
207 event_notify.pic_struct =
208 pic_struct->progressive_only;
209 dprintk(VIDC_DBG,
210 "Progressive only flag: %d\n",
211 pic_struct->progressive_only);
212 data_ptr +=
213 sizeof(struct hfi_pic_struct);
214 break;
215 case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
216 data_ptr = data_ptr + sizeof(u32);
217 colour_info =
218 (struct hfi_colour_space *) data_ptr;
219 event_notify.colour_space =
220 colour_info->colour_space;
221 dprintk(VIDC_DBG,
222 "Colour space value is: %d\n",
223 colour_info->colour_space);
224 data_ptr +=
225 sizeof(struct hfi_colour_space);
226 break;
Chinmay Sawarkarb3c6ccb2017-02-23 18:01:32 -0800227 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
228 data_ptr = data_ptr + sizeof(u32);
229 entropy_mode = *(u32 *)data_ptr;
230 event_notify.entropy_mode = entropy_mode;
231 dprintk(VIDC_DBG,
232 "Entropy Mode: 0x%x\n", entropy_mode);
233 data_ptr +=
234 sizeof(u32);
235 break;
Praneeth Paladugu520e9b22017-05-31 13:25:18 -0700236 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
237 data_ptr = data_ptr + sizeof(u32);
238 buf_req =
239 (struct hfi_buffer_requirements *)
240 data_ptr;
241 event_notify.capture_buf_count =
242 buf_req->buffer_count_min;
243 dprintk(VIDC_DBG,
244 "Capture Count : 0x%x\n",
245 event_notify.capture_buf_count);
246 data_ptr +=
247 sizeof(struct hfi_buffer_requirements);
248 break;
249 case HFI_INDEX_EXTRADATA_INPUT_CROP:
250 data_ptr = data_ptr + sizeof(u32);
251 crop_info = (struct
252 hfi_index_extradata_input_crop_payload *)
253 data_ptr;
254 event_notify.crop_data.left = crop_info->left;
255 event_notify.crop_data.top = crop_info->top;
256 event_notify.crop_data.width = crop_info->width;
257 event_notify.crop_data.height =
258 crop_info->height;
259 dprintk(VIDC_DBG,
260 "CROP info : Left = %d Top = %d\n",
261 crop_info->left,
262 crop_info->top);
263 dprintk(VIDC_DBG,
264 "CROP info : Width = %d Height = %d\n",
265 crop_info->width,
266 crop_info->height);
267 data_ptr +=
268 sizeof(struct
269 hfi_index_extradata_input_crop_payload);
270 break;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800271 default:
272 dprintk(VIDC_ERR,
273 "%s cmd: %#x not supported\n",
274 __func__, prop_id);
275 break;
276 }
277 num_properties_changed--;
278 } while (num_properties_changed > 0);
279 }
280
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -0700281 info->response_type = HAL_SESSION_EVENT_CHANGE;
282 info->response.event = event_notify;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800283
284 return 0;
285}
286
287static int hfi_process_evt_release_buffer_ref(u32 device_id,
288 struct hfi_msg_event_notify_packet *pkt,
289 struct msm_vidc_cb_info *info)
290{
291 struct msm_vidc_cb_event event_notify = {0};
292 struct hfi_msg_release_buffer_ref_event_packet *data;
293
294 dprintk(VIDC_DBG,
295 "RECEIVED: EVENT_NOTIFY - release_buffer_reference\n");
296 if (sizeof(struct hfi_msg_event_notify_packet)
297 > pkt->size) {
298 dprintk(VIDC_ERR,
299 "hal_process_session_init_done: bad_pkt_size\n");
300 return -E2BIG;
301 }
302
303 data = (struct hfi_msg_release_buffer_ref_event_packet *)
304 pkt->rg_ext_event_data;
305
306 event_notify.device_id = device_id;
307 event_notify.session_id = (void *)(uintptr_t)pkt->session_id;
308 event_notify.status = VIDC_ERR_NONE;
309 event_notify.hal_event_type = HAL_EVENT_RELEASE_BUFFER_REFERENCE;
310 event_notify.packet_buffer = data->packet_buffer;
311 event_notify.extra_data_buffer = data->extra_data_buffer;
312
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -0700313 info->response_type = HAL_SESSION_EVENT_CHANGE;
314 info->response.event = event_notify;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800315
316 return 0;
317}
318
319static int hfi_process_sys_error(u32 device_id, struct msm_vidc_cb_info *info)
320{
321 struct msm_vidc_cb_cmd_done cmd_done = {0};
322
323 cmd_done.device_id = device_id;
324
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -0700325 info->response_type = HAL_SYS_ERROR;
326 info->response.cmd = cmd_done;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800327
328 return 0;
329}
330
331static int hfi_process_session_error(u32 device_id,
332 struct hfi_msg_event_notify_packet *pkt,
333 struct msm_vidc_cb_info *info)
334{
335 struct msm_vidc_cb_cmd_done cmd_done = {0};
336
337 cmd_done.device_id = device_id;
338 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
339 cmd_done.status = hfi_map_err_status(pkt->event_data1);
Maheshwar Ajja99422322017-07-07 17:31:15 -0700340 info->response.cmd = cmd_done;
Maheshwar Ajja266828742017-04-20 15:48:33 -0700341 dprintk(VIDC_INFO, "Received: SESSION_ERROR with event id : %#x %#x\n",
342 pkt->event_data1, pkt->event_data2);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800343 switch (pkt->event_data1) {
Maheshwar Ajja99422322017-07-07 17:31:15 -0700344 /* Ignore below errors */
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800345 case HFI_ERR_SESSION_INVALID_SCALE_FACTOR:
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800346 case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED:
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800347 dprintk(VIDC_INFO, "Non Fatal: HFI_EVENT_SESSION_ERROR\n");
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -0700348 info->response_type = HAL_RESPONSE_UNUSED;
Maheshwar Ajja99422322017-07-07 17:31:15 -0700349 break;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800350 default:
Maheshwar Ajja99422322017-07-07 17:31:15 -0700351 /* All other errors are not expected and treated as sys error */
Maheshwar Ajja266828742017-04-20 15:48:33 -0700352 dprintk(VIDC_ERR,
Maheshwar Ajja99422322017-07-07 17:31:15 -0700353 "%s: data1 %#x, data2 %#x, treat as sys error\n",
354 __func__, pkt->event_data1, pkt->event_data2);
355 info->response_type = HAL_SYS_ERROR;
356 break;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800357 }
Maheshwar Ajja99422322017-07-07 17:31:15 -0700358
359 return 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800360}
361
362static int hfi_process_event_notify(u32 device_id,
363 struct hfi_msg_event_notify_packet *pkt,
364 struct msm_vidc_cb_info *info)
365{
366 dprintk(VIDC_DBG, "Received: EVENT_NOTIFY\n");
367
368 if (pkt->size < sizeof(struct hfi_msg_event_notify_packet)) {
369 dprintk(VIDC_ERR, "Invalid Params\n");
370 return -E2BIG;
371 }
372
373 switch (pkt->event_id) {
374 case HFI_EVENT_SYS_ERROR:
375 dprintk(VIDC_ERR, "HFI_EVENT_SYS_ERROR: %d, %#x\n",
376 pkt->event_data1, pkt->event_data2);
377 return hfi_process_sys_error(device_id, info);
378 case HFI_EVENT_SESSION_ERROR:
379 dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR[%#x]\n",
380 pkt->session_id);
381 return hfi_process_session_error(device_id, pkt, info);
382
383 case HFI_EVENT_SESSION_SEQUENCE_CHANGED:
384 dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%#x]\n",
385 pkt->session_id);
386 return hfi_process_sess_evt_seq_changed(device_id, pkt, info);
387
388 case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
389 dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%#x]\n",
390 pkt->session_id);
391 return hfi_process_evt_release_buffer_ref(device_id, pkt, info);
392
393 case HFI_EVENT_SESSION_PROPERTY_CHANGED:
394 default:
395 *info = (struct msm_vidc_cb_info) {
396 .response_type = HAL_RESPONSE_UNUSED,
397 };
398
399 return 0;
400 }
401}
402
403static int hfi_process_sys_init_done(u32 device_id,
404 struct hfi_msg_sys_init_done_packet *pkt,
405 struct msm_vidc_cb_info *info)
406{
407 struct msm_vidc_cb_cmd_done cmd_done = {0};
408 enum vidc_status status = VIDC_ERR_NONE;
409
410 dprintk(VIDC_DBG, "RECEIVED: SYS_INIT_DONE\n");
411 if (sizeof(struct hfi_msg_sys_init_done_packet) > pkt->size) {
412 dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", __func__,
413 pkt->size);
414 return -E2BIG;
415 }
416 if (!pkt->num_properties) {
417 dprintk(VIDC_ERR,
418 "hal_process_sys_init_done: no_properties\n");
419 status = VIDC_ERR_FAIL;
420 goto err_no_prop;
421 }
422
423 status = hfi_map_err_status(pkt->error_type);
424 if (status) {
425 dprintk(VIDC_ERR, "%s: status %#x\n",
426 __func__, status);
427 goto err_no_prop;
428 }
429
430err_no_prop:
431 cmd_done.device_id = device_id;
432 cmd_done.session_id = NULL;
433 cmd_done.status = (u32)status;
434 cmd_done.size = sizeof(struct vidc_hal_sys_init_done);
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -0700435
436 info->response_type = HAL_SYS_INIT_DONE;
437 info->response.cmd = cmd_done;
438
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800439 return 0;
440}
441
442static int hfi_process_sys_rel_resource_done(u32 device_id,
443 struct hfi_msg_sys_release_resource_done_packet *pkt,
444 struct msm_vidc_cb_info *info)
445{
446 struct msm_vidc_cb_cmd_done cmd_done = {0};
447 enum vidc_status status = VIDC_ERR_NONE;
448 u32 pkt_size;
449
450 dprintk(VIDC_DBG, "RECEIVED: SYS_RELEASE_RESOURCE_DONE\n");
451 pkt_size = sizeof(struct hfi_msg_sys_release_resource_done_packet);
452 if (pkt_size > pkt->size) {
453 dprintk(VIDC_ERR,
454 "hal_process_sys_rel_resource_done: bad size: %d\n",
455 pkt->size);
456 return -E2BIG;
457 }
458
459 status = hfi_map_err_status(pkt->error_type);
460 cmd_done.device_id = device_id;
461 cmd_done.session_id = NULL;
462 cmd_done.status = (u32) status;
463 cmd_done.size = 0;
464
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -0700465 info->response_type = HAL_SYS_RELEASE_RESOURCE_DONE;
466 info->response.cmd = cmd_done;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800467
468 return 0;
469}
470
471enum hal_capability get_hal_cap_type(u32 capability_type)
472{
473 enum hal_capability hal_cap = 0;
474
475 switch (capability_type) {
476 case HFI_CAPABILITY_FRAME_WIDTH:
477 hal_cap = HAL_CAPABILITY_FRAME_WIDTH;
478 break;
479 case HFI_CAPABILITY_FRAME_HEIGHT:
480 hal_cap = HAL_CAPABILITY_FRAME_HEIGHT;
481 break;
482 case HFI_CAPABILITY_MBS_PER_FRAME:
483 hal_cap = HAL_CAPABILITY_MBS_PER_FRAME;
484 break;
485 case HFI_CAPABILITY_MBS_PER_SECOND:
486 hal_cap = HAL_CAPABILITY_MBS_PER_SECOND;
487 break;
488 case HFI_CAPABILITY_FRAMERATE:
489 hal_cap = HAL_CAPABILITY_FRAMERATE;
490 break;
491 case HFI_CAPABILITY_SCALE_X:
492 hal_cap = HAL_CAPABILITY_SCALE_X;
493 break;
494 case HFI_CAPABILITY_SCALE_Y:
495 hal_cap = HAL_CAPABILITY_SCALE_Y;
496 break;
497 case HFI_CAPABILITY_BITRATE:
498 hal_cap = HAL_CAPABILITY_BITRATE;
499 break;
500 case HFI_CAPABILITY_BFRAME:
501 hal_cap = HAL_CAPABILITY_BFRAME;
502 break;
503 case HFI_CAPABILITY_PEAKBITRATE:
504 hal_cap = HAL_CAPABILITY_PEAKBITRATE;
505 break;
506 case HFI_CAPABILITY_HIER_P_NUM_ENH_LAYERS:
507 hal_cap = HAL_CAPABILITY_HIER_P_NUM_ENH_LAYERS;
508 break;
509 case HFI_CAPABILITY_ENC_LTR_COUNT:
510 hal_cap = HAL_CAPABILITY_ENC_LTR_COUNT;
511 break;
512 case HFI_CAPABILITY_CP_OUTPUT2_THRESH:
513 hal_cap = HAL_CAPABILITY_SECURE_OUTPUT2_THRESHOLD;
514 break;
515 case HFI_CAPABILITY_HIER_B_NUM_ENH_LAYERS:
516 hal_cap = HAL_CAPABILITY_HIER_B_NUM_ENH_LAYERS;
517 break;
518 case HFI_CAPABILITY_LCU_SIZE:
519 hal_cap = HAL_CAPABILITY_LCU_SIZE;
520 break;
521 case HFI_CAPABILITY_HIER_P_HYBRID_NUM_ENH_LAYERS:
522 hal_cap = HAL_CAPABILITY_HIER_P_HYBRID_NUM_ENH_LAYERS;
523 break;
524 case HFI_CAPABILITY_MBS_PER_SECOND_POWERSAVE:
525 hal_cap = HAL_CAPABILITY_MBS_PER_SECOND_POWER_SAVE;
526 break;
Praneeth Paladugu520c7592017-01-26 13:53:14 -0800527 case HFI_CAPABILITY_EXTRADATA:
528 hal_cap = HAL_CAPABILITY_EXTRADATA;
529 break;
530 case HFI_CAPABILITY_PROFILE:
531 hal_cap = HAL_CAPABILITY_PROFILE;
532 break;
533 case HFI_CAPABILITY_LEVEL:
534 hal_cap = HAL_CAPABILITY_LEVEL;
535 break;
536 case HFI_CAPABILITY_I_FRAME_QP:
537 hal_cap = HAL_CAPABILITY_I_FRAME_QP;
538 break;
539 case HFI_CAPABILITY_P_FRAME_QP:
540 hal_cap = HAL_CAPABILITY_P_FRAME_QP;
541 break;
542 case HFI_CAPABILITY_B_FRAME_QP:
543 hal_cap = HAL_CAPABILITY_B_FRAME_QP;
544 break;
545 case HFI_CAPABILITY_RATE_CONTROL_MODES:
546 hal_cap = HAL_CAPABILITY_RATE_CONTROL_MODES;
547 break;
548 case HFI_CAPABILITY_BLUR_WIDTH:
549 hal_cap = HAL_CAPABILITY_BLUR_WIDTH;
550 break;
551 case HFI_CAPABILITY_BLUR_HEIGHT:
552 hal_cap = HAL_CAPABILITY_BLUR_HEIGHT;
553 break;
554 case HFI_CAPABILITY_SLICE_DELIVERY_MODES:
555 hal_cap = HAL_CAPABILITY_SLICE_DELIVERY_MODES;
556 break;
557 case HFI_CAPABILITY_SLICE_BYTE:
558 hal_cap = HAL_CAPABILITY_SLICE_BYTE;
559 break;
560 case HFI_CAPABILITY_SLICE_MB:
561 hal_cap = HAL_CAPABILITY_SLICE_MB;
562 break;
563 case HFI_CAPABILITY_SECURE:
564 hal_cap = HAL_CAPABILITY_SECURE;
565 break;
566 case HFI_CAPABILITY_MAX_NUM_B_FRAMES:
567 hal_cap = HAL_CAPABILITY_MAX_NUM_B_FRAMES;
568 break;
569 case HFI_CAPABILITY_MAX_VIDEOCORES:
570 hal_cap = HAL_CAPABILITY_MAX_VIDEOCORES;
571 break;
572 case HFI_CAPABILITY_MAX_WORKMODES:
573 hal_cap = HAL_CAPABILITY_MAX_WORKMODES;
574 break;
575 case HFI_CAPABILITY_UBWC_CR_STATS:
576 hal_cap = HAL_CAPABILITY_UBWC_CR_STATS;
577 break;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800578 default:
579 dprintk(VIDC_DBG, "%s: unknown capablity %#x\n",
580 __func__, capability_type);
581 break;
582 }
583
584 return hal_cap;
585}
586
587static inline void copy_cap_prop(
588 struct hfi_capability_supported *in,
589 struct msm_vidc_capability *capability)
590{
591 struct hal_capability_supported *out = NULL;
592
593 if (!in || !capability) {
594 dprintk(VIDC_ERR, "%s Invalid input parameters\n",
595 __func__);
596 return;
597 }
598
599 switch (in->capability_type) {
600 case HFI_CAPABILITY_FRAME_WIDTH:
601 out = &capability->width;
602 break;
603 case HFI_CAPABILITY_FRAME_HEIGHT:
604 out = &capability->height;
605 break;
606 case HFI_CAPABILITY_MBS_PER_FRAME:
607 out = &capability->mbs_per_frame;
608 break;
609 case HFI_CAPABILITY_MBS_PER_SECOND:
610 out = &capability->mbs_per_sec;
611 break;
612 case HFI_CAPABILITY_FRAMERATE:
613 out = &capability->frame_rate;
614 break;
615 case HFI_CAPABILITY_SCALE_X:
616 out = &capability->scale_x;
617 break;
618 case HFI_CAPABILITY_SCALE_Y:
619 out = &capability->scale_y;
620 break;
621 case HFI_CAPABILITY_BITRATE:
622 out = &capability->bitrate;
623 break;
624 case HFI_CAPABILITY_BFRAME:
625 out = &capability->bframe;
626 break;
627 case HFI_CAPABILITY_PEAKBITRATE:
628 out = &capability->peakbitrate;
629 break;
630 case HFI_CAPABILITY_HIER_P_NUM_ENH_LAYERS:
631 out = &capability->hier_p;
632 break;
633 case HFI_CAPABILITY_ENC_LTR_COUNT:
634 out = &capability->ltr_count;
635 break;
636 case HFI_CAPABILITY_CP_OUTPUT2_THRESH:
637 out = &capability->secure_output2_threshold;
638 break;
639 case HFI_CAPABILITY_HIER_B_NUM_ENH_LAYERS:
640 out = &capability->hier_b;
641 break;
642 case HFI_CAPABILITY_LCU_SIZE:
643 out = &capability->lcu_size;
644 break;
645 case HFI_CAPABILITY_HIER_P_HYBRID_NUM_ENH_LAYERS:
646 out = &capability->hier_p_hybrid;
647 break;
648 case HFI_CAPABILITY_MBS_PER_SECOND_POWERSAVE:
649 out = &capability->mbs_per_sec_power_save;
650 break;
Praneeth Paladugu520c7592017-01-26 13:53:14 -0800651 case HFI_CAPABILITY_EXTRADATA:
652 out = &capability->extradata;
653 break;
654 case HFI_CAPABILITY_PROFILE:
655 out = &capability->profile;
656 break;
657 case HFI_CAPABILITY_LEVEL:
658 out = &capability->level;
659 break;
660 case HFI_CAPABILITY_I_FRAME_QP:
661 out = &capability->i_qp;
662 break;
663 case HFI_CAPABILITY_P_FRAME_QP:
664 out = &capability->p_qp;
665 break;
666 case HFI_CAPABILITY_B_FRAME_QP:
667 out = &capability->b_qp;
668 break;
669 case HFI_CAPABILITY_RATE_CONTROL_MODES:
670 out = &capability->rc_modes;
671 break;
672 case HFI_CAPABILITY_BLUR_WIDTH:
673 out = &capability->blur_width;
674 break;
675 case HFI_CAPABILITY_BLUR_HEIGHT:
676 out = &capability->blur_height;
677 break;
678 case HFI_CAPABILITY_SLICE_DELIVERY_MODES:
679 out = &capability->slice_delivery_mode;
680 break;
681 case HFI_CAPABILITY_SLICE_BYTE:
682 out = &capability->slice_bytes;
683 break;
684 case HFI_CAPABILITY_SLICE_MB:
685 out = &capability->slice_mbs;
686 break;
687 case HFI_CAPABILITY_SECURE:
688 out = &capability->secure;
689 break;
690 case HFI_CAPABILITY_MAX_NUM_B_FRAMES:
691 out = &capability->max_num_b_frames;
692 break;
693 case HFI_CAPABILITY_MAX_VIDEOCORES:
694 out = &capability->max_video_cores;
695 break;
696 case HFI_CAPABILITY_MAX_WORKMODES:
697 out = &capability->max_work_modes;
698 break;
699 case HFI_CAPABILITY_UBWC_CR_STATS:
700 out = &capability->ubwc_cr_stats;
701 break;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800702 default:
703 dprintk(VIDC_DBG, "%s: unknown capablity %#x\n",
704 __func__, in->capability_type);
705 break;
706 }
707
708 if (out) {
709 out->capability_type = get_hal_cap_type(in->capability_type);
710 out->min = in->min;
711 out->max = in->max;
712 out->step_size = in->step_size;
713 }
714}
715
716static int hfi_fill_codec_info(u8 *data_ptr,
717 struct vidc_hal_sys_init_done *sys_init_done) {
718 u32 i;
719 u32 codecs = 0, codec_count = 0, size = 0;
720 struct msm_vidc_capability *capability;
721 u32 prop_id = *((u32 *)data_ptr);
722 u8 *orig_data_ptr = data_ptr;
723
724 if (prop_id == HFI_PROPERTY_PARAM_CODEC_SUPPORTED) {
725 struct hfi_codec_supported *prop;
726
727 data_ptr = data_ptr + sizeof(u32);
728 prop = (struct hfi_codec_supported *) data_ptr;
729 sys_init_done->dec_codec_supported =
730 prop->decoder_codec_supported;
731 sys_init_done->enc_codec_supported =
732 prop->encoder_codec_supported;
733 size = sizeof(struct hfi_codec_supported) + sizeof(u32);
734 } else {
735 dprintk(VIDC_WARN,
736 "%s: prop_id %#x, expected codec_supported property\n",
737 __func__, prop_id);
738 }
739
740 codecs = sys_init_done->dec_codec_supported;
741 for (i = 0; i < 8 * sizeof(codecs); i++) {
742 if ((1 << i) & codecs) {
743 capability =
744 &sys_init_done->capabilities[codec_count++];
745 capability->codec =
746 vidc_get_hal_codec((1 << i) & codecs);
747 capability->domain =
748 vidc_get_hal_domain(HFI_VIDEO_DOMAIN_DECODER);
749 }
750 }
751 codecs = sys_init_done->enc_codec_supported;
752 for (i = 0; i < 8 * sizeof(codecs); i++) {
753 if ((1 << i) & codecs) {
754 capability =
755 &sys_init_done->capabilities[codec_count++];
756 capability->codec =
757 vidc_get_hal_codec((1 << i) & codecs);
758 capability->domain =
759 vidc_get_hal_domain(HFI_VIDEO_DOMAIN_ENCODER);
760 }
761 }
762 sys_init_done->codec_count = codec_count;
763
764 prop_id = *((u32 *)(orig_data_ptr + size));
765 if (prop_id == HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED) {
766 struct hfi_max_sessions_supported *prop =
767 (struct hfi_max_sessions_supported *)
768 (orig_data_ptr + size + sizeof(u32));
769
770 sys_init_done->max_sessions_supported = prop->max_sessions;
771 size += sizeof(struct hfi_max_sessions_supported) + sizeof(u32);
772 dprintk(VIDC_DBG, "max_sessions_supported %d\n",
773 prop->max_sessions);
774 }
775 return size;
776}
777
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800778static int copy_caps_to_sessions(struct hfi_capability_supported *cap,
779 u32 num_caps, struct msm_vidc_capability *capabilities,
780 u32 num_sessions, u32 codecs, u32 domain)
781{
782 u32 i = 0, j = 0;
783 struct msm_vidc_capability *capability;
784 u32 sess_codec;
785 u32 sess_domain;
786
787 /*
788 * iterate over num_sessions and copy all the capabilities
789 * to matching sessions.
790 */
791 for (i = 0; i < num_sessions; i++) {
792 sess_codec = 0;
793 sess_domain = 0;
794 capability = &capabilities[i];
795
796 if (capability->codec)
797 sess_codec =
798 vidc_get_hfi_codec(capability->codec);
799 if (capability->domain)
800 sess_domain =
801 vidc_get_hfi_domain(capability->domain);
802
803 if (!(sess_codec & codecs && sess_domain & domain))
804 continue;
805
806 for (j = 0; j < num_caps; j++)
807 copy_cap_prop(&cap[j], capability);
808 }
809
810 return 0;
811}
812
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800813static enum vidc_status hfi_parse_init_done_properties(
814 struct msm_vidc_capability *capabilities,
815 u32 num_sessions, u8 *data_ptr, u32 num_properties,
Praneeth Paladugu520c7592017-01-26 13:53:14 -0800816 u32 rem_bytes)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800817{
818 enum vidc_status status = VIDC_ERR_NONE;
819 u32 prop_id, next_offset;
Channagoud Kadabi075db3b2017-03-16 14:26:17 -0700820 u32 codecs = 0, domain = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800821
822 while (status == VIDC_ERR_NONE && num_properties &&
823 rem_bytes >= sizeof(u32)) {
824
825 prop_id = *((u32 *)data_ptr);
826 next_offset = sizeof(u32);
827
828 switch (prop_id) {
829 case HFI_PROPERTY_PARAM_CODEC_MASK_SUPPORTED:
830 {
831 struct hfi_codec_mask_supported *prop =
832 (struct hfi_codec_mask_supported *)
833 (data_ptr + next_offset);
834
835 codecs = prop->codecs;
836 domain = prop->video_domains;
837 next_offset += sizeof(struct hfi_codec_mask_supported);
838 num_properties--;
839 break;
840 }
841 case HFI_PROPERTY_PARAM_CAPABILITY_SUPPORTED:
842 {
843 struct hfi_capability_supported_info *prop =
844 (struct hfi_capability_supported_info *)
845 (data_ptr + next_offset);
846
847 if ((rem_bytes - next_offset) < prop->num_capabilities *
848 sizeof(struct hfi_capability_supported)) {
849 status = VIDC_ERR_BAD_PARAM;
850 break;
851 }
852 next_offset += sizeof(u32) +
853 prop->num_capabilities *
854 sizeof(struct hfi_capability_supported);
855
856 copy_caps_to_sessions(&prop->rg_data[0],
857 prop->num_capabilities,
858 capabilities, num_sessions,
859 codecs, domain);
860 num_properties--;
861 break;
862 }
863 case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED:
864 {
865 struct hfi_uncompressed_format_supported *prop =
866 (struct hfi_uncompressed_format_supported *)
867 (data_ptr + next_offset);
868 u32 num_format_entries;
869 char *fmt_ptr;
870 struct hfi_uncompressed_plane_info *plane_info;
871
872 if ((rem_bytes - next_offset) < sizeof(*prop)) {
873 status = VIDC_ERR_BAD_PARAM;
874 break;
875 }
876 num_format_entries = prop->format_entries;
877 next_offset = sizeof(*prop);
878 fmt_ptr = (char *)&prop->rg_format_info[0];
879
880 while (num_format_entries) {
881 u32 bytes_to_skip;
882
883 plane_info =
884 (struct hfi_uncompressed_plane_info *) fmt_ptr;
885
886 if ((rem_bytes - next_offset) <
887 sizeof(*plane_info)) {
888 status = VIDC_ERR_BAD_PARAM;
889 break;
890 }
891 bytes_to_skip = sizeof(*plane_info) -
892 sizeof(struct
893 hfi_uncompressed_plane_constraints) +
894 plane_info->num_planes *
895 sizeof(struct
896 hfi_uncompressed_plane_constraints);
897
898 fmt_ptr += bytes_to_skip;
899 next_offset += bytes_to_skip;
900 num_format_entries--;
901 }
902 num_properties--;
903 break;
904 }
905 case HFI_PROPERTY_PARAM_PROPERTIES_SUPPORTED:
906 {
907 struct hfi_properties_supported *prop =
908 (struct hfi_properties_supported *)
909 (data_ptr + next_offset);
910 next_offset += sizeof(*prop) - sizeof(u32)
911 + prop->num_properties * sizeof(u32);
912 num_properties--;
913 break;
914 }
915 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED:
916 {
917 struct msm_vidc_capability capability;
918 char *ptr = NULL;
919 u32 count = 0;
920 u32 prof_count = 0;
921 struct hfi_profile_level *prof_level;
922 struct hfi_profile_level_supported *prop =
923 (struct hfi_profile_level_supported *)
924 (data_ptr + next_offset);
925
926 ptr = (char *) &prop->rg_profile_level[0];
927 prof_count = prop->profile_count;
928 next_offset += sizeof(u32);
929
930 if (prof_count > MAX_PROFILE_COUNT) {
931 prof_count = MAX_PROFILE_COUNT;
932 dprintk(VIDC_WARN,
933 "prop count exceeds max profile count\n");
934 break;
935 }
936 while (prof_count) {
937 prof_level = (struct hfi_profile_level *)ptr;
938 capability.
939 profile_level.profile_level[count].profile
940 = prof_level->profile;
941 capability.
942 profile_level.profile_level[count].level
943 = prof_level->level;
944 prof_count--;
945 count++;
946 ptr += sizeof(struct hfi_profile_level);
947 next_offset += sizeof(struct hfi_profile_level);
948 }
949 num_properties--;
950 break;
951 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800952 case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SUPPORTED:
953 {
954 next_offset +=
955 sizeof(struct hfi_nal_stream_format_supported);
956 num_properties--;
957 break;
958 }
959 case HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT:
960 {
961 next_offset += sizeof(u32);
962 num_properties--;
963 break;
964 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800965 case HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH:
966 {
967 next_offset +=
968 sizeof(struct hfi_intra_refresh);
969 num_properties--;
970 break;
971 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800972 default:
973 dprintk(VIDC_DBG,
974 "%s: default case - data_ptr %pK, prop_id 0x%x\n",
975 __func__, data_ptr, prop_id);
976 break;
977 }
978 rem_bytes -= next_offset;
979 data_ptr += next_offset;
980 }
981
982 return status;
983}
984
985enum vidc_status hfi_process_sys_init_done_prop_read(
986 struct hfi_msg_sys_init_done_packet *pkt,
987 struct vidc_hal_sys_init_done *sys_init_done)
988{
989 enum vidc_status status = VIDC_ERR_NONE;
990 u32 rem_bytes, bytes_read, num_properties;
991 u8 *data_ptr;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800992
993 if (!pkt || !sys_init_done) {
994 dprintk(VIDC_ERR,
995 "hfi_msg_sys_init_done: Invalid input\n");
996 return VIDC_ERR_FAIL;
997 }
998
999 rem_bytes = pkt->size - sizeof(struct
1000 hfi_msg_sys_init_done_packet) + sizeof(u32);
1001
1002 if (!rem_bytes) {
1003 dprintk(VIDC_ERR,
1004 "hfi_msg_sys_init_done: missing_prop_info\n");
1005 return VIDC_ERR_FAIL;
1006 }
1007
1008 status = hfi_map_err_status(pkt->error_type);
1009 if (status) {
1010 dprintk(VIDC_ERR, "%s: status %#x\n", __func__, status);
1011 return status;
1012 }
1013
1014 data_ptr = (u8 *) &pkt->rg_property_data[0];
1015 num_properties = pkt->num_properties;
1016 dprintk(VIDC_DBG,
1017 "%s: data_start %pK, num_properties %#x\n",
1018 __func__, data_ptr, num_properties);
1019 if (!num_properties) {
1020 sys_init_done->capabilities = NULL;
1021 dprintk(VIDC_DBG,
1022 "Venus didn't set any properties in SYS_INIT_DONE");
1023 return status;
1024 }
1025 bytes_read = hfi_fill_codec_info(data_ptr, sys_init_done);
1026 data_ptr += bytes_read;
1027 rem_bytes -= bytes_read;
1028 num_properties--;
1029
1030 status = hfi_parse_init_done_properties(
1031 sys_init_done->capabilities,
1032 VIDC_MAX_SESSIONS, data_ptr, num_properties,
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001033 rem_bytes);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001034 if (status) {
1035 dprintk(VIDC_ERR, "%s: parse status %#x\n",
1036 __func__, status);
1037 return status;
1038 }
1039
1040 return status;
1041}
1042
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001043static void hfi_process_sess_get_prop_buf_req(
1044 struct hfi_msg_session_property_info_packet *prop,
1045 struct buffer_requirements *buffreq)
1046{
1047 struct hfi_buffer_requirements *hfi_buf_req;
1048 u32 req_bytes;
1049
1050 if (!prop) {
1051 dprintk(VIDC_ERR,
1052 "hal_process_sess_get_prop_buf_req: bad_prop: %pK\n",
1053 prop);
1054 return;
1055 }
1056
1057 req_bytes = prop->size - sizeof(
1058 struct hfi_msg_session_property_info_packet);
1059 if (!req_bytes || req_bytes % sizeof(struct hfi_buffer_requirements) ||
1060 !prop->rg_property_data[1]) {
1061 dprintk(VIDC_ERR,
1062 "hal_process_sess_get_prop_buf_req: bad_pkt: %d\n",
1063 req_bytes);
1064 return;
1065 }
1066
1067 hfi_buf_req = (struct hfi_buffer_requirements *)
1068 &prop->rg_property_data[1];
1069
1070 if (!hfi_buf_req) {
1071 dprintk(VIDC_ERR, "%s - invalid buffer req pointer\n",
1072 __func__);
1073 return;
1074 }
1075
1076 while (req_bytes) {
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001077 dprintk(VIDC_DBG, "got buffer requirements for: %d\n",
1078 hfi_buf_req->buffer_type);
1079 switch (hfi_buf_req->buffer_type) {
1080 case HFI_BUFFER_INPUT:
1081 memcpy(&buffreq->buffer[0], hfi_buf_req,
1082 sizeof(struct hfi_buffer_requirements));
1083 buffreq->buffer[0].buffer_type = HAL_BUFFER_INPUT;
1084 break;
1085 case HFI_BUFFER_OUTPUT:
1086 memcpy(&buffreq->buffer[1], hfi_buf_req,
1087 sizeof(struct hfi_buffer_requirements));
1088 buffreq->buffer[1].buffer_type = HAL_BUFFER_OUTPUT;
1089 break;
1090 case HFI_BUFFER_OUTPUT2:
1091 memcpy(&buffreq->buffer[2], hfi_buf_req,
1092 sizeof(struct hfi_buffer_requirements));
1093 buffreq->buffer[2].buffer_type = HAL_BUFFER_OUTPUT2;
1094 break;
1095 case HFI_BUFFER_EXTRADATA_INPUT:
1096 memcpy(&buffreq->buffer[3], hfi_buf_req,
1097 sizeof(struct hfi_buffer_requirements));
1098 buffreq->buffer[3].buffer_type =
1099 HAL_BUFFER_EXTRADATA_INPUT;
1100 break;
1101 case HFI_BUFFER_EXTRADATA_OUTPUT:
1102 memcpy(&buffreq->buffer[4], hfi_buf_req,
1103 sizeof(struct hfi_buffer_requirements));
1104 buffreq->buffer[4].buffer_type =
1105 HAL_BUFFER_EXTRADATA_OUTPUT;
1106 break;
1107 case HFI_BUFFER_EXTRADATA_OUTPUT2:
1108 memcpy(&buffreq->buffer[5], hfi_buf_req,
1109 sizeof(struct hfi_buffer_requirements));
1110 buffreq->buffer[5].buffer_type =
1111 HAL_BUFFER_EXTRADATA_OUTPUT2;
1112 break;
Chinmay Sawarkare6468ec2017-05-23 18:20:51 -07001113 case HFI_BUFFER_COMMON_INTERNAL_SCRATCH:
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001114 memcpy(&buffreq->buffer[6], hfi_buf_req,
1115 sizeof(struct hfi_buffer_requirements));
1116 buffreq->buffer[6].buffer_type =
1117 HAL_BUFFER_INTERNAL_SCRATCH;
1118 break;
Chinmay Sawarkare6468ec2017-05-23 18:20:51 -07001119 case HFI_BUFFER_COMMON_INTERNAL_SCRATCH_1:
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001120 memcpy(&buffreq->buffer[7], hfi_buf_req,
1121 sizeof(struct hfi_buffer_requirements));
1122 buffreq->buffer[7].buffer_type =
1123 HAL_BUFFER_INTERNAL_SCRATCH_1;
1124 break;
Chinmay Sawarkare6468ec2017-05-23 18:20:51 -07001125 case HFI_BUFFER_COMMON_INTERNAL_SCRATCH_2:
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001126 memcpy(&buffreq->buffer[8], hfi_buf_req,
1127 sizeof(struct hfi_buffer_requirements));
1128 buffreq->buffer[8].buffer_type =
1129 HAL_BUFFER_INTERNAL_SCRATCH_2;
1130 break;
1131 case HFI_BUFFER_INTERNAL_PERSIST:
1132 memcpy(&buffreq->buffer[9], hfi_buf_req,
1133 sizeof(struct hfi_buffer_requirements));
1134 buffreq->buffer[9].buffer_type =
1135 HAL_BUFFER_INTERNAL_PERSIST;
1136 break;
1137 case HFI_BUFFER_INTERNAL_PERSIST_1:
1138 memcpy(&buffreq->buffer[10], hfi_buf_req,
1139 sizeof(struct hfi_buffer_requirements));
1140 buffreq->buffer[10].buffer_type =
1141 HAL_BUFFER_INTERNAL_PERSIST_1;
1142 break;
1143 default:
1144 dprintk(VIDC_ERR,
1145 "hal_process_sess_get_prop_buf_req: bad_buffer_type: %d\n",
1146 hfi_buf_req->buffer_type);
1147 break;
1148 }
1149 req_bytes -= sizeof(struct hfi_buffer_requirements);
1150 hfi_buf_req++;
1151 }
1152}
1153
1154static int hfi_process_session_prop_info(u32 device_id,
1155 struct hfi_msg_session_property_info_packet *pkt,
1156 struct msm_vidc_cb_info *info)
1157{
1158 struct msm_vidc_cb_cmd_done cmd_done = {0};
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001159 struct buffer_requirements buff_req = { { {0} } };
1160
1161 dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO[%#x]\n",
1162 pkt->session_id);
1163
1164 if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) {
1165 dprintk(VIDC_ERR,
1166 "hal_process_session_prop_info: bad_pkt_size\n");
1167 return -E2BIG;
1168 } else if (!pkt->num_properties) {
1169 dprintk(VIDC_ERR,
1170 "hal_process_session_prop_info: no_properties\n");
1171 return -EINVAL;
1172 }
1173
1174 switch (pkt->rg_property_data[0]) {
1175 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
1176 hfi_process_sess_get_prop_buf_req(pkt, &buff_req);
1177 cmd_done.device_id = device_id;
1178 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1179 cmd_done.status = VIDC_ERR_NONE;
1180 cmd_done.data.property.buf_req = buff_req;
1181 cmd_done.size = sizeof(buff_req);
1182
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07001183 info->response_type = HAL_SESSION_PROPERTY_INFO;
1184 info->response.cmd = cmd_done;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001185
1186 return 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001187 default:
1188 dprintk(VIDC_DBG,
1189 "hal_process_session_prop_info: unknown_prop_id: %x\n",
1190 pkt->rg_property_data[0]);
1191 return -ENOTSUPP;
1192 }
1193}
1194
1195static int hfi_process_session_init_done(u32 device_id,
1196 struct hfi_msg_sys_session_init_done_packet *pkt,
1197 struct msm_vidc_cb_info *info)
1198{
1199 struct msm_vidc_cb_cmd_done cmd_done = {0};
1200 struct vidc_hal_session_init_done session_init_done = { {0} };
1201
1202 dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE[%x]\n", pkt->session_id);
1203
1204 if (sizeof(struct hfi_msg_sys_session_init_done_packet) > pkt->size) {
1205 dprintk(VIDC_ERR,
1206 "hal_process_session_init_done: bad_pkt_size\n");
1207 return -E2BIG;
1208 }
1209
1210 cmd_done.device_id = device_id;
1211 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1212 cmd_done.status = hfi_map_err_status(pkt->error_type);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001213 cmd_done.data.session_init_done = session_init_done;
1214 cmd_done.size = sizeof(struct vidc_hal_session_init_done);
1215
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07001216 info->response_type = HAL_SESSION_INIT_DONE;
1217 info->response.cmd = cmd_done;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001218
1219 return 0;
1220}
1221
1222static int hfi_process_session_load_res_done(u32 device_id,
1223 struct hfi_msg_session_load_resources_done_packet *pkt,
1224 struct msm_vidc_cb_info *info)
1225{
1226 struct msm_vidc_cb_cmd_done cmd_done = {0};
1227
1228 dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%#x]\n",
1229 pkt->session_id);
1230
1231 if (sizeof(struct hfi_msg_session_load_resources_done_packet) !=
1232 pkt->size) {
1233 dprintk(VIDC_ERR,
1234 "hal_process_session_load_res_done: bad packet size: %d\n",
1235 pkt->size);
1236 return -E2BIG;
1237 }
1238
1239 cmd_done.device_id = device_id;
1240 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1241 cmd_done.status = hfi_map_err_status(pkt->error_type);
1242 cmd_done.size = 0;
1243
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07001244 info->response_type = HAL_SESSION_LOAD_RESOURCE_DONE;
1245 info->response.cmd = cmd_done;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001246
1247 return 0;
1248}
1249
1250static int hfi_process_session_flush_done(u32 device_id,
1251 struct hfi_msg_session_flush_done_packet *pkt,
1252 struct msm_vidc_cb_info *info)
1253{
1254 struct msm_vidc_cb_cmd_done cmd_done = {0};
1255
1256 dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n",
1257 pkt->session_id);
1258
1259 if (sizeof(struct hfi_msg_session_flush_done_packet) != pkt->size) {
1260 dprintk(VIDC_ERR,
1261 "hal_process_session_flush_done: bad packet size: %d\n",
1262 pkt->size);
1263 return -E2BIG;
1264 }
1265
1266 cmd_done.device_id = device_id;
1267 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1268 cmd_done.status = hfi_map_err_status(pkt->error_type);
1269 cmd_done.size = sizeof(u32);
1270
1271 switch (pkt->flush_type) {
1272 case HFI_FLUSH_OUTPUT:
1273 cmd_done.data.flush_type = HAL_FLUSH_OUTPUT;
1274 break;
1275 case HFI_FLUSH_INPUT:
1276 cmd_done.data.flush_type = HAL_FLUSH_INPUT;
1277 break;
1278 case HFI_FLUSH_ALL:
1279 cmd_done.data.flush_type = HAL_FLUSH_ALL;
1280 break;
1281 default:
1282 dprintk(VIDC_ERR,
1283 "%s: invalid flush type!", __func__);
1284 return -EINVAL;
1285 }
1286
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07001287 info->response_type = HAL_SESSION_FLUSH_DONE;
1288 info->response.cmd = cmd_done;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001289
1290 return 0;
1291}
1292
1293static int hfi_process_session_etb_done(u32 device_id,
1294 struct hfi_msg_session_empty_buffer_done_packet *pkt,
1295 struct msm_vidc_cb_info *info)
1296{
1297 struct msm_vidc_cb_data_done data_done = {0};
1298 struct hfi_picture_type *hfi_picture_type = NULL;
1299
1300 dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id);
1301
1302 if (!pkt || pkt->size <
1303 sizeof(struct hfi_msg_session_empty_buffer_done_packet)) {
1304 dprintk(VIDC_ERR,
1305 "hal_process_session_etb_done: bad_pkt_size\n");
1306 return -E2BIG;
1307 }
1308
1309 data_done.device_id = device_id;
1310 data_done.session_id = (void *)(uintptr_t)pkt->session_id;
1311 data_done.status = hfi_map_err_status(pkt->error_type);
1312 data_done.size = sizeof(struct msm_vidc_cb_data_done);
1313 data_done.clnt_data = pkt->input_tag;
Praneeth Paladugu319e7922017-03-16 11:09:06 -07001314 data_done.input_done.recon_stats.buffer_index =
1315 pkt->ubwc_cr_stats.frame_index;
1316 memcpy(&data_done.input_done.recon_stats.ubwc_stats_info,
1317 &pkt->ubwc_cr_stats.ubwc_stats_info,
1318 sizeof(data_done.input_done.recon_stats.ubwc_stats_info));
1319 data_done.input_done.recon_stats.complexity_number =
1320 pkt->ubwc_cr_stats.complexity_number;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001321 data_done.input_done.offset = pkt->offset;
1322 data_done.input_done.filled_len = pkt->filled_len;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001323 data_done.input_done.packet_buffer = pkt->packet_buffer;
1324 data_done.input_done.extra_data_buffer = pkt->extra_data_buffer;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001325 data_done.input_done.status =
1326 hfi_map_err_status(pkt->error_type);
1327 hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[0];
1328 if (hfi_picture_type->is_sync_frame) {
1329 if (hfi_picture_type->picture_type)
1330 data_done.input_done.flags =
1331 hfi_picture_type->picture_type;
1332 else
1333 dprintk(VIDC_DBG,
1334 "Non-Sync frame sent for H264/HEVC\n");
1335 }
1336
1337 trace_msm_v4l2_vidc_buffer_event_end("ETB",
1338 (u32)pkt->packet_buffer, -1, -1,
1339 pkt->filled_len, pkt->offset);
1340
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07001341 info->response_type = HAL_SESSION_ETB_DONE;
1342 info->response.data = data_done;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001343
1344 return 0;
1345}
1346
1347static int hfi_process_session_ftb_done(
1348 u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr,
1349 struct msm_vidc_cb_info *info)
1350{
1351 struct msm_vidc_cb_data_done data_done = {0};
1352 bool is_decoder = false, is_encoder = false;
1353
1354 if (!msg_hdr) {
1355 dprintk(VIDC_ERR, "Invalid Params\n");
1356 return -EINVAL;
1357 }
1358
1359 is_encoder = msg_hdr->size == sizeof(struct
1360 hfi_msg_session_fill_buffer_done_compressed_packet) + 4;
1361 is_decoder = msg_hdr->size == sizeof(struct
1362 hfi_msg_session_fbd_uncompressed_plane0_packet) + 4;
1363
1364 if (!(is_encoder ^ is_decoder)) {
1365 dprintk(VIDC_ERR, "Ambiguous packet (%#x) received (size %d)\n",
1366 msg_hdr->packet, msg_hdr->size);
1367 return -EBADHANDLE;
1368 }
1369
1370 if (is_encoder) {
1371 struct hfi_msg_session_fill_buffer_done_compressed_packet *pkt =
1372 (struct hfi_msg_session_fill_buffer_done_compressed_packet *)
1373 msg_hdr;
1374 dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%#x]\n",
1375 pkt->session_id);
1376 if (sizeof(struct
1377 hfi_msg_session_fill_buffer_done_compressed_packet)
1378 > pkt->size) {
1379 dprintk(VIDC_ERR,
1380 "hal_process_session_ftb_done: bad_pkt_size\n");
1381 return -E2BIG;
1382 } else if (pkt->error_type != HFI_ERR_NONE) {
1383 dprintk(VIDC_ERR,
1384 "got buffer back with error %x\n",
1385 pkt->error_type);
1386 /* Proceed with the FBD */
1387 }
1388
1389 data_done.device_id = device_id;
1390 data_done.session_id = (void *)(uintptr_t)pkt->session_id;
1391 data_done.status = hfi_map_err_status(pkt->error_type);
1392 data_done.size = sizeof(struct msm_vidc_cb_data_done);
1393 data_done.clnt_data = 0;
1394
1395 data_done.output_done.timestamp_hi = pkt->time_stamp_hi;
1396 data_done.output_done.timestamp_lo = pkt->time_stamp_lo;
1397 data_done.output_done.flags1 = pkt->flags;
1398 data_done.output_done.mark_target = pkt->mark_target;
1399 data_done.output_done.mark_data = pkt->mark_data;
1400 data_done.output_done.stats = pkt->stats;
1401 data_done.output_done.offset1 = pkt->offset;
1402 data_done.output_done.alloc_len1 = pkt->alloc_len;
1403 data_done.output_done.filled_len1 = pkt->filled_len;
1404 data_done.output_done.picture_type = pkt->picture_type;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001405 data_done.output_done.packet_buffer1 = pkt->packet_buffer;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001406 data_done.output_done.extra_data_buffer =
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001407 pkt->extra_data_buffer;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001408 data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT;
1409 } else /* if (is_decoder) */ {
1410 struct hfi_msg_session_fbd_uncompressed_plane0_packet *pkt =
1411 (struct hfi_msg_session_fbd_uncompressed_plane0_packet *)
1412 msg_hdr;
1413
1414 dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%#x]\n",
1415 pkt->session_id);
1416 if (sizeof(
1417 struct hfi_msg_session_fbd_uncompressed_plane0_packet) >
1418 pkt->size) {
1419 dprintk(VIDC_ERR,
1420 "hal_process_session_ftb_done: bad_pkt_size\n");
1421 return -E2BIG;
1422 }
1423
1424 data_done.device_id = device_id;
1425 data_done.session_id = (void *)(uintptr_t)pkt->session_id;
1426 data_done.status = hfi_map_err_status(pkt->error_type);
1427 data_done.size = sizeof(struct msm_vidc_cb_data_done);
1428 data_done.clnt_data = 0;
1429
1430 data_done.output_done.stream_id = pkt->stream_id;
1431 data_done.output_done.view_id = pkt->view_id;
1432 data_done.output_done.timestamp_hi = pkt->time_stamp_hi;
1433 data_done.output_done.timestamp_lo = pkt->time_stamp_lo;
1434 data_done.output_done.flags1 = pkt->flags;
1435 data_done.output_done.mark_target = pkt->mark_target;
1436 data_done.output_done.mark_data = pkt->mark_data;
1437 data_done.output_done.stats = pkt->stats;
1438 data_done.output_done.alloc_len1 = pkt->alloc_len;
1439 data_done.output_done.filled_len1 = pkt->filled_len;
1440 data_done.output_done.offset1 = pkt->offset;
1441 data_done.output_done.frame_width = pkt->frame_width;
1442 data_done.output_done.frame_height = pkt->frame_height;
1443 data_done.output_done.start_x_coord = pkt->start_x_coord;
1444 data_done.output_done.start_y_coord = pkt->start_y_coord;
1445 data_done.output_done.input_tag1 = pkt->input_tag;
1446 data_done.output_done.picture_type = pkt->picture_type;
1447 data_done.output_done.packet_buffer1 = pkt->packet_buffer;
1448 data_done.output_done.extra_data_buffer =
1449 pkt->extra_data_buffer;
1450
1451 if (!pkt->stream_id)
1452 data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT;
1453 else if (pkt->stream_id == 1)
1454 data_done.output_done.buffer_type = HAL_BUFFER_OUTPUT2;
1455 }
1456
1457 trace_msm_v4l2_vidc_buffer_event_end("FTB",
1458 (u32)data_done.output_done.packet_buffer1,
1459 (((u64)data_done.output_done.timestamp_hi) << 32)
1460 + ((u64)data_done.output_done.timestamp_lo),
1461 data_done.output_done.alloc_len1,
1462 data_done.output_done.filled_len1,
1463 data_done.output_done.offset1);
1464
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07001465 info->response_type = HAL_SESSION_FTB_DONE;
1466 info->response.data = data_done;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001467
1468 return 0;
1469}
1470
1471static int hfi_process_session_start_done(u32 device_id,
1472 struct hfi_msg_session_start_done_packet *pkt,
1473 struct msm_vidc_cb_info *info)
1474{
1475 struct msm_vidc_cb_cmd_done cmd_done = {0};
1476
1477 dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%#x]\n",
1478 pkt->session_id);
1479
1480 if (!pkt || pkt->size !=
1481 sizeof(struct hfi_msg_session_start_done_packet)) {
1482 dprintk(VIDC_ERR, "%s: bad packet/packet size\n",
1483 __func__);
1484 return -E2BIG;
1485 }
1486
1487 cmd_done.device_id = device_id;
1488 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1489 cmd_done.status = hfi_map_err_status(pkt->error_type);
1490 cmd_done.size = 0;
1491
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07001492 info->response_type = HAL_SESSION_START_DONE;
1493 info->response.cmd = cmd_done;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001494 return 0;
1495}
1496
1497static int hfi_process_session_stop_done(u32 device_id,
1498 struct hfi_msg_session_stop_done_packet *pkt,
1499 struct msm_vidc_cb_info *info)
1500{
1501 struct msm_vidc_cb_cmd_done cmd_done = {0};
1502
1503 dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%#x]\n",
1504 pkt->session_id);
1505
1506 if (!pkt || pkt->size !=
1507 sizeof(struct hfi_msg_session_stop_done_packet)) {
1508 dprintk(VIDC_ERR, "%s: bad packet/packet size\n",
1509 __func__);
1510 return -E2BIG;
1511 }
1512
1513 cmd_done.device_id = device_id;
1514 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1515 cmd_done.status = hfi_map_err_status(pkt->error_type);
1516 cmd_done.size = 0;
1517
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07001518 info->response_type = HAL_SESSION_STOP_DONE;
1519 info->response.cmd = cmd_done;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001520
1521 return 0;
1522}
1523
1524static int hfi_process_session_rel_res_done(u32 device_id,
1525 struct hfi_msg_session_release_resources_done_packet *pkt,
1526 struct msm_vidc_cb_info *info)
1527{
1528 struct msm_vidc_cb_cmd_done cmd_done = {0};
1529
1530 dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%#x]\n",
1531 pkt->session_id);
1532
1533 if (!pkt || pkt->size !=
1534 sizeof(struct hfi_msg_session_release_resources_done_packet)) {
1535 dprintk(VIDC_ERR, "%s: bad packet/packet size\n",
1536 __func__);
1537 return -E2BIG;
1538 }
1539
1540 cmd_done.device_id = device_id;
1541 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1542 cmd_done.status = hfi_map_err_status(pkt->error_type);
1543 cmd_done.size = 0;
1544
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07001545 info->response_type = HAL_SESSION_RELEASE_RESOURCE_DONE;
1546 info->response.cmd = cmd_done;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001547
1548 return 0;
1549}
1550
1551static int hfi_process_session_rel_buf_done(u32 device_id,
1552 struct hfi_msg_session_release_buffers_done_packet *pkt,
1553 struct msm_vidc_cb_info *info)
1554{
1555 struct msm_vidc_cb_cmd_done cmd_done = {0};
1556
1557 if (!pkt || pkt->size <
1558 sizeof(struct hfi_msg_session_release_buffers_done_packet)) {
1559 dprintk(VIDC_ERR, "bad packet/packet size %d\n",
1560 pkt ? pkt->size : 0);
1561 return -E2BIG;
1562 }
1563 dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%#x]\n",
1564 pkt->session_id);
1565
1566 cmd_done.device_id = device_id;
1567 cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done);
1568 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1569 cmd_done.status = hfi_map_err_status(pkt->error_type);
1570 if (pkt->rg_buffer_info) {
1571 cmd_done.data.buffer_info =
1572 *(struct hal_buffer_info *)pkt->rg_buffer_info;
1573 cmd_done.size = sizeof(struct hal_buffer_info);
1574 } else {
1575 dprintk(VIDC_ERR, "invalid payload in rel_buff_done\n");
1576 }
1577
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07001578 info->response_type = HAL_SESSION_RELEASE_BUFFER_DONE;
1579 info->response.cmd = cmd_done;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001580
1581 return 0;
1582}
1583
1584static int hfi_process_session_end_done(u32 device_id,
1585 struct hfi_msg_sys_session_end_done_packet *pkt,
1586 struct msm_vidc_cb_info *info)
1587{
1588 struct msm_vidc_cb_cmd_done cmd_done = {0};
1589
1590 dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%#x]\n", pkt->session_id);
1591
1592 if (!pkt || pkt->size !=
1593 sizeof(struct hfi_msg_sys_session_end_done_packet)) {
1594 dprintk(VIDC_ERR, "%s: bad packet/packet size\n", __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
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07001603 info->response_type = HAL_SESSION_END_DONE;
1604 info->response.cmd = cmd_done;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001605
1606 return 0;
1607}
1608
1609static int hfi_process_session_abort_done(u32 device_id,
1610 struct hfi_msg_sys_session_abort_done_packet *pkt,
1611 struct msm_vidc_cb_info *info)
1612{
1613 struct msm_vidc_cb_cmd_done cmd_done = {0};
1614
1615 dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%#x]\n",
1616 pkt->session_id);
1617
1618 if (!pkt || pkt->size !=
1619 sizeof(struct hfi_msg_sys_session_abort_done_packet)) {
1620 dprintk(VIDC_ERR, "%s: bad packet/packet size: %d\n",
1621 __func__, pkt ? pkt->size : 0);
1622 return -E2BIG;
1623 }
1624 cmd_done.device_id = device_id;
1625 cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
1626 cmd_done.status = hfi_map_err_status(pkt->error_type);
1627 cmd_done.size = 0;
1628
Chinmay Sawarkarcbd3f592017-04-10 15:42:30 -07001629 info->response_type = HAL_SESSION_ABORT_DONE;
1630 info->response.cmd = cmd_done;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001631
1632 return 0;
1633}
1634
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001635static void hfi_process_sys_get_prop_image_version(
1636 struct hfi_msg_sys_property_info_packet *pkt)
1637{
1638 int i = 0;
1639 u32 smem_block_size = 0;
1640 u8 *smem_table_ptr;
1641 char version[256];
1642 const u32 version_string_size = 128;
1643 const u32 smem_image_index_venus = 14 * 128;
1644 u8 *str_image_version;
1645 int req_bytes;
1646
1647 req_bytes = pkt->size - sizeof(*pkt);
1648 if (req_bytes < version_string_size ||
1649 !pkt->rg_property_data[1] ||
1650 pkt->num_properties > 1) {
1651 dprintk(VIDC_ERR,
1652 "hfi_process_sys_get_prop_image_version: bad_pkt: %d\n",
1653 req_bytes);
1654 return;
1655 }
1656 str_image_version = (u8 *)&pkt->rg_property_data[1];
1657 /*
1658 * The version string returned by firmware includes null
1659 * characters at the start and in between. Replace the null
1660 * characters with space, to print the version info.
1661 */
1662 for (i = 0; i < version_string_size; i++) {
1663 if (str_image_version[i] != '\0')
1664 version[i] = str_image_version[i];
1665 else
1666 version[i] = ' ';
1667 }
1668 version[i] = '\0';
1669 dprintk(VIDC_DBG, "F/W version: %s\n", version);
1670
1671 smem_table_ptr = smem_get_entry(SMEM_IMAGE_VERSION_TABLE,
1672 &smem_block_size, 0, SMEM_ANY_HOST_FLAG);
1673 if ((smem_image_index_venus + version_string_size) <= smem_block_size &&
1674 smem_table_ptr)
1675 memcpy(smem_table_ptr + smem_image_index_venus,
1676 str_image_version, version_string_size);
1677}
1678
1679static int hfi_process_sys_property_info(u32 device_id,
1680 struct hfi_msg_sys_property_info_packet *pkt,
1681 struct msm_vidc_cb_info *info)
1682{
1683 if (!pkt) {
1684 dprintk(VIDC_ERR, "%s: invalid param\n", __func__);
1685 return -EINVAL;
1686 } else if (pkt->size < sizeof(*pkt)) {
1687 dprintk(VIDC_ERR,
1688 "hfi_process_sys_property_info: bad_pkt_size\n");
1689 return -E2BIG;
1690 } else if (!pkt->num_properties) {
1691 dprintk(VIDC_ERR,
1692 "hfi_process_sys_property_info: no_properties\n");
1693 return -EINVAL;
1694 }
1695
1696 switch (pkt->rg_property_data[0]) {
1697 case HFI_PROPERTY_SYS_IMAGE_VERSION:
1698 hfi_process_sys_get_prop_image_version(pkt);
1699
1700 *info = (struct msm_vidc_cb_info) {
1701 .response_type = HAL_RESPONSE_UNUSED,
1702 };
1703 return 0;
1704 default:
1705 dprintk(VIDC_DBG,
1706 "hfi_process_sys_property_info: unknown_prop_id: %x\n",
1707 pkt->rg_property_data[0]);
1708 return -ENOTSUPP;
1709 }
1710
1711}
1712
1713static int hfi_process_ignore(u32 device_id,
1714 struct vidc_hal_msg_pkt_hdr *msg_hdr,
1715 struct msm_vidc_cb_info *info)
1716{
1717 *info = (struct msm_vidc_cb_info) {
1718 .response_type = HAL_RESPONSE_UNUSED,
1719 };
1720
1721 return 0;
1722}
1723
1724int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr,
1725 struct msm_vidc_cb_info *info)
1726{
1727 typedef int (*pkt_func_def)(u32, void *, struct msm_vidc_cb_info *info);
1728 pkt_func_def pkt_func = NULL;
1729
1730 if (!info || !msg_hdr || msg_hdr->size < VIDC_IFACEQ_MIN_PKT_SIZE) {
1731 dprintk(VIDC_ERR, "%s: bad packet/packet size\n",
1732 __func__);
1733 return -EINVAL;
1734 }
1735
1736 dprintk(VIDC_DBG, "Parse response %#x\n", msg_hdr->packet);
1737 switch (msg_hdr->packet) {
1738 case HFI_MSG_EVENT_NOTIFY:
1739 pkt_func = (pkt_func_def)hfi_process_event_notify;
1740 break;
1741 case HFI_MSG_SYS_INIT_DONE:
1742 pkt_func = (pkt_func_def)hfi_process_sys_init_done;
1743 break;
1744 case HFI_MSG_SYS_SESSION_INIT_DONE:
1745 pkt_func = (pkt_func_def)hfi_process_session_init_done;
1746 break;
1747 case HFI_MSG_SYS_PROPERTY_INFO:
1748 pkt_func = (pkt_func_def)hfi_process_sys_property_info;
1749 break;
1750 case HFI_MSG_SYS_SESSION_END_DONE:
1751 pkt_func = (pkt_func_def)hfi_process_session_end_done;
1752 break;
1753 case HFI_MSG_SESSION_LOAD_RESOURCES_DONE:
1754 pkt_func = (pkt_func_def)hfi_process_session_load_res_done;
1755 break;
1756 case HFI_MSG_SESSION_START_DONE:
1757 pkt_func = (pkt_func_def)hfi_process_session_start_done;
1758 break;
1759 case HFI_MSG_SESSION_STOP_DONE:
1760 pkt_func = (pkt_func_def)hfi_process_session_stop_done;
1761 break;
1762 case HFI_MSG_SESSION_EMPTY_BUFFER_DONE:
1763 pkt_func = (pkt_func_def)hfi_process_session_etb_done;
1764 break;
1765 case HFI_MSG_SESSION_FILL_BUFFER_DONE:
1766 pkt_func = (pkt_func_def)hfi_process_session_ftb_done;
1767 break;
1768 case HFI_MSG_SESSION_FLUSH_DONE:
1769 pkt_func = (pkt_func_def)hfi_process_session_flush_done;
1770 break;
1771 case HFI_MSG_SESSION_PROPERTY_INFO:
1772 pkt_func = (pkt_func_def)hfi_process_session_prop_info;
1773 break;
1774 case HFI_MSG_SESSION_RELEASE_RESOURCES_DONE:
1775 pkt_func = (pkt_func_def)hfi_process_session_rel_res_done;
1776 break;
1777 case HFI_MSG_SYS_RELEASE_RESOURCE:
1778 pkt_func = (pkt_func_def)hfi_process_sys_rel_resource_done;
1779 break;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001780 case HFI_MSG_SESSION_RELEASE_BUFFERS_DONE:
1781 pkt_func = (pkt_func_def)hfi_process_session_rel_buf_done;
1782 break;
1783 case HFI_MSG_SYS_SESSION_ABORT_DONE:
1784 pkt_func = (pkt_func_def)hfi_process_session_abort_done;
1785 break;
1786 case HFI_MSG_SESSION_SYNC_DONE:
1787 pkt_func = (pkt_func_def)hfi_process_ignore;
1788 break;
1789 default:
1790 dprintk(VIDC_DBG, "Unable to parse message: %#x\n",
1791 msg_hdr->packet);
1792 break;
1793 }
1794
1795 return pkt_func ? pkt_func(device_id, msg_hdr, info) : -ENOTSUPP;
1796}