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