blob: f5722b8fb9ffd30149cc050dde4d2370338ea7e6 [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/jiffies.h>
15#include <linux/sched.h>
16#include <linux/slab.h>
17#include <linux/kernel.h>
18#include <linux/bitops.h>
19#include <soc/qcom/subsystem_restart.h>
20#include <asm/div64.h>
21#include "msm_vidc_common.h"
22#include "vidc_hfi_api.h"
23#include "msm_vidc_debug.h"
24#include "msm_vidc_clocks.h"
25
26#define IS_ALREADY_IN_STATE(__p, __d) ({\
27 int __rc = (__p >= __d);\
28 __rc; \
29})
30
31#define SUM_ARRAY(__arr, __start, __end) ({\
32 int __index;\
33 typeof((__arr)[0]) __sum = 0;\
34 for (__index = (__start); __index <= (__end); __index++) {\
35 if (__index >= 0 && __index < ARRAY_SIZE(__arr))\
36 __sum += __arr[__index];\
37 } \
38 __sum;\
39})
40
41#define V4L2_EVENT_SEQ_CHANGED_SUFFICIENT \
42 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT
43#define V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT \
44 V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT
45#define V4L2_EVENT_RELEASE_BUFFER_REFERENCE \
46 V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE
47
48#define MAX_SUPPORTED_INSTANCES 16
49
50const char *const mpeg_video_vidc_extradata[] = {
51 "Extradata none",
52 "Extradata MB Quantization",
53 "Extradata Interlace Video",
54 "Extradata VC1 Framedisp",
55 "Extradata VC1 Seqdisp",
56 "Extradata timestamp",
57 "Extradata S3D Frame Packing",
58 "Extradata Frame Rate",
59 "Extradata Panscan Window",
60 "Extradata Recovery point SEI",
61 "Extradata Multislice info",
62 "Extradata number of concealed MB",
63 "Extradata metadata filler",
64 "Extradata input crop",
65 "Extradata digital zoom",
66 "Extradata aspect ratio",
67 "Extradata mpeg2 seqdisp",
68 "Extradata stream userdata",
69 "Extradata frame QP",
70 "Extradata frame bits info",
71 "Extradata LTR",
72 "Extradata macroblock metadata",
73 "Extradata VQZip SEI",
74 "Extradata YUV Stats",
75 "Extradata ROI QP",
76 "Extradata output crop",
77 "Extradata display colour SEI",
78 "Extradata light level SEI",
79 "Extradata PQ Info",
80 "Extradata display VUI",
81 "Extradata vpx color space",
82};
83
84struct getprop_buf {
85 struct list_head list;
86 void *data;
87};
88
89static void msm_comm_generate_session_error(struct msm_vidc_inst *inst);
90static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst);
91static void handle_session_error(enum hal_command_response cmd, void *data);
92static void msm_vidc_print_running_insts(struct msm_vidc_core *core);
93static void msm_comm_print_debug_info(struct msm_vidc_inst *inst);
94
95bool msm_comm_turbo_session(struct msm_vidc_inst *inst)
96{
97 return !!(inst->flags & VIDC_TURBO);
98}
99
100static inline bool is_thumbnail_session(struct msm_vidc_inst *inst)
101{
102 return !!(inst->flags & VIDC_THUMBNAIL);
103}
104
105static inline bool is_low_power_session(struct msm_vidc_inst *inst)
106{
107 return !!(inst->flags & VIDC_LOW_POWER);
108}
109
110static inline bool is_realtime_session(struct msm_vidc_inst *inst)
111{
112 return !!(inst->flags & VIDC_REALTIME);
113}
114
115int msm_comm_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
116{
117 return v4l2_g_ctrl(&inst->ctrl_handler, ctrl);
118}
119
120int msm_comm_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
121{
122 return v4l2_s_ctrl(NULL, &inst->ctrl_handler, ctrl);
123}
124
125int msm_comm_g_ctrl_for_id(struct msm_vidc_inst *inst, int id)
126{
127 int rc = 0;
128 struct v4l2_control ctrl = {
129 .id = id,
130 };
131
132 rc = msm_comm_g_ctrl(inst, &ctrl);
133 return rc ?: ctrl.value;
134}
135
136static struct v4l2_ctrl **get_super_cluster(struct msm_vidc_inst *inst,
137 int num_ctrls)
138{
139 int c = 0;
140 struct v4l2_ctrl **cluster = kmalloc(sizeof(struct v4l2_ctrl *) *
141 num_ctrls, GFP_KERNEL);
142
143 if (!cluster || !inst)
144 return NULL;
145
146 for (c = 0; c < num_ctrls; c++)
147 cluster[c] = inst->ctrls[c];
148
149 return cluster;
150}
151
152int msm_comm_ctrl_init(struct msm_vidc_inst *inst,
153 struct msm_vidc_ctrl *drv_ctrls, u32 num_ctrls,
154 const struct v4l2_ctrl_ops *ctrl_ops)
155{
156 int idx = 0;
157 struct v4l2_ctrl_config ctrl_cfg = {0};
158 int ret_val = 0;
159
160 if (!inst || !drv_ctrls || !ctrl_ops || !num_ctrls) {
161 dprintk(VIDC_ERR, "%s - invalid input\n", __func__);
162 return -EINVAL;
163 }
164
165 inst->ctrls = kcalloc(num_ctrls, sizeof(struct v4l2_ctrl *),
166 GFP_KERNEL);
167 if (!inst->ctrls) {
168 dprintk(VIDC_ERR, "%s - failed to allocate ctrl\n", __func__);
169 return -ENOMEM;
170 }
171
172 ret_val = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls);
173
174 if (ret_val) {
175 dprintk(VIDC_ERR, "CTRL ERR: Control handler init failed, %d\n",
176 inst->ctrl_handler.error);
177 return ret_val;
178 }
179
180 for (; idx < num_ctrls; idx++) {
181 struct v4l2_ctrl *ctrl = NULL;
182
183 if (1) {
184 /*add private control*/
185 ctrl_cfg.def = drv_ctrls[idx].default_value;
186 ctrl_cfg.flags = 0;
187 ctrl_cfg.id = drv_ctrls[idx].id;
188 ctrl_cfg.max = drv_ctrls[idx].maximum;
189 ctrl_cfg.min = drv_ctrls[idx].minimum;
190 ctrl_cfg.menu_skip_mask =
191 drv_ctrls[idx].menu_skip_mask;
192 ctrl_cfg.name = drv_ctrls[idx].name;
193 ctrl_cfg.ops = ctrl_ops;
194 ctrl_cfg.step = drv_ctrls[idx].step;
195 ctrl_cfg.type = drv_ctrls[idx].type;
196 ctrl_cfg.qmenu = drv_ctrls[idx].qmenu;
197
198 ctrl = v4l2_ctrl_new_custom(&inst->ctrl_handler,
199 &ctrl_cfg, NULL);
200 } else {
201 if (drv_ctrls[idx].type == V4L2_CTRL_TYPE_MENU) {
202 ctrl = v4l2_ctrl_new_std_menu(
203 &inst->ctrl_handler,
204 ctrl_ops,
205 drv_ctrls[idx].id,
206 drv_ctrls[idx].maximum,
207 drv_ctrls[idx].menu_skip_mask,
208 drv_ctrls[idx].default_value);
209 } else {
210 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
211 ctrl_ops,
212 drv_ctrls[idx].id,
213 drv_ctrls[idx].minimum,
214 drv_ctrls[idx].maximum,
215 drv_ctrls[idx].step,
216 drv_ctrls[idx].default_value);
217 }
218 }
219
220 if (!ctrl) {
221 dprintk(VIDC_ERR, "%s - invalid ctrl %s\n", __func__,
222 drv_ctrls[idx].name);
223 return -EINVAL;
224 }
225
226 ret_val = inst->ctrl_handler.error;
227 if (ret_val) {
228 dprintk(VIDC_ERR,
229 "Error adding ctrl (%s) to ctrl handle, %d\n",
230 drv_ctrls[idx].name, inst->ctrl_handler.error);
231 return ret_val;
232 }
233
234 ctrl->flags |= drv_ctrls[idx].flags;
235 inst->ctrls[idx] = ctrl;
236 }
237
238 /* Construct a super cluster of all controls */
239 inst->cluster = get_super_cluster(inst, num_ctrls);
240 if (!inst->cluster) {
241 dprintk(VIDC_WARN,
242 "Failed to setup super cluster\n");
243 return -EINVAL;
244 }
245
246 v4l2_ctrl_cluster(num_ctrls, inst->cluster);
247
248 return ret_val;
249}
250
251int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst)
252{
253 if (!inst) {
254 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
255 return -EINVAL;
256 }
257
258 kfree(inst->ctrls);
259 kfree(inst->cluster);
260 v4l2_ctrl_handler_free(&inst->ctrl_handler);
261
262 return 0;
263}
264
265enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst)
266{
267 switch (msm_comm_g_ctrl_for_id(inst,
268 V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE)) {
269 case V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY:
270 return HAL_VIDEO_DECODER_SECONDARY;
271 case V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY:
272 default:
273 return HAL_VIDEO_DECODER_PRIMARY;
274 }
275}
276
277static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst)
278{
279 int output_port_mbs, capture_port_mbs;
280 int fps;
281
282 output_port_mbs = inst->in_reconfig ?
283 NUM_MBS_PER_FRAME(inst->reconfig_width,
284 inst->reconfig_height) :
285 NUM_MBS_PER_FRAME(inst->prop.width[OUTPUT_PORT],
286 inst->prop.height[OUTPUT_PORT]);
287
288 capture_port_mbs = NUM_MBS_PER_FRAME(inst->prop.width[CAPTURE_PORT],
289 inst->prop.height[CAPTURE_PORT]);
290
291 if (inst->operating_rate) {
292 fps = (inst->operating_rate >> 16) ?
293 inst->operating_rate >> 16 : 1;
294 /*
295 * Check if operating rate is less than fps.
296 * If Yes, then use fps to scale clocks
297 */
298 fps = fps > inst->prop.fps ? fps : inst->prop.fps;
299 return max(output_port_mbs, capture_port_mbs) * fps;
300 } else {
301 return max(output_port_mbs, capture_port_mbs) * inst->prop.fps;
302 }
303}
304
305int msm_comm_get_inst_load(struct msm_vidc_inst *inst,
306 enum load_calc_quirks quirks)
307{
308 int load = 0;
309
310 mutex_lock(&inst->lock);
311
312 if (!(inst->state >= MSM_VIDC_OPEN_DONE &&
313 inst->state < MSM_VIDC_STOP_DONE))
314 goto exit;
315
316 load = msm_comm_get_mbs_per_sec(inst);
317
318 if (is_thumbnail_session(inst)) {
319 if (quirks & LOAD_CALC_IGNORE_THUMBNAIL_LOAD)
320 load = 0;
321 }
322
323 if (msm_comm_turbo_session(inst)) {
324 if (!(quirks & LOAD_CALC_IGNORE_TURBO_LOAD))
325 load = inst->core->resources.max_load;
326 }
327
328 /* Clock and Load calculations for REALTIME/NON-REALTIME
329 * OPERATING RATE SET/NO OPERATING RATE SET
330 *
331 * | OPERATING RATE SET | OPERATING RATE NOT SET |
332 * ----------------|--------------------- |------------------------|
333 * REALTIME | load = res * op_rate | load = res * fps |
334 * | clk = res * op_rate | clk = res * fps |
335 * ----------------|----------------------|------------------------|
336 * NON-REALTIME | load = res * 1 fps | load = res * 1 fps |
337 * | clk = res * op_rate | clk = res * fps |
338 * ----------------|----------------------|------------------------|
339 */
340
341 if (!is_realtime_session(inst) &&
342 (quirks & LOAD_CALC_IGNORE_NON_REALTIME_LOAD)) {
343 if (!inst->prop.fps) {
344 dprintk(VIDC_INFO, "instance:%pK fps = 0\n", inst);
345 load = 0;
346 } else {
347 load = msm_comm_get_mbs_per_sec(inst) / inst->prop.fps;
348 }
349 }
350
351exit:
352 mutex_unlock(&inst->lock);
353 return load;
354}
355
356int msm_comm_get_load(struct msm_vidc_core *core,
357 enum session_type type, enum load_calc_quirks quirks)
358{
359 struct msm_vidc_inst *inst = NULL;
360 int num_mbs_per_sec = 0;
361
362 if (!core) {
363 dprintk(VIDC_ERR, "Invalid args: %pK\n", core);
364 return -EINVAL;
365 }
366
367 mutex_lock(&core->lock);
368 list_for_each_entry(inst, &core->instances, list) {
369 if (inst->session_type != type)
370 continue;
371
372 num_mbs_per_sec += msm_comm_get_inst_load(inst, quirks);
373 }
374 mutex_unlock(&core->lock);
375
376 return num_mbs_per_sec;
377}
378
379enum hal_domain get_hal_domain(int session_type)
380{
381 enum hal_domain domain;
382
383 switch (session_type) {
384 case MSM_VIDC_ENCODER:
385 domain = HAL_VIDEO_DOMAIN_ENCODER;
386 break;
387 case MSM_VIDC_DECODER:
388 domain = HAL_VIDEO_DOMAIN_DECODER;
389 break;
390 default:
391 dprintk(VIDC_ERR, "Wrong domain\n");
392 domain = HAL_UNUSED_DOMAIN;
393 break;
394 }
395
396 return domain;
397}
398
399enum hal_video_codec get_hal_codec(int fourcc)
400{
401 enum hal_video_codec codec;
402
403 switch (fourcc) {
404 case V4L2_PIX_FMT_H264:
405 case V4L2_PIX_FMT_H264_NO_SC:
406 codec = HAL_VIDEO_CODEC_H264;
407 break;
408 case V4L2_PIX_FMT_H264_MVC:
409 codec = HAL_VIDEO_CODEC_MVC;
410 break;
411 case V4L2_PIX_FMT_H263:
412 codec = HAL_VIDEO_CODEC_H263;
413 break;
414 case V4L2_PIX_FMT_MPEG1:
415 codec = HAL_VIDEO_CODEC_MPEG1;
416 break;
417 case V4L2_PIX_FMT_MPEG2:
418 codec = HAL_VIDEO_CODEC_MPEG2;
419 break;
420 case V4L2_PIX_FMT_MPEG4:
421 codec = HAL_VIDEO_CODEC_MPEG4;
422 break;
423 case V4L2_PIX_FMT_VC1_ANNEX_G:
424 case V4L2_PIX_FMT_VC1_ANNEX_L:
425 codec = HAL_VIDEO_CODEC_VC1;
426 break;
427 case V4L2_PIX_FMT_VP8:
428 codec = HAL_VIDEO_CODEC_VP8;
429 break;
430 case V4L2_PIX_FMT_VP9:
431 codec = HAL_VIDEO_CODEC_VP9;
432 break;
433 case V4L2_PIX_FMT_HEVC:
434 codec = HAL_VIDEO_CODEC_HEVC;
435 break;
436 default:
437 dprintk(VIDC_ERR, "Wrong codec: %d\n", fourcc);
438 codec = HAL_UNUSED_CODEC;
439 break;
440 }
441
442 return codec;
443}
444
445static enum hal_uncompressed_format get_hal_uncompressed(int fourcc)
446{
447 enum hal_uncompressed_format format = HAL_UNUSED_COLOR;
448
449 switch (fourcc) {
450 case V4L2_PIX_FMT_NV12:
451 format = HAL_COLOR_FORMAT_NV12;
452 break;
453 case V4L2_PIX_FMT_NV21:
454 format = HAL_COLOR_FORMAT_NV21;
455 break;
456 case V4L2_PIX_FMT_NV12_UBWC:
457 format = HAL_COLOR_FORMAT_NV12_UBWC;
458 break;
459 case V4L2_PIX_FMT_NV12_TP10_UBWC:
460 format = HAL_COLOR_FORMAT_NV12_TP10_UBWC;
461 break;
462 case V4L2_PIX_FMT_RGB32:
463 format = HAL_COLOR_FORMAT_RGBA8888;
464 break;
465 default:
466 format = HAL_UNUSED_COLOR;
467 break;
468 }
469
470 return format;
471}
472
473static int msm_comm_vote_bus(struct msm_vidc_core *core)
474{
475 int rc = 0, vote_data_count = 0, i = 0;
476 struct hfi_device *hdev;
477 struct msm_vidc_inst *inst = NULL;
478 struct vidc_bus_vote_data *vote_data = NULL;
479 unsigned long core_freq = 0;
480
481 if (!core) {
482 dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core);
483 return -EINVAL;
484 }
485
486 hdev = core->device;
487 if (!hdev) {
488 dprintk(VIDC_ERR, "%s Invalid device handle: %pK\n",
489 __func__, hdev);
490 return -EINVAL;
491 }
492
493 mutex_lock(&core->lock);
494 list_for_each_entry(inst, &core->instances, list)
495 ++vote_data_count;
496
497 vote_data = kcalloc(vote_data_count, sizeof(*vote_data),
498 GFP_TEMPORARY);
499 if (!vote_data) {
500 dprintk(VIDC_ERR, "%s: failed to allocate memory\n", __func__);
501 rc = -ENOMEM;
502 goto fail_alloc;
503 }
504
505 core_freq = call_hfi_op(hdev, get_core_clock_rate,
506 hdev->hfi_device_data, 0);
507
508 list_for_each_entry(inst, &core->instances, list) {
509 int codec = 0, yuv = 0;
510
511 codec = inst->session_type == MSM_VIDC_DECODER ?
512 inst->fmts[OUTPUT_PORT].fourcc :
513 inst->fmts[CAPTURE_PORT].fourcc;
514
515 yuv = inst->session_type == MSM_VIDC_DECODER ?
516 inst->fmts[CAPTURE_PORT].fourcc :
517 inst->fmts[OUTPUT_PORT].fourcc;
518
519 vote_data[i].domain = get_hal_domain(inst->session_type);
520 vote_data[i].codec = get_hal_codec(codec);
521 vote_data[i].width = max(inst->prop.width[CAPTURE_PORT],
522 inst->prop.width[OUTPUT_PORT]);
523 vote_data[i].height = max(inst->prop.height[CAPTURE_PORT],
524 inst->prop.height[OUTPUT_PORT]);
525
526 if (inst->operating_rate)
527 vote_data[i].fps = (inst->operating_rate >> 16) ?
528 inst->operating_rate >> 16 : 1;
529 else
530 vote_data[i].fps = inst->prop.fps;
531
532 if (msm_comm_turbo_session(inst))
533 vote_data[i].power_mode = VIDC_POWER_TURBO;
534 else if (is_low_power_session(inst))
535 vote_data[i].power_mode = VIDC_POWER_LOW;
536 else
537 vote_data[i].power_mode = VIDC_POWER_NORMAL;
538 if (i == 0) {
539 vote_data[i].imem_ab_tbl = core->resources.imem_ab_tbl;
540 vote_data[i].imem_ab_tbl_size =
541 core->resources.imem_ab_tbl_size;
542 vote_data[i].core_freq = core_freq;
543 }
544
545 /*
546 * TODO: support for OBP-DBP split mode hasn't been yet
547 * implemented, once it is, this part of code needs to be
548 * revisited since passing in accurate information to the bus
549 * governor will drastically reduce bandwidth
550 */
551 vote_data[i].color_formats[0] = get_hal_uncompressed(yuv);
552 vote_data[i].num_formats = 1;
553 i++;
554 }
555 mutex_unlock(&core->lock);
556
557 rc = call_hfi_op(hdev, vote_bus, hdev->hfi_device_data, vote_data,
558 vote_data_count);
559 if (rc)
560 dprintk(VIDC_ERR, "Failed to scale bus: %d\n", rc);
561
562 kfree(vote_data);
563 return rc;
564
565fail_alloc:
566 mutex_unlock(&core->lock);
567 return rc;
568}
569
570struct msm_vidc_core *get_vidc_core(int core_id)
571{
572 struct msm_vidc_core *core;
573 int found = 0;
574
575 if (core_id > MSM_VIDC_CORES_MAX) {
576 dprintk(VIDC_ERR, "Core id = %d is greater than max = %d\n",
577 core_id, MSM_VIDC_CORES_MAX);
578 return NULL;
579 }
580 mutex_lock(&vidc_driver->lock);
581 list_for_each_entry(core, &vidc_driver->cores, list) {
582 if (core->id == core_id) {
583 found = 1;
584 break;
585 }
586 }
587 mutex_unlock(&vidc_driver->lock);
588 if (found)
589 return core;
590 return NULL;
591}
592
593const struct msm_vidc_format *msm_comm_get_pixel_fmt_index(
594 const struct msm_vidc_format fmt[], int size, int index, int fmt_type)
595{
596 int i, k = 0;
597
598 if (!fmt || index < 0) {
599 dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK, index = %d\n",
600 fmt, index);
601 return NULL;
602 }
603 for (i = 0; i < size; i++) {
604 if (fmt[i].type != fmt_type)
605 continue;
606 if (k == index)
607 break;
608 k++;
609 }
610 if (i == size) {
611 dprintk(VIDC_INFO, "Format not found\n");
612 return NULL;
613 }
614 return &fmt[i];
615}
616struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc(
617 struct msm_vidc_format fmt[], int size, int fourcc, int fmt_type)
618{
619 int i;
620
621 if (!fmt) {
622 dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK\n", fmt);
623 return NULL;
624 }
625 for (i = 0; i < size; i++) {
626 if (fmt[i].fourcc == fourcc)
627 break;
628 }
629 if (i == size) {
630 dprintk(VIDC_INFO, "Format not found\n");
631 return NULL;
632 }
633 return &fmt[i];
634}
635
636struct buf_queue *msm_comm_get_vb2q(
637 struct msm_vidc_inst *inst, enum v4l2_buf_type type)
638{
639 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
640 return &inst->bufq[CAPTURE_PORT];
641 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
642 return &inst->bufq[OUTPUT_PORT];
643 return NULL;
644}
645
646static void handle_sys_init_done(enum hal_command_response cmd, void *data)
647{
648 struct msm_vidc_cb_cmd_done *response = data;
649 struct msm_vidc_core *core;
650 struct vidc_hal_sys_init_done *sys_init_msg;
651 u32 index;
652
653 if (!IS_HAL_SYS_CMD(cmd)) {
654 dprintk(VIDC_ERR, "%s - invalid cmd\n", __func__);
655 return;
656 }
657
658 index = SYS_MSG_INDEX(cmd);
659
660 if (!response) {
661 dprintk(VIDC_ERR,
662 "Failed to get valid response for sys init\n");
663 return;
664 }
665 core = get_vidc_core(response->device_id);
666 if (!core) {
667 dprintk(VIDC_ERR, "Wrong device_id received\n");
668 return;
669 }
670 sys_init_msg = &response->data.sys_init_done;
671 if (!sys_init_msg) {
672 dprintk(VIDC_ERR, "sys_init_done message not proper\n");
673 return;
674 }
675
676 core->enc_codec_supported = sys_init_msg->enc_codec_supported;
677 core->dec_codec_supported = sys_init_msg->dec_codec_supported;
678
679 /* This should come from sys_init_done */
680 core->resources.max_inst_count =
681 sys_init_msg->max_sessions_supported ? :
682 MAX_SUPPORTED_INSTANCES;
683
684 core->resources.max_secure_inst_count =
685 core->resources.max_secure_inst_count ? :
686 core->resources.max_inst_count;
687
688 if (core->id == MSM_VIDC_CORE_VENUS &&
689 (core->dec_codec_supported & HAL_VIDEO_CODEC_H264))
690 core->dec_codec_supported |=
691 HAL_VIDEO_CODEC_MVC;
692
693 core->codec_count = sys_init_msg->codec_count;
694 memcpy(core->capabilities, sys_init_msg->capabilities,
695 sys_init_msg->codec_count * sizeof(struct msm_vidc_capability));
696
697 dprintk(VIDC_DBG,
698 "%s: supported_codecs[%d]: enc = %#x, dec = %#x\n",
699 __func__, core->codec_count, core->enc_codec_supported,
700 core->dec_codec_supported);
701
702 complete(&(core->completions[index]));
703}
704
705static void put_inst(struct msm_vidc_inst *inst)
706{
707 void put_inst_helper(struct kref *kref)
708 {
709 struct msm_vidc_inst *inst = container_of(kref,
710 struct msm_vidc_inst, kref);
711
712 msm_vidc_destroy(inst);
713 }
714
715 if (!inst)
716 return;
717
718 kref_put(&inst->kref, put_inst_helper);
719}
720
721static struct msm_vidc_inst *get_inst(struct msm_vidc_core *core,
722 void *session_id)
723{
724 struct msm_vidc_inst *inst = NULL;
725 bool matches = false;
726
727 if (!core || !session_id)
728 return NULL;
729
730 mutex_lock(&core->lock);
731 /*
732 * This is as good as !list_empty(!inst->list), but at this point
733 * we don't really know if inst was kfree'd via close syscall before
734 * hardware could respond. So manually walk thru the list of active
735 * sessions
736 */
737 list_for_each_entry(inst, &core->instances, list) {
738 if (inst == session_id) {
739 /*
740 * Even if the instance is valid, we really shouldn't
741 * be receiving or handling callbacks when we've deleted
742 * our session with HFI
743 */
744 matches = !!inst->session;
745 break;
746 }
747 }
748
749 /*
750 * kref_* is atomic_int backed, so no need for inst->lock. But we can
751 * always acquire inst->lock and release it in put_inst for a stronger
752 * locking system.
753 */
754 inst = (matches && kref_get_unless_zero(&inst->kref)) ? inst : NULL;
755 mutex_unlock(&core->lock);
756
757 return inst;
758}
759
760static void handle_session_release_buf_done(enum hal_command_response cmd,
761 void *data)
762{
763 struct msm_vidc_cb_cmd_done *response = data;
764 struct msm_vidc_inst *inst;
765 struct internal_buf *buf;
766 struct list_head *ptr, *next;
767 struct hal_buffer_info *buffer;
768 u32 buf_found = false;
769 u32 address;
770
771 if (!response) {
772 dprintk(VIDC_ERR, "Invalid release_buf_done response\n");
773 return;
774 }
775
776 inst = get_inst(get_vidc_core(response->device_id),
777 response->session_id);
778 if (!inst) {
779 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
780 return;
781 }
782
783 buffer = &response->data.buffer_info;
784 address = buffer->buffer_addr;
785
786 mutex_lock(&inst->scratchbufs.lock);
787 list_for_each_safe(ptr, next, &inst->scratchbufs.list) {
788 buf = list_entry(ptr, struct internal_buf, list);
789 if (address == (u32)buf->handle->device_addr) {
790 dprintk(VIDC_DBG, "releasing scratch: %pa\n",
791 &buf->handle->device_addr);
792 buf_found = true;
793 }
794 }
795 mutex_unlock(&inst->scratchbufs.lock);
796
797 mutex_lock(&inst->persistbufs.lock);
798 list_for_each_safe(ptr, next, &inst->persistbufs.list) {
799 buf = list_entry(ptr, struct internal_buf, list);
800 if (address == (u32)buf->handle->device_addr) {
801 dprintk(VIDC_DBG, "releasing persist: %pa\n",
802 &buf->handle->device_addr);
803 buf_found = true;
804 }
805 }
806 mutex_unlock(&inst->persistbufs.lock);
807
808 if (!buf_found)
809 dprintk(VIDC_ERR, "invalid buffer received from firmware");
810 if (IS_HAL_SESSION_CMD(cmd))
811 complete(&inst->completions[SESSION_MSG_INDEX(cmd)]);
812 else
813 dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd);
814
815 put_inst(inst);
816}
817
818static void handle_sys_release_res_done(
819 enum hal_command_response cmd, void *data)
820{
821 struct msm_vidc_cb_cmd_done *response = data;
822 struct msm_vidc_core *core;
823
824 if (!response) {
825 dprintk(VIDC_ERR,
826 "Failed to get valid response for sys init\n");
827 return;
828 }
829 core = get_vidc_core(response->device_id);
830 if (!core) {
831 dprintk(VIDC_ERR, "Wrong device_id received\n");
832 return;
833 }
834 complete(&core->completions[
835 SYS_MSG_INDEX(HAL_SYS_RELEASE_RESOURCE_DONE)]);
836}
837
838static void change_inst_state(struct msm_vidc_inst *inst,
839 enum instance_state state)
840{
841 if (!inst) {
842 dprintk(VIDC_ERR, "Invalid parameter %s\n", __func__);
843 return;
844 }
845 mutex_lock(&inst->lock);
846 if (inst->state == MSM_VIDC_CORE_INVALID) {
847 dprintk(VIDC_DBG,
848 "Inst: %pK is in bad state can't change state to %d\n",
849 inst, state);
850 goto exit;
851 }
852 dprintk(VIDC_DBG, "Moved inst: %pK from state: %d to state: %d\n",
853 inst, inst->state, state);
854 inst->state = state;
855exit:
856 mutex_unlock(&inst->lock);
857}
858
859static int signal_session_msg_receipt(enum hal_command_response cmd,
860 struct msm_vidc_inst *inst)
861{
862 if (!inst) {
863 dprintk(VIDC_ERR, "Invalid(%pK) instance id\n", inst);
864 return -EINVAL;
865 }
866 if (IS_HAL_SESSION_CMD(cmd)) {
867 complete(&inst->completions[SESSION_MSG_INDEX(cmd)]);
868 } else {
869 dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd);
870 return -EINVAL;
871 }
872 return 0;
873}
874
875static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst,
876 enum hal_command_response cmd)
877{
878 int rc = 0;
879 struct hfi_device *hdev;
880
881 if (!IS_HAL_SESSION_CMD(cmd)) {
882 dprintk(VIDC_ERR, "Invalid inst cmd response: %d\n", cmd);
883 return -EINVAL;
884 }
885 hdev = (struct hfi_device *)(inst->core->device);
886 rc = wait_for_completion_timeout(
887 &inst->completions[SESSION_MSG_INDEX(cmd)],
888 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
889 if (!rc) {
890 dprintk(VIDC_ERR, "Wait interrupted or timed out: %d\n",
891 SESSION_MSG_INDEX(cmd));
892 msm_comm_kill_session(inst);
893 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
894 dprintk(VIDC_ERR,
895 "sess resp timeout can potentially crash the system\n");
896 msm_comm_print_debug_info(inst);
897 msm_vidc_handle_hw_error(inst->core);
898 rc = -EIO;
899 } else {
900 rc = 0;
901 }
902 return rc;
903}
904
905static int wait_for_state(struct msm_vidc_inst *inst,
906 enum instance_state flipped_state,
907 enum instance_state desired_state,
908 enum hal_command_response hal_cmd)
909{
910 int rc = 0;
911
912 if (IS_ALREADY_IN_STATE(flipped_state, desired_state)) {
913 dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n",
914 inst, inst->state);
915 goto err_same_state;
916 }
917 dprintk(VIDC_DBG, "Waiting for hal_cmd: %d\n", hal_cmd);
918 rc = wait_for_sess_signal_receipt(inst, hal_cmd);
919 if (!rc)
920 change_inst_state(inst, desired_state);
921err_same_state:
922 return rc;
923}
924
925void msm_vidc_queue_v4l2_event(struct msm_vidc_inst *inst, int event_type)
926{
927 struct v4l2_event event = {.id = 0, .type = event_type};
928
929 v4l2_event_queue_fh(&inst->event_handler, &event);
930}
931
932static void msm_comm_generate_max_clients_error(struct msm_vidc_inst *inst)
933{
934 enum hal_command_response cmd = HAL_SESSION_ERROR;
935 struct msm_vidc_cb_cmd_done response = {0};
936
937 if (!inst) {
938 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
939 return;
940 }
941 dprintk(VIDC_ERR, "%s: Too many clients\n", __func__);
942 response.session_id = inst;
943 response.status = VIDC_ERR_MAX_CLIENTS;
944 handle_session_error(cmd, (void *)&response);
945}
946
947static void print_cap(const char *type,
948 struct hal_capability_supported *cap)
949{
950 dprintk(VIDC_DBG,
951 "%-24s: %-8d %-8d %-8d\n",
952 type, cap->min, cap->max, cap->step_size);
953}
954
Praneeth Paladugue1679112017-01-27 10:07:15 -0800955static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst,
956 u32 id, struct hal_capability_supported *capability)
957{
958 struct v4l2_ctrl *ctrl = NULL;
959 int rc = 0;
960
961 ctrl = v4l2_ctrl_find(&inst->ctrl_handler, id);
962 if (ctrl) {
963 v4l2_ctrl_modify_range(ctrl, capability->min,
964 capability->max, ctrl->step,
965 capability->min);
966 dprintk(VIDC_DBG,
967 "%s: Updated Range = %lld --> %lld Def value = %lld\n",
968 ctrl->name, ctrl->minimum, ctrl->maximum,
969 ctrl->default_value);
970 } else {
971 dprintk(VIDC_ERR,
972 "Failed to find Conrol %d\n", id);
973 rc = -EINVAL;
974 }
975
976 return rc;
977 }
978
979static void msm_vidc_comm_update_ctrl_limits(struct msm_vidc_inst *inst)
980{
981 msm_vidc_comm_update_ctrl(inst,
982 V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE,
983 &inst->capability.hier_p_hybrid);
984 msm_vidc_comm_update_ctrl(inst,
985 V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS,
986 &inst->capability.hier_b);
987 msm_vidc_comm_update_ctrl(inst,
988 V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS,
989 &inst->capability.hier_p);
990 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE,
991 &inst->capability.bitrate);
992 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
993 &inst->capability.peakbitrate);
Praneeth Paladugu7fbd2792017-01-27 13:39:03 -0800994 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP,
995 &inst->capability.i_qp);
996 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP,
997 &inst->capability.p_qp);
998 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP,
999 &inst->capability.b_qp);
1000 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP_MIN,
1001 &inst->capability.i_qp);
1002 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP_MIN,
1003 &inst->capability.p_qp);
1004 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP_MIN,
1005 &inst->capability.b_qp);
1006 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP_MAX,
1007 &inst->capability.i_qp);
1008 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP_MAX,
1009 &inst->capability.p_qp);
1010 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP_MAX,
1011 &inst->capability.b_qp);
Praneeth Paladugue1679112017-01-27 10:07:15 -08001012 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_BLUR_WIDTH,
1013 &inst->capability.blur_width);
1014 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_BLUR_HEIGHT,
1015 &inst->capability.blur_height);
1016 msm_vidc_comm_update_ctrl(inst,
1017 V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
1018 &inst->capability.slice_bytes);
1019 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
1020 &inst->capability.slice_mbs);
1021 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT,
1022 &inst->capability.ltr_count);
1023 msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES,
1024 &inst->capability.bframe);
1025}
1026
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001027static void handle_session_init_done(enum hal_command_response cmd, void *data)
1028{
1029 struct msm_vidc_cb_cmd_done *response = data;
1030 struct msm_vidc_inst *inst = NULL;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001031 struct msm_vidc_capability *capability = NULL;
1032 struct hfi_device *hdev;
1033 struct msm_vidc_core *core;
1034 u32 i, codec;
1035
1036 if (!response) {
1037 dprintk(VIDC_ERR,
1038 "Failed to get valid response for session init\n");
1039 return;
1040 }
1041
1042 inst = get_inst(get_vidc_core(response->device_id),
1043 response->session_id);
1044
1045 if (!inst) {
1046 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1047 return;
1048 }
1049
1050 if (response->status) {
1051 dprintk(VIDC_ERR,
1052 "Session init response from FW : %#x\n",
1053 response->status);
1054 if (response->status == VIDC_ERR_MAX_CLIENTS)
1055 msm_comm_generate_max_clients_error(inst);
1056 else
1057 msm_comm_generate_session_error(inst);
1058
1059 signal_session_msg_receipt(cmd, inst);
1060 put_inst(inst);
1061 return;
1062 }
1063
1064 core = inst->core;
1065 hdev = inst->core->device;
1066 codec = inst->session_type == MSM_VIDC_DECODER ?
1067 inst->fmts[OUTPUT_PORT].fourcc :
1068 inst->fmts[CAPTURE_PORT].fourcc;
1069
1070 /* check if capabilities are available for this session */
1071 for (i = 0; i < VIDC_MAX_SESSIONS; i++) {
1072 if (core->capabilities[i].codec ==
1073 get_hal_codec(codec) &&
1074 core->capabilities[i].domain ==
1075 get_hal_domain(inst->session_type)) {
1076 capability = &core->capabilities[i];
1077 break;
1078 }
1079 }
1080
1081 if (capability) {
1082 dprintk(VIDC_DBG,
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001083 "%s: capabilities for codec 0x%x, domain %#x\n",
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001084 __func__, capability->codec, capability->domain);
1085 memcpy(&inst->capability, capability,
1086 sizeof(struct msm_vidc_capability));
1087 } else {
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001088 dprintk(VIDC_ERR,
1089 "Watch out : Some property may fail inst %pK\n", inst);
1090 dprintk(VIDC_ERR,
1091 "Caps N/A for codec 0x%x, domain %#x\n",
1092 inst->capability.codec, inst->capability.domain);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001093 }
1094 inst->capability.pixelprocess_capabilities =
1095 call_hfi_op(hdev, get_core_capabilities, hdev->hfi_device_data);
1096
1097 dprintk(VIDC_DBG,
1098 "Capability type : min max step size\n");
1099 print_cap("width", &inst->capability.width);
1100 print_cap("height", &inst->capability.height);
1101 print_cap("mbs_per_frame", &inst->capability.mbs_per_frame);
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001102 print_cap("mbs_per_sec", &inst->capability.mbs_per_sec);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001103 print_cap("frame_rate", &inst->capability.frame_rate);
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001104 print_cap("bitrate", &inst->capability.bitrate);
1105 print_cap("peak_bitrate", &inst->capability.peakbitrate);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001106 print_cap("scale_x", &inst->capability.scale_x);
1107 print_cap("scale_y", &inst->capability.scale_y);
1108 print_cap("hier_p", &inst->capability.hier_p);
1109 print_cap("ltr_count", &inst->capability.ltr_count);
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001110 print_cap("bframe", &inst->capability.bframe);
1111 print_cap("secure_output2_threshold",
1112 &inst->capability.secure_output2_threshold);
1113 print_cap("hier_b", &inst->capability.hier_b);
1114 print_cap("lcu_size", &inst->capability.lcu_size);
1115 print_cap("hier_p_hybrid", &inst->capability.hier_p_hybrid);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001116 print_cap("mbs_per_sec_low_power",
1117 &inst->capability.mbs_per_sec_power_save);
Praneeth Paladugu520c7592017-01-26 13:53:14 -08001118 print_cap("extradata", &inst->capability.extradata);
1119 print_cap("profile", &inst->capability.profile);
1120 print_cap("level", &inst->capability.level);
1121 print_cap("i_qp", &inst->capability.i_qp);
1122 print_cap("p_qp", &inst->capability.p_qp);
1123 print_cap("b_qp", &inst->capability.b_qp);
1124 print_cap("rc_modes", &inst->capability.rc_modes);
1125 print_cap("blur_width", &inst->capability.blur_width);
1126 print_cap("blur_height", &inst->capability.blur_height);
1127 print_cap("slice_delivery_mode", &inst->capability.slice_delivery_mode);
1128 print_cap("slice_bytes", &inst->capability.slice_bytes);
1129 print_cap("slice_mbs", &inst->capability.slice_mbs);
1130 print_cap("secure", &inst->capability.secure);
1131 print_cap("max_num_b_frames", &inst->capability.max_num_b_frames);
1132 print_cap("max_video_cores", &inst->capability.max_video_cores);
1133 print_cap("max_work_modes", &inst->capability.max_work_modes);
1134 print_cap("ubwc_cr_stats", &inst->capability.ubwc_cr_stats);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001135
1136 signal_session_msg_receipt(cmd, inst);
Praneeth Paladugue1679112017-01-27 10:07:15 -08001137
1138 /*
1139 * Update controls after informing session_init_done to avoid
1140 * timeouts.
1141 */
1142
1143 msm_vidc_comm_update_ctrl_limits(inst);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001144 put_inst(inst);
1145}
1146
1147static void handle_event_change(enum hal_command_response cmd, void *data)
1148{
1149 struct msm_vidc_inst *inst = NULL;
1150 struct msm_vidc_cb_event *event_notify = data;
1151 int event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1152 struct v4l2_event seq_changed_event = {0};
1153 int rc = 0;
1154 struct hfi_device *hdev;
1155 u32 *ptr = NULL;
1156
1157 if (!event_notify) {
1158 dprintk(VIDC_WARN, "Got an empty event from hfi\n");
1159 return;
1160 }
1161
1162 inst = get_inst(get_vidc_core(event_notify->device_id),
1163 event_notify->session_id);
1164 if (!inst || !inst->core || !inst->core->device) {
1165 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1166 goto err_bad_event;
1167 }
1168 hdev = inst->core->device;
1169
1170 switch (event_notify->hal_event_type) {
1171 case HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES:
1172 event = V4L2_EVENT_SEQ_CHANGED_SUFFICIENT;
1173
1174 if (msm_comm_get_stream_output_mode(inst) ==
1175 HAL_VIDEO_DECODER_SECONDARY) {
1176 struct hal_frame_size frame_sz;
1177
1178 frame_sz.buffer_type = HAL_BUFFER_OUTPUT2;
1179 frame_sz.width = event_notify->width;
1180 frame_sz.height = event_notify->height;
1181 dprintk(VIDC_DBG,
1182 "Update OPB dimensions to firmware if buffer requirements are sufficient\n");
1183 rc = msm_comm_try_set_prop(inst,
1184 HAL_PARAM_FRAME_SIZE, &frame_sz);
1185 }
1186
1187 dprintk(VIDC_DBG,
1188 "send session_continue after sufficient event\n");
1189 rc = call_hfi_op(hdev, session_continue,
1190 (void *) inst->session);
1191 if (rc) {
1192 dprintk(VIDC_ERR,
1193 "%s - failed to send session_continue\n",
1194 __func__);
1195 goto err_bad_event;
1196 }
1197 break;
1198 case HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES:
1199 event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1200 break;
1201 case HAL_EVENT_RELEASE_BUFFER_REFERENCE:
1202 {
1203 struct v4l2_event buf_event = {0};
1204 struct buffer_info *binfo = NULL, *temp = NULL;
1205 u32 *ptr = NULL;
1206
1207 dprintk(VIDC_DBG, "%s - inst: %pK buffer: %pa extra: %pa\n",
1208 __func__, inst, &event_notify->packet_buffer,
1209 &event_notify->extra_data_buffer);
1210
1211 if (inst->state == MSM_VIDC_CORE_INVALID ||
1212 inst->core->state == VIDC_CORE_INVALID) {
1213 dprintk(VIDC_DBG,
1214 "Event release buf ref received in invalid state - discard\n");
1215 goto err_bad_event;
1216 }
1217
1218 /*
1219 * Get the buffer_info entry for the
1220 * device address.
1221 */
1222 binfo = device_to_uvaddr(&inst->registeredbufs,
1223 event_notify->packet_buffer);
1224 if (!binfo) {
1225 dprintk(VIDC_ERR,
1226 "%s buffer not found in registered list\n",
1227 __func__);
1228 goto err_bad_event;
1229 }
1230
1231 /* Fill event data to be sent to client*/
1232 buf_event.type = V4L2_EVENT_RELEASE_BUFFER_REFERENCE;
1233 ptr = (u32 *)buf_event.u.data;
1234 ptr[0] = binfo->fd[0];
1235 ptr[1] = binfo->buff_off[0];
1236
1237 dprintk(VIDC_DBG,
1238 "RELEASE REFERENCE EVENT FROM F/W - fd = %d offset = %d\n",
1239 ptr[0], ptr[1]);
1240
1241 /* Decrement buffer reference count*/
1242 mutex_lock(&inst->registeredbufs.lock);
1243 list_for_each_entry(temp, &inst->registeredbufs.list,
1244 list) {
1245 if (temp == binfo) {
1246 buf_ref_put(inst, binfo);
1247 break;
1248 }
1249 }
1250
1251 /*
1252 * Release buffer and remove from list
1253 * if reference goes to zero.
1254 */
1255 if (unmap_and_deregister_buf(inst, binfo))
1256 dprintk(VIDC_ERR,
1257 "%s: buffer unmap failed\n", __func__);
1258 mutex_unlock(&inst->registeredbufs.lock);
1259
1260 /*send event to client*/
1261 v4l2_event_queue_fh(&inst->event_handler, &buf_event);
1262 goto err_bad_event;
1263 }
1264 default:
1265 break;
1266 }
1267
1268 /* Bit depth and pic struct changed event are combined into a single
1269 * event (insufficient event) for the userspace. Currently bitdepth
1270 * changes is only for HEVC and interlaced support is for all
1271 * codecs except HEVC
1272 * event data is now as follows:
1273 * u32 *ptr = seq_changed_event.u.data;
1274 * ptr[0] = height
1275 * ptr[1] = width
1276 * ptr[2] = flag to indicate bit depth or/and pic struct changed
1277 * ptr[3] = bit depth
1278 * ptr[4] = pic struct (progressive or interlaced)
1279 * ptr[5] = colour space
1280 */
1281
1282 ptr = (u32 *)seq_changed_event.u.data;
1283
1284 if (ptr != NULL) {
1285 ptr[2] = 0x0;
1286 ptr[3] = inst->bit_depth;
1287 ptr[4] = inst->pic_struct;
1288 ptr[5] = inst->colour_space;
1289
1290 if (inst->bit_depth != event_notify->bit_depth) {
1291 inst->bit_depth = event_notify->bit_depth;
1292 ptr[2] |= V4L2_EVENT_BITDEPTH_FLAG;
1293 ptr[3] = inst->bit_depth;
1294 event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1295 dprintk(VIDC_DBG,
1296 "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT due to bit-depth change\n");
1297 }
1298
1299 if (inst->pic_struct != event_notify->pic_struct) {
1300 inst->pic_struct = event_notify->pic_struct;
1301 event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1302 ptr[2] |= V4L2_EVENT_PICSTRUCT_FLAG;
1303 ptr[4] = inst->pic_struct;
1304 dprintk(VIDC_DBG,
1305 "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT due to pic-struct change\n");
1306 }
1307
1308 if (inst->bit_depth == MSM_VIDC_BIT_DEPTH_10
1309 && inst->colour_space !=
1310 event_notify->colour_space) {
1311 inst->colour_space = event_notify->colour_space;
1312 event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
1313 ptr[2] |= V4L2_EVENT_COLOUR_SPACE_FLAG;
1314 ptr[5] = inst->colour_space;
1315 dprintk(VIDC_DBG,
1316 "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT due to colour space change\n");
1317 }
1318
1319 }
1320
1321 if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) {
1322 dprintk(VIDC_DBG, "V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT\n");
1323 inst->reconfig_height = event_notify->height;
1324 inst->reconfig_width = event_notify->width;
1325 inst->in_reconfig = true;
1326 } else {
1327 dprintk(VIDC_DBG, "V4L2_EVENT_SEQ_CHANGED_SUFFICIENT\n");
1328 dprintk(VIDC_DBG,
1329 "event_notify->height = %d event_notify->width = %d\n",
1330 event_notify->height,
1331 event_notify->width);
1332 inst->prop.height[OUTPUT_PORT] = event_notify->height;
1333 inst->prop.width[OUTPUT_PORT] = event_notify->width;
1334 }
1335
1336 if (inst->session_type == MSM_VIDC_DECODER)
1337 msm_dcvs_init_load(inst);
1338
1339 rc = msm_vidc_check_session_supported(inst);
1340 if (!rc) {
1341 seq_changed_event.type = event;
1342 if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) {
1343 u32 *ptr = NULL;
1344
1345 ptr = (u32 *)seq_changed_event.u.data;
1346 ptr[0] = event_notify->height;
1347 ptr[1] = event_notify->width;
1348 }
1349 v4l2_event_queue_fh(&inst->event_handler, &seq_changed_event);
1350 } else if (rc == -ENOTSUPP) {
1351 msm_vidc_queue_v4l2_event(inst,
1352 V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED);
1353 } else if (rc == -EBUSY) {
1354 msm_vidc_queue_v4l2_event(inst,
1355 V4L2_EVENT_MSM_VIDC_HW_OVERLOAD);
1356 }
1357
1358err_bad_event:
1359 put_inst(inst);
1360}
1361
1362static void handle_session_prop_info(enum hal_command_response cmd, void *data)
1363{
1364 struct msm_vidc_cb_cmd_done *response = data;
1365 struct getprop_buf *getprop;
1366 struct msm_vidc_inst *inst;
1367
1368 if (!response) {
1369 dprintk(VIDC_ERR,
1370 "Failed to get valid response for prop info\n");
1371 return;
1372 }
1373
1374 inst = get_inst(get_vidc_core(response->device_id),
1375 response->session_id);
1376 if (!inst) {
1377 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1378 return;
1379 }
1380
1381 getprop = kzalloc(sizeof(*getprop), GFP_KERNEL);
1382 if (!getprop) {
1383 dprintk(VIDC_ERR, "%s: getprop kzalloc failed\n", __func__);
1384 goto err_prop_info;
1385 }
1386
1387 getprop->data = kmemdup(&response->data.property,
1388 sizeof(union hal_get_property), GFP_KERNEL);
1389 if (!getprop->data) {
1390 dprintk(VIDC_ERR, "%s: kmemdup failed\n", __func__);
1391 kfree(getprop);
1392 goto err_prop_info;
1393 }
1394
1395 mutex_lock(&inst->pending_getpropq.lock);
1396 list_add_tail(&getprop->list, &inst->pending_getpropq.list);
1397 mutex_unlock(&inst->pending_getpropq.lock);
1398
1399 signal_session_msg_receipt(cmd, inst);
1400err_prop_info:
1401 put_inst(inst);
1402}
1403
1404static void handle_load_resource_done(enum hal_command_response cmd, void *data)
1405{
1406 struct msm_vidc_cb_cmd_done *response = data;
1407 struct msm_vidc_inst *inst;
1408
1409 if (!response) {
1410 dprintk(VIDC_ERR,
1411 "Failed to get valid response for load resource\n");
1412 return;
1413 }
1414
1415 inst = get_inst(get_vidc_core(response->device_id),
1416 response->session_id);
1417 if (!inst) {
1418 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1419 return;
1420 }
1421
1422 if (response->status) {
1423 dprintk(VIDC_ERR,
1424 "Load resource response from FW : %#x\n",
1425 response->status);
1426 msm_comm_generate_session_error(inst);
1427 }
1428
1429 put_inst(inst);
1430}
1431
1432static void handle_start_done(enum hal_command_response cmd, void *data)
1433{
1434 struct msm_vidc_cb_cmd_done *response = data;
1435 struct msm_vidc_inst *inst;
1436
1437 if (!response) {
1438 dprintk(VIDC_ERR, "Failed to get valid response for start\n");
1439 return;
1440 }
1441
1442 inst = get_inst(get_vidc_core(response->device_id),
1443 response->session_id);
1444 if (!inst) {
1445 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1446 return;
1447 }
1448
1449 signal_session_msg_receipt(cmd, inst);
1450 put_inst(inst);
1451}
1452
1453static void handle_stop_done(enum hal_command_response cmd, void *data)
1454{
1455 struct msm_vidc_cb_cmd_done *response = data;
1456 struct msm_vidc_inst *inst;
1457
1458 if (!response) {
1459 dprintk(VIDC_ERR, "Failed to get valid response for stop\n");
1460 return;
1461 }
1462
1463 inst = get_inst(get_vidc_core(response->device_id),
1464 response->session_id);
1465 if (!inst) {
1466 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1467 return;
1468 }
1469
1470 signal_session_msg_receipt(cmd, inst);
1471 put_inst(inst);
1472}
1473
1474static void handle_release_res_done(enum hal_command_response cmd, void *data)
1475{
1476 struct msm_vidc_cb_cmd_done *response = data;
1477 struct msm_vidc_inst *inst;
1478
1479 if (!response) {
1480 dprintk(VIDC_ERR,
1481 "Failed to get valid response for release resource\n");
1482 return;
1483 }
1484
1485 inst = get_inst(get_vidc_core(response->device_id),
1486 response->session_id);
1487 if (!inst) {
1488 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1489 return;
1490 }
1491
1492 signal_session_msg_receipt(cmd, inst);
1493 put_inst(inst);
1494}
1495
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001496void msm_comm_validate_output_buffers(struct msm_vidc_inst *inst)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001497{
1498 struct internal_buf *binfo;
1499 u32 buffers_owned_by_driver = 0;
1500 struct hal_buffer_requirements *output_buf;
1501
1502 output_buf = get_buff_req_buffer(inst, HAL_BUFFER_OUTPUT);
1503
1504 if (!output_buf) {
1505 dprintk(VIDC_DBG,
1506 "This output buffer not required, buffer_type: %x\n",
1507 HAL_BUFFER_OUTPUT);
1508 return;
1509 }
1510 mutex_lock(&inst->outputbufs.lock);
1511 list_for_each_entry(binfo, &inst->outputbufs.list, list) {
1512 if (binfo->buffer_ownership != DRIVER) {
1513 dprintk(VIDC_DBG,
1514 "This buffer is with FW %pa\n",
1515 &binfo->handle->device_addr);
1516 continue;
1517 }
1518 buffers_owned_by_driver++;
1519 }
1520 mutex_unlock(&inst->outputbufs.lock);
1521
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001522 if (buffers_owned_by_driver != output_buf->buffer_count_actual) {
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001523 dprintk(VIDC_WARN,
1524 "OUTPUT Buffer count mismatch %d of %d\n",
1525 buffers_owned_by_driver,
1526 output_buf->buffer_count_actual);
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001527 msm_vidc_handle_hw_error(inst->core);
1528 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001529}
1530
1531int msm_comm_queue_output_buffers(struct msm_vidc_inst *inst)
1532{
1533 struct internal_buf *binfo;
1534 struct hfi_device *hdev;
1535 struct msm_smem *handle;
1536 struct vidc_frame_data frame_data = {0};
1537 struct hal_buffer_requirements *output_buf, *extra_buf;
1538 int rc = 0;
1539
1540 if (!inst || !inst->core || !inst->core->device) {
1541 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
1542 return -EINVAL;
1543 }
1544
1545 hdev = inst->core->device;
1546
1547 output_buf = get_buff_req_buffer(inst, HAL_BUFFER_OUTPUT);
1548 if (!output_buf) {
1549 dprintk(VIDC_DBG,
1550 "This output buffer not required, buffer_type: %x\n",
1551 HAL_BUFFER_OUTPUT);
1552 return 0;
1553 }
1554 dprintk(VIDC_DBG,
1555 "output: num = %d, size = %d\n",
1556 output_buf->buffer_count_actual,
1557 output_buf->buffer_size);
1558
1559 extra_buf = get_buff_req_buffer(inst, HAL_BUFFER_EXTRADATA_OUTPUT);
1560
1561 mutex_lock(&inst->outputbufs.lock);
1562 list_for_each_entry(binfo, &inst->outputbufs.list, list) {
1563 if (binfo->buffer_ownership != DRIVER)
1564 continue;
1565 handle = binfo->handle;
1566 frame_data.alloc_len = output_buf->buffer_size;
1567 frame_data.filled_len = 0;
1568 frame_data.offset = 0;
1569 frame_data.device_addr = handle->device_addr;
1570 frame_data.flags = 0;
1571 frame_data.extradata_addr = handle->device_addr +
1572 output_buf->buffer_size;
1573 frame_data.buffer_type = HAL_BUFFER_OUTPUT;
1574 frame_data.extradata_size = extra_buf ?
1575 extra_buf->buffer_size : 0;
1576 rc = call_hfi_op(hdev, session_ftb,
1577 (void *) inst->session, &frame_data);
1578 binfo->buffer_ownership = FIRMWARE;
1579 }
1580 mutex_unlock(&inst->outputbufs.lock);
1581
1582 return 0;
1583}
1584
1585static void handle_session_flush(enum hal_command_response cmd, void *data)
1586{
1587 struct msm_vidc_cb_cmd_done *response = data;
1588 struct msm_vidc_inst *inst;
1589 struct v4l2_event flush_event = {0};
1590 u32 *ptr = NULL;
1591 enum hal_flush flush_type;
1592 int rc;
1593
1594 if (!response) {
1595 dprintk(VIDC_ERR, "Failed to get valid response for flush\n");
1596 return;
1597 }
1598
1599 inst = get_inst(get_vidc_core(response->device_id),
1600 response->session_id);
1601 if (!inst) {
1602 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1603 return;
1604 }
1605
1606 if (msm_comm_get_stream_output_mode(inst) ==
1607 HAL_VIDEO_DECODER_SECONDARY) {
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08001608
1609 if (!(inst->fmts[OUTPUT_PORT].defer_outputs &&
1610 inst->in_reconfig))
1611 msm_comm_validate_output_buffers(inst);
1612
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001613 if (!inst->in_reconfig) {
1614 rc = msm_comm_queue_output_buffers(inst);
1615 if (rc) {
1616 dprintk(VIDC_ERR,
1617 "Failed to queue output buffers: %d\n",
1618 rc);
1619 }
1620 }
1621 }
1622 atomic_dec(&inst->in_flush);
1623 flush_event.type = V4L2_EVENT_MSM_VIDC_FLUSH_DONE;
1624 ptr = (u32 *)flush_event.u.data;
1625
1626 flush_type = response->data.flush_type;
1627 switch (flush_type) {
1628 case HAL_FLUSH_INPUT:
1629 ptr[0] = V4L2_QCOM_CMD_FLUSH_OUTPUT;
1630 break;
1631 case HAL_FLUSH_OUTPUT:
1632 ptr[0] = V4L2_QCOM_CMD_FLUSH_CAPTURE;
1633 break;
1634 case HAL_FLUSH_ALL:
1635 ptr[0] |= V4L2_QCOM_CMD_FLUSH_CAPTURE;
1636 ptr[0] |= V4L2_QCOM_CMD_FLUSH_OUTPUT;
1637 break;
1638 default:
1639 dprintk(VIDC_ERR, "Invalid flush type received!");
1640 goto exit;
1641 }
1642
1643 dprintk(VIDC_DBG,
1644 "Notify flush complete, flush_type: %x\n", flush_type);
1645 v4l2_event_queue_fh(&inst->event_handler, &flush_event);
1646
1647exit:
1648 put_inst(inst);
1649}
1650
1651static void handle_session_error(enum hal_command_response cmd, void *data)
1652{
1653 struct msm_vidc_cb_cmd_done *response = data;
1654 struct hfi_device *hdev = NULL;
1655 struct msm_vidc_inst *inst = NULL;
1656 int event = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
1657
1658 if (!response) {
1659 dprintk(VIDC_ERR,
1660 "Failed to get valid response for session error\n");
1661 return;
1662 }
1663
1664 inst = get_inst(get_vidc_core(response->device_id),
1665 response->session_id);
1666 if (!inst) {
1667 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1668 return;
1669 }
1670
1671 hdev = inst->core->device;
1672 dprintk(VIDC_WARN, "Session error received for session %pK\n", inst);
1673 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
1674
1675 if (response->status == VIDC_ERR_MAX_CLIENTS) {
1676 dprintk(VIDC_WARN, "Too many clients, rejecting %pK", inst);
1677 event = V4L2_EVENT_MSM_VIDC_MAX_CLIENTS;
1678
1679 /*
1680 * Clean the HFI session now. Since inst->state is moved to
1681 * INVALID, forward thread doesn't know FW has valid session
1682 * or not. This is the last place driver knows that there is
1683 * no session in FW. Hence clean HFI session now.
1684 */
1685
1686 msm_comm_session_clean(inst);
1687 } else if (response->status == VIDC_ERR_NOT_SUPPORTED) {
1688 dprintk(VIDC_WARN, "Unsupported bitstream in %pK", inst);
1689 event = V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED;
1690 } else {
1691 dprintk(VIDC_WARN, "Unknown session error (%d) for %pK\n",
1692 response->status, inst);
1693 event = V4L2_EVENT_MSM_VIDC_SYS_ERROR;
1694 }
1695
1696 msm_vidc_queue_v4l2_event(inst, event);
1697 put_inst(inst);
1698}
1699
1700static void msm_comm_clean_notify_client(struct msm_vidc_core *core)
1701{
1702 struct msm_vidc_inst *inst = NULL;
1703
1704 if (!core) {
1705 dprintk(VIDC_ERR, "%s: Invalid params\n", __func__);
1706 return;
1707 }
1708
1709 dprintk(VIDC_WARN, "%s: Core %pK\n", __func__, core);
1710 mutex_lock(&core->lock);
1711 core->state = VIDC_CORE_INVALID;
1712
1713 list_for_each_entry(inst, &core->instances, list) {
1714 mutex_lock(&inst->lock);
1715 inst->state = MSM_VIDC_CORE_INVALID;
1716 mutex_unlock(&inst->lock);
1717 dprintk(VIDC_WARN,
1718 "%s Send sys error for inst %pK\n", __func__, inst);
1719 msm_vidc_queue_v4l2_event(inst,
1720 V4L2_EVENT_MSM_VIDC_SYS_ERROR);
1721 }
1722 mutex_unlock(&core->lock);
1723}
1724
1725static void handle_sys_error(enum hal_command_response cmd, void *data)
1726{
1727 struct msm_vidc_cb_cmd_done *response = data;
1728 struct msm_vidc_core *core = NULL;
1729 struct hfi_device *hdev = NULL;
1730 struct msm_vidc_inst *inst = NULL;
1731 int rc = 0;
1732
1733 subsystem_crashed("venus");
1734 if (!response) {
1735 dprintk(VIDC_ERR,
1736 "Failed to get valid response for sys error\n");
1737 return;
1738 }
1739
1740 core = get_vidc_core(response->device_id);
1741 if (!core) {
1742 dprintk(VIDC_ERR,
1743 "Got SYS_ERR but unable to identify core\n");
1744 return;
1745 }
1746
1747 mutex_lock(&core->lock);
1748 if (core->state == VIDC_CORE_INVALID ||
1749 core->state == VIDC_CORE_UNINIT) {
1750 dprintk(VIDC_ERR,
1751 "%s: Core already moved to state %d\n",
1752 __func__, core->state);
1753 mutex_unlock(&core->lock);
1754 return;
1755 }
1756 mutex_unlock(&core->lock);
1757
1758 dprintk(VIDC_WARN, "SYS_ERROR %d received for core %pK\n", cmd, core);
1759 msm_comm_clean_notify_client(core);
1760
1761 hdev = core->device;
1762 mutex_lock(&core->lock);
1763 if (core->state == VIDC_CORE_INVALID) {
1764 dprintk(VIDC_DBG, "Calling core_release\n");
1765 rc = call_hfi_op(hdev, core_release,
1766 hdev->hfi_device_data);
1767 if (rc) {
1768 dprintk(VIDC_ERR, "core_release failed\n");
1769 mutex_unlock(&core->lock);
1770 return;
1771 }
1772 core->state = VIDC_CORE_UNINIT;
1773 }
1774 mutex_unlock(&core->lock);
1775
1776 msm_vidc_print_running_insts(core);
1777 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
1778 dprintk(VIDC_ERR,
1779 "SYS_ERROR can potentially crash the system\n");
1780
1781 /*
1782 * For SYS_ERROR, there will not be any inst pointer.
1783 * Just grab one of the inst from instances list and
1784 * use it.
1785 */
1786
1787 mutex_lock(&core->lock);
1788 inst = list_first_entry_or_null(&core->instances,
1789 struct msm_vidc_inst, list);
1790 mutex_unlock(&core->lock);
1791
1792 msm_comm_print_debug_info(inst);
1793
1794 msm_vidc_handle_hw_error(core);
1795}
1796
1797void msm_comm_session_clean(struct msm_vidc_inst *inst)
1798{
1799 int rc = 0;
1800 struct hfi_device *hdev = NULL;
1801
1802 if (!inst || !inst->core || !inst->core->device) {
1803 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
1804 return;
1805 }
1806
1807 hdev = inst->core->device;
1808 mutex_lock(&inst->lock);
1809 if (hdev && inst->session) {
1810 dprintk(VIDC_DBG, "cleaning up instance: %pK\n", inst);
1811 rc = call_hfi_op(hdev, session_clean,
1812 (void *)inst->session);
1813 if (rc) {
1814 dprintk(VIDC_ERR,
1815 "Session clean failed :%pK\n", inst);
1816 }
1817 inst->session = NULL;
1818 }
1819 mutex_unlock(&inst->lock);
1820}
1821
1822static void handle_session_close(enum hal_command_response cmd, void *data)
1823{
1824 struct msm_vidc_cb_cmd_done *response = data;
1825 struct msm_vidc_inst *inst;
1826
1827 if (!response) {
1828 dprintk(VIDC_ERR,
1829 "Failed to get valid response for session close\n");
1830 return;
1831 }
1832
1833 inst = get_inst(get_vidc_core(response->device_id),
1834 response->session_id);
1835 if (!inst) {
1836 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1837 return;
1838 }
1839
1840 signal_session_msg_receipt(cmd, inst);
1841 show_stats(inst);
1842 put_inst(inst);
1843}
1844
1845static struct vb2_buffer *get_vb_from_device_addr(struct buf_queue *bufq,
1846 unsigned long dev_addr)
1847{
1848 struct vb2_buffer *vb = NULL;
1849 struct vb2_queue *q = NULL;
1850 int found = 0;
1851
1852 if (!bufq) {
1853 dprintk(VIDC_ERR, "Invalid parameter\n");
1854 return NULL;
1855 }
1856 q = &bufq->vb2_bufq;
1857 mutex_lock(&bufq->lock);
1858 list_for_each_entry(vb, &q->queued_list, queued_entry) {
1859 if (vb->planes[0].m.userptr == dev_addr &&
1860 vb->state == VB2_BUF_STATE_ACTIVE) {
1861 found = 1;
1862 dprintk(VIDC_DBG, "Found v4l2_buf index : %d\n",
1863 vb->index);
1864 break;
1865 }
1866 }
1867 mutex_unlock(&bufq->lock);
1868 if (!found) {
1869 dprintk(VIDC_DBG,
1870 "Failed to find buffer in queued list: %#lx, qtype = %d\n",
1871 dev_addr, q->type);
1872 vb = NULL;
1873 }
1874 return vb;
1875}
1876
1877static void handle_ebd(enum hal_command_response cmd, void *data)
1878{
1879 struct msm_vidc_cb_data_done *response = data;
1880 struct vb2_buffer *vb;
1881 struct msm_vidc_inst *inst;
1882 struct vidc_hal_ebd *empty_buf_done;
1883 struct vb2_v4l2_buffer *vbuf = NULL;
1884
1885 if (!response) {
1886 dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
1887 return;
1888 }
1889
1890 inst = get_inst(get_vidc_core(response->device_id),
1891 response->session_id);
1892 if (!inst) {
1893 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
1894 return;
1895 }
1896
1897 vb = get_vb_from_device_addr(&inst->bufq[OUTPUT_PORT],
1898 response->input_done.packet_buffer);
1899 if (vb) {
1900 vbuf = to_vb2_v4l2_buffer(vb);
1901 vb->planes[0].bytesused = response->input_done.filled_len;
1902 vb->planes[0].data_offset = response->input_done.offset;
1903 if (vb->planes[0].data_offset > vb->planes[0].length)
1904 dprintk(VIDC_INFO, "data_offset overflow length\n");
1905 if (vb->planes[0].bytesused > vb->planes[0].length)
1906 dprintk(VIDC_INFO, "bytesused overflow length\n");
1907 if (vb->planes[0].m.userptr !=
1908 response->clnt_data)
1909 dprintk(VIDC_INFO, "Client data != bufaddr\n");
1910 empty_buf_done = (struct vidc_hal_ebd *)&response->input_done;
1911 if (empty_buf_done) {
1912 if (empty_buf_done->status == VIDC_ERR_NOT_SUPPORTED) {
1913 dprintk(VIDC_INFO,
1914 "Failed : Unsupported input stream\n");
1915 vbuf->flags |=
1916 V4L2_QCOM_BUF_INPUT_UNSUPPORTED;
1917 }
1918 if (empty_buf_done->status == VIDC_ERR_BITSTREAM_ERR) {
1919 dprintk(VIDC_INFO,
1920 "Failed : Corrupted input stream\n");
1921 vbuf->flags |=
1922 V4L2_QCOM_BUF_DATA_CORRUPT;
1923 }
1924 if (empty_buf_done->flags & HAL_BUFFERFLAG_SYNCFRAME)
1925 vbuf->flags |=
1926 V4L2_QCOM_BUF_FLAG_IDRFRAME |
1927 V4L2_BUF_FLAG_KEYFRAME;
1928 }
1929 dprintk(VIDC_DBG,
1930 "Got ebd from hal: device_addr: %pa, alloc: %d, status: %#x, pic_type: %#x, flags: %#x\n",
1931 &empty_buf_done->packet_buffer,
1932 empty_buf_done->alloc_len, empty_buf_done->status,
1933 empty_buf_done->picture_type, empty_buf_done->flags);
1934
1935 mutex_lock(&inst->bufq[OUTPUT_PORT].lock);
1936 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
1937 mutex_unlock(&inst->bufq[OUTPUT_PORT].lock);
1938 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_EBD);
1939 }
1940
1941 put_inst(inst);
1942}
1943
1944int buf_ref_get(struct msm_vidc_inst *inst, struct buffer_info *binfo)
1945{
1946 int cnt = 0;
1947
1948 if (!inst || !binfo)
1949 return -EINVAL;
1950
1951 atomic_inc(&binfo->ref_count);
1952 cnt = atomic_read(&binfo->ref_count);
1953 if (cnt > 2) {
1954 dprintk(VIDC_DBG, "%s: invalid ref_cnt: %d\n", __func__, cnt);
1955 cnt = -EINVAL;
1956 }
1957 if (cnt == 2)
1958 inst->buffers_held_in_driver++;
1959
1960 dprintk(VIDC_DBG, "REF_GET[%d] fd[0] = %d\n", cnt, binfo->fd[0]);
1961
1962 return cnt;
1963}
1964
1965int buf_ref_put(struct msm_vidc_inst *inst, struct buffer_info *binfo)
1966{
1967 int rc = 0;
1968 int cnt;
1969 bool release_buf = false;
1970 bool qbuf_again = false;
1971
1972 if (!inst || !binfo)
1973 return -EINVAL;
1974
1975 atomic_dec(&binfo->ref_count);
1976 cnt = atomic_read(&binfo->ref_count);
1977 dprintk(VIDC_DBG, "REF_PUT[%d] fd[0] = %d\n", cnt, binfo->fd[0]);
1978 if (!cnt)
1979 release_buf = true;
1980 else if (cnt == 1)
1981 qbuf_again = true;
1982 else {
1983 dprintk(VIDC_DBG, "%s: invalid ref_cnt: %d\n", __func__, cnt);
1984 cnt = -EINVAL;
1985 }
1986
1987 if (cnt < 0)
1988 return cnt;
1989
1990 if (release_buf) {
1991 /*
1992 * We can not delete binfo here as we need to set the user
1993 * virtual address saved in binfo->uvaddr to the dequeued v4l2
1994 * buffer.
1995 *
1996 * We will set the pending_deletion flag to true here and delete
1997 * binfo from registered list in dqbuf after setting the uvaddr.
1998 */
1999 dprintk(VIDC_DBG, "fd[0] = %d -> pending_deletion = true\n",
2000 binfo->fd[0]);
2001 binfo->pending_deletion = true;
2002 } else if (qbuf_again) {
2003 inst->buffers_held_in_driver--;
2004 rc = qbuf_dynamic_buf(inst, binfo);
2005 if (!rc)
2006 return rc;
2007 }
2008 return cnt;
2009}
2010
2011static void handle_dynamic_buffer(struct msm_vidc_inst *inst,
2012 ion_phys_addr_t device_addr, u32 flags)
2013{
2014 struct buffer_info *binfo = NULL, *temp = NULL;
2015
2016 /*
2017 * Update reference count and release OR queue back the buffer,
2018 * only when firmware is not holding a reference.
2019 */
2020 if (inst->buffer_mode_set[CAPTURE_PORT] == HAL_BUFFER_MODE_DYNAMIC) {
2021 binfo = device_to_uvaddr(&inst->registeredbufs, device_addr);
2022 if (!binfo) {
2023 dprintk(VIDC_ERR,
2024 "%s buffer not found in registered list\n",
2025 __func__);
2026 return;
2027 }
2028 if (flags & HAL_BUFFERFLAG_READONLY) {
2029 dprintk(VIDC_DBG,
2030 "FBD fd[0] = %d -> Reference with f/w, addr: %pa\n",
2031 binfo->fd[0], &device_addr);
2032 } else {
2033 dprintk(VIDC_DBG,
2034 "FBD fd[0] = %d -> FBD_ref_released, addr: %pa\n",
2035 binfo->fd[0], &device_addr);
2036
2037 mutex_lock(&inst->registeredbufs.lock);
2038 list_for_each_entry(temp, &inst->registeredbufs.list,
2039 list) {
2040 if (temp == binfo) {
2041 buf_ref_put(inst, binfo);
2042 break;
2043 }
2044 }
2045 mutex_unlock(&inst->registeredbufs.lock);
2046 }
2047 }
2048}
2049
2050static int handle_multi_stream_buffers(struct msm_vidc_inst *inst,
2051 ion_phys_addr_t dev_addr)
2052{
2053 struct internal_buf *binfo;
2054 struct msm_smem *handle;
2055 bool found = false;
2056
2057 mutex_lock(&inst->outputbufs.lock);
2058 list_for_each_entry(binfo, &inst->outputbufs.list, list) {
2059 handle = binfo->handle;
2060 if (handle && dev_addr == handle->device_addr) {
2061 if (binfo->buffer_ownership == DRIVER) {
2062 dprintk(VIDC_ERR,
2063 "FW returned same buffer: %pa\n",
2064 &dev_addr);
2065 break;
2066 }
2067 binfo->buffer_ownership = DRIVER;
2068 found = true;
2069 break;
2070 }
2071 }
2072 mutex_unlock(&inst->outputbufs.lock);
2073
2074 if (!found) {
2075 dprintk(VIDC_ERR,
2076 "Failed to find output buffer in queued list: %pa\n",
2077 &dev_addr);
2078 }
2079
2080 return 0;
2081}
2082
2083enum hal_buffer msm_comm_get_hal_output_buffer(struct msm_vidc_inst *inst)
2084{
2085 if (msm_comm_get_stream_output_mode(inst) ==
2086 HAL_VIDEO_DECODER_SECONDARY)
2087 return HAL_BUFFER_OUTPUT2;
2088 else
2089 return HAL_BUFFER_OUTPUT;
2090}
2091
2092static void handle_fbd(enum hal_command_response cmd, void *data)
2093{
2094 struct msm_vidc_cb_data_done *response = data;
2095 struct msm_vidc_inst *inst;
2096 struct vb2_buffer *vb = NULL;
2097 struct vidc_hal_fbd *fill_buf_done;
2098 enum hal_buffer buffer_type;
2099 int extra_idx = 0;
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002100 u64 time_nsec = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002101 struct vb2_v4l2_buffer *vbuf = NULL;
2102
2103 if (!response) {
2104 dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
2105 return;
2106 }
2107
2108 inst = get_inst(get_vidc_core(response->device_id),
2109 response->session_id);
2110 if (!inst) {
2111 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
2112 return;
2113 }
2114
2115 fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
2116 buffer_type = msm_comm_get_hal_output_buffer(inst);
2117 if (fill_buf_done->buffer_type == buffer_type) {
2118 vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
2119 fill_buf_done->packet_buffer1);
2120 } else {
2121 if (handle_multi_stream_buffers(inst,
2122 fill_buf_done->packet_buffer1))
2123 dprintk(VIDC_ERR,
2124 "Failed : Output buffer not found %pa\n",
2125 &fill_buf_done->packet_buffer1);
2126 goto err_handle_fbd;
2127 }
2128
2129 if (vb) {
2130 vbuf = to_vb2_v4l2_buffer(vb);
2131 vb->planes[0].bytesused = fill_buf_done->filled_len1;
2132 vb->planes[0].data_offset = fill_buf_done->offset1;
2133 if (vb->planes[0].data_offset > vb->planes[0].length)
2134 dprintk(VIDC_INFO,
2135 "fbd:Overflow data_offset = %d; length = %d\n",
2136 vb->planes[0].data_offset,
2137 vb->planes[0].length);
2138 if (vb->planes[0].bytesused > vb->planes[0].length)
2139 dprintk(VIDC_INFO,
2140 "fbd:Overflow bytesused = %d; length = %d\n",
2141 vb->planes[0].bytesused,
2142 vb->planes[0].length);
2143 if (!(fill_buf_done->flags1 &
2144 HAL_BUFFERFLAG_TIMESTAMPINVALID)) {
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002145 time_nsec = fill_buf_done->timestamp_hi;
2146 time_nsec = (time_nsec << 32) |
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002147 fill_buf_done->timestamp_lo;
2148 } else {
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002149 time_nsec = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002150 dprintk(VIDC_DBG,
2151 "Set zero timestamp for buffer %pa, filled: %d, (hi:%u, lo:%u)\n",
2152 &fill_buf_done->packet_buffer1,
2153 fill_buf_done->filled_len1,
2154 fill_buf_done->timestamp_hi,
2155 fill_buf_done->timestamp_lo);
2156 }
2157 vbuf->flags = 0;
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002158 vb->timestamp = time_nsec;
2159
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002160 extra_idx =
2161 EXTRADATA_IDX(inst->fmts[CAPTURE_PORT].num_planes);
2162 if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
2163 vb->planes[extra_idx].m.userptr =
2164 (unsigned long)fill_buf_done->extra_data_buffer;
2165 vb->planes[extra_idx].bytesused =
2166 vb->planes[extra_idx].length;
2167 vb->planes[extra_idx].data_offset = 0;
2168 }
2169
2170 handle_dynamic_buffer(inst, fill_buf_done->packet_buffer1,
2171 fill_buf_done->flags1);
2172 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_READONLY)
2173 vbuf->flags |= V4L2_QCOM_BUF_FLAG_READONLY;
2174 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOS)
2175 vbuf->flags |= V4L2_QCOM_BUF_FLAG_EOS;
2176 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_CODECCONFIG)
2177 vbuf->flags &= ~V4L2_QCOM_BUF_FLAG_CODECCONFIG;
2178 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_SYNCFRAME)
2179 vbuf->flags |= V4L2_QCOM_BUF_FLAG_IDRFRAME;
2180 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_EOSEQ)
2181 vbuf->flags |= V4L2_QCOM_BUF_FLAG_EOSEQ;
2182 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DECODEONLY)
2183 vbuf->flags |= V4L2_QCOM_BUF_FLAG_DECODEONLY;
2184 if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DATACORRUPT)
2185 vbuf->flags |= V4L2_QCOM_BUF_DATA_CORRUPT;
2186
2187 switch (fill_buf_done->picture_type) {
2188 case HAL_PICTURE_IDR:
2189 vbuf->flags |= V4L2_QCOM_BUF_FLAG_IDRFRAME;
2190 vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
2191 break;
2192 case HAL_PICTURE_I:
2193 vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
2194 break;
2195 case HAL_PICTURE_P:
2196 vbuf->flags |= V4L2_BUF_FLAG_PFRAME;
2197 break;
2198 case HAL_PICTURE_B:
2199 vbuf->flags |= V4L2_BUF_FLAG_BFRAME;
2200 break;
2201 case HAL_FRAME_NOTCODED:
2202 case HAL_UNUSED_PICT:
2203 /* Do we need to care about these? */
2204 case HAL_FRAME_YUV:
2205 break;
2206 default:
2207 break;
2208 }
2209
2210 inst->count.fbd++;
2211
2212 if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
2213 dprintk(VIDC_DBG,
2214 "extradata: userptr = %pK;"
2215 " bytesused = %d; length = %d\n",
2216 (u8 *)vb->planes[extra_idx].m.userptr,
2217 vb->planes[extra_idx].bytesused,
2218 vb->planes[extra_idx].length);
2219 }
2220 dprintk(VIDC_DBG,
2221 "Got fbd from hal: device_addr: %pa, alloc: %d, filled: %d, offset: %d, ts: %lld, flags: %#x, crop: %d %d %d %d, pic_type: %#x, mark_data: %#x\n",
2222 &fill_buf_done->packet_buffer1, fill_buf_done->alloc_len1,
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002223 fill_buf_done->filled_len1, fill_buf_done->offset1, time_nsec,
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002224 fill_buf_done->flags1, fill_buf_done->start_x_coord,
2225 fill_buf_done->start_y_coord, fill_buf_done->frame_width,
2226 fill_buf_done->frame_height, fill_buf_done->picture_type,
2227 fill_buf_done->mark_data);
2228
2229 mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
2230 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
2231 mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
2232 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FBD);
2233 }
2234
2235err_handle_fbd:
2236 put_inst(inst);
2237}
2238
2239static void handle_seq_hdr_done(enum hal_command_response cmd, void *data)
2240{
2241 struct msm_vidc_cb_data_done *response = data;
2242 struct msm_vidc_inst *inst;
2243 struct vb2_buffer *vb;
2244 struct vidc_hal_fbd *fill_buf_done;
2245 struct vb2_v4l2_buffer *vbuf;
2246
2247 if (!response) {
2248 dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
2249 return;
2250 }
2251
2252 inst = get_inst(get_vidc_core(response->device_id),
2253 response->session_id);
2254 if (!inst) {
2255 dprintk(VIDC_WARN, "Got a response for an inactive session\n");
2256 return;
2257 }
2258
2259 fill_buf_done = (struct vidc_hal_fbd *)&response->output_done;
2260 vb = get_vb_from_device_addr(&inst->bufq[CAPTURE_PORT],
2261 fill_buf_done->packet_buffer1);
2262 if (!vb) {
2263 dprintk(VIDC_ERR,
2264 "Failed to find video buffer for seq_hdr_done: %pa\n",
2265 &fill_buf_done->packet_buffer1);
2266 goto err_seq_hdr_done;
2267 }
2268 vbuf = to_vb2_v4l2_buffer(vb);
2269// vb->timestamp = (u64) ns_to_timeval(0);
2270
2271 vb->planes[0].bytesused = fill_buf_done->filled_len1;
2272 vb->planes[0].data_offset = fill_buf_done->offset1;
2273
2274 vbuf->flags = V4L2_QCOM_BUF_FLAG_CODECCONFIG;
2275
2276 dprintk(VIDC_DBG, "Filled length = %d; offset = %d; flags %x\n",
2277 vb->planes[0].bytesused,
2278 vb->planes[0].data_offset,
2279 vbuf->flags);
2280 mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
2281 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
2282 mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
2283
2284err_seq_hdr_done:
2285 put_inst(inst);
2286}
2287
2288void handle_cmd_response(enum hal_command_response cmd, void *data)
2289{
2290 dprintk(VIDC_DBG, "Command response = %d\n", cmd);
2291 switch (cmd) {
2292 case HAL_SYS_INIT_DONE:
2293 handle_sys_init_done(cmd, data);
2294 break;
2295 case HAL_SYS_RELEASE_RESOURCE_DONE:
2296 handle_sys_release_res_done(cmd, data);
2297 break;
2298 case HAL_SESSION_INIT_DONE:
2299 handle_session_init_done(cmd, data);
2300 break;
2301 case HAL_SESSION_PROPERTY_INFO:
2302 handle_session_prop_info(cmd, data);
2303 break;
2304 case HAL_SESSION_LOAD_RESOURCE_DONE:
2305 handle_load_resource_done(cmd, data);
2306 break;
2307 case HAL_SESSION_START_DONE:
2308 handle_start_done(cmd, data);
2309 break;
2310 case HAL_SESSION_ETB_DONE:
2311 handle_ebd(cmd, data);
2312 break;
2313 case HAL_SESSION_FTB_DONE:
2314 handle_fbd(cmd, data);
2315 break;
2316 case HAL_SESSION_STOP_DONE:
2317 handle_stop_done(cmd, data);
2318 break;
2319 case HAL_SESSION_RELEASE_RESOURCE_DONE:
2320 handle_release_res_done(cmd, data);
2321 break;
2322 case HAL_SESSION_END_DONE:
2323 case HAL_SESSION_ABORT_DONE:
2324 handle_session_close(cmd, data);
2325 break;
2326 case HAL_SESSION_EVENT_CHANGE:
2327 handle_event_change(cmd, data);
2328 break;
2329 case HAL_SESSION_FLUSH_DONE:
2330 handle_session_flush(cmd, data);
2331 break;
2332 case HAL_SESSION_GET_SEQ_HDR_DONE:
2333 handle_seq_hdr_done(cmd, data);
2334 break;
2335 case HAL_SYS_WATCHDOG_TIMEOUT:
2336 case HAL_SYS_ERROR:
2337 handle_sys_error(cmd, data);
2338 break;
2339 case HAL_SESSION_ERROR:
2340 handle_session_error(cmd, data);
2341 break;
2342 case HAL_SESSION_RELEASE_BUFFER_DONE:
2343 handle_session_release_buf_done(cmd, data);
2344 break;
2345 default:
2346 dprintk(VIDC_DBG, "response unhandled: %d\n", cmd);
2347 break;
2348 }
2349}
2350
2351int msm_comm_scale_clocks(struct msm_vidc_core *core)
2352{
2353 int num_mbs_per_sec, enc_mbs_per_sec, dec_mbs_per_sec;
2354
2355 enc_mbs_per_sec =
2356 msm_comm_get_load(core, MSM_VIDC_ENCODER, LOAD_CALC_NO_QUIRKS);
2357 dec_mbs_per_sec =
2358 msm_comm_get_load(core, MSM_VIDC_DECODER, LOAD_CALC_NO_QUIRKS);
2359
2360 if (enc_mbs_per_sec >= dec_mbs_per_sec) {
2361 /*
2362 * If Encoder load is higher, use that load. Encoder votes for higher
2363 * clock. Since Encoder and Deocder run on parallel cores, this clock
2364 * should suffice decoder usecases.
2365 */
2366 num_mbs_per_sec = enc_mbs_per_sec;
2367 } else {
2368 /*
2369 * If Decoder load is higher, it's tricky to decide clock. Decoder
2370 * higher load might results less clocks than Encoder smaller load.
2371 * At this point driver doesn't know which clock to vote. Hence use
2372 * total load.
2373 */
2374 num_mbs_per_sec = enc_mbs_per_sec + dec_mbs_per_sec;
2375 }
2376
2377 return msm_comm_scale_clocks_load(core, num_mbs_per_sec,
2378 LOAD_CALC_NO_QUIRKS);
2379}
2380
2381int msm_comm_scale_clocks_load(struct msm_vidc_core *core,
2382 int num_mbs_per_sec, enum load_calc_quirks quirks)
2383{
2384 int rc = 0;
2385 struct hfi_device *hdev;
2386 struct msm_vidc_inst *inst = NULL;
2387 unsigned long instant_bitrate = 0;
2388 int num_sessions = 0;
2389 struct vidc_clk_scale_data clk_scale_data = { {0} };
2390 int codec = 0;
2391
2392 if (!core) {
2393 dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core);
2394 return -EINVAL;
2395 }
2396
2397 hdev = core->device;
2398 if (!hdev) {
2399 dprintk(VIDC_ERR, "%s Invalid device handle: %pK\n",
2400 __func__, hdev);
2401 return -EINVAL;
2402 }
2403
2404 mutex_lock(&core->lock);
2405 list_for_each_entry(inst, &core->instances, list) {
2406
2407 codec = inst->session_type == MSM_VIDC_DECODER ?
2408 inst->fmts[OUTPUT_PORT].fourcc :
2409 inst->fmts[CAPTURE_PORT].fourcc;
2410
2411 if (msm_comm_turbo_session(inst))
2412 clk_scale_data.power_mode[num_sessions] =
2413 VIDC_POWER_TURBO;
2414 else if (is_low_power_session(inst))
2415 clk_scale_data.power_mode[num_sessions] =
2416 VIDC_POWER_LOW;
2417 else
2418 clk_scale_data.power_mode[num_sessions] =
2419 VIDC_POWER_NORMAL;
2420
2421 if (inst->dcvs_mode)
2422 clk_scale_data.load[num_sessions] = inst->dcvs.load;
2423 else
2424 clk_scale_data.load[num_sessions] =
2425 msm_comm_get_inst_load(inst, quirks);
2426
2427 clk_scale_data.session[num_sessions] =
2428 VIDC_VOTE_DATA_SESSION_VAL(
2429 get_hal_codec(codec),
2430 get_hal_domain(inst->session_type));
2431 num_sessions++;
2432
2433 if (inst->instant_bitrate > instant_bitrate)
2434 instant_bitrate = inst->instant_bitrate;
2435
2436 }
2437 clk_scale_data.num_sessions = num_sessions;
2438 mutex_unlock(&core->lock);
2439
2440
2441 rc = call_hfi_op(hdev, scale_clocks,
2442 hdev->hfi_device_data, num_mbs_per_sec,
2443 &clk_scale_data, instant_bitrate);
2444 if (rc)
2445 dprintk(VIDC_ERR, "Failed to set clock rate: %d\n", rc);
2446
2447 return rc;
2448}
2449
2450void msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst)
2451{
2452 struct msm_vidc_core *core;
2453 struct hfi_device *hdev;
2454
2455 if (!inst || !inst->core || !inst->core->device) {
2456 dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
2457 return;
2458 }
2459 core = inst->core;
2460 hdev = core->device;
2461
2462 if (msm_comm_scale_clocks(core)) {
2463 dprintk(VIDC_WARN,
2464 "Failed to scale clocks. Performance might be impacted\n");
2465 }
2466 if (msm_comm_vote_bus(core)) {
2467 dprintk(VIDC_WARN,
2468 "Failed to scale DDR bus. Performance might be impacted\n");
2469 }
2470}
2471
2472static inline enum msm_vidc_thermal_level msm_comm_vidc_thermal_level(int level)
2473{
2474 switch (level) {
2475 case 0:
2476 return VIDC_THERMAL_NORMAL;
2477 case 1:
2478 return VIDC_THERMAL_LOW;
2479 case 2:
2480 return VIDC_THERMAL_HIGH;
2481 default:
2482 return VIDC_THERMAL_CRITICAL;
2483 }
2484}
2485
2486static unsigned long msm_comm_get_clock_rate(struct msm_vidc_core *core)
2487{
2488 struct hfi_device *hdev;
2489 unsigned long freq = 0;
2490
2491 if (!core || !core->device) {
2492 dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
2493 return -EINVAL;
2494 }
2495 hdev = core->device;
2496
2497 freq = call_hfi_op(hdev, get_core_clock_rate, hdev->hfi_device_data, 1);
2498 dprintk(VIDC_DBG, "clock freq %ld\n", freq);
2499
2500 return freq;
2501}
2502
2503static bool is_core_turbo(struct msm_vidc_core *core, unsigned long freq)
2504{
2505 int i = 0;
2506 struct msm_vidc_platform_resources *res = &core->resources;
2507 struct load_freq_table *table = res->load_freq_tbl;
2508 u32 max_freq = 0;
2509
2510 for (i = 0; i < res->load_freq_tbl_size; i++) {
2511 if (max_freq < table[i].freq)
2512 max_freq = table[i].freq;
2513 }
2514 return freq >= max_freq;
2515}
2516
2517static bool is_thermal_permissible(struct msm_vidc_core *core)
2518{
2519 enum msm_vidc_thermal_level tl;
2520 unsigned long freq = 0;
2521 bool is_turbo = false;
2522
2523 if (!core->resources.thermal_mitigable)
2524 return true;
2525
2526 if (msm_vidc_thermal_mitigation_disabled) {
2527 dprintk(VIDC_DBG,
2528 "Thermal mitigation not enabled. debugfs %d\n",
2529 msm_vidc_thermal_mitigation_disabled);
2530 return true;
2531 }
2532
2533 tl = msm_comm_vidc_thermal_level(vidc_driver->thermal_level);
2534 freq = msm_comm_get_clock_rate(core);
2535
2536 is_turbo = is_core_turbo(core, freq);
2537 dprintk(VIDC_DBG,
2538 "Core freq %ld Thermal level %d Turbo mode %d\n",
2539 freq, tl, is_turbo);
2540
2541 if (is_turbo && tl >= VIDC_THERMAL_LOW) {
2542 dprintk(VIDC_ERR,
2543 "Video session not allowed. Turbo mode %d Thermal level %d\n",
2544 is_turbo, tl);
2545 return false;
2546 }
2547 return true;
2548}
2549
2550static int msm_comm_session_abort(struct msm_vidc_inst *inst)
2551{
2552 int rc = 0, abort_completion = 0;
2553 struct hfi_device *hdev;
2554
2555 if (!inst || !inst->core || !inst->core->device) {
2556 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
2557 return -EINVAL;
2558 }
2559 hdev = inst->core->device;
2560 abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE);
2561
2562 rc = call_hfi_op(hdev, session_abort, (void *)inst->session);
2563 if (rc) {
2564 dprintk(VIDC_ERR,
2565 "%s session_abort failed rc: %d\n", __func__, rc);
2566 return rc;
2567 }
2568 rc = wait_for_completion_timeout(
2569 &inst->completions[abort_completion],
2570 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
2571 if (!rc) {
2572 dprintk(VIDC_ERR,
2573 "%s: Wait interrupted or timed out [%pK]: %d\n",
2574 __func__, inst, abort_completion);
2575 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
2576 dprintk(VIDC_ERR,
2577 "ABORT timeout can potentially crash the system\n");
2578 msm_comm_print_debug_info(inst);
2579
2580 msm_vidc_handle_hw_error(inst->core);
2581 rc = -EBUSY;
2582 } else {
2583 rc = 0;
2584 }
2585 msm_comm_session_clean(inst);
2586 return rc;
2587}
2588
2589static void handle_thermal_event(struct msm_vidc_core *core)
2590{
2591 int rc = 0;
2592 struct msm_vidc_inst *inst;
2593
2594 if (!core || !core->device) {
2595 dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
2596 return;
2597 }
2598 mutex_lock(&core->lock);
2599 list_for_each_entry(inst, &core->instances, list) {
2600 if (!inst->session)
2601 continue;
2602
2603 mutex_unlock(&core->lock);
2604 if (inst->state >= MSM_VIDC_OPEN_DONE &&
2605 inst->state < MSM_VIDC_CLOSE_DONE) {
2606 dprintk(VIDC_WARN, "%s: abort inst %pK\n",
2607 __func__, inst);
2608 rc = msm_comm_session_abort(inst);
2609 if (rc) {
2610 dprintk(VIDC_ERR,
2611 "%s session_abort failed rc: %d\n",
2612 __func__, rc);
2613 goto err_sess_abort;
2614 }
2615 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
2616 dprintk(VIDC_WARN,
2617 "%s Send sys error for inst %pK\n",
2618 __func__, inst);
2619 msm_vidc_queue_v4l2_event(inst,
2620 V4L2_EVENT_MSM_VIDC_SYS_ERROR);
2621 } else {
2622 msm_comm_generate_session_error(inst);
2623 }
2624 mutex_lock(&core->lock);
2625 }
2626 mutex_unlock(&core->lock);
2627 return;
2628
2629err_sess_abort:
2630 msm_comm_clean_notify_client(core);
2631}
2632
2633void msm_comm_handle_thermal_event(void)
2634{
2635 struct msm_vidc_core *core;
2636
2637 list_for_each_entry(core, &vidc_driver->cores, list) {
2638 if (!is_thermal_permissible(core)) {
2639 dprintk(VIDC_WARN,
2640 "Thermal level critical, stop all active sessions!\n");
2641 handle_thermal_event(core);
2642 }
2643 }
2644}
2645
2646int msm_comm_check_core_init(struct msm_vidc_core *core)
2647{
2648 int rc = 0;
2649 struct hfi_device *hdev;
2650 struct msm_vidc_inst *inst = NULL;
2651
2652 mutex_lock(&core->lock);
2653 if (core->state >= VIDC_CORE_INIT_DONE) {
2654 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
2655 core->id, core->state);
2656 goto exit;
2657 }
2658 dprintk(VIDC_DBG, "Waiting for SYS_INIT_DONE\n");
2659 hdev = (struct hfi_device *)core->device;
2660 rc = wait_for_completion_timeout(
2661 &core->completions[SYS_MSG_INDEX(HAL_SYS_INIT_DONE)],
2662 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
2663 if (!rc) {
2664 dprintk(VIDC_ERR, "%s: Wait interrupted or timed out: %d\n",
2665 __func__, SYS_MSG_INDEX(HAL_SYS_INIT_DONE));
2666 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
2667 dprintk(VIDC_ERR,
2668 "SYS_INIT timeout can potentially crash the system\n");
2669 /*
2670 * For SYS_INIT, there will not be any inst pointer.
2671 * Just grab one of the inst from instances list and
2672 * use it.
2673 */
2674 inst = list_first_entry(&core->instances,
2675 struct msm_vidc_inst, list);
2676
2677 mutex_unlock(&core->lock);
2678 msm_comm_print_debug_info(inst);
2679 mutex_lock(&core->lock);
2680
2681 msm_vidc_handle_hw_error(core);
2682 rc = -EIO;
2683 goto exit;
2684 } else {
2685 core->state = VIDC_CORE_INIT_DONE;
2686 rc = 0;
2687 }
2688 dprintk(VIDC_DBG, "SYS_INIT_DONE!!!\n");
2689exit:
2690 mutex_unlock(&core->lock);
2691 return rc;
2692}
2693
2694static int msm_comm_init_core_done(struct msm_vidc_inst *inst)
2695{
2696 int rc = 0;
2697
2698 rc = msm_comm_check_core_init(inst->core);
2699 if (rc) {
2700 dprintk(VIDC_ERR, "%s - failed to initialize core\n", __func__);
2701 msm_comm_generate_sys_error(inst);
2702 return rc;
2703 }
2704 change_inst_state(inst, MSM_VIDC_CORE_INIT_DONE);
2705 return rc;
2706}
2707
2708static int msm_comm_init_core(struct msm_vidc_inst *inst)
2709{
2710 int rc = 0;
2711 struct hfi_device *hdev;
2712 struct msm_vidc_core *core;
2713
2714 if (!inst || !inst->core || !inst->core->device)
2715 return -EINVAL;
2716
2717 core = inst->core;
2718 hdev = core->device;
2719 mutex_lock(&core->lock);
2720 if (core->state >= VIDC_CORE_INIT) {
2721 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
2722 core->id, core->state);
2723 goto core_already_inited;
2724 }
2725 if (!core->capabilities) {
2726 core->capabilities = kzalloc(VIDC_MAX_SESSIONS *
2727 sizeof(struct msm_vidc_capability), GFP_KERNEL);
2728 if (!core->capabilities) {
2729 dprintk(VIDC_ERR,
2730 "%s: failed to allocate capabilities\n",
2731 __func__);
2732 rc = -ENOMEM;
2733 goto fail_cap_alloc;
2734 }
2735 } else {
2736 dprintk(VIDC_WARN,
2737 "%s: capabilities memory is expected to be freed\n",
2738 __func__);
2739 }
2740
2741 rc = call_hfi_op(hdev, core_init, hdev->hfi_device_data);
2742 if (rc) {
2743 dprintk(VIDC_ERR, "Failed to init core, id = %d\n",
2744 core->id);
2745 goto fail_core_init;
2746 }
2747 core->state = VIDC_CORE_INIT;
2748 core->smmu_fault_handled = false;
2749core_already_inited:
2750 change_inst_state(inst, MSM_VIDC_CORE_INIT);
2751 mutex_unlock(&core->lock);
2752 return rc;
2753
2754fail_core_init:
2755 kfree(core->capabilities);
2756fail_cap_alloc:
2757 core->capabilities = NULL;
2758 core->state = VIDC_CORE_UNINIT;
2759 mutex_unlock(&core->lock);
2760 return rc;
2761}
2762
2763static int msm_vidc_deinit_core(struct msm_vidc_inst *inst)
2764{
2765 struct msm_vidc_core *core;
2766 struct hfi_device *hdev;
2767
2768 if (!inst || !inst->core || !inst->core->device) {
2769 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
2770 return -EINVAL;
2771 }
2772
2773 core = inst->core;
2774 hdev = core->device;
2775
2776 mutex_lock(&core->lock);
2777 if (core->state == VIDC_CORE_UNINIT) {
2778 dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n",
2779 core->id, core->state);
2780 goto core_already_uninited;
2781 }
2782 mutex_unlock(&core->lock);
2783
2784 msm_comm_scale_clocks_and_bus(inst);
2785
2786 mutex_lock(&core->lock);
2787
2788 if (!core->resources.never_unload_fw) {
2789 cancel_delayed_work(&core->fw_unload_work);
2790
2791 /*
2792 * Delay unloading of firmware. This is useful
2793 * in avoiding firmware download delays in cases where we
2794 * will have a burst of back to back video playback sessions
2795 * e.g. thumbnail generation.
2796 */
2797 schedule_delayed_work(&core->fw_unload_work,
2798 msecs_to_jiffies(core->state == VIDC_CORE_INVALID ?
2799 0 : msm_vidc_firmware_unload_delay));
2800
2801 dprintk(VIDC_DBG, "firmware unload delayed by %u ms\n",
2802 core->state == VIDC_CORE_INVALID ?
2803 0 : msm_vidc_firmware_unload_delay);
2804 }
2805
2806core_already_uninited:
2807 change_inst_state(inst, MSM_VIDC_CORE_UNINIT);
2808 mutex_unlock(&core->lock);
2809 return 0;
2810}
2811
2812int msm_comm_force_cleanup(struct msm_vidc_inst *inst)
2813{
2814 msm_comm_kill_session(inst);
2815 return msm_vidc_deinit_core(inst);
2816}
2817
2818static int msm_comm_session_init(int flipped_state,
2819 struct msm_vidc_inst *inst)
2820{
2821 int rc = 0;
2822 int fourcc = 0;
2823 struct hfi_device *hdev;
2824
2825 if (!inst || !inst->core || !inst->core->device) {
2826 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
2827 return -EINVAL;
2828 }
2829 hdev = inst->core->device;
2830
2831 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) {
2832 dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n",
2833 inst, inst->state);
2834 goto exit;
2835 }
2836 if (inst->session_type == MSM_VIDC_DECODER) {
2837 fourcc = inst->fmts[OUTPUT_PORT].fourcc;
2838 } else if (inst->session_type == MSM_VIDC_ENCODER) {
2839 fourcc = inst->fmts[CAPTURE_PORT].fourcc;
2840 } else {
2841 dprintk(VIDC_ERR, "Invalid session\n");
2842 return -EINVAL;
2843 }
2844
2845 rc = call_hfi_op(hdev, session_init, hdev->hfi_device_data,
2846 inst, get_hal_domain(inst->session_type),
2847 get_hal_codec(fourcc),
2848 &inst->session);
2849
2850 if (rc || !inst->session) {
2851 dprintk(VIDC_ERR,
2852 "Failed to call session init for: %pK, %pK, %d, %d\n",
2853 inst->core->device, inst,
2854 inst->session_type, fourcc);
2855 rc = -EINVAL;
2856 goto exit;
2857 }
2858 change_inst_state(inst, MSM_VIDC_OPEN);
2859exit:
2860 return rc;
2861}
2862
2863static void msm_vidc_print_running_insts(struct msm_vidc_core *core)
2864{
2865 struct msm_vidc_inst *temp;
2866
2867 dprintk(VIDC_ERR, "Running instances:\n");
2868 dprintk(VIDC_ERR, "%4s|%4s|%4s|%4s|%4s\n",
2869 "type", "w", "h", "fps", "prop");
2870
2871 mutex_lock(&core->lock);
2872 list_for_each_entry(temp, &core->instances, list) {
2873 if (temp->state >= MSM_VIDC_OPEN_DONE &&
2874 temp->state < MSM_VIDC_STOP_DONE) {
2875 char properties[4] = "";
2876
2877 if (is_thumbnail_session(temp))
2878 strlcat(properties, "N", sizeof(properties));
2879
2880 if (msm_comm_turbo_session(temp))
2881 strlcat(properties, "T", sizeof(properties));
2882
2883 dprintk(VIDC_ERR, "%4d|%4d|%4d|%4d|%4s\n",
2884 temp->session_type,
2885 max(temp->prop.width[CAPTURE_PORT],
2886 temp->prop.width[OUTPUT_PORT]),
2887 max(temp->prop.height[CAPTURE_PORT],
2888 temp->prop.height[OUTPUT_PORT]),
2889 temp->prop.fps, properties);
2890 }
2891 }
2892 mutex_unlock(&core->lock);
2893}
2894
2895static int msm_vidc_load_resources(int flipped_state,
2896 struct msm_vidc_inst *inst)
2897{
2898 int rc = 0;
2899 struct hfi_device *hdev;
2900 int num_mbs_per_sec = 0, max_load_adj = 0;
2901 struct msm_vidc_core *core;
2902 enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD |
2903 LOAD_CALC_IGNORE_THUMBNAIL_LOAD |
2904 LOAD_CALC_IGNORE_NON_REALTIME_LOAD;
2905
2906 if (!inst || !inst->core || !inst->core->device) {
2907 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
2908 return -EINVAL;
2909 }
2910
2911 core = inst->core;
2912 if (core->state == VIDC_CORE_INVALID) {
2913 dprintk(VIDC_ERR,
2914 "Core is in bad state can't do load res\n");
2915 return -EINVAL;
2916 }
2917
2918 if (inst->state == MSM_VIDC_CORE_INVALID) {
2919 dprintk(VIDC_ERR,
2920 "Instance is in invalid state can't do load res\n");
2921 return -EINVAL;
2922 }
2923
2924 num_mbs_per_sec =
2925 msm_comm_get_load(core, MSM_VIDC_DECODER, quirks) +
2926 msm_comm_get_load(core, MSM_VIDC_ENCODER, quirks);
2927
2928 max_load_adj = core->resources.max_load +
2929 inst->capability.mbs_per_frame.max;
2930
2931 if (num_mbs_per_sec > max_load_adj) {
2932 dprintk(VIDC_ERR, "HW is overloaded, needed: %d max: %d\n",
2933 num_mbs_per_sec, max_load_adj);
2934 msm_vidc_print_running_insts(core);
2935 inst->state = MSM_VIDC_CORE_INVALID;
2936 msm_comm_kill_session(inst);
2937 return -EBUSY;
2938 }
2939
2940 hdev = core->device;
2941 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) {
2942 dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n",
2943 inst, inst->state);
2944 goto exit;
2945 }
2946
2947 rc = call_hfi_op(hdev, session_load_res, (void *) inst->session);
2948 if (rc) {
2949 dprintk(VIDC_ERR,
2950 "Failed to send load resources\n");
2951 goto exit;
2952 }
2953 change_inst_state(inst, MSM_VIDC_LOAD_RESOURCES);
2954exit:
2955 return rc;
2956}
2957
2958static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst)
2959{
2960 int rc = 0;
2961 struct hfi_device *hdev;
2962
2963 if (!inst || !inst->core || !inst->core->device) {
2964 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
2965 return -EINVAL;
2966 }
2967 if (inst->state == MSM_VIDC_CORE_INVALID ||
2968 inst->core->state == VIDC_CORE_INVALID) {
2969 dprintk(VIDC_ERR,
2970 "Core is in bad state can't do start\n");
2971 return -EINVAL;
2972 }
2973
2974 hdev = inst->core->device;
2975
2976 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) {
2977 dprintk(VIDC_INFO,
2978 "inst: %pK is already in state: %d\n",
2979 inst, inst->state);
2980 goto exit;
2981 }
2982 rc = call_hfi_op(hdev, session_start, (void *) inst->session);
2983 if (rc) {
2984 dprintk(VIDC_ERR,
2985 "Failed to send start\n");
2986 goto exit;
2987 }
2988 change_inst_state(inst, MSM_VIDC_START);
2989exit:
2990 return rc;
2991}
2992
2993static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst)
2994{
2995 int rc = 0;
2996 struct hfi_device *hdev;
2997
2998 if (!inst || !inst->core || !inst->core->device) {
2999 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3000 return -EINVAL;
3001 }
3002 hdev = inst->core->device;
3003
3004 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) {
3005 dprintk(VIDC_INFO,
3006 "inst: %pK is already in state: %d\n",
3007 inst, inst->state);
3008 goto exit;
3009 }
3010 dprintk(VIDC_DBG, "Send Stop to hal\n");
3011 rc = call_hfi_op(hdev, session_stop, (void *) inst->session);
3012 if (rc) {
3013 dprintk(VIDC_ERR, "Failed to send stop\n");
3014 goto exit;
3015 }
3016 change_inst_state(inst, MSM_VIDC_STOP);
3017exit:
3018 return rc;
3019}
3020
3021static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst)
3022{
3023 int rc = 0;
3024 struct hfi_device *hdev;
3025
3026 if (!inst || !inst->core || !inst->core->device) {
3027 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3028 return -EINVAL;
3029 }
3030 hdev = inst->core->device;
3031
3032 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) {
3033 dprintk(VIDC_INFO,
3034 "inst: %pK is already in state: %d\n",
3035 inst, inst->state);
3036 goto exit;
3037 }
3038 dprintk(VIDC_DBG,
3039 "Send release res to hal\n");
3040 rc = call_hfi_op(hdev, session_release_res, (void *) inst->session);
3041 if (rc) {
3042 dprintk(VIDC_ERR,
3043 "Failed to send release resources\n");
3044 goto exit;
3045 }
3046 change_inst_state(inst, MSM_VIDC_RELEASE_RESOURCES);
3047exit:
3048 return rc;
3049}
3050
3051static int msm_comm_session_close(int flipped_state,
3052 struct msm_vidc_inst *inst)
3053{
3054 int rc = 0;
3055 struct hfi_device *hdev;
3056
3057 if (!inst || !inst->core || !inst->core->device) {
3058 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
3059 return -EINVAL;
3060 }
3061 hdev = inst->core->device;
3062 if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) {
3063 dprintk(VIDC_INFO,
3064 "inst: %pK is already in state: %d\n",
3065 inst, inst->state);
3066 goto exit;
3067 }
3068 dprintk(VIDC_DBG,
3069 "Send session close to hal\n");
3070 rc = call_hfi_op(hdev, session_end, (void *) inst->session);
3071 if (rc) {
3072 dprintk(VIDC_ERR,
3073 "Failed to send close\n");
3074 goto exit;
3075 }
3076 change_inst_state(inst, MSM_VIDC_CLOSE);
3077exit:
3078 return rc;
3079}
3080
3081int msm_comm_suspend(int core_id)
3082{
3083 struct hfi_device *hdev;
3084 struct msm_vidc_core *core;
3085 int rc = 0;
3086
3087 core = get_vidc_core(core_id);
3088 if (!core) {
3089 dprintk(VIDC_ERR,
3090 "%s: Failed to find core for core_id = %d\n",
3091 __func__, core_id);
3092 return -EINVAL;
3093 }
3094
3095 hdev = (struct hfi_device *)core->device;
3096 if (!hdev) {
3097 dprintk(VIDC_ERR, "%s Invalid device handle\n", __func__);
3098 return -EINVAL;
3099 }
3100
3101 mutex_lock(&core->lock);
3102 if (core->state == VIDC_CORE_INVALID) {
3103 dprintk(VIDC_ERR,
3104 "%s - fw is not in proper state, skip suspend\n",
3105 __func__);
3106 rc = -EINVAL;
3107 goto exit;
3108 }
3109
3110 rc = call_hfi_op(hdev, suspend, hdev->hfi_device_data);
3111 if (rc)
3112 dprintk(VIDC_WARN, "Failed to suspend\n");
3113
3114exit:
3115 mutex_unlock(&core->lock);
3116 return rc;
3117}
3118
3119static int get_flipped_state(int present_state,
3120 int desired_state)
3121{
3122 int flipped_state = present_state;
3123
3124 if (flipped_state < MSM_VIDC_STOP
3125 && desired_state > MSM_VIDC_STOP) {
3126 flipped_state = MSM_VIDC_STOP + (MSM_VIDC_STOP - flipped_state);
3127 flipped_state &= 0xFFFE;
3128 flipped_state = flipped_state - 1;
3129 } else if (flipped_state > MSM_VIDC_STOP
3130 && desired_state < MSM_VIDC_STOP) {
3131 flipped_state = MSM_VIDC_STOP -
3132 (flipped_state - MSM_VIDC_STOP + 1);
3133 flipped_state &= 0xFFFE;
3134 flipped_state = flipped_state - 1;
3135 }
3136 return flipped_state;
3137}
3138
3139struct hal_buffer_requirements *get_buff_req_buffer(
3140 struct msm_vidc_inst *inst, enum hal_buffer buffer_type)
3141{
3142 int i;
3143
3144 for (i = 0; i < HAL_BUFFER_MAX; i++) {
3145 if (inst->buff_req.buffer[i].buffer_type == buffer_type)
3146 return &inst->buff_req.buffer[i];
3147 }
3148 return NULL;
3149}
3150
3151static int set_output_buffers(struct msm_vidc_inst *inst,
3152 enum hal_buffer buffer_type)
3153{
3154 int rc = 0;
3155 struct msm_smem *handle;
3156 struct internal_buf *binfo;
3157 u32 smem_flags = 0, buffer_size;
3158 struct hal_buffer_requirements *output_buf, *extradata_buf;
3159 int i;
3160 struct hfi_device *hdev;
3161 struct hal_buffer_size_minimum b;
3162
3163 hdev = inst->core->device;
3164
3165 output_buf = get_buff_req_buffer(inst, buffer_type);
3166 if (!output_buf) {
3167 dprintk(VIDC_DBG,
3168 "This output buffer not required, buffer_type: %x\n",
3169 buffer_type);
3170 return 0;
3171 }
3172 dprintk(VIDC_DBG,
3173 "output: num = %d, size = %d\n",
3174 output_buf->buffer_count_actual,
3175 output_buf->buffer_size);
3176
3177 buffer_size = output_buf->buffer_size;
3178 b.buffer_type = buffer_type;
3179 b.buffer_size = buffer_size;
3180 rc = call_hfi_op(hdev, session_set_property,
3181 inst->session, HAL_PARAM_BUFFER_SIZE_MINIMUM,
3182 &b);
3183
3184 extradata_buf = get_buff_req_buffer(inst, HAL_BUFFER_EXTRADATA_OUTPUT);
3185 if (extradata_buf) {
3186 dprintk(VIDC_DBG,
3187 "extradata: num = %d, size = %d\n",
3188 extradata_buf->buffer_count_actual,
3189 extradata_buf->buffer_size);
3190 buffer_size += extradata_buf->buffer_size;
3191 } else {
3192 dprintk(VIDC_DBG,
3193 "This extradata buffer not required, buffer_type: %x\n",
3194 buffer_type);
3195 }
3196
3197 if (inst->flags & VIDC_SECURE)
3198 smem_flags |= SMEM_SECURE;
3199
3200 if (output_buf->buffer_size) {
3201 for (i = 0; i < output_buf->buffer_count_actual;
3202 i++) {
3203 handle = msm_comm_smem_alloc(inst,
3204 buffer_size, 1, smem_flags,
3205 buffer_type, 0);
3206 if (!handle) {
3207 dprintk(VIDC_ERR,
3208 "Failed to allocate output memory\n");
3209 rc = -ENOMEM;
3210 goto err_no_mem;
3211 }
3212 rc = msm_comm_smem_cache_operations(inst,
3213 handle, SMEM_CACHE_CLEAN);
3214 if (rc) {
3215 dprintk(VIDC_WARN,
3216 "Failed to clean cache may cause undefined behavior\n");
3217 }
3218 binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
3219 if (!binfo) {
3220 dprintk(VIDC_ERR, "Out of memory\n");
3221 rc = -ENOMEM;
3222 goto fail_kzalloc;
3223 }
3224
3225 binfo->handle = handle;
3226 binfo->buffer_type = buffer_type;
3227 binfo->buffer_ownership = DRIVER;
3228 dprintk(VIDC_DBG, "Output buffer address: %pa\n",
3229 &handle->device_addr);
3230
3231 if (inst->buffer_mode_set[CAPTURE_PORT] ==
3232 HAL_BUFFER_MODE_STATIC) {
3233 struct vidc_buffer_addr_info buffer_info = {0};
3234
3235 buffer_info.buffer_size =
3236 output_buf->buffer_size;
3237 buffer_info.buffer_type = buffer_type;
3238 buffer_info.num_buffers = 1;
3239 buffer_info.align_device_addr =
3240 handle->device_addr;
3241 buffer_info.extradata_addr =
3242 handle->device_addr +
3243 output_buf->buffer_size;
3244 if (extradata_buf)
3245 buffer_info.extradata_size =
3246 extradata_buf->buffer_size;
3247 rc = call_hfi_op(hdev, session_set_buffers,
3248 (void *) inst->session, &buffer_info);
3249 if (rc) {
3250 dprintk(VIDC_ERR,
3251 "%s : session_set_buffers failed\n",
3252 __func__);
3253 goto fail_set_buffers;
3254 }
3255 }
3256 mutex_lock(&inst->outputbufs.lock);
3257 list_add_tail(&binfo->list, &inst->outputbufs.list);
3258 mutex_unlock(&inst->outputbufs.lock);
3259 }
3260 }
3261 return rc;
3262fail_set_buffers:
3263 kfree(binfo);
3264fail_kzalloc:
3265 msm_comm_smem_free(inst, handle);
3266err_no_mem:
3267 return rc;
3268}
3269
3270static inline char *get_buffer_name(enum hal_buffer buffer_type)
3271{
3272 switch (buffer_type) {
3273 case HAL_BUFFER_INPUT: return "input";
3274 case HAL_BUFFER_OUTPUT: return "output";
3275 case HAL_BUFFER_OUTPUT2: return "output_2";
3276 case HAL_BUFFER_EXTRADATA_INPUT: return "input_extra";
3277 case HAL_BUFFER_EXTRADATA_OUTPUT: return "output_extra";
3278 case HAL_BUFFER_EXTRADATA_OUTPUT2: return "output2_extra";
3279 case HAL_BUFFER_INTERNAL_SCRATCH: return "scratch";
3280 case HAL_BUFFER_INTERNAL_SCRATCH_1: return "scratch_1";
3281 case HAL_BUFFER_INTERNAL_SCRATCH_2: return "scratch_2";
3282 case HAL_BUFFER_INTERNAL_PERSIST: return "persist";
3283 case HAL_BUFFER_INTERNAL_PERSIST_1: return "persist_1";
3284 case HAL_BUFFER_INTERNAL_CMD_QUEUE: return "queue";
3285 default: return "????";
3286 }
3287}
3288
3289static int set_internal_buf_on_fw(struct msm_vidc_inst *inst,
3290 enum hal_buffer buffer_type,
3291 struct msm_smem *handle, bool reuse)
3292{
3293 struct vidc_buffer_addr_info buffer_info;
3294 struct hfi_device *hdev;
3295 int rc = 0;
3296
3297 if (!inst || !inst->core || !inst->core->device || !handle) {
3298 dprintk(VIDC_ERR, "%s - invalid params\n", __func__);
3299 return -EINVAL;
3300 }
3301
3302 hdev = inst->core->device;
3303
3304 rc = msm_comm_smem_cache_operations(inst,
3305 handle, SMEM_CACHE_CLEAN);
3306 if (rc) {
3307 dprintk(VIDC_WARN,
3308 "Failed to clean cache. Undefined behavior\n");
3309 }
3310
3311 buffer_info.buffer_size = handle->size;
3312 buffer_info.buffer_type = buffer_type;
3313 buffer_info.num_buffers = 1;
3314 buffer_info.align_device_addr = handle->device_addr;
3315 dprintk(VIDC_DBG, "%s %s buffer : %pa\n",
3316 reuse ? "Reusing" : "Allocated",
3317 get_buffer_name(buffer_type),
3318 &buffer_info.align_device_addr);
3319
3320 rc = call_hfi_op(hdev, session_set_buffers,
3321 (void *) inst->session, &buffer_info);
3322 if (rc) {
3323 dprintk(VIDC_ERR,
3324 "vidc_hal_session_set_buffers failed\n");
3325 return rc;
3326 }
3327 return 0;
3328}
3329
3330static bool reuse_internal_buffers(struct msm_vidc_inst *inst,
3331 enum hal_buffer buffer_type, struct msm_vidc_list *buf_list)
3332{
3333 struct internal_buf *buf;
3334 int rc = 0;
3335 bool reused = false;
3336
3337 if (!inst || !buf_list) {
3338 dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
3339 return false;
3340 }
3341
3342 mutex_lock(&buf_list->lock);
3343 list_for_each_entry(buf, &buf_list->list, list) {
3344 if (!buf->handle) {
3345 reused = false;
3346 break;
3347 }
3348
3349 if (buf->buffer_type != buffer_type)
3350 continue;
3351
3352 /*
3353 * Persist buffer size won't change with resolution. If they
3354 * are in queue means that they are already allocated and
3355 * given to HW. HW can use them without reallocation. These
3356 * buffers are not released as part of port reconfig. So
3357 * driver no need to set them again.
3358 */
3359
3360 if (buffer_type != HAL_BUFFER_INTERNAL_PERSIST
3361 && buffer_type != HAL_BUFFER_INTERNAL_PERSIST_1) {
3362
3363 rc = set_internal_buf_on_fw(inst, buffer_type,
3364 buf->handle, true);
3365 if (rc) {
3366 dprintk(VIDC_ERR,
3367 "%s: session_set_buffers failed\n",
3368 __func__);
3369 reused = false;
3370 break;
3371 }
3372 }
3373 reused = true;
3374 dprintk(VIDC_DBG,
3375 "Re-using internal buffer type : %d\n", buffer_type);
3376 }
3377 mutex_unlock(&buf_list->lock);
3378 return reused;
3379}
3380
3381static int allocate_and_set_internal_bufs(struct msm_vidc_inst *inst,
3382 struct hal_buffer_requirements *internal_bufreq,
3383 struct msm_vidc_list *buf_list)
3384{
3385 struct msm_smem *handle;
3386 struct internal_buf *binfo;
3387 u32 smem_flags = 0;
3388 int rc = 0;
3389 int i = 0;
3390
3391 if (!inst || !internal_bufreq || !buf_list)
3392 return -EINVAL;
3393
3394 if (!internal_bufreq->buffer_size)
3395 return 0;
3396
3397 if (inst->flags & VIDC_SECURE)
3398 smem_flags |= SMEM_SECURE;
3399
3400 for (i = 0; i < internal_bufreq->buffer_count_actual; i++) {
3401 handle = msm_comm_smem_alloc(inst, internal_bufreq->buffer_size,
3402 1, smem_flags, internal_bufreq->buffer_type, 0);
3403 if (!handle) {
3404 dprintk(VIDC_ERR,
3405 "Failed to allocate scratch memory\n");
3406 rc = -ENOMEM;
3407 goto err_no_mem;
3408 }
3409
3410 binfo = kzalloc(sizeof(*binfo), GFP_KERNEL);
3411 if (!binfo) {
3412 dprintk(VIDC_ERR, "Out of memory\n");
3413 rc = -ENOMEM;
3414 goto fail_kzalloc;
3415 }
3416
3417 binfo->handle = handle;
3418 binfo->buffer_type = internal_bufreq->buffer_type;
3419
3420 rc = set_internal_buf_on_fw(inst, internal_bufreq->buffer_type,
3421 handle, false);
3422 if (rc)
3423 goto fail_set_buffers;
3424
3425 mutex_lock(&buf_list->lock);
3426 list_add_tail(&binfo->list, &buf_list->list);
3427 mutex_unlock(&buf_list->lock);
3428 }
3429 return rc;
3430
3431fail_set_buffers:
3432 kfree(binfo);
3433fail_kzalloc:
3434 msm_comm_smem_free(inst, handle);
3435err_no_mem:
3436 return rc;
3437
3438}
3439
3440static int set_internal_buffers(struct msm_vidc_inst *inst,
3441 enum hal_buffer buffer_type, struct msm_vidc_list *buf_list)
3442{
3443 struct hal_buffer_requirements *internal_buf;
3444
3445 internal_buf = get_buff_req_buffer(inst, buffer_type);
3446 if (!internal_buf) {
3447 dprintk(VIDC_DBG,
3448 "This internal buffer not required, buffer_type: %x\n",
3449 buffer_type);
3450 return 0;
3451 }
3452
3453 dprintk(VIDC_DBG, "Buffer type %s: num = %d, size = %d\n",
3454 get_buffer_name(buffer_type),
3455 internal_buf->buffer_count_actual, internal_buf->buffer_size);
3456
3457 /*
3458 * Try reusing existing internal buffers first.
3459 * If it's not possible to reuse, allocate new buffers.
3460 */
3461 if (reuse_internal_buffers(inst, buffer_type, buf_list))
3462 return 0;
3463
3464 return allocate_and_set_internal_bufs(inst, internal_buf,
3465 buf_list);
3466}
3467
3468int msm_comm_try_state(struct msm_vidc_inst *inst, int state)
3469{
3470 int rc = 0;
3471 int flipped_state;
3472 struct msm_vidc_core *core;
3473
3474 if (!inst) {
3475 dprintk(VIDC_ERR,
3476 "Invalid instance pointer = %pK\n", inst);
3477 return -EINVAL;
3478 }
3479 dprintk(VIDC_DBG,
3480 "Trying to move inst: %pK from: %#x to %#x\n",
3481 inst, inst->state, state);
3482 core = inst->core;
3483 if (!core) {
3484 dprintk(VIDC_ERR,
3485 "Invalid core pointer = %pK\n", inst);
3486 return -EINVAL;
3487 }
3488 mutex_lock(&inst->sync_lock);
3489 if (inst->state == MSM_VIDC_CORE_INVALID ||
3490 core->state == VIDC_CORE_INVALID) {
3491 dprintk(VIDC_ERR,
3492 "Core is in bad state can't change the state\n");
3493 rc = -EINVAL;
3494 goto exit;
3495 }
3496 flipped_state = get_flipped_state(inst->state, state);
3497 dprintk(VIDC_DBG,
3498 "flipped_state = %#x\n", flipped_state);
3499 switch (flipped_state) {
3500 case MSM_VIDC_CORE_UNINIT_DONE:
3501 case MSM_VIDC_CORE_INIT:
3502 rc = msm_comm_init_core(inst);
3503 if (rc || state <= get_flipped_state(inst->state, state))
3504 break;
3505 case MSM_VIDC_CORE_INIT_DONE:
3506 rc = msm_comm_init_core_done(inst);
3507 if (rc || state <= get_flipped_state(inst->state, state))
3508 break;
3509 case MSM_VIDC_OPEN:
3510 rc = msm_comm_session_init(flipped_state, inst);
3511 if (rc || state <= get_flipped_state(inst->state, state))
3512 break;
3513 case MSM_VIDC_OPEN_DONE:
3514 rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE,
3515 HAL_SESSION_INIT_DONE);
3516 if (rc || state <= get_flipped_state(inst->state, state))
3517 break;
3518 case MSM_VIDC_LOAD_RESOURCES:
3519 rc = msm_vidc_load_resources(flipped_state, inst);
3520 if (rc || state <= get_flipped_state(inst->state, state))
3521 break;
3522 case MSM_VIDC_LOAD_RESOURCES_DONE:
3523 case MSM_VIDC_START:
3524 rc = msm_vidc_start(flipped_state, inst);
3525 if (rc || state <= get_flipped_state(inst->state, state))
3526 break;
3527 case MSM_VIDC_START_DONE:
3528 rc = wait_for_state(inst, flipped_state, MSM_VIDC_START_DONE,
3529 HAL_SESSION_START_DONE);
3530 if (rc || state <= get_flipped_state(inst->state, state))
3531 break;
3532 case MSM_VIDC_STOP:
3533 rc = msm_vidc_stop(flipped_state, inst);
3534 if (rc || state <= get_flipped_state(inst->state, state))
3535 break;
3536 case MSM_VIDC_STOP_DONE:
3537 rc = wait_for_state(inst, flipped_state, MSM_VIDC_STOP_DONE,
3538 HAL_SESSION_STOP_DONE);
3539 if (rc || state <= get_flipped_state(inst->state, state))
3540 break;
3541 dprintk(VIDC_DBG, "Moving to Stop Done state\n");
3542 case MSM_VIDC_RELEASE_RESOURCES:
3543 rc = msm_vidc_release_res(flipped_state, inst);
3544 if (rc || state <= get_flipped_state(inst->state, state))
3545 break;
3546 case MSM_VIDC_RELEASE_RESOURCES_DONE:
3547 rc = wait_for_state(inst, flipped_state,
3548 MSM_VIDC_RELEASE_RESOURCES_DONE,
3549 HAL_SESSION_RELEASE_RESOURCE_DONE);
3550 if (rc || state <= get_flipped_state(inst->state, state))
3551 break;
3552 dprintk(VIDC_DBG,
3553 "Moving to release resources done state\n");
3554 case MSM_VIDC_CLOSE:
3555 rc = msm_comm_session_close(flipped_state, inst);
3556 if (rc || state <= get_flipped_state(inst->state, state))
3557 break;
3558 case MSM_VIDC_CLOSE_DONE:
3559 rc = wait_for_state(inst, flipped_state, MSM_VIDC_CLOSE_DONE,
3560 HAL_SESSION_END_DONE);
3561 if (rc || state <= get_flipped_state(inst->state, state))
3562 break;
3563 msm_comm_session_clean(inst);
3564 case MSM_VIDC_CORE_UNINIT:
3565 case MSM_VIDC_CORE_INVALID:
3566 dprintk(VIDC_DBG, "Sending core uninit\n");
3567 rc = msm_vidc_deinit_core(inst);
3568 if (rc || state == get_flipped_state(inst->state, state))
3569 break;
3570 default:
3571 dprintk(VIDC_ERR, "State not recognized\n");
3572 rc = -EINVAL;
3573 break;
3574 }
3575exit:
3576 mutex_unlock(&inst->sync_lock);
3577 if (rc)
3578 dprintk(VIDC_ERR,
3579 "Failed to move from state: %d to %d\n",
3580 inst->state, state);
3581 else
3582 trace_msm_vidc_common_state_change((void *)inst,
3583 inst->state, state);
3584 return rc;
3585}
3586
3587int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd)
3588{
3589 struct msm_vidc_inst *inst = instance;
3590 struct v4l2_decoder_cmd *dec = NULL;
3591 struct v4l2_encoder_cmd *enc = NULL;
3592 struct msm_vidc_core *core;
3593 int which_cmd = 0, flags = 0, rc = 0;
3594
3595 if (!inst || !inst->core || !cmd) {
3596 dprintk(VIDC_ERR, "%s invalid params\n", __func__);
3597 return -EINVAL;
3598 }
3599 core = inst->core;
3600 if (inst->session_type == MSM_VIDC_ENCODER) {
3601 enc = (struct v4l2_encoder_cmd *)cmd;
3602 which_cmd = enc->cmd;
3603 flags = enc->flags;
3604 } else if (inst->session_type == MSM_VIDC_DECODER) {
3605 dec = (struct v4l2_decoder_cmd *)cmd;
3606 which_cmd = dec->cmd;
3607 flags = dec->flags;
3608 }
3609
3610
3611 switch (which_cmd) {
3612 case V4L2_QCOM_CMD_FLUSH:
3613 if (core->state != VIDC_CORE_INVALID &&
3614 inst->state == MSM_VIDC_CORE_INVALID) {
3615 rc = msm_comm_kill_session(inst);
3616 if (rc)
3617 dprintk(VIDC_ERR,
3618 "Fail to clean session: %d\n",
3619 rc);
3620 }
3621 rc = msm_comm_flush(inst, flags);
3622 if (rc) {
3623 dprintk(VIDC_ERR,
3624 "Failed to flush buffers: %d\n", rc);
3625 }
3626 break;
3627 case V4L2_DEC_QCOM_CMD_RECONFIG_HINT:
3628 {
3629 u32 *ptr = NULL;
3630 struct hal_buffer_requirements *output_buf;
3631
3632 rc = msm_comm_try_get_bufreqs(inst);
3633 if (rc) {
3634 dprintk(VIDC_ERR,
3635 "Getting buffer requirements failed: %d\n",
3636 rc);
3637 break;
3638 }
3639
3640 output_buf = get_buff_req_buffer(inst,
3641 msm_comm_get_hal_output_buffer(inst));
3642 if (output_buf) {
3643 if (dec) {
3644 ptr = (u32 *)dec->raw.data;
3645 ptr[0] = output_buf->buffer_size;
3646 ptr[1] = output_buf->buffer_count_actual;
3647 dprintk(VIDC_DBG,
3648 "Reconfig hint, size is %u, count is %u\n",
3649 ptr[0], ptr[1]);
3650 } else {
3651 dprintk(VIDC_ERR, "Null decoder\n");
3652 }
3653 } else {
3654 dprintk(VIDC_DBG,
3655 "This output buffer not required, buffer_type: %x\n",
3656 HAL_BUFFER_OUTPUT);
3657 }
3658 break;
3659 }
3660 default:
3661 dprintk(VIDC_ERR, "Unknown Command %d\n", which_cmd);
3662 rc = -ENOTSUPP;
3663 break;
3664 }
3665 return rc;
3666}
3667
3668static void populate_frame_data(struct vidc_frame_data *data,
3669 const struct vb2_buffer *vb, struct msm_vidc_inst *inst)
3670{
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003671 int extra_idx;
3672 enum v4l2_buf_type type = vb->type;
3673 enum vidc_ports port = type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
3674 OUTPUT_PORT : CAPTURE_PORT;
3675 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
3676
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003677 data->alloc_len = vb->planes[0].length;
3678 data->device_addr = vb->planes[0].m.userptr;
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08003679 data->timestamp = vb->timestamp;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003680 data->flags = 0;
3681 data->clnt_data = data->device_addr;
3682
3683 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
3684 bool pic_decoding_mode = msm_comm_g_ctrl_for_id(inst,
3685 V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE);
3686
3687 data->buffer_type = HAL_BUFFER_INPUT;
3688 data->filled_len = vb->planes[0].bytesused;
3689 data->offset = vb->planes[0].data_offset;
3690
3691 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_EOS)
3692 data->flags |= HAL_BUFFERFLAG_EOS;
3693
3694 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
3695 data->flags |= HAL_BUFFERFLAG_CODECCONFIG;
3696
3697 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY)
3698 data->flags |= HAL_BUFFERFLAG_DECODEONLY;
3699
3700 if (vbuf->flags & V4L2_QCOM_BUF_TIMESTAMP_INVALID)
3701 data->timestamp = LLONG_MAX;
3702
3703 /* XXX: This is a dirty hack necessitated by the firmware,
3704 * which refuses to issue FBDs for non I-frames in Picture Type
3705 * Decoding mode, unless we pass in non-zero value in mark_data
3706 * and mark_target.
3707 */
3708 data->mark_data = data->mark_target =
3709 pic_decoding_mode ? 0xdeadbeef : 0;
3710
3711 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
3712 data->buffer_type = msm_comm_get_hal_output_buffer(inst);
3713 }
3714
3715 extra_idx = EXTRADATA_IDX(inst->fmts[port].num_planes);
3716 if (extra_idx && extra_idx < VIDEO_MAX_PLANES &&
3717 vb->planes[extra_idx].m.userptr) {
3718 data->extradata_addr = vb->planes[extra_idx].m.userptr;
3719 data->extradata_size = vb->planes[extra_idx].length;
3720 data->flags |= HAL_BUFFERFLAG_EXTRADATA;
3721 }
3722}
3723
3724static unsigned int count_single_batch(struct msm_vidc_list *list,
3725 enum v4l2_buf_type type)
3726{
3727 struct vb2_buf_entry *buf;
3728 int count = 0;
3729 struct vb2_v4l2_buffer *vbuf = NULL;
3730
3731 mutex_lock(&list->lock);
3732 list_for_each_entry(buf, &list->list, list) {
3733 if (buf->vb->type != type)
3734 continue;
3735
3736 ++count;
3737
3738 vbuf = to_vb2_v4l2_buffer(buf->vb);
3739 if (!(vbuf->flags & V4L2_MSM_BUF_FLAG_DEFER))
3740 goto found_batch;
3741 }
3742 /* don't have a full batch */
3743 count = 0;
3744
3745found_batch:
3746 mutex_unlock(&list->lock);
3747 return count;
3748}
3749
3750static unsigned int count_buffers(struct msm_vidc_list *list,
3751 enum v4l2_buf_type type)
3752{
3753 struct vb2_buf_entry *buf;
3754 int count = 0;
3755
3756 mutex_lock(&list->lock);
3757 list_for_each_entry(buf, &list->list, list) {
3758 if (buf->vb->type != type)
3759 continue;
3760
3761 ++count;
3762 }
3763 mutex_unlock(&list->lock);
3764
3765 return count;
3766}
3767
3768static void log_frame(struct msm_vidc_inst *inst, struct vidc_frame_data *data,
3769 enum v4l2_buf_type type)
3770{
3771 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
3772 dprintk(VIDC_DBG,
3773 "Sending etb (%pa) to hal: filled: %d, ts: %lld, flags = %#x\n",
3774 &data->device_addr, data->filled_len,
3775 data->timestamp, data->flags);
3776 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_ETB);
3777
3778 if (msm_vidc_bitrate_clock_scaling &&
3779 inst->session_type == MSM_VIDC_DECODER &&
3780 !inst->dcvs_mode)
3781 inst->instant_bitrate =
3782 data->filled_len * 8 * inst->prop.fps;
3783 else
3784 inst->instant_bitrate = 0;
3785 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
3786 dprintk(VIDC_DBG,
3787 "Sending ftb (%pa) to hal: size: %d, ts: %lld, flags = %#x\n",
3788 &data->device_addr, data->alloc_len,
3789 data->timestamp, data->flags);
3790 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FTB);
3791 }
3792
3793 msm_dcvs_check_and_scale_clocks(inst,
3794 type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
3795
3796 if (msm_vidc_bitrate_clock_scaling && !inst->dcvs_mode &&
3797 type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
3798 inst->session_type == MSM_VIDC_DECODER)
3799 if (msm_comm_scale_clocks(inst->core))
3800 dprintk(VIDC_WARN,
3801 "Failed to scale clocks. Performance might be impacted\n");
3802
3803 if (msm_comm_vote_bus(inst->core))
3804 dprintk(VIDC_WARN,
3805 "Failed to scale bus. Performance might be impacted\n");
3806}
3807
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003808/*
3809 * Attempts to queue `vb` to hardware. If, for various reasons, the buffer
3810 * cannot be queued to hardware, the buffer will be staged for commit in the
3811 * pending queue. Once the hardware reaches a good state (or if `vb` is NULL,
3812 * the subsequent *_qbuf will commit the previously staged buffers to hardware.
3813 */
3814int msm_comm_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb)
3815{
3816 int rc = 0, capture_count, output_count;
3817 struct msm_vidc_core *core;
3818 struct hfi_device *hdev;
3819 struct {
3820 struct vidc_frame_data *data;
3821 int count;
3822 } etbs, ftbs;
3823 bool defer = false, batch_mode;
3824 struct vb2_buf_entry *temp, *next;
3825 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
3826
3827 if (!inst) {
3828 dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__);
3829 return -EINVAL;
3830 }
3831
3832 core = inst->core;
3833 hdev = core->device;
3834
3835 if (inst->state == MSM_VIDC_CORE_INVALID ||
3836 core->state == VIDC_CORE_INVALID ||
3837 core->state == VIDC_CORE_UNINIT) {
3838 dprintk(VIDC_ERR, "Core is in bad state. Can't Queue\n");
3839 return -EINVAL;
3840 }
3841
3842 /*
3843 * Stick the buffer into the pendinq, we'll pop it out later on
3844 * if we want to commit it to hardware
3845 */
3846 if (vb) {
3847 temp = kzalloc(sizeof(*temp), GFP_KERNEL);
3848 if (!temp) {
3849 dprintk(VIDC_ERR, "Out of memory\n");
3850 goto err_no_mem;
3851 }
3852
3853 temp->vb = vb;
3854 mutex_lock(&inst->pendingq.lock);
3855 list_add_tail(&temp->list, &inst->pendingq.list);
3856 mutex_unlock(&inst->pendingq.lock);
3857 }
3858
3859 batch_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_VIDC_QBUF_MODE)
3860 == V4L2_VIDC_QBUF_BATCHED;
3861 capture_count = (batch_mode ? &count_single_batch : &count_buffers)
3862 (&inst->pendingq, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
3863 output_count = (batch_mode ? &count_single_batch : &count_buffers)
3864 (&inst->pendingq, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
3865
3866 /*
3867 * Somewhat complicated logic to prevent queuing the buffer to hardware.
3868 * Don't queue if:
3869 * 1) Hardware isn't ready (that's simple)
3870 */
3871 defer = defer ?: inst->state != MSM_VIDC_START_DONE;
3872
3873 /*
3874 * 2) The client explicitly tells us not to because it wants this
3875 * buffer to be batched with future frames. The batch size (on both
3876 * capabilities) is completely determined by the client.
3877 */
3878 defer = defer ?: vbuf && vbuf->flags & V4L2_MSM_BUF_FLAG_DEFER;
3879
3880 /* 3) If we're in batch mode, we must have full batches of both types */
3881 defer = defer ?: batch_mode && (!output_count || !capture_count);
3882
3883 if (defer) {
3884 dprintk(VIDC_DBG, "Deferring queue of %pK\n", vb);
3885 return 0;
3886 }
3887
3888 dprintk(VIDC_DBG, "%sing %d etbs and %d ftbs\n",
3889 batch_mode ? "Batch" : "Process",
3890 output_count, capture_count);
3891
3892 etbs.data = kcalloc(output_count, sizeof(*etbs.data), GFP_KERNEL);
3893 ftbs.data = kcalloc(capture_count, sizeof(*ftbs.data), GFP_KERNEL);
3894 /*
3895 * Note that it's perfectly normal for (e|f)tbs.data to be NULL if
3896 * we're not in batch mode (i.e. (output|capture)_count == 0)
3897 */
3898 if ((!etbs.data && output_count) ||
3899 (!ftbs.data && capture_count)) {
3900 dprintk(VIDC_ERR, "Failed to alloc memory for batching\n");
3901 kfree(etbs.data);
3902 etbs.data = NULL;
3903
3904 kfree(ftbs.data);
3905 ftbs.data = NULL;
3906 goto err_no_mem;
3907 }
3908
3909 etbs.count = ftbs.count = 0;
3910
3911 /*
3912 * Try to collect all pending buffers into 2 batches of ftb and etb
3913 * Note that these "batches" might be empty if we're no in batching mode
3914 * and the pendingq is empty
3915 */
3916 mutex_lock(&inst->pendingq.lock);
3917 list_for_each_entry_safe(temp, next, &inst->pendingq.list, list) {
3918 struct vidc_frame_data *frame_data = NULL;
3919
3920 switch (temp->vb->type) {
3921 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
3922 if (ftbs.count < capture_count && ftbs.data)
3923 frame_data = &ftbs.data[ftbs.count++];
3924 break;
3925 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
3926 if (etbs.count < output_count && etbs.data)
3927 frame_data = &etbs.data[etbs.count++];
3928 break;
3929 default:
3930 break;
3931 }
3932
3933 if (!frame_data)
3934 continue;
3935
3936 populate_frame_data(frame_data, temp->vb, inst);
3937
3938 list_del(&temp->list);
3939 kfree(temp);
3940 }
3941 mutex_unlock(&inst->pendingq.lock);
3942
3943 /* Finally commit all our frame(s) to H/W */
3944 if (batch_mode) {
3945 int ftb_index = 0, c = 0;
3946
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003947 ftb_index = c;
3948 rc = call_hfi_op(hdev, session_process_batch, inst->session,
3949 etbs.count, etbs.data,
3950 ftbs.count - ftb_index, &ftbs.data[ftb_index]);
3951 if (rc) {
3952 dprintk(VIDC_ERR,
3953 "Failed to queue batch of %d ETBs and %d FTBs\n",
3954 etbs.count, ftbs.count);
3955 goto err_bad_input;
3956 }
3957
3958 for (c = ftb_index; c < ftbs.count; ++c) {
3959 log_frame(inst, &ftbs.data[c],
3960 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
3961 }
3962
3963 for (c = 0; c < etbs.count; ++c) {
3964 log_frame(inst, &etbs.data[c],
3965 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
3966 }
3967 }
3968
3969 if (!batch_mode && etbs.count) {
3970 int c = 0;
3971
3972 for (c = 0; c < etbs.count; ++c) {
3973 struct vidc_frame_data *frame_data = &etbs.data[c];
3974
3975 rc = call_hfi_op(hdev, session_etb, inst->session,
3976 frame_data);
3977 if (rc) {
3978 dprintk(VIDC_ERR, "Failed to issue etb: %d\n",
3979 rc);
3980 goto err_bad_input;
3981 }
3982
3983 log_frame(inst, frame_data,
3984 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
3985 }
3986 }
3987
3988 if (!batch_mode && ftbs.count) {
3989 int c = 0;
3990
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003991 for (; c < ftbs.count; ++c) {
3992 struct vidc_frame_data *frame_data = &ftbs.data[c];
3993
3994 rc = call_hfi_op(hdev, session_ftb,
3995 inst->session, frame_data);
3996 if (rc) {
3997 dprintk(VIDC_ERR, "Failed to issue ftb: %d\n",
3998 rc);
3999 goto err_bad_input;
4000 }
4001
4002 log_frame(inst, frame_data,
4003 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
4004 }
4005 }
4006
4007err_bad_input:
4008 if (rc)
4009 dprintk(VIDC_ERR, "Failed to queue buffer\n");
4010
4011 kfree(etbs.data);
4012 kfree(ftbs.data);
4013err_no_mem:
4014 return rc;
4015}
4016
4017int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst)
4018{
4019 int rc = 0, i = 0;
4020 union hal_get_property hprop;
4021
4022 rc = msm_comm_try_get_prop(inst, HAL_PARAM_GET_BUFFER_REQUIREMENTS,
4023 &hprop);
4024 if (rc) {
4025 dprintk(VIDC_ERR, "Failed getting buffer requirements: %d", rc);
4026 return rc;
4027 }
4028
4029 dprintk(VIDC_DBG, "Buffer requirements:\n");
4030 dprintk(VIDC_DBG, "%15s %8s %8s\n", "buffer type", "count", "size");
4031 for (i = 0; i < HAL_BUFFER_MAX; i++) {
4032 struct hal_buffer_requirements req = hprop.buf_req.buffer[i];
4033
4034 inst->buff_req.buffer[i] = req;
4035 dprintk(VIDC_DBG, "%15s %8d %8d\n",
4036 get_buffer_name(req.buffer_type),
4037 req.buffer_count_actual, req.buffer_size);
4038 }
4039
4040 dprintk(VIDC_PROF, "Input buffers: %d, Output buffers: %d\n",
4041 inst->buff_req.buffer[0].buffer_count_actual,
4042 inst->buff_req.buffer[1].buffer_count_actual);
4043 return rc;
4044}
4045
4046int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
4047 union hal_get_property *hprop)
4048{
4049 int rc = 0;
4050 struct hfi_device *hdev;
4051 struct getprop_buf *buf;
4052
4053 if (!inst || !inst->core || !inst->core->device) {
4054 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4055 return -EINVAL;
4056 }
4057
4058 hdev = inst->core->device;
4059 mutex_lock(&inst->sync_lock);
4060 if (inst->state < MSM_VIDC_OPEN_DONE ||
4061 inst->state >= MSM_VIDC_CLOSE) {
4062
4063 /* No need to check inst->state == MSM_VIDC_INVALID since
4064 * INVALID is > CLOSE_DONE. When core went to INVALID state,
4065 * we put all the active instances in INVALID. So > CLOSE_DONE
4066 * is enough check to have.
4067 */
4068
4069 dprintk(VIDC_ERR,
4070 "In Wrong state to call Buf Req: Inst %pK or Core %pK\n",
4071 inst, inst->core);
4072 rc = -EAGAIN;
4073 mutex_unlock(&inst->sync_lock);
4074 goto exit;
4075 }
4076 mutex_unlock(&inst->sync_lock);
4077
4078 switch (ptype) {
4079 case HAL_PARAM_PROFILE_LEVEL_CURRENT:
4080 case HAL_CONFIG_VDEC_ENTROPY:
4081 rc = call_hfi_op(hdev, session_get_property, inst->session,
4082 ptype);
4083 break;
4084 case HAL_PARAM_GET_BUFFER_REQUIREMENTS:
4085 rc = call_hfi_op(hdev, session_get_buf_req, inst->session);
4086 break;
4087 default:
4088 rc = -EAGAIN;
4089 break;
4090 }
4091
4092 if (rc) {
4093 dprintk(VIDC_ERR, "Can't query hardware for property: %d\n",
4094 rc);
4095 goto exit;
4096 }
4097
4098 rc = wait_for_completion_timeout(&inst->completions[
4099 SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO)],
4100 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
4101 if (!rc) {
4102 dprintk(VIDC_ERR,
4103 "%s: Wait interrupted or timed out [%pK]: %d\n",
4104 __func__, inst,
4105 SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO));
4106 inst->state = MSM_VIDC_CORE_INVALID;
4107 msm_comm_kill_session(inst);
4108 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
4109 dprintk(VIDC_ERR,
4110 "SESS_PROP timeout can potentially crash the system\n");
4111 if (inst->core->resources.debug_timeout)
4112 msm_comm_print_debug_info(inst);
4113
4114 msm_vidc_handle_hw_error(inst->core);
4115 rc = -ETIMEDOUT;
4116 goto exit;
4117 } else {
4118 /* wait_for_completion_timeout returns jiffies before expiry */
4119 rc = 0;
4120 }
4121
4122 mutex_lock(&inst->pending_getpropq.lock);
4123 if (!list_empty(&inst->pending_getpropq.list)) {
4124 buf = list_first_entry(&inst->pending_getpropq.list,
4125 struct getprop_buf, list);
4126 *hprop = *(union hal_get_property *)buf->data;
4127 kfree(buf->data);
4128 list_del(&buf->list);
4129 kfree(buf);
4130 } else {
4131 dprintk(VIDC_ERR, "%s getprop list empty\n", __func__);
4132 rc = -EINVAL;
4133 }
4134 mutex_unlock(&inst->pending_getpropq.lock);
4135exit:
4136 return rc;
4137}
4138
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004139int msm_comm_release_output_buffers(struct msm_vidc_inst *inst,
4140 bool force_release)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004141{
4142 struct msm_smem *handle;
4143 struct internal_buf *buf, *dummy;
4144 struct vidc_buffer_addr_info buffer_info;
4145 int rc = 0;
4146 struct msm_vidc_core *core;
4147 struct hfi_device *hdev;
4148
4149 if (!inst) {
4150 dprintk(VIDC_ERR,
4151 "Invalid instance pointer = %pK\n", inst);
4152 return -EINVAL;
4153 }
4154 mutex_lock(&inst->outputbufs.lock);
4155 if (list_empty(&inst->outputbufs.list)) {
4156 dprintk(VIDC_DBG, "%s - No OUTPUT buffers allocated\n",
4157 __func__);
4158 mutex_unlock(&inst->outputbufs.lock);
4159 return 0;
4160 }
4161 mutex_unlock(&inst->outputbufs.lock);
4162
4163 core = inst->core;
4164 if (!core) {
4165 dprintk(VIDC_ERR,
4166 "Invalid core pointer = %pK\n", core);
4167 return -EINVAL;
4168 }
4169 hdev = core->device;
4170 if (!hdev) {
4171 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4172 return -EINVAL;
4173 }
4174 mutex_lock(&inst->outputbufs.lock);
4175 list_for_each_entry_safe(buf, dummy, &inst->outputbufs.list, list) {
4176 handle = buf->handle;
4177 if (!handle) {
4178 dprintk(VIDC_ERR, "%s - invalid handle\n", __func__);
4179 goto exit;
4180 }
4181
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004182 if ((buf->buffer_ownership == FIRMWARE) && !force_release) {
4183 dprintk(VIDC_INFO, "DPB is with f/w. Can't free it\n");
4184 continue;
4185 }
4186
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004187 buffer_info.buffer_size = handle->size;
4188 buffer_info.buffer_type = buf->buffer_type;
4189 buffer_info.num_buffers = 1;
4190 buffer_info.align_device_addr = handle->device_addr;
4191 if (inst->buffer_mode_set[CAPTURE_PORT] ==
4192 HAL_BUFFER_MODE_STATIC &&
4193 inst->state != MSM_VIDC_CORE_INVALID &&
4194 core->state != VIDC_CORE_INVALID) {
4195 buffer_info.response_required = false;
4196 rc = call_hfi_op(hdev, session_release_buffers,
4197 (void *)inst->session, &buffer_info);
4198 if (rc) {
4199 dprintk(VIDC_WARN,
4200 "Rel output buf fail:%pa, %d\n",
4201 &buffer_info.align_device_addr,
4202 buffer_info.buffer_size);
4203 }
4204 }
4205
4206 list_del(&buf->list);
4207 msm_comm_smem_free(inst, buf->handle);
4208 kfree(buf);
4209 }
4210
4211exit:
4212 mutex_unlock(&inst->outputbufs.lock);
4213 return rc;
4214}
4215
4216static enum hal_buffer scratch_buf_sufficient(struct msm_vidc_inst *inst,
4217 enum hal_buffer buffer_type)
4218{
4219 struct hal_buffer_requirements *bufreq = NULL;
4220 struct internal_buf *buf;
4221 int count = 0;
4222
4223 if (!inst) {
4224 dprintk(VIDC_ERR, "%s - invalid param\n", __func__);
4225 goto not_sufficient;
4226 }
4227
4228 bufreq = get_buff_req_buffer(inst, buffer_type);
4229 if (!bufreq)
4230 goto not_sufficient;
4231
4232 /* Check if current scratch buffers are sufficient */
4233 mutex_lock(&inst->scratchbufs.lock);
4234
4235 list_for_each_entry(buf, &inst->scratchbufs.list, list) {
4236 if (!buf->handle) {
4237 dprintk(VIDC_ERR, "%s: invalid buf handle\n", __func__);
4238 mutex_unlock(&inst->scratchbufs.lock);
4239 goto not_sufficient;
4240 }
4241 if (buf->buffer_type == buffer_type &&
4242 buf->handle->size >= bufreq->buffer_size)
4243 count++;
4244 }
4245 mutex_unlock(&inst->scratchbufs.lock);
4246
4247 if (count != bufreq->buffer_count_actual)
4248 goto not_sufficient;
4249
4250 dprintk(VIDC_DBG,
4251 "Existing scratch buffer is sufficient for buffer type %#x\n",
4252 buffer_type);
4253
4254 return buffer_type;
4255
4256not_sufficient:
4257 return HAL_BUFFER_NONE;
4258}
4259
4260int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst,
4261 bool check_for_reuse)
4262{
4263 struct msm_smem *handle;
4264 struct internal_buf *buf, *dummy;
4265 struct vidc_buffer_addr_info buffer_info;
4266 int rc = 0;
4267 struct msm_vidc_core *core;
4268 struct hfi_device *hdev;
4269 enum hal_buffer sufficiency = HAL_BUFFER_NONE;
4270
4271 if (!inst) {
4272 dprintk(VIDC_ERR,
4273 "Invalid instance pointer = %pK\n", inst);
4274 return -EINVAL;
4275 }
4276 core = inst->core;
4277 if (!core) {
4278 dprintk(VIDC_ERR,
4279 "Invalid core pointer = %pK\n", core);
4280 return -EINVAL;
4281 }
4282 hdev = core->device;
4283 if (!hdev) {
4284 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4285 return -EINVAL;
4286 }
4287
4288 if (check_for_reuse) {
4289 sufficiency |= scratch_buf_sufficient(inst,
4290 HAL_BUFFER_INTERNAL_SCRATCH);
4291
4292 sufficiency |= scratch_buf_sufficient(inst,
4293 HAL_BUFFER_INTERNAL_SCRATCH_1);
4294
4295 sufficiency |= scratch_buf_sufficient(inst,
4296 HAL_BUFFER_INTERNAL_SCRATCH_2);
4297 }
4298
4299 mutex_lock(&inst->scratchbufs.lock);
4300 list_for_each_entry_safe(buf, dummy, &inst->scratchbufs.list, list) {
4301 if (!buf->handle) {
4302 dprintk(VIDC_ERR, "%s - buf->handle NULL\n", __func__);
4303 rc = -EINVAL;
4304 goto exit;
4305 }
4306
4307 handle = buf->handle;
4308 buffer_info.buffer_size = handle->size;
4309 buffer_info.buffer_type = buf->buffer_type;
4310 buffer_info.num_buffers = 1;
4311 buffer_info.align_device_addr = handle->device_addr;
4312 if (inst->state != MSM_VIDC_CORE_INVALID &&
4313 core->state != VIDC_CORE_INVALID) {
4314 buffer_info.response_required = true;
4315 rc = call_hfi_op(hdev, session_release_buffers,
4316 (void *)inst->session, &buffer_info);
4317 if (rc) {
4318 dprintk(VIDC_WARN,
4319 "Rel scrtch buf fail:%pa, %d\n",
4320 &buffer_info.align_device_addr,
4321 buffer_info.buffer_size);
4322 }
4323 mutex_unlock(&inst->scratchbufs.lock);
4324 rc = wait_for_sess_signal_receipt(inst,
4325 HAL_SESSION_RELEASE_BUFFER_DONE);
4326 if (rc) {
4327 change_inst_state(inst,
4328 MSM_VIDC_CORE_INVALID);
4329 msm_comm_kill_session(inst);
4330 }
4331 mutex_lock(&inst->scratchbufs.lock);
4332 }
4333
4334 /*If scratch buffers can be reused, do not free the buffers*/
4335 if (sufficiency & buf->buffer_type)
4336 continue;
4337
4338 list_del(&buf->list);
4339 msm_comm_smem_free(inst, buf->handle);
4340 kfree(buf);
4341 }
4342
4343exit:
4344 mutex_unlock(&inst->scratchbufs.lock);
4345 return rc;
4346}
4347
4348int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst)
4349{
4350 struct msm_smem *handle;
4351 struct list_head *ptr, *next;
4352 struct internal_buf *buf;
4353 struct vidc_buffer_addr_info buffer_info;
4354 int rc = 0;
4355 struct msm_vidc_core *core;
4356 struct hfi_device *hdev;
4357
4358 if (!inst) {
4359 dprintk(VIDC_ERR,
4360 "Invalid instance pointer = %pK\n", inst);
4361 return -EINVAL;
4362 }
4363 core = inst->core;
4364 if (!core) {
4365 dprintk(VIDC_ERR,
4366 "Invalid core pointer = %pK\n", core);
4367 return -EINVAL;
4368 }
4369 hdev = core->device;
4370 if (!hdev) {
4371 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4372 return -EINVAL;
4373 }
4374
4375 mutex_lock(&inst->persistbufs.lock);
4376 list_for_each_safe(ptr, next, &inst->persistbufs.list) {
4377 buf = list_entry(ptr, struct internal_buf, list);
4378 handle = buf->handle;
4379 buffer_info.buffer_size = handle->size;
4380 buffer_info.buffer_type = buf->buffer_type;
4381 buffer_info.num_buffers = 1;
4382 buffer_info.align_device_addr = handle->device_addr;
4383 if (inst->state != MSM_VIDC_CORE_INVALID &&
4384 core->state != VIDC_CORE_INVALID) {
4385 buffer_info.response_required = true;
4386 rc = call_hfi_op(hdev, session_release_buffers,
4387 (void *)inst->session, &buffer_info);
4388 if (rc) {
4389 dprintk(VIDC_WARN,
4390 "Rel prst buf fail:%pa, %d\n",
4391 &buffer_info.align_device_addr,
4392 buffer_info.buffer_size);
4393 }
4394 mutex_unlock(&inst->persistbufs.lock);
4395 rc = wait_for_sess_signal_receipt(inst,
4396 HAL_SESSION_RELEASE_BUFFER_DONE);
4397 if (rc) {
4398 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
4399 msm_comm_kill_session(inst);
4400 }
4401 mutex_lock(&inst->persistbufs.lock);
4402 }
4403 list_del(&buf->list);
4404 msm_comm_smem_free(inst, buf->handle);
4405 kfree(buf);
4406 }
4407 mutex_unlock(&inst->persistbufs.lock);
4408 return rc;
4409}
4410
4411int msm_comm_try_set_prop(struct msm_vidc_inst *inst,
4412 enum hal_property ptype, void *pdata)
4413{
4414 int rc = 0;
4415 struct hfi_device *hdev;
4416
4417 if (!inst) {
4418 dprintk(VIDC_ERR, "Invalid input: %pK\n", inst);
4419 return -EINVAL;
4420 }
4421
4422 if (!inst->core || !inst->core->device) {
4423 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4424 return -EINVAL;
4425 }
4426 hdev = inst->core->device;
4427
4428 mutex_lock(&inst->sync_lock);
4429 if (inst->state < MSM_VIDC_OPEN_DONE || inst->state >= MSM_VIDC_CLOSE) {
4430 dprintk(VIDC_ERR, "Not in proper state to set property\n");
4431 rc = -EAGAIN;
4432 goto exit;
4433 }
4434 rc = call_hfi_op(hdev, session_set_property, (void *)inst->session,
4435 ptype, pdata);
4436 if (rc)
4437 dprintk(VIDC_ERR, "Failed to set hal property for framesize\n");
4438exit:
4439 mutex_unlock(&inst->sync_lock);
4440 return rc;
4441}
4442
4443int msm_comm_set_output_buffers(struct msm_vidc_inst *inst)
4444{
4445 int rc = 0;
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004446 bool force_release = true;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004447
4448 if (!inst || !inst->core || !inst->core->device) {
4449 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4450 return -EINVAL;
4451 }
4452
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004453 if (inst->fmts[OUTPUT_PORT].defer_outputs)
4454 force_release = false;
4455
4456 if (msm_comm_release_output_buffers(inst, force_release))
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004457 dprintk(VIDC_WARN, "Failed to release output buffers\n");
4458
4459 rc = set_output_buffers(inst, HAL_BUFFER_OUTPUT);
4460 if (rc)
4461 goto error;
4462 return rc;
4463error:
Vaibhav Deshu Venkatesh8c9b6db2017-02-08 11:22:36 -08004464 msm_comm_release_output_buffers(inst, true);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08004465 return rc;
4466}
4467
4468int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst)
4469{
4470 int rc = 0;
4471
4472 if (!inst || !inst->core || !inst->core->device) {
4473 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4474 return -EINVAL;
4475 }
4476
4477 if (msm_comm_release_scratch_buffers(inst, true))
4478 dprintk(VIDC_WARN, "Failed to release scratch buffers\n");
4479
4480 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH,
4481 &inst->scratchbufs);
4482 if (rc)
4483 goto error;
4484
4485 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_1,
4486 &inst->scratchbufs);
4487 if (rc)
4488 goto error;
4489
4490 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_2,
4491 &inst->scratchbufs);
4492 if (rc)
4493 goto error;
4494
4495 return rc;
4496error:
4497 msm_comm_release_scratch_buffers(inst, false);
4498 return rc;
4499}
4500
4501int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst)
4502{
4503 int rc = 0;
4504
4505 if (!inst || !inst->core || !inst->core->device) {
4506 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4507 return -EINVAL;
4508 }
4509
4510 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST,
4511 &inst->persistbufs);
4512 if (rc)
4513 goto error;
4514
4515 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST_1,
4516 &inst->persistbufs);
4517 if (rc)
4518 goto error;
4519 return rc;
4520error:
4521 msm_comm_release_persist_buffers(inst);
4522 return rc;
4523}
4524
4525static void msm_comm_flush_in_invalid_state(struct msm_vidc_inst *inst)
4526{
4527 struct list_head *ptr, *next;
4528 enum vidc_ports ports[] = {OUTPUT_PORT, CAPTURE_PORT};
4529 int c = 0;
4530
4531 for (c = 0; c < ARRAY_SIZE(ports); ++c) {
4532 enum vidc_ports port = ports[c];
4533
4534 dprintk(VIDC_DBG, "Flushing buffers of type %d in bad state\n",
4535 port);
4536 mutex_lock(&inst->bufq[port].lock);
4537 list_for_each_safe(ptr, next, &inst->bufq[port].
4538 vb2_bufq.queued_list) {
4539 struct vb2_buffer *vb = container_of(ptr,
4540 struct vb2_buffer, queued_entry);
4541
4542 vb->planes[0].bytesused = 0;
4543 vb->planes[0].data_offset = 0;
4544
4545 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
4546 }
4547 mutex_unlock(&inst->bufq[port].lock);
4548 }
4549
4550 msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_FLUSH_DONE);
4551}
4552
4553void msm_comm_flush_dynamic_buffers(struct msm_vidc_inst *inst)
4554{
4555 struct buffer_info *binfo = NULL;
4556
4557 if (inst->buffer_mode_set[CAPTURE_PORT] != HAL_BUFFER_MODE_DYNAMIC)
4558 return;
4559
4560 /*
4561 * dynamic buffer mode:- if flush is called during seek
4562 * driver should not queue any new buffer it has been holding.
4563 *
4564 * Each dynamic o/p buffer can have one of following ref_count:
4565 * ref_count : 0 - f/w has released reference and sent fbd back.
4566 * The buffer has been returned back to client.
4567 *
4568 * ref_count : 1 - f/w is holding reference. f/w may have released
4569 * fbd as read_only OR fbd is pending. f/w will
4570 * release reference before sending flush_done.
4571 *
4572 * ref_count : 2 - f/w is holding reference, f/w has released fbd as
4573 * read_only, which client has queued back to driver.
4574 * driver holds this buffer and will queue back
4575 * only when f/w releases the reference. During
4576 * flush_done, f/w will release the reference but driver
4577 * should not queue back the buffer to f/w.
4578 * Flush all buffers with ref_count 2.
4579 */
4580 mutex_lock(&inst->registeredbufs.lock);
4581 if (!list_empty(&inst->registeredbufs.list)) {
4582 struct v4l2_event buf_event = {0};
4583 u32 *ptr = NULL;
4584
4585 list_for_each_entry(binfo, &inst->registeredbufs.list, list) {
4586 if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
4587 atomic_read(&binfo->ref_count) == 2) {
4588
4589 atomic_dec(&binfo->ref_count);
4590 buf_event.type =
4591 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER;
4592 ptr = (u32 *)buf_event.u.data;
4593 ptr[0] = binfo->fd[0];
4594 ptr[1] = binfo->buff_off[0];
4595 ptr[2] = binfo->uvaddr[0];
4596 ptr[3] = (u32) binfo->timestamp.tv_sec;
4597 ptr[4] = (u32) binfo->timestamp.tv_usec;
4598 ptr[5] = binfo->v4l2_index;
4599 dprintk(VIDC_DBG,
4600 "released buffer held in driver before issuing flush: %pa fd[0]: %d\n",
4601 &binfo->device_addr[0], binfo->fd[0]);
4602 /*send event to client*/
4603 v4l2_event_queue_fh(&inst->event_handler,
4604 &buf_event);
4605 }
4606 }
4607 }
4608 mutex_unlock(&inst->registeredbufs.lock);
4609}
4610
4611void msm_comm_flush_pending_dynamic_buffers(struct msm_vidc_inst *inst)
4612{
4613 struct buffer_info *binfo = NULL;
4614
4615 if (!inst)
4616 return;
4617
4618 if (inst->buffer_mode_set[CAPTURE_PORT] != HAL_BUFFER_MODE_DYNAMIC)
4619 return;
4620
4621 if (list_empty(&inst->pendingq.list) ||
4622 list_empty(&inst->registeredbufs.list))
4623 return;
4624
4625 /*
4626 * Dynamic Buffer mode - Since pendingq is not empty
4627 * no output buffers have been sent to firmware yet.
4628 * Hence remove reference to all pendingq o/p buffers
4629 * before flushing them.
4630 */
4631
4632 mutex_lock(&inst->registeredbufs.lock);
4633 list_for_each_entry(binfo, &inst->registeredbufs.list, list) {
4634 if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
4635 dprintk(VIDC_DBG,
4636 "%s: binfo = %pK device_addr = %pa\n",
4637 __func__, binfo, &binfo->device_addr[0]);
4638 buf_ref_put(inst, binfo);
4639 }
4640 }
4641 mutex_unlock(&inst->registeredbufs.lock);
4642}
4643
4644int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags)
4645{
4646 int rc = 0;
4647 bool ip_flush = false;
4648 bool op_flush = false;
4649 struct vb2_buf_entry *temp, *next;
4650 struct mutex *lock;
4651 struct msm_vidc_core *core;
4652 struct hfi_device *hdev;
4653
4654 if (!inst) {
4655 dprintk(VIDC_ERR,
4656 "Invalid instance pointer = %pK\n", inst);
4657 return -EINVAL;
4658 }
4659 core = inst->core;
4660 if (!core) {
4661 dprintk(VIDC_ERR,
4662 "Invalid core pointer = %pK\n", core);
4663 return -EINVAL;
4664 }
4665 hdev = core->device;
4666 if (!hdev) {
4667 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4668 return -EINVAL;
4669 }
4670
4671 ip_flush = flags & V4L2_QCOM_CMD_FLUSH_OUTPUT;
4672 op_flush = flags & V4L2_QCOM_CMD_FLUSH_CAPTURE;
4673
4674 if (ip_flush && !op_flush) {
4675 dprintk(VIDC_INFO, "Input only flush not supported\n");
4676 return 0;
4677 }
4678
4679 msm_comm_flush_dynamic_buffers(inst);
4680
4681 if (inst->state == MSM_VIDC_CORE_INVALID ||
4682 core->state == VIDC_CORE_INVALID ||
4683 core->state == VIDC_CORE_UNINIT) {
4684 dprintk(VIDC_ERR,
4685 "Core %pK and inst %pK are in bad state\n",
4686 core, inst);
4687 msm_comm_flush_in_invalid_state(inst);
4688 return 0;
4689 }
4690
4691 if (inst->in_reconfig && !ip_flush && op_flush) {
4692 mutex_lock(&inst->pendingq.lock);
4693 if (!list_empty(&inst->pendingq.list)) {
4694 /*
4695 * Execution can never reach here since port reconfig
4696 * wont happen unless pendingq is emptied out
4697 * (both pendingq and flush being secured with same
4698 * lock). Printing a message here incase this breaks.
4699 */
4700 dprintk(VIDC_WARN,
4701 "FLUSH BUG: Pending q not empty! It should be empty\n");
4702 }
4703 mutex_unlock(&inst->pendingq.lock);
4704 atomic_inc(&inst->in_flush);
4705 dprintk(VIDC_DBG, "Send flush Output to firmware\n");
4706 rc = call_hfi_op(hdev, session_flush, inst->session,
4707 HAL_FLUSH_OUTPUT);
4708 } else {
4709 msm_comm_flush_pending_dynamic_buffers(inst);
4710 /*
4711 * If flush is called after queueing buffers but before
4712 * streamon driver should flush the pending queue
4713 */
4714 mutex_lock(&inst->pendingq.lock);
4715 list_for_each_entry_safe(temp, next,
4716 &inst->pendingq.list, list) {
4717 enum v4l2_buf_type type = temp->vb->type;
4718
4719 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
4720 lock = &inst->bufq[CAPTURE_PORT].lock;
4721 else
4722 lock = &inst->bufq[OUTPUT_PORT].lock;
4723
4724 temp->vb->planes[0].bytesused = 0;
4725
4726 mutex_lock(lock);
4727 vb2_buffer_done(temp->vb, VB2_BUF_STATE_DONE);
4728 msm_vidc_debugfs_update(inst,
4729 type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ?
4730 MSM_VIDC_DEBUGFS_EVENT_FBD :
4731 MSM_VIDC_DEBUGFS_EVENT_EBD);
4732 list_del(&temp->list);
4733 mutex_unlock(lock);
4734
4735 kfree(temp);
4736 }
4737 mutex_unlock(&inst->pendingq.lock);
4738
4739 /*Do not send flush in case of session_error */
4740 if (!(inst->state == MSM_VIDC_CORE_INVALID &&
4741 core->state != VIDC_CORE_INVALID)) {
4742 atomic_inc(&inst->in_flush);
4743 dprintk(VIDC_DBG, "Send flush all to firmware\n");
4744 rc = call_hfi_op(hdev, session_flush, inst->session,
4745 HAL_FLUSH_ALL);
4746 }
4747 }
4748
4749 return rc;
4750}
4751
4752
4753enum hal_extradata_id msm_comm_get_hal_extradata_index(
4754 enum v4l2_mpeg_vidc_extradata index)
4755{
4756 int ret = 0;
4757
4758 switch (index) {
4759 case V4L2_MPEG_VIDC_EXTRADATA_NONE:
4760 ret = HAL_EXTRADATA_NONE;
4761 break;
4762 case V4L2_MPEG_VIDC_EXTRADATA_MB_QUANTIZATION:
4763 ret = HAL_EXTRADATA_MB_QUANTIZATION;
4764 break;
4765 case V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO:
4766 ret = HAL_EXTRADATA_INTERLACE_VIDEO;
4767 break;
4768 case V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP:
4769 ret = HAL_EXTRADATA_TIMESTAMP;
4770 break;
4771 case V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING:
4772 ret = HAL_EXTRADATA_S3D_FRAME_PACKING;
4773 break;
4774 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE:
4775 ret = HAL_EXTRADATA_FRAME_RATE;
4776 break;
4777 case V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW:
4778 ret = HAL_EXTRADATA_PANSCAN_WINDOW;
4779 break;
4780 case V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
4781 ret = HAL_EXTRADATA_RECOVERY_POINT_SEI;
4782 break;
4783 case V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO:
4784 ret = HAL_EXTRADATA_MULTISLICE_INFO;
4785 break;
4786 case V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB:
4787 ret = HAL_EXTRADATA_NUM_CONCEALED_MB;
4788 break;
4789 case V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER:
4790 ret = HAL_EXTRADATA_METADATA_FILLER;
4791 break;
4792 case V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO:
4793 ret = HAL_EXTRADATA_ASPECT_RATIO;
4794 break;
4795 case V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP:
4796 ret = HAL_EXTRADATA_INPUT_CROP;
4797 break;
4798 case V4L2_MPEG_VIDC_EXTRADATA_DIGITAL_ZOOM:
4799 ret = HAL_EXTRADATA_DIGITAL_ZOOM;
4800 break;
4801 case V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP:
4802 ret = HAL_EXTRADATA_MPEG2_SEQDISP;
4803 break;
4804 case V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA:
4805 ret = HAL_EXTRADATA_STREAM_USERDATA;
4806 break;
4807 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP:
4808 ret = HAL_EXTRADATA_FRAME_QP;
4809 break;
4810 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO:
4811 ret = HAL_EXTRADATA_FRAME_BITS_INFO;
4812 break;
4813 case V4L2_MPEG_VIDC_EXTRADATA_LTR:
4814 ret = HAL_EXTRADATA_LTR_INFO;
4815 break;
4816 case V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI:
4817 ret = HAL_EXTRADATA_METADATA_MBI;
4818 break;
4819 case V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI:
4820 ret = HAL_EXTRADATA_VQZIP_SEI;
4821 break;
4822 case V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS:
4823 ret = HAL_EXTRADATA_YUV_STATS;
4824 break;
4825 case V4L2_MPEG_VIDC_EXTRADATA_ROI_QP:
4826 ret = HAL_EXTRADATA_ROI_QP;
4827 break;
4828 case V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP:
4829 ret = HAL_EXTRADATA_OUTPUT_CROP;
4830 break;
4831 case V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI:
4832 ret = HAL_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI;
4833 break;
4834 case V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI:
4835 ret = HAL_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI;
4836 break;
4837 case V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO:
4838 ret = HAL_EXTRADATA_PQ_INFO;
4839 break;
4840
4841 case V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY:
4842 ret = HAL_EXTRADATA_VUI_DISPLAY_INFO;
4843 break;
4844 case V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE:
4845 ret = HAL_EXTRADATA_VPX_COLORSPACE;
4846 break;
4847 default:
4848 dprintk(VIDC_WARN, "Extradata not found: %d\n", index);
4849 break;
4850 }
4851 return ret;
4852};
4853
4854int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
4855 enum hal_ssr_trigger_type type)
4856{
4857 int rc = 0;
4858 struct hfi_device *hdev;
4859
4860 if (!core || !core->device) {
4861 dprintk(VIDC_WARN, "Invalid parameters: %pK\n", core);
4862 return -EINVAL;
4863 }
4864 hdev = core->device;
4865 if (core->state == VIDC_CORE_INIT_DONE) {
4866 /*
4867 * In current implementation user-initiated SSR triggers
4868 * a fatal error from hardware. However, there is no way
4869 * to know if fatal error is due to SSR or not. Handle
4870 * user SSR as non-fatal.
4871 */
4872 mutex_lock(&core->lock);
4873 core->resources.debug_timeout = false;
4874 mutex_unlock(&core->lock);
4875 rc = call_hfi_op(hdev, core_trigger_ssr,
4876 hdev->hfi_device_data, type);
4877 }
4878
4879 return rc;
4880}
4881
4882static int msm_vidc_load_supported(struct msm_vidc_inst *inst)
4883{
4884 int num_mbs_per_sec = 0, max_load_adj = 0;
4885 enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD |
4886 LOAD_CALC_IGNORE_THUMBNAIL_LOAD |
4887 LOAD_CALC_IGNORE_NON_REALTIME_LOAD;
4888
4889 if (inst->state == MSM_VIDC_OPEN_DONE) {
4890 max_load_adj = inst->core->resources.max_load +
4891 inst->capability.mbs_per_frame.max;
4892 num_mbs_per_sec = msm_comm_get_load(inst->core,
4893 MSM_VIDC_DECODER, quirks);
4894 num_mbs_per_sec += msm_comm_get_load(inst->core,
4895 MSM_VIDC_ENCODER, quirks);
4896 if (num_mbs_per_sec > max_load_adj) {
4897 dprintk(VIDC_ERR,
4898 "H/W is overloaded. needed: %d max: %d\n",
4899 num_mbs_per_sec,
4900 max_load_adj);
4901 msm_vidc_print_running_insts(inst->core);
4902 return -EBUSY;
4903 }
4904 }
4905 return 0;
4906}
4907
4908int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst)
4909{
4910 u32 x_min, x_max, y_min, y_max;
4911 u32 input_height, input_width, output_height, output_width;
4912
4913 input_height = inst->prop.height[OUTPUT_PORT];
4914 input_width = inst->prop.width[OUTPUT_PORT];
4915 output_height = inst->prop.height[CAPTURE_PORT];
4916 output_width = inst->prop.width[CAPTURE_PORT];
4917
4918 if (!input_height || !input_width || !output_height || !output_width) {
4919 dprintk(VIDC_ERR,
4920 "Invalid : Input height = %d width = %d",
4921 input_height, input_width);
4922 dprintk(VIDC_ERR,
4923 " output height = %d width = %d\n",
4924 output_height, output_width);
4925 return -ENOTSUPP;
4926 }
4927
4928 if (!inst->capability.scale_x.min ||
4929 !inst->capability.scale_x.max ||
4930 !inst->capability.scale_y.min ||
4931 !inst->capability.scale_y.max) {
4932
4933 if (input_width * input_height !=
4934 output_width * output_height) {
4935 dprintk(VIDC_ERR,
4936 "%s: scaling is not supported (%dx%d != %dx%d)\n",
4937 __func__, input_width, input_height,
4938 output_width, output_height);
4939 return -ENOTSUPP;
4940 }
4941
4942 dprintk(VIDC_DBG, "%s: supported WxH = %dx%d\n",
4943 __func__, input_width, input_height);
4944 return 0;
4945 }
4946
4947 x_min = (1<<16)/inst->capability.scale_x.min;
4948 y_min = (1<<16)/inst->capability.scale_y.min;
4949 x_max = inst->capability.scale_x.max >> 16;
4950 y_max = inst->capability.scale_y.max >> 16;
4951
4952 if (input_height > output_height) {
4953 if (input_height > x_min * output_height) {
4954 dprintk(VIDC_ERR,
4955 "Unsupported height downscale ratio %d vs %d\n",
4956 input_height/output_height, x_min);
4957 return -ENOTSUPP;
4958 }
4959 } else {
4960 if (output_height > x_max * input_height) {
4961 dprintk(VIDC_ERR,
4962 "Unsupported height upscale ratio %d vs %d\n",
4963 input_height/output_height, x_max);
4964 return -ENOTSUPP;
4965 }
4966 }
4967 if (input_width > output_width) {
4968 if (input_width > y_min * output_width) {
4969 dprintk(VIDC_ERR,
4970 "Unsupported width downscale ratio %d vs %d\n",
4971 input_width/output_width, y_min);
4972 return -ENOTSUPP;
4973 }
4974 } else {
4975 if (output_width > y_max * input_width) {
4976 dprintk(VIDC_ERR,
4977 "Unsupported width upscale ratio %d vs %d\n",
4978 input_width/output_width, y_max);
4979 return -ENOTSUPP;
4980 }
4981 }
4982 return 0;
4983}
4984
4985int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
4986{
4987 struct msm_vidc_capability *capability;
4988 int rc = 0;
4989 struct hfi_device *hdev;
4990 struct msm_vidc_core *core;
4991
4992 if (!inst || !inst->core || !inst->core->device) {
4993 dprintk(VIDC_WARN, "%s: Invalid parameter\n", __func__);
4994 return -EINVAL;
4995 }
4996 capability = &inst->capability;
4997 hdev = inst->core->device;
4998 core = inst->core;
4999 rc = msm_vidc_load_supported(inst);
5000 if (rc) {
5001 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
5002 msm_comm_kill_session(inst);
5003 dprintk(VIDC_WARN,
5004 "%s: Hardware is overloaded\n", __func__);
5005 return rc;
5006 }
5007
5008 if (!is_thermal_permissible(core)) {
5009 dprintk(VIDC_WARN,
5010 "Thermal level critical, stop all active sessions!\n");
5011 return -ENOTSUPP;
5012 }
5013
5014 if (!rc)
5015 msm_dcvs_try_enable(inst);
5016
5017 if (!rc) {
5018 if (inst->prop.width[CAPTURE_PORT] < capability->width.min ||
5019 inst->prop.height[CAPTURE_PORT] <
5020 capability->height.min) {
5021 dprintk(VIDC_ERR,
5022 "Unsupported WxH = (%u)x(%u), min supported is - (%u)x(%u)\n",
5023 inst->prop.width[CAPTURE_PORT],
5024 inst->prop.height[CAPTURE_PORT],
5025 capability->width.min,
5026 capability->height.min);
5027 rc = -ENOTSUPP;
5028 }
5029 if (!rc && inst->prop.width[CAPTURE_PORT] >
5030 capability->width.max) {
5031 dprintk(VIDC_ERR,
5032 "Unsupported width = %u supported max width = %u",
5033 inst->prop.width[CAPTURE_PORT],
5034 capability->width.max);
5035 rc = -ENOTSUPP;
5036 }
5037
5038 if (!rc && inst->prop.height[CAPTURE_PORT]
5039 * inst->prop.width[CAPTURE_PORT] >
5040 capability->width.max * capability->height.max) {
5041 dprintk(VIDC_ERR,
5042 "Unsupported WxH = (%u)x(%u), max supported is - (%u)x(%u)\n",
5043 inst->prop.width[CAPTURE_PORT],
5044 inst->prop.height[CAPTURE_PORT],
5045 capability->width.max, capability->height.max);
5046 rc = -ENOTSUPP;
5047 }
5048 }
5049 if (rc) {
5050 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
5051 msm_comm_kill_session(inst);
5052 dprintk(VIDC_ERR,
5053 "%s: Resolution unsupported\n", __func__);
5054 }
5055 return rc;
5056}
5057
5058static void msm_comm_generate_session_error(struct msm_vidc_inst *inst)
5059{
5060 enum hal_command_response cmd = HAL_SESSION_ERROR;
5061 struct msm_vidc_cb_cmd_done response = {0};
5062
5063 dprintk(VIDC_WARN, "msm_comm_generate_session_error\n");
5064 if (!inst || !inst->core) {
5065 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5066 return;
5067 }
5068
5069 response.session_id = inst;
5070 response.status = VIDC_ERR_FAIL;
5071 handle_session_error(cmd, (void *)&response);
5072}
5073
5074static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst)
5075{
5076 struct msm_vidc_core *core;
5077 enum hal_command_response cmd = HAL_SYS_ERROR;
5078 struct msm_vidc_cb_cmd_done response = {0};
5079
5080 if (!inst || !inst->core) {
5081 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5082 return;
5083 }
5084 core = inst->core;
5085 response.device_id = (u32) core->id;
5086 handle_sys_error(cmd, (void *) &response);
5087
5088}
5089
5090int msm_comm_kill_session(struct msm_vidc_inst *inst)
5091{
5092 int rc = 0;
5093
5094 if (!inst || !inst->core || !inst->core->device) {
5095 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5096 return -EINVAL;
5097 } else if (!inst->session) {
5098 /* There's no hfi session to kill */
5099 return 0;
5100 }
5101
5102 /*
5103 * We're internally forcibly killing the session, if fw is aware of
5104 * the session send session_abort to firmware to clean up and release
5105 * the session, else just kill the session inside the driver.
5106 */
5107 if ((inst->state >= MSM_VIDC_OPEN_DONE &&
5108 inst->state < MSM_VIDC_CLOSE_DONE) ||
5109 inst->state == MSM_VIDC_CORE_INVALID) {
5110 if (msm_comm_session_abort(inst)) {
5111 msm_comm_generate_sys_error(inst);
5112 return 0;
5113 }
5114 change_inst_state(inst, MSM_VIDC_CLOSE_DONE);
5115 msm_comm_generate_session_error(inst);
5116 } else {
5117 dprintk(VIDC_WARN,
5118 "Inactive session %pK, triggering an internal session error\n",
5119 inst);
5120 msm_comm_generate_session_error(inst);
5121
5122 }
5123
5124 return rc;
5125}
5126
5127struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst,
5128 size_t size, u32 align, u32 flags,
5129 enum hal_buffer buffer_type, int map_kernel)
5130{
5131 struct msm_smem *m = NULL;
5132
5133 if (!inst || !inst->core) {
5134 dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst);
5135 return NULL;
5136 }
5137 m = msm_smem_alloc(inst->mem_client, size, align,
5138 flags, buffer_type, map_kernel);
5139 return m;
5140}
5141
5142void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem)
5143{
5144 if (!inst || !inst->core || !mem) {
5145 dprintk(VIDC_ERR,
5146 "%s: invalid params: %pK %pK\n", __func__, inst, mem);
5147 return;
5148 }
5149 msm_smem_free(inst->mem_client, mem);
5150}
5151
5152int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst,
5153 struct msm_smem *mem, enum smem_cache_ops cache_ops)
5154{
5155 if (!inst || !mem) {
5156 dprintk(VIDC_ERR,
5157 "%s: invalid params: %pK %pK\n", __func__, inst, mem);
5158 return -EINVAL;
5159 }
5160 return msm_smem_cache_operations(inst->mem_client, mem, cache_ops);
5161}
5162
5163struct msm_smem *msm_comm_smem_user_to_kernel(struct msm_vidc_inst *inst,
5164 int fd, u32 offset, enum hal_buffer buffer_type)
5165{
5166 struct msm_smem *m = NULL;
5167
5168 if (!inst || !inst->core) {
5169 dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst);
5170 return NULL;
5171 }
5172
5173 if (inst->state == MSM_VIDC_CORE_INVALID) {
5174 dprintk(VIDC_ERR, "Core in Invalid state, returning from %s\n",
5175 __func__);
5176 return NULL;
5177 }
5178
5179 m = msm_smem_user_to_kernel(inst->mem_client,
5180 fd, offset, buffer_type);
5181 return m;
5182}
5183
5184void msm_vidc_fw_unload_handler(struct work_struct *work)
5185{
5186 struct msm_vidc_core *core = NULL;
5187 struct hfi_device *hdev = NULL;
5188 int rc = 0;
5189
5190 core = container_of(work, struct msm_vidc_core, fw_unload_work.work);
5191 if (!core || !core->device) {
5192 dprintk(VIDC_ERR, "%s - invalid work or core handle\n",
5193 __func__);
5194 return;
5195 }
5196
5197 hdev = core->device;
5198
5199 mutex_lock(&core->lock);
5200 if (list_empty(&core->instances) &&
5201 core->state != VIDC_CORE_UNINIT) {
5202 if (core->state > VIDC_CORE_INIT) {
5203 dprintk(VIDC_DBG, "Calling vidc_hal_core_release\n");
5204 rc = call_hfi_op(hdev, core_release,
5205 hdev->hfi_device_data);
5206 if (rc) {
5207 dprintk(VIDC_ERR,
5208 "Failed to release core, id = %d\n",
5209 core->id);
5210 mutex_unlock(&core->lock);
5211 return;
5212 }
5213 }
5214 core->state = VIDC_CORE_UNINIT;
5215 kfree(core->capabilities);
5216 core->capabilities = NULL;
5217 }
5218 mutex_unlock(&core->lock);
5219}
5220
5221int msm_comm_set_color_format(struct msm_vidc_inst *inst,
5222 enum hal_buffer buffer_type, int fourcc)
5223{
5224 struct hal_uncompressed_format_select hal_fmt = {0};
5225 enum hal_uncompressed_format format = HAL_UNUSED_COLOR;
5226 int rc = 0;
5227 struct hfi_device *hdev;
5228
5229 if (!inst || !inst->core || !inst->core->device) {
5230 dprintk(VIDC_ERR, "%s - invalid param\n", __func__);
5231 return -EINVAL;
5232 }
5233
5234 hdev = inst->core->device;
5235
5236 format = get_hal_uncompressed(fourcc);
5237 if (format == HAL_UNUSED_COLOR) {
5238 dprintk(VIDC_ERR, "Using unsupported colorformat %#x\n",
5239 fourcc);
5240 rc = -ENOTSUPP;
5241 goto exit;
5242 }
5243
5244 hal_fmt.buffer_type = buffer_type;
5245 hal_fmt.format = format;
5246
5247 rc = call_hfi_op(hdev, session_set_property, inst->session,
5248 HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT, &hal_fmt);
5249 if (rc)
5250 dprintk(VIDC_ERR,
5251 "Failed to set input color format\n");
5252 else
5253 dprintk(VIDC_DBG, "Setting uncompressed colorformat to %#x\n",
5254 format);
5255
5256exit:
5257 return rc;
5258}
5259
5260int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
5261{
5262 u32 property_id = 0;
5263 u64 us_per_frame = 0;
5264 void *pdata;
5265 int rc = 0, fps = 0;
5266 struct hal_frame_rate frame_rate;
5267 struct hfi_device *hdev;
5268
5269 if (!inst || !inst->core || !inst->core->device || !a) {
5270 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
5271 return -EINVAL;
5272 }
5273
5274 hdev = inst->core->device;
5275 property_id = HAL_CONFIG_FRAME_RATE;
5276
5277 if (a->parm.output.timeperframe.denominator) {
5278 switch (a->type) {
5279 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
5280 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
5281 us_per_frame = a->parm.output.timeperframe.numerator *
5282 (u64)USEC_PER_SEC;
5283 do_div(us_per_frame, a->parm.output.
5284 timeperframe.denominator);
5285 break;
5286 default:
5287 dprintk(VIDC_ERR,
5288 "Scale clocks : Unknown buffer type %d\n",
5289 a->type);
5290 break;
5291 }
5292 }
5293
5294 if (!us_per_frame) {
5295 dprintk(VIDC_ERR,
5296 "Failed to scale clocks : time between frames is 0\n");
5297 rc = -EINVAL;
5298 goto exit;
5299 }
5300
5301 fps = USEC_PER_SEC;
5302 do_div(fps, us_per_frame);
5303
5304 if (fps % 15 == 14 || fps % 24 == 23)
5305 fps = fps + 1;
5306 else if ((fps > 1) && (fps % 24 == 1 || fps % 15 == 1))
5307 fps = fps - 1;
5308
Praneeth Paladugue1679112017-01-27 10:07:15 -08005309 if (fps < inst->capability.frame_rate.min ||
5310 fps > inst->capability.frame_rate.max) {
5311 dprintk(VIDC_ERR,
5312 "FPS is out of limits : fps = %d Min = %d, Max = %d\n",
5313 fps, inst->capability.frame_rate.min,
5314 inst->capability.frame_rate.max);
5315 rc = -EINVAL;
5316 goto exit;
5317 }
5318
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08005319 if (inst->prop.fps != fps) {
5320 dprintk(VIDC_PROF, "reported fps changed for %pK: %d->%d\n",
5321 inst, inst->prop.fps, fps);
5322 inst->prop.fps = fps;
5323 frame_rate.frame_rate = inst->prop.fps * BIT(16);
5324 frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
5325 pdata = &frame_rate;
5326 if (inst->session_type == MSM_VIDC_ENCODER) {
5327 rc = call_hfi_op(hdev, session_set_property,
5328 inst->session, property_id, pdata);
5329
5330 if (rc)
5331 dprintk(VIDC_WARN,
5332 "Failed to set frame rate %d\n", rc);
5333 } else {
5334 msm_dcvs_init_load(inst);
5335 }
5336 msm_comm_scale_clocks_and_bus(inst);
5337 msm_dcvs_try_enable(inst);
5338 }
5339exit:
5340 return rc;
5341}
5342
5343void msm_comm_print_inst_info(struct msm_vidc_inst *inst)
5344{
5345 struct buffer_info *temp;
5346 struct internal_buf *buf;
5347 int i = 0;
5348 bool is_decode = false;
5349 enum vidc_ports port;
5350 bool is_secure = false;
5351
5352 if (!inst) {
5353 dprintk(VIDC_ERR, "%s - invalid param %pK\n",
5354 __func__, inst);
5355 return;
5356 }
5357
5358 is_decode = inst->session_type == MSM_VIDC_DECODER;
5359 port = is_decode ? OUTPUT_PORT : CAPTURE_PORT;
5360 is_secure = inst->flags & VIDC_SECURE;
5361 dprintk(VIDC_ERR,
5362 "%s session, %s, Codec type: %s HxW: %d x %d fps: %d bitrate: %d bit-depth: %s\n",
5363 is_decode ? "Decode" : "Encode",
5364 is_secure ? "Secure" : "Non-Secure",
5365 inst->fmts[port].name,
5366 inst->prop.height[port], inst->prop.width[port],
5367 inst->prop.fps, inst->prop.bitrate,
5368 !inst->bit_depth ? "8" : "10");
5369
5370 dprintk(VIDC_ERR,
5371 "---Buffer details for inst: %pK of type: %d---\n",
5372 inst, inst->session_type);
5373 mutex_lock(&inst->registeredbufs.lock);
5374 dprintk(VIDC_ERR, "registered buffer list:\n");
5375 list_for_each_entry(temp, &inst->registeredbufs.list, list)
5376 for (i = 0; i < temp->num_planes; i++)
5377 dprintk(VIDC_ERR,
5378 "type: %d plane: %d addr: %pa size: %d\n",
5379 temp->type, i, &temp->device_addr[i],
5380 temp->size[i]);
5381
5382 mutex_unlock(&inst->registeredbufs.lock);
5383
5384 mutex_lock(&inst->scratchbufs.lock);
5385 dprintk(VIDC_ERR, "scratch buffer list:\n");
5386 list_for_each_entry(buf, &inst->scratchbufs.list, list)
5387 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5388 buf->buffer_type, &buf->handle->device_addr,
5389 buf->handle->size);
5390 mutex_unlock(&inst->scratchbufs.lock);
5391
5392 mutex_lock(&inst->persistbufs.lock);
5393 dprintk(VIDC_ERR, "persist buffer list:\n");
5394 list_for_each_entry(buf, &inst->persistbufs.list, list)
5395 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5396 buf->buffer_type, &buf->handle->device_addr,
5397 buf->handle->size);
5398 mutex_unlock(&inst->persistbufs.lock);
5399
5400 mutex_lock(&inst->outputbufs.lock);
5401 dprintk(VIDC_ERR, "dpb buffer list:\n");
5402 list_for_each_entry(buf, &inst->outputbufs.list, list)
5403 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5404 buf->buffer_type, &buf->handle->device_addr,
5405 buf->handle->size);
5406 mutex_unlock(&inst->outputbufs.lock);
5407}
5408
5409static void msm_comm_print_debug_info(struct msm_vidc_inst *inst)
5410{
5411 struct msm_vidc_core *core = NULL;
5412 struct msm_vidc_inst *temp = NULL;
5413
5414 if (!inst || !inst->core) {
5415 dprintk(VIDC_ERR, "%s - invalid param %pK %pK\n",
5416 __func__, inst, core);
5417 return;
5418 }
5419 core = inst->core;
5420
5421 dprintk(VIDC_ERR, "Venus core frequency = %lu",
5422 msm_comm_get_clock_rate(core));
5423 mutex_lock(&core->lock);
5424 dprintk(VIDC_ERR, "Printing instance info that caused Error\n");
5425 msm_comm_print_inst_info(inst);
5426 dprintk(VIDC_ERR, "Printing remaining instances info\n");
5427 list_for_each_entry(temp, &core->instances, list) {
5428 /* inst already printed above. Hence don't repeat.*/
5429 if (temp == inst)
5430 continue;
5431 msm_comm_print_inst_info(temp);
5432 }
5433 mutex_unlock(&core->lock);
5434}