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