blob: 564ab99bd5816b9ac07e4df8635ae5f9c48416d5 [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;
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002015 u64 time_nsec = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002016 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)) {
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002060 time_nsec = fill_buf_done->timestamp_hi;
2061 time_nsec = (time_nsec << 32) |
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002062 fill_buf_done->timestamp_lo;
2063 } else {
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002064 time_nsec = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002065 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;
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002073 vb->timestamp = time_nsec;
2074
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002075 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,
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08002138 fill_buf_done->filled_len1, fill_buf_done->offset1, time_nsec,
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002139 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{
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003586 int extra_idx;
3587 enum v4l2_buf_type type = vb->type;
3588 enum vidc_ports port = type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
3589 OUTPUT_PORT : CAPTURE_PORT;
3590 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
3591
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003592 data->alloc_len = vb->planes[0].length;
3593 data->device_addr = vb->planes[0].m.userptr;
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08003594 data->timestamp = vb->timestamp;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003595 data->flags = 0;
3596 data->clnt_data = data->device_addr;
3597
3598 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
3599 bool pic_decoding_mode = msm_comm_g_ctrl_for_id(inst,
3600 V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE);
3601
3602 data->buffer_type = HAL_BUFFER_INPUT;
3603 data->filled_len = vb->planes[0].bytesused;
3604 data->offset = vb->planes[0].data_offset;
3605
3606 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_EOS)
3607 data->flags |= HAL_BUFFERFLAG_EOS;
3608
3609 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG)
3610 data->flags |= HAL_BUFFERFLAG_CODECCONFIG;
3611
3612 if (vbuf->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY)
3613 data->flags |= HAL_BUFFERFLAG_DECODEONLY;
3614
3615 if (vbuf->flags & V4L2_QCOM_BUF_TIMESTAMP_INVALID)
3616 data->timestamp = LLONG_MAX;
3617
3618 /* XXX: This is a dirty hack necessitated by the firmware,
3619 * which refuses to issue FBDs for non I-frames in Picture Type
3620 * Decoding mode, unless we pass in non-zero value in mark_data
3621 * and mark_target.
3622 */
3623 data->mark_data = data->mark_target =
3624 pic_decoding_mode ? 0xdeadbeef : 0;
3625
3626 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
3627 data->buffer_type = msm_comm_get_hal_output_buffer(inst);
3628 }
3629
3630 extra_idx = EXTRADATA_IDX(inst->fmts[port].num_planes);
3631 if (extra_idx && extra_idx < VIDEO_MAX_PLANES &&
3632 vb->planes[extra_idx].m.userptr) {
3633 data->extradata_addr = vb->planes[extra_idx].m.userptr;
3634 data->extradata_size = vb->planes[extra_idx].length;
3635 data->flags |= HAL_BUFFERFLAG_EXTRADATA;
3636 }
3637}
3638
3639static unsigned int count_single_batch(struct msm_vidc_list *list,
3640 enum v4l2_buf_type type)
3641{
3642 struct vb2_buf_entry *buf;
3643 int count = 0;
3644 struct vb2_v4l2_buffer *vbuf = NULL;
3645
3646 mutex_lock(&list->lock);
3647 list_for_each_entry(buf, &list->list, list) {
3648 if (buf->vb->type != type)
3649 continue;
3650
3651 ++count;
3652
3653 vbuf = to_vb2_v4l2_buffer(buf->vb);
3654 if (!(vbuf->flags & V4L2_MSM_BUF_FLAG_DEFER))
3655 goto found_batch;
3656 }
3657 /* don't have a full batch */
3658 count = 0;
3659
3660found_batch:
3661 mutex_unlock(&list->lock);
3662 return count;
3663}
3664
3665static unsigned int count_buffers(struct msm_vidc_list *list,
3666 enum v4l2_buf_type type)
3667{
3668 struct vb2_buf_entry *buf;
3669 int count = 0;
3670
3671 mutex_lock(&list->lock);
3672 list_for_each_entry(buf, &list->list, list) {
3673 if (buf->vb->type != type)
3674 continue;
3675
3676 ++count;
3677 }
3678 mutex_unlock(&list->lock);
3679
3680 return count;
3681}
3682
3683static void log_frame(struct msm_vidc_inst *inst, struct vidc_frame_data *data,
3684 enum v4l2_buf_type type)
3685{
3686 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
3687 dprintk(VIDC_DBG,
3688 "Sending etb (%pa) to hal: filled: %d, ts: %lld, flags = %#x\n",
3689 &data->device_addr, data->filled_len,
3690 data->timestamp, data->flags);
3691 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_ETB);
3692
3693 if (msm_vidc_bitrate_clock_scaling &&
3694 inst->session_type == MSM_VIDC_DECODER &&
3695 !inst->dcvs_mode)
3696 inst->instant_bitrate =
3697 data->filled_len * 8 * inst->prop.fps;
3698 else
3699 inst->instant_bitrate = 0;
3700 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
3701 dprintk(VIDC_DBG,
3702 "Sending ftb (%pa) to hal: size: %d, ts: %lld, flags = %#x\n",
3703 &data->device_addr, data->alloc_len,
3704 data->timestamp, data->flags);
3705 msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FTB);
3706 }
3707
3708 msm_dcvs_check_and_scale_clocks(inst,
3709 type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
3710
3711 if (msm_vidc_bitrate_clock_scaling && !inst->dcvs_mode &&
3712 type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
3713 inst->session_type == MSM_VIDC_DECODER)
3714 if (msm_comm_scale_clocks(inst->core))
3715 dprintk(VIDC_WARN,
3716 "Failed to scale clocks. Performance might be impacted\n");
3717
3718 if (msm_comm_vote_bus(inst->core))
3719 dprintk(VIDC_WARN,
3720 "Failed to scale bus. Performance might be impacted\n");
3721}
3722
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003723/*
3724 * Attempts to queue `vb` to hardware. If, for various reasons, the buffer
3725 * cannot be queued to hardware, the buffer will be staged for commit in the
3726 * pending queue. Once the hardware reaches a good state (or if `vb` is NULL,
3727 * the subsequent *_qbuf will commit the previously staged buffers to hardware.
3728 */
3729int msm_comm_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb)
3730{
3731 int rc = 0, capture_count, output_count;
3732 struct msm_vidc_core *core;
3733 struct hfi_device *hdev;
3734 struct {
3735 struct vidc_frame_data *data;
3736 int count;
3737 } etbs, ftbs;
3738 bool defer = false, batch_mode;
3739 struct vb2_buf_entry *temp, *next;
3740 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
3741
3742 if (!inst) {
3743 dprintk(VIDC_ERR, "%s: Invalid arguments\n", __func__);
3744 return -EINVAL;
3745 }
3746
3747 core = inst->core;
3748 hdev = core->device;
3749
3750 if (inst->state == MSM_VIDC_CORE_INVALID ||
3751 core->state == VIDC_CORE_INVALID ||
3752 core->state == VIDC_CORE_UNINIT) {
3753 dprintk(VIDC_ERR, "Core is in bad state. Can't Queue\n");
3754 return -EINVAL;
3755 }
3756
3757 /*
3758 * Stick the buffer into the pendinq, we'll pop it out later on
3759 * if we want to commit it to hardware
3760 */
3761 if (vb) {
3762 temp = kzalloc(sizeof(*temp), GFP_KERNEL);
3763 if (!temp) {
3764 dprintk(VIDC_ERR, "Out of memory\n");
3765 goto err_no_mem;
3766 }
3767
3768 temp->vb = vb;
3769 mutex_lock(&inst->pendingq.lock);
3770 list_add_tail(&temp->list, &inst->pendingq.list);
3771 mutex_unlock(&inst->pendingq.lock);
3772 }
3773
3774 batch_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_VIDC_QBUF_MODE)
3775 == V4L2_VIDC_QBUF_BATCHED;
3776 capture_count = (batch_mode ? &count_single_batch : &count_buffers)
3777 (&inst->pendingq, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
3778 output_count = (batch_mode ? &count_single_batch : &count_buffers)
3779 (&inst->pendingq, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
3780
3781 /*
3782 * Somewhat complicated logic to prevent queuing the buffer to hardware.
3783 * Don't queue if:
3784 * 1) Hardware isn't ready (that's simple)
3785 */
3786 defer = defer ?: inst->state != MSM_VIDC_START_DONE;
3787
3788 /*
3789 * 2) The client explicitly tells us not to because it wants this
3790 * buffer to be batched with future frames. The batch size (on both
3791 * capabilities) is completely determined by the client.
3792 */
3793 defer = defer ?: vbuf && vbuf->flags & V4L2_MSM_BUF_FLAG_DEFER;
3794
3795 /* 3) If we're in batch mode, we must have full batches of both types */
3796 defer = defer ?: batch_mode && (!output_count || !capture_count);
3797
3798 if (defer) {
3799 dprintk(VIDC_DBG, "Deferring queue of %pK\n", vb);
3800 return 0;
3801 }
3802
3803 dprintk(VIDC_DBG, "%sing %d etbs and %d ftbs\n",
3804 batch_mode ? "Batch" : "Process",
3805 output_count, capture_count);
3806
3807 etbs.data = kcalloc(output_count, sizeof(*etbs.data), GFP_KERNEL);
3808 ftbs.data = kcalloc(capture_count, sizeof(*ftbs.data), GFP_KERNEL);
3809 /*
3810 * Note that it's perfectly normal for (e|f)tbs.data to be NULL if
3811 * we're not in batch mode (i.e. (output|capture)_count == 0)
3812 */
3813 if ((!etbs.data && output_count) ||
3814 (!ftbs.data && capture_count)) {
3815 dprintk(VIDC_ERR, "Failed to alloc memory for batching\n");
3816 kfree(etbs.data);
3817 etbs.data = NULL;
3818
3819 kfree(ftbs.data);
3820 ftbs.data = NULL;
3821 goto err_no_mem;
3822 }
3823
3824 etbs.count = ftbs.count = 0;
3825
3826 /*
3827 * Try to collect all pending buffers into 2 batches of ftb and etb
3828 * Note that these "batches" might be empty if we're no in batching mode
3829 * and the pendingq is empty
3830 */
3831 mutex_lock(&inst->pendingq.lock);
3832 list_for_each_entry_safe(temp, next, &inst->pendingq.list, list) {
3833 struct vidc_frame_data *frame_data = NULL;
3834
3835 switch (temp->vb->type) {
3836 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
3837 if (ftbs.count < capture_count && ftbs.data)
3838 frame_data = &ftbs.data[ftbs.count++];
3839 break;
3840 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
3841 if (etbs.count < output_count && etbs.data)
3842 frame_data = &etbs.data[etbs.count++];
3843 break;
3844 default:
3845 break;
3846 }
3847
3848 if (!frame_data)
3849 continue;
3850
3851 populate_frame_data(frame_data, temp->vb, inst);
3852
3853 list_del(&temp->list);
3854 kfree(temp);
3855 }
3856 mutex_unlock(&inst->pendingq.lock);
3857
3858 /* Finally commit all our frame(s) to H/W */
3859 if (batch_mode) {
3860 int ftb_index = 0, c = 0;
3861
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003862 ftb_index = c;
3863 rc = call_hfi_op(hdev, session_process_batch, inst->session,
3864 etbs.count, etbs.data,
3865 ftbs.count - ftb_index, &ftbs.data[ftb_index]);
3866 if (rc) {
3867 dprintk(VIDC_ERR,
3868 "Failed to queue batch of %d ETBs and %d FTBs\n",
3869 etbs.count, ftbs.count);
3870 goto err_bad_input;
3871 }
3872
3873 for (c = ftb_index; c < ftbs.count; ++c) {
3874 log_frame(inst, &ftbs.data[c],
3875 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
3876 }
3877
3878 for (c = 0; c < etbs.count; ++c) {
3879 log_frame(inst, &etbs.data[c],
3880 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
3881 }
3882 }
3883
3884 if (!batch_mode && etbs.count) {
3885 int c = 0;
3886
3887 for (c = 0; c < etbs.count; ++c) {
3888 struct vidc_frame_data *frame_data = &etbs.data[c];
3889
3890 rc = call_hfi_op(hdev, session_etb, inst->session,
3891 frame_data);
3892 if (rc) {
3893 dprintk(VIDC_ERR, "Failed to issue etb: %d\n",
3894 rc);
3895 goto err_bad_input;
3896 }
3897
3898 log_frame(inst, frame_data,
3899 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
3900 }
3901 }
3902
3903 if (!batch_mode && ftbs.count) {
3904 int c = 0;
3905
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08003906 for (; c < ftbs.count; ++c) {
3907 struct vidc_frame_data *frame_data = &ftbs.data[c];
3908
3909 rc = call_hfi_op(hdev, session_ftb,
3910 inst->session, frame_data);
3911 if (rc) {
3912 dprintk(VIDC_ERR, "Failed to issue ftb: %d\n",
3913 rc);
3914 goto err_bad_input;
3915 }
3916
3917 log_frame(inst, frame_data,
3918 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
3919 }
3920 }
3921
3922err_bad_input:
3923 if (rc)
3924 dprintk(VIDC_ERR, "Failed to queue buffer\n");
3925
3926 kfree(etbs.data);
3927 kfree(ftbs.data);
3928err_no_mem:
3929 return rc;
3930}
3931
3932int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst)
3933{
3934 int rc = 0, i = 0;
3935 union hal_get_property hprop;
3936
3937 rc = msm_comm_try_get_prop(inst, HAL_PARAM_GET_BUFFER_REQUIREMENTS,
3938 &hprop);
3939 if (rc) {
3940 dprintk(VIDC_ERR, "Failed getting buffer requirements: %d", rc);
3941 return rc;
3942 }
3943
3944 dprintk(VIDC_DBG, "Buffer requirements:\n");
3945 dprintk(VIDC_DBG, "%15s %8s %8s\n", "buffer type", "count", "size");
3946 for (i = 0; i < HAL_BUFFER_MAX; i++) {
3947 struct hal_buffer_requirements req = hprop.buf_req.buffer[i];
3948
3949 inst->buff_req.buffer[i] = req;
3950 dprintk(VIDC_DBG, "%15s %8d %8d\n",
3951 get_buffer_name(req.buffer_type),
3952 req.buffer_count_actual, req.buffer_size);
3953 }
3954
3955 dprintk(VIDC_PROF, "Input buffers: %d, Output buffers: %d\n",
3956 inst->buff_req.buffer[0].buffer_count_actual,
3957 inst->buff_req.buffer[1].buffer_count_actual);
3958 return rc;
3959}
3960
3961int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
3962 union hal_get_property *hprop)
3963{
3964 int rc = 0;
3965 struct hfi_device *hdev;
3966 struct getprop_buf *buf;
3967
3968 if (!inst || !inst->core || !inst->core->device) {
3969 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
3970 return -EINVAL;
3971 }
3972
3973 hdev = inst->core->device;
3974 mutex_lock(&inst->sync_lock);
3975 if (inst->state < MSM_VIDC_OPEN_DONE ||
3976 inst->state >= MSM_VIDC_CLOSE) {
3977
3978 /* No need to check inst->state == MSM_VIDC_INVALID since
3979 * INVALID is > CLOSE_DONE. When core went to INVALID state,
3980 * we put all the active instances in INVALID. So > CLOSE_DONE
3981 * is enough check to have.
3982 */
3983
3984 dprintk(VIDC_ERR,
3985 "In Wrong state to call Buf Req: Inst %pK or Core %pK\n",
3986 inst, inst->core);
3987 rc = -EAGAIN;
3988 mutex_unlock(&inst->sync_lock);
3989 goto exit;
3990 }
3991 mutex_unlock(&inst->sync_lock);
3992
3993 switch (ptype) {
3994 case HAL_PARAM_PROFILE_LEVEL_CURRENT:
3995 case HAL_CONFIG_VDEC_ENTROPY:
3996 rc = call_hfi_op(hdev, session_get_property, inst->session,
3997 ptype);
3998 break;
3999 case HAL_PARAM_GET_BUFFER_REQUIREMENTS:
4000 rc = call_hfi_op(hdev, session_get_buf_req, inst->session);
4001 break;
4002 default:
4003 rc = -EAGAIN;
4004 break;
4005 }
4006
4007 if (rc) {
4008 dprintk(VIDC_ERR, "Can't query hardware for property: %d\n",
4009 rc);
4010 goto exit;
4011 }
4012
4013 rc = wait_for_completion_timeout(&inst->completions[
4014 SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO)],
4015 msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
4016 if (!rc) {
4017 dprintk(VIDC_ERR,
4018 "%s: Wait interrupted or timed out [%pK]: %d\n",
4019 __func__, inst,
4020 SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO));
4021 inst->state = MSM_VIDC_CORE_INVALID;
4022 msm_comm_kill_session(inst);
4023 call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
4024 dprintk(VIDC_ERR,
4025 "SESS_PROP timeout can potentially crash the system\n");
4026 if (inst->core->resources.debug_timeout)
4027 msm_comm_print_debug_info(inst);
4028
4029 msm_vidc_handle_hw_error(inst->core);
4030 rc = -ETIMEDOUT;
4031 goto exit;
4032 } else {
4033 /* wait_for_completion_timeout returns jiffies before expiry */
4034 rc = 0;
4035 }
4036
4037 mutex_lock(&inst->pending_getpropq.lock);
4038 if (!list_empty(&inst->pending_getpropq.list)) {
4039 buf = list_first_entry(&inst->pending_getpropq.list,
4040 struct getprop_buf, list);
4041 *hprop = *(union hal_get_property *)buf->data;
4042 kfree(buf->data);
4043 list_del(&buf->list);
4044 kfree(buf);
4045 } else {
4046 dprintk(VIDC_ERR, "%s getprop list empty\n", __func__);
4047 rc = -EINVAL;
4048 }
4049 mutex_unlock(&inst->pending_getpropq.lock);
4050exit:
4051 return rc;
4052}
4053
4054int msm_comm_release_output_buffers(struct msm_vidc_inst *inst)
4055{
4056 struct msm_smem *handle;
4057 struct internal_buf *buf, *dummy;
4058 struct vidc_buffer_addr_info buffer_info;
4059 int rc = 0;
4060 struct msm_vidc_core *core;
4061 struct hfi_device *hdev;
4062
4063 if (!inst) {
4064 dprintk(VIDC_ERR,
4065 "Invalid instance pointer = %pK\n", inst);
4066 return -EINVAL;
4067 }
4068 mutex_lock(&inst->outputbufs.lock);
4069 if (list_empty(&inst->outputbufs.list)) {
4070 dprintk(VIDC_DBG, "%s - No OUTPUT buffers allocated\n",
4071 __func__);
4072 mutex_unlock(&inst->outputbufs.lock);
4073 return 0;
4074 }
4075 mutex_unlock(&inst->outputbufs.lock);
4076
4077 core = inst->core;
4078 if (!core) {
4079 dprintk(VIDC_ERR,
4080 "Invalid core pointer = %pK\n", core);
4081 return -EINVAL;
4082 }
4083 hdev = core->device;
4084 if (!hdev) {
4085 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4086 return -EINVAL;
4087 }
4088 mutex_lock(&inst->outputbufs.lock);
4089 list_for_each_entry_safe(buf, dummy, &inst->outputbufs.list, list) {
4090 handle = buf->handle;
4091 if (!handle) {
4092 dprintk(VIDC_ERR, "%s - invalid handle\n", __func__);
4093 goto exit;
4094 }
4095
4096 buffer_info.buffer_size = handle->size;
4097 buffer_info.buffer_type = buf->buffer_type;
4098 buffer_info.num_buffers = 1;
4099 buffer_info.align_device_addr = handle->device_addr;
4100 if (inst->buffer_mode_set[CAPTURE_PORT] ==
4101 HAL_BUFFER_MODE_STATIC &&
4102 inst->state != MSM_VIDC_CORE_INVALID &&
4103 core->state != VIDC_CORE_INVALID) {
4104 buffer_info.response_required = false;
4105 rc = call_hfi_op(hdev, session_release_buffers,
4106 (void *)inst->session, &buffer_info);
4107 if (rc) {
4108 dprintk(VIDC_WARN,
4109 "Rel output buf fail:%pa, %d\n",
4110 &buffer_info.align_device_addr,
4111 buffer_info.buffer_size);
4112 }
4113 }
4114
4115 list_del(&buf->list);
4116 msm_comm_smem_free(inst, buf->handle);
4117 kfree(buf);
4118 }
4119
4120exit:
4121 mutex_unlock(&inst->outputbufs.lock);
4122 return rc;
4123}
4124
4125static enum hal_buffer scratch_buf_sufficient(struct msm_vidc_inst *inst,
4126 enum hal_buffer buffer_type)
4127{
4128 struct hal_buffer_requirements *bufreq = NULL;
4129 struct internal_buf *buf;
4130 int count = 0;
4131
4132 if (!inst) {
4133 dprintk(VIDC_ERR, "%s - invalid param\n", __func__);
4134 goto not_sufficient;
4135 }
4136
4137 bufreq = get_buff_req_buffer(inst, buffer_type);
4138 if (!bufreq)
4139 goto not_sufficient;
4140
4141 /* Check if current scratch buffers are sufficient */
4142 mutex_lock(&inst->scratchbufs.lock);
4143
4144 list_for_each_entry(buf, &inst->scratchbufs.list, list) {
4145 if (!buf->handle) {
4146 dprintk(VIDC_ERR, "%s: invalid buf handle\n", __func__);
4147 mutex_unlock(&inst->scratchbufs.lock);
4148 goto not_sufficient;
4149 }
4150 if (buf->buffer_type == buffer_type &&
4151 buf->handle->size >= bufreq->buffer_size)
4152 count++;
4153 }
4154 mutex_unlock(&inst->scratchbufs.lock);
4155
4156 if (count != bufreq->buffer_count_actual)
4157 goto not_sufficient;
4158
4159 dprintk(VIDC_DBG,
4160 "Existing scratch buffer is sufficient for buffer type %#x\n",
4161 buffer_type);
4162
4163 return buffer_type;
4164
4165not_sufficient:
4166 return HAL_BUFFER_NONE;
4167}
4168
4169int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst,
4170 bool check_for_reuse)
4171{
4172 struct msm_smem *handle;
4173 struct internal_buf *buf, *dummy;
4174 struct vidc_buffer_addr_info buffer_info;
4175 int rc = 0;
4176 struct msm_vidc_core *core;
4177 struct hfi_device *hdev;
4178 enum hal_buffer sufficiency = HAL_BUFFER_NONE;
4179
4180 if (!inst) {
4181 dprintk(VIDC_ERR,
4182 "Invalid instance pointer = %pK\n", inst);
4183 return -EINVAL;
4184 }
4185 core = inst->core;
4186 if (!core) {
4187 dprintk(VIDC_ERR,
4188 "Invalid core pointer = %pK\n", core);
4189 return -EINVAL;
4190 }
4191 hdev = core->device;
4192 if (!hdev) {
4193 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4194 return -EINVAL;
4195 }
4196
4197 if (check_for_reuse) {
4198 sufficiency |= scratch_buf_sufficient(inst,
4199 HAL_BUFFER_INTERNAL_SCRATCH);
4200
4201 sufficiency |= scratch_buf_sufficient(inst,
4202 HAL_BUFFER_INTERNAL_SCRATCH_1);
4203
4204 sufficiency |= scratch_buf_sufficient(inst,
4205 HAL_BUFFER_INTERNAL_SCRATCH_2);
4206 }
4207
4208 mutex_lock(&inst->scratchbufs.lock);
4209 list_for_each_entry_safe(buf, dummy, &inst->scratchbufs.list, list) {
4210 if (!buf->handle) {
4211 dprintk(VIDC_ERR, "%s - buf->handle NULL\n", __func__);
4212 rc = -EINVAL;
4213 goto exit;
4214 }
4215
4216 handle = buf->handle;
4217 buffer_info.buffer_size = handle->size;
4218 buffer_info.buffer_type = buf->buffer_type;
4219 buffer_info.num_buffers = 1;
4220 buffer_info.align_device_addr = handle->device_addr;
4221 if (inst->state != MSM_VIDC_CORE_INVALID &&
4222 core->state != VIDC_CORE_INVALID) {
4223 buffer_info.response_required = true;
4224 rc = call_hfi_op(hdev, session_release_buffers,
4225 (void *)inst->session, &buffer_info);
4226 if (rc) {
4227 dprintk(VIDC_WARN,
4228 "Rel scrtch buf fail:%pa, %d\n",
4229 &buffer_info.align_device_addr,
4230 buffer_info.buffer_size);
4231 }
4232 mutex_unlock(&inst->scratchbufs.lock);
4233 rc = wait_for_sess_signal_receipt(inst,
4234 HAL_SESSION_RELEASE_BUFFER_DONE);
4235 if (rc) {
4236 change_inst_state(inst,
4237 MSM_VIDC_CORE_INVALID);
4238 msm_comm_kill_session(inst);
4239 }
4240 mutex_lock(&inst->scratchbufs.lock);
4241 }
4242
4243 /*If scratch buffers can be reused, do not free the buffers*/
4244 if (sufficiency & buf->buffer_type)
4245 continue;
4246
4247 list_del(&buf->list);
4248 msm_comm_smem_free(inst, buf->handle);
4249 kfree(buf);
4250 }
4251
4252exit:
4253 mutex_unlock(&inst->scratchbufs.lock);
4254 return rc;
4255}
4256
4257int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst)
4258{
4259 struct msm_smem *handle;
4260 struct list_head *ptr, *next;
4261 struct internal_buf *buf;
4262 struct vidc_buffer_addr_info buffer_info;
4263 int rc = 0;
4264 struct msm_vidc_core *core;
4265 struct hfi_device *hdev;
4266
4267 if (!inst) {
4268 dprintk(VIDC_ERR,
4269 "Invalid instance pointer = %pK\n", inst);
4270 return -EINVAL;
4271 }
4272 core = inst->core;
4273 if (!core) {
4274 dprintk(VIDC_ERR,
4275 "Invalid core pointer = %pK\n", core);
4276 return -EINVAL;
4277 }
4278 hdev = core->device;
4279 if (!hdev) {
4280 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4281 return -EINVAL;
4282 }
4283
4284 mutex_lock(&inst->persistbufs.lock);
4285 list_for_each_safe(ptr, next, &inst->persistbufs.list) {
4286 buf = list_entry(ptr, struct internal_buf, list);
4287 handle = buf->handle;
4288 buffer_info.buffer_size = handle->size;
4289 buffer_info.buffer_type = buf->buffer_type;
4290 buffer_info.num_buffers = 1;
4291 buffer_info.align_device_addr = handle->device_addr;
4292 if (inst->state != MSM_VIDC_CORE_INVALID &&
4293 core->state != VIDC_CORE_INVALID) {
4294 buffer_info.response_required = true;
4295 rc = call_hfi_op(hdev, session_release_buffers,
4296 (void *)inst->session, &buffer_info);
4297 if (rc) {
4298 dprintk(VIDC_WARN,
4299 "Rel prst buf fail:%pa, %d\n",
4300 &buffer_info.align_device_addr,
4301 buffer_info.buffer_size);
4302 }
4303 mutex_unlock(&inst->persistbufs.lock);
4304 rc = wait_for_sess_signal_receipt(inst,
4305 HAL_SESSION_RELEASE_BUFFER_DONE);
4306 if (rc) {
4307 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
4308 msm_comm_kill_session(inst);
4309 }
4310 mutex_lock(&inst->persistbufs.lock);
4311 }
4312 list_del(&buf->list);
4313 msm_comm_smem_free(inst, buf->handle);
4314 kfree(buf);
4315 }
4316 mutex_unlock(&inst->persistbufs.lock);
4317 return rc;
4318}
4319
4320int msm_comm_try_set_prop(struct msm_vidc_inst *inst,
4321 enum hal_property ptype, void *pdata)
4322{
4323 int rc = 0;
4324 struct hfi_device *hdev;
4325
4326 if (!inst) {
4327 dprintk(VIDC_ERR, "Invalid input: %pK\n", inst);
4328 return -EINVAL;
4329 }
4330
4331 if (!inst->core || !inst->core->device) {
4332 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4333 return -EINVAL;
4334 }
4335 hdev = inst->core->device;
4336
4337 mutex_lock(&inst->sync_lock);
4338 if (inst->state < MSM_VIDC_OPEN_DONE || inst->state >= MSM_VIDC_CLOSE) {
4339 dprintk(VIDC_ERR, "Not in proper state to set property\n");
4340 rc = -EAGAIN;
4341 goto exit;
4342 }
4343 rc = call_hfi_op(hdev, session_set_property, (void *)inst->session,
4344 ptype, pdata);
4345 if (rc)
4346 dprintk(VIDC_ERR, "Failed to set hal property for framesize\n");
4347exit:
4348 mutex_unlock(&inst->sync_lock);
4349 return rc;
4350}
4351
4352int msm_comm_set_output_buffers(struct msm_vidc_inst *inst)
4353{
4354 int rc = 0;
4355
4356 if (!inst || !inst->core || !inst->core->device) {
4357 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4358 return -EINVAL;
4359 }
4360
4361 if (msm_comm_release_output_buffers(inst))
4362 dprintk(VIDC_WARN, "Failed to release output buffers\n");
4363
4364 rc = set_output_buffers(inst, HAL_BUFFER_OUTPUT);
4365 if (rc)
4366 goto error;
4367 return rc;
4368error:
4369 msm_comm_release_output_buffers(inst);
4370 return rc;
4371}
4372
4373int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst)
4374{
4375 int rc = 0;
4376
4377 if (!inst || !inst->core || !inst->core->device) {
4378 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4379 return -EINVAL;
4380 }
4381
4382 if (msm_comm_release_scratch_buffers(inst, true))
4383 dprintk(VIDC_WARN, "Failed to release scratch buffers\n");
4384
4385 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH,
4386 &inst->scratchbufs);
4387 if (rc)
4388 goto error;
4389
4390 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_1,
4391 &inst->scratchbufs);
4392 if (rc)
4393 goto error;
4394
4395 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_SCRATCH_2,
4396 &inst->scratchbufs);
4397 if (rc)
4398 goto error;
4399
4400 return rc;
4401error:
4402 msm_comm_release_scratch_buffers(inst, false);
4403 return rc;
4404}
4405
4406int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst)
4407{
4408 int rc = 0;
4409
4410 if (!inst || !inst->core || !inst->core->device) {
4411 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
4412 return -EINVAL;
4413 }
4414
4415 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST,
4416 &inst->persistbufs);
4417 if (rc)
4418 goto error;
4419
4420 rc = set_internal_buffers(inst, HAL_BUFFER_INTERNAL_PERSIST_1,
4421 &inst->persistbufs);
4422 if (rc)
4423 goto error;
4424 return rc;
4425error:
4426 msm_comm_release_persist_buffers(inst);
4427 return rc;
4428}
4429
4430static void msm_comm_flush_in_invalid_state(struct msm_vidc_inst *inst)
4431{
4432 struct list_head *ptr, *next;
4433 enum vidc_ports ports[] = {OUTPUT_PORT, CAPTURE_PORT};
4434 int c = 0;
4435
4436 for (c = 0; c < ARRAY_SIZE(ports); ++c) {
4437 enum vidc_ports port = ports[c];
4438
4439 dprintk(VIDC_DBG, "Flushing buffers of type %d in bad state\n",
4440 port);
4441 mutex_lock(&inst->bufq[port].lock);
4442 list_for_each_safe(ptr, next, &inst->bufq[port].
4443 vb2_bufq.queued_list) {
4444 struct vb2_buffer *vb = container_of(ptr,
4445 struct vb2_buffer, queued_entry);
4446
4447 vb->planes[0].bytesused = 0;
4448 vb->planes[0].data_offset = 0;
4449
4450 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
4451 }
4452 mutex_unlock(&inst->bufq[port].lock);
4453 }
4454
4455 msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_FLUSH_DONE);
4456}
4457
4458void msm_comm_flush_dynamic_buffers(struct msm_vidc_inst *inst)
4459{
4460 struct buffer_info *binfo = NULL;
4461
4462 if (inst->buffer_mode_set[CAPTURE_PORT] != HAL_BUFFER_MODE_DYNAMIC)
4463 return;
4464
4465 /*
4466 * dynamic buffer mode:- if flush is called during seek
4467 * driver should not queue any new buffer it has been holding.
4468 *
4469 * Each dynamic o/p buffer can have one of following ref_count:
4470 * ref_count : 0 - f/w has released reference and sent fbd back.
4471 * The buffer has been returned back to client.
4472 *
4473 * ref_count : 1 - f/w is holding reference. f/w may have released
4474 * fbd as read_only OR fbd is pending. f/w will
4475 * release reference before sending flush_done.
4476 *
4477 * ref_count : 2 - f/w is holding reference, f/w has released fbd as
4478 * read_only, which client has queued back to driver.
4479 * driver holds this buffer and will queue back
4480 * only when f/w releases the reference. During
4481 * flush_done, f/w will release the reference but driver
4482 * should not queue back the buffer to f/w.
4483 * Flush all buffers with ref_count 2.
4484 */
4485 mutex_lock(&inst->registeredbufs.lock);
4486 if (!list_empty(&inst->registeredbufs.list)) {
4487 struct v4l2_event buf_event = {0};
4488 u32 *ptr = NULL;
4489
4490 list_for_each_entry(binfo, &inst->registeredbufs.list, list) {
4491 if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
4492 atomic_read(&binfo->ref_count) == 2) {
4493
4494 atomic_dec(&binfo->ref_count);
4495 buf_event.type =
4496 V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER;
4497 ptr = (u32 *)buf_event.u.data;
4498 ptr[0] = binfo->fd[0];
4499 ptr[1] = binfo->buff_off[0];
4500 ptr[2] = binfo->uvaddr[0];
4501 ptr[3] = (u32) binfo->timestamp.tv_sec;
4502 ptr[4] = (u32) binfo->timestamp.tv_usec;
4503 ptr[5] = binfo->v4l2_index;
4504 dprintk(VIDC_DBG,
4505 "released buffer held in driver before issuing flush: %pa fd[0]: %d\n",
4506 &binfo->device_addr[0], binfo->fd[0]);
4507 /*send event to client*/
4508 v4l2_event_queue_fh(&inst->event_handler,
4509 &buf_event);
4510 }
4511 }
4512 }
4513 mutex_unlock(&inst->registeredbufs.lock);
4514}
4515
4516void msm_comm_flush_pending_dynamic_buffers(struct msm_vidc_inst *inst)
4517{
4518 struct buffer_info *binfo = NULL;
4519
4520 if (!inst)
4521 return;
4522
4523 if (inst->buffer_mode_set[CAPTURE_PORT] != HAL_BUFFER_MODE_DYNAMIC)
4524 return;
4525
4526 if (list_empty(&inst->pendingq.list) ||
4527 list_empty(&inst->registeredbufs.list))
4528 return;
4529
4530 /*
4531 * Dynamic Buffer mode - Since pendingq is not empty
4532 * no output buffers have been sent to firmware yet.
4533 * Hence remove reference to all pendingq o/p buffers
4534 * before flushing them.
4535 */
4536
4537 mutex_lock(&inst->registeredbufs.lock);
4538 list_for_each_entry(binfo, &inst->registeredbufs.list, list) {
4539 if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
4540 dprintk(VIDC_DBG,
4541 "%s: binfo = %pK device_addr = %pa\n",
4542 __func__, binfo, &binfo->device_addr[0]);
4543 buf_ref_put(inst, binfo);
4544 }
4545 }
4546 mutex_unlock(&inst->registeredbufs.lock);
4547}
4548
4549int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags)
4550{
4551 int rc = 0;
4552 bool ip_flush = false;
4553 bool op_flush = false;
4554 struct vb2_buf_entry *temp, *next;
4555 struct mutex *lock;
4556 struct msm_vidc_core *core;
4557 struct hfi_device *hdev;
4558
4559 if (!inst) {
4560 dprintk(VIDC_ERR,
4561 "Invalid instance pointer = %pK\n", inst);
4562 return -EINVAL;
4563 }
4564 core = inst->core;
4565 if (!core) {
4566 dprintk(VIDC_ERR,
4567 "Invalid core pointer = %pK\n", core);
4568 return -EINVAL;
4569 }
4570 hdev = core->device;
4571 if (!hdev) {
4572 dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev);
4573 return -EINVAL;
4574 }
4575
4576 ip_flush = flags & V4L2_QCOM_CMD_FLUSH_OUTPUT;
4577 op_flush = flags & V4L2_QCOM_CMD_FLUSH_CAPTURE;
4578
4579 if (ip_flush && !op_flush) {
4580 dprintk(VIDC_INFO, "Input only flush not supported\n");
4581 return 0;
4582 }
4583
4584 msm_comm_flush_dynamic_buffers(inst);
4585
4586 if (inst->state == MSM_VIDC_CORE_INVALID ||
4587 core->state == VIDC_CORE_INVALID ||
4588 core->state == VIDC_CORE_UNINIT) {
4589 dprintk(VIDC_ERR,
4590 "Core %pK and inst %pK are in bad state\n",
4591 core, inst);
4592 msm_comm_flush_in_invalid_state(inst);
4593 return 0;
4594 }
4595
4596 if (inst->in_reconfig && !ip_flush && op_flush) {
4597 mutex_lock(&inst->pendingq.lock);
4598 if (!list_empty(&inst->pendingq.list)) {
4599 /*
4600 * Execution can never reach here since port reconfig
4601 * wont happen unless pendingq is emptied out
4602 * (both pendingq and flush being secured with same
4603 * lock). Printing a message here incase this breaks.
4604 */
4605 dprintk(VIDC_WARN,
4606 "FLUSH BUG: Pending q not empty! It should be empty\n");
4607 }
4608 mutex_unlock(&inst->pendingq.lock);
4609 atomic_inc(&inst->in_flush);
4610 dprintk(VIDC_DBG, "Send flush Output to firmware\n");
4611 rc = call_hfi_op(hdev, session_flush, inst->session,
4612 HAL_FLUSH_OUTPUT);
4613 } else {
4614 msm_comm_flush_pending_dynamic_buffers(inst);
4615 /*
4616 * If flush is called after queueing buffers but before
4617 * streamon driver should flush the pending queue
4618 */
4619 mutex_lock(&inst->pendingq.lock);
4620 list_for_each_entry_safe(temp, next,
4621 &inst->pendingq.list, list) {
4622 enum v4l2_buf_type type = temp->vb->type;
4623
4624 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
4625 lock = &inst->bufq[CAPTURE_PORT].lock;
4626 else
4627 lock = &inst->bufq[OUTPUT_PORT].lock;
4628
4629 temp->vb->planes[0].bytesused = 0;
4630
4631 mutex_lock(lock);
4632 vb2_buffer_done(temp->vb, VB2_BUF_STATE_DONE);
4633 msm_vidc_debugfs_update(inst,
4634 type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ?
4635 MSM_VIDC_DEBUGFS_EVENT_FBD :
4636 MSM_VIDC_DEBUGFS_EVENT_EBD);
4637 list_del(&temp->list);
4638 mutex_unlock(lock);
4639
4640 kfree(temp);
4641 }
4642 mutex_unlock(&inst->pendingq.lock);
4643
4644 /*Do not send flush in case of session_error */
4645 if (!(inst->state == MSM_VIDC_CORE_INVALID &&
4646 core->state != VIDC_CORE_INVALID)) {
4647 atomic_inc(&inst->in_flush);
4648 dprintk(VIDC_DBG, "Send flush all to firmware\n");
4649 rc = call_hfi_op(hdev, session_flush, inst->session,
4650 HAL_FLUSH_ALL);
4651 }
4652 }
4653
4654 return rc;
4655}
4656
4657
4658enum hal_extradata_id msm_comm_get_hal_extradata_index(
4659 enum v4l2_mpeg_vidc_extradata index)
4660{
4661 int ret = 0;
4662
4663 switch (index) {
4664 case V4L2_MPEG_VIDC_EXTRADATA_NONE:
4665 ret = HAL_EXTRADATA_NONE;
4666 break;
4667 case V4L2_MPEG_VIDC_EXTRADATA_MB_QUANTIZATION:
4668 ret = HAL_EXTRADATA_MB_QUANTIZATION;
4669 break;
4670 case V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO:
4671 ret = HAL_EXTRADATA_INTERLACE_VIDEO;
4672 break;
4673 case V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP:
4674 ret = HAL_EXTRADATA_TIMESTAMP;
4675 break;
4676 case V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING:
4677 ret = HAL_EXTRADATA_S3D_FRAME_PACKING;
4678 break;
4679 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE:
4680 ret = HAL_EXTRADATA_FRAME_RATE;
4681 break;
4682 case V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW:
4683 ret = HAL_EXTRADATA_PANSCAN_WINDOW;
4684 break;
4685 case V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
4686 ret = HAL_EXTRADATA_RECOVERY_POINT_SEI;
4687 break;
4688 case V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO:
4689 ret = HAL_EXTRADATA_MULTISLICE_INFO;
4690 break;
4691 case V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB:
4692 ret = HAL_EXTRADATA_NUM_CONCEALED_MB;
4693 break;
4694 case V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER:
4695 ret = HAL_EXTRADATA_METADATA_FILLER;
4696 break;
4697 case V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO:
4698 ret = HAL_EXTRADATA_ASPECT_RATIO;
4699 break;
4700 case V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP:
4701 ret = HAL_EXTRADATA_INPUT_CROP;
4702 break;
4703 case V4L2_MPEG_VIDC_EXTRADATA_DIGITAL_ZOOM:
4704 ret = HAL_EXTRADATA_DIGITAL_ZOOM;
4705 break;
4706 case V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP:
4707 ret = HAL_EXTRADATA_MPEG2_SEQDISP;
4708 break;
4709 case V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA:
4710 ret = HAL_EXTRADATA_STREAM_USERDATA;
4711 break;
4712 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP:
4713 ret = HAL_EXTRADATA_FRAME_QP;
4714 break;
4715 case V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO:
4716 ret = HAL_EXTRADATA_FRAME_BITS_INFO;
4717 break;
4718 case V4L2_MPEG_VIDC_EXTRADATA_LTR:
4719 ret = HAL_EXTRADATA_LTR_INFO;
4720 break;
4721 case V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI:
4722 ret = HAL_EXTRADATA_METADATA_MBI;
4723 break;
4724 case V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI:
4725 ret = HAL_EXTRADATA_VQZIP_SEI;
4726 break;
4727 case V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS:
4728 ret = HAL_EXTRADATA_YUV_STATS;
4729 break;
4730 case V4L2_MPEG_VIDC_EXTRADATA_ROI_QP:
4731 ret = HAL_EXTRADATA_ROI_QP;
4732 break;
4733 case V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP:
4734 ret = HAL_EXTRADATA_OUTPUT_CROP;
4735 break;
4736 case V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI:
4737 ret = HAL_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI;
4738 break;
4739 case V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI:
4740 ret = HAL_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI;
4741 break;
4742 case V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO:
4743 ret = HAL_EXTRADATA_PQ_INFO;
4744 break;
4745
4746 case V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY:
4747 ret = HAL_EXTRADATA_VUI_DISPLAY_INFO;
4748 break;
4749 case V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE:
4750 ret = HAL_EXTRADATA_VPX_COLORSPACE;
4751 break;
4752 default:
4753 dprintk(VIDC_WARN, "Extradata not found: %d\n", index);
4754 break;
4755 }
4756 return ret;
4757};
4758
4759int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
4760 enum hal_ssr_trigger_type type)
4761{
4762 int rc = 0;
4763 struct hfi_device *hdev;
4764
4765 if (!core || !core->device) {
4766 dprintk(VIDC_WARN, "Invalid parameters: %pK\n", core);
4767 return -EINVAL;
4768 }
4769 hdev = core->device;
4770 if (core->state == VIDC_CORE_INIT_DONE) {
4771 /*
4772 * In current implementation user-initiated SSR triggers
4773 * a fatal error from hardware. However, there is no way
4774 * to know if fatal error is due to SSR or not. Handle
4775 * user SSR as non-fatal.
4776 */
4777 mutex_lock(&core->lock);
4778 core->resources.debug_timeout = false;
4779 mutex_unlock(&core->lock);
4780 rc = call_hfi_op(hdev, core_trigger_ssr,
4781 hdev->hfi_device_data, type);
4782 }
4783
4784 return rc;
4785}
4786
4787static int msm_vidc_load_supported(struct msm_vidc_inst *inst)
4788{
4789 int num_mbs_per_sec = 0, max_load_adj = 0;
4790 enum load_calc_quirks quirks = LOAD_CALC_IGNORE_TURBO_LOAD |
4791 LOAD_CALC_IGNORE_THUMBNAIL_LOAD |
4792 LOAD_CALC_IGNORE_NON_REALTIME_LOAD;
4793
4794 if (inst->state == MSM_VIDC_OPEN_DONE) {
4795 max_load_adj = inst->core->resources.max_load +
4796 inst->capability.mbs_per_frame.max;
4797 num_mbs_per_sec = msm_comm_get_load(inst->core,
4798 MSM_VIDC_DECODER, quirks);
4799 num_mbs_per_sec += msm_comm_get_load(inst->core,
4800 MSM_VIDC_ENCODER, quirks);
4801 if (num_mbs_per_sec > max_load_adj) {
4802 dprintk(VIDC_ERR,
4803 "H/W is overloaded. needed: %d max: %d\n",
4804 num_mbs_per_sec,
4805 max_load_adj);
4806 msm_vidc_print_running_insts(inst->core);
4807 return -EBUSY;
4808 }
4809 }
4810 return 0;
4811}
4812
4813int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst)
4814{
4815 u32 x_min, x_max, y_min, y_max;
4816 u32 input_height, input_width, output_height, output_width;
4817
4818 input_height = inst->prop.height[OUTPUT_PORT];
4819 input_width = inst->prop.width[OUTPUT_PORT];
4820 output_height = inst->prop.height[CAPTURE_PORT];
4821 output_width = inst->prop.width[CAPTURE_PORT];
4822
4823 if (!input_height || !input_width || !output_height || !output_width) {
4824 dprintk(VIDC_ERR,
4825 "Invalid : Input height = %d width = %d",
4826 input_height, input_width);
4827 dprintk(VIDC_ERR,
4828 " output height = %d width = %d\n",
4829 output_height, output_width);
4830 return -ENOTSUPP;
4831 }
4832
4833 if (!inst->capability.scale_x.min ||
4834 !inst->capability.scale_x.max ||
4835 !inst->capability.scale_y.min ||
4836 !inst->capability.scale_y.max) {
4837
4838 if (input_width * input_height !=
4839 output_width * output_height) {
4840 dprintk(VIDC_ERR,
4841 "%s: scaling is not supported (%dx%d != %dx%d)\n",
4842 __func__, input_width, input_height,
4843 output_width, output_height);
4844 return -ENOTSUPP;
4845 }
4846
4847 dprintk(VIDC_DBG, "%s: supported WxH = %dx%d\n",
4848 __func__, input_width, input_height);
4849 return 0;
4850 }
4851
4852 x_min = (1<<16)/inst->capability.scale_x.min;
4853 y_min = (1<<16)/inst->capability.scale_y.min;
4854 x_max = inst->capability.scale_x.max >> 16;
4855 y_max = inst->capability.scale_y.max >> 16;
4856
4857 if (input_height > output_height) {
4858 if (input_height > x_min * output_height) {
4859 dprintk(VIDC_ERR,
4860 "Unsupported height downscale ratio %d vs %d\n",
4861 input_height/output_height, x_min);
4862 return -ENOTSUPP;
4863 }
4864 } else {
4865 if (output_height > x_max * input_height) {
4866 dprintk(VIDC_ERR,
4867 "Unsupported height upscale ratio %d vs %d\n",
4868 input_height/output_height, x_max);
4869 return -ENOTSUPP;
4870 }
4871 }
4872 if (input_width > output_width) {
4873 if (input_width > y_min * output_width) {
4874 dprintk(VIDC_ERR,
4875 "Unsupported width downscale ratio %d vs %d\n",
4876 input_width/output_width, y_min);
4877 return -ENOTSUPP;
4878 }
4879 } else {
4880 if (output_width > y_max * input_width) {
4881 dprintk(VIDC_ERR,
4882 "Unsupported width upscale ratio %d vs %d\n",
4883 input_width/output_width, y_max);
4884 return -ENOTSUPP;
4885 }
4886 }
4887 return 0;
4888}
4889
4890int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
4891{
4892 struct msm_vidc_capability *capability;
4893 int rc = 0;
4894 struct hfi_device *hdev;
4895 struct msm_vidc_core *core;
4896
4897 if (!inst || !inst->core || !inst->core->device) {
4898 dprintk(VIDC_WARN, "%s: Invalid parameter\n", __func__);
4899 return -EINVAL;
4900 }
4901 capability = &inst->capability;
4902 hdev = inst->core->device;
4903 core = inst->core;
4904 rc = msm_vidc_load_supported(inst);
4905 if (rc) {
4906 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
4907 msm_comm_kill_session(inst);
4908 dprintk(VIDC_WARN,
4909 "%s: Hardware is overloaded\n", __func__);
4910 return rc;
4911 }
4912
4913 if (!is_thermal_permissible(core)) {
4914 dprintk(VIDC_WARN,
4915 "Thermal level critical, stop all active sessions!\n");
4916 return -ENOTSUPP;
4917 }
4918
4919 if (!rc)
4920 msm_dcvs_try_enable(inst);
4921
4922 if (!rc) {
4923 if (inst->prop.width[CAPTURE_PORT] < capability->width.min ||
4924 inst->prop.height[CAPTURE_PORT] <
4925 capability->height.min) {
4926 dprintk(VIDC_ERR,
4927 "Unsupported WxH = (%u)x(%u), min supported is - (%u)x(%u)\n",
4928 inst->prop.width[CAPTURE_PORT],
4929 inst->prop.height[CAPTURE_PORT],
4930 capability->width.min,
4931 capability->height.min);
4932 rc = -ENOTSUPP;
4933 }
4934 if (!rc && inst->prop.width[CAPTURE_PORT] >
4935 capability->width.max) {
4936 dprintk(VIDC_ERR,
4937 "Unsupported width = %u supported max width = %u",
4938 inst->prop.width[CAPTURE_PORT],
4939 capability->width.max);
4940 rc = -ENOTSUPP;
4941 }
4942
4943 if (!rc && inst->prop.height[CAPTURE_PORT]
4944 * inst->prop.width[CAPTURE_PORT] >
4945 capability->width.max * capability->height.max) {
4946 dprintk(VIDC_ERR,
4947 "Unsupported WxH = (%u)x(%u), max supported is - (%u)x(%u)\n",
4948 inst->prop.width[CAPTURE_PORT],
4949 inst->prop.height[CAPTURE_PORT],
4950 capability->width.max, capability->height.max);
4951 rc = -ENOTSUPP;
4952 }
4953 }
4954 if (rc) {
4955 change_inst_state(inst, MSM_VIDC_CORE_INVALID);
4956 msm_comm_kill_session(inst);
4957 dprintk(VIDC_ERR,
4958 "%s: Resolution unsupported\n", __func__);
4959 }
4960 return rc;
4961}
4962
4963static void msm_comm_generate_session_error(struct msm_vidc_inst *inst)
4964{
4965 enum hal_command_response cmd = HAL_SESSION_ERROR;
4966 struct msm_vidc_cb_cmd_done response = {0};
4967
4968 dprintk(VIDC_WARN, "msm_comm_generate_session_error\n");
4969 if (!inst || !inst->core) {
4970 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
4971 return;
4972 }
4973
4974 response.session_id = inst;
4975 response.status = VIDC_ERR_FAIL;
4976 handle_session_error(cmd, (void *)&response);
4977}
4978
4979static void msm_comm_generate_sys_error(struct msm_vidc_inst *inst)
4980{
4981 struct msm_vidc_core *core;
4982 enum hal_command_response cmd = HAL_SYS_ERROR;
4983 struct msm_vidc_cb_cmd_done response = {0};
4984
4985 if (!inst || !inst->core) {
4986 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
4987 return;
4988 }
4989 core = inst->core;
4990 response.device_id = (u32) core->id;
4991 handle_sys_error(cmd, (void *) &response);
4992
4993}
4994
4995int msm_comm_kill_session(struct msm_vidc_inst *inst)
4996{
4997 int rc = 0;
4998
4999 if (!inst || !inst->core || !inst->core->device) {
5000 dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
5001 return -EINVAL;
5002 } else if (!inst->session) {
5003 /* There's no hfi session to kill */
5004 return 0;
5005 }
5006
5007 /*
5008 * We're internally forcibly killing the session, if fw is aware of
5009 * the session send session_abort to firmware to clean up and release
5010 * the session, else just kill the session inside the driver.
5011 */
5012 if ((inst->state >= MSM_VIDC_OPEN_DONE &&
5013 inst->state < MSM_VIDC_CLOSE_DONE) ||
5014 inst->state == MSM_VIDC_CORE_INVALID) {
5015 if (msm_comm_session_abort(inst)) {
5016 msm_comm_generate_sys_error(inst);
5017 return 0;
5018 }
5019 change_inst_state(inst, MSM_VIDC_CLOSE_DONE);
5020 msm_comm_generate_session_error(inst);
5021 } else {
5022 dprintk(VIDC_WARN,
5023 "Inactive session %pK, triggering an internal session error\n",
5024 inst);
5025 msm_comm_generate_session_error(inst);
5026
5027 }
5028
5029 return rc;
5030}
5031
5032struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst,
5033 size_t size, u32 align, u32 flags,
5034 enum hal_buffer buffer_type, int map_kernel)
5035{
5036 struct msm_smem *m = NULL;
5037
5038 if (!inst || !inst->core) {
5039 dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst);
5040 return NULL;
5041 }
5042 m = msm_smem_alloc(inst->mem_client, size, align,
5043 flags, buffer_type, map_kernel);
5044 return m;
5045}
5046
5047void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem)
5048{
5049 if (!inst || !inst->core || !mem) {
5050 dprintk(VIDC_ERR,
5051 "%s: invalid params: %pK %pK\n", __func__, inst, mem);
5052 return;
5053 }
5054 msm_smem_free(inst->mem_client, mem);
5055}
5056
5057int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst,
5058 struct msm_smem *mem, enum smem_cache_ops cache_ops)
5059{
5060 if (!inst || !mem) {
5061 dprintk(VIDC_ERR,
5062 "%s: invalid params: %pK %pK\n", __func__, inst, mem);
5063 return -EINVAL;
5064 }
5065 return msm_smem_cache_operations(inst->mem_client, mem, cache_ops);
5066}
5067
5068struct msm_smem *msm_comm_smem_user_to_kernel(struct msm_vidc_inst *inst,
5069 int fd, u32 offset, enum hal_buffer buffer_type)
5070{
5071 struct msm_smem *m = NULL;
5072
5073 if (!inst || !inst->core) {
5074 dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst);
5075 return NULL;
5076 }
5077
5078 if (inst->state == MSM_VIDC_CORE_INVALID) {
5079 dprintk(VIDC_ERR, "Core in Invalid state, returning from %s\n",
5080 __func__);
5081 return NULL;
5082 }
5083
5084 m = msm_smem_user_to_kernel(inst->mem_client,
5085 fd, offset, buffer_type);
5086 return m;
5087}
5088
5089void msm_vidc_fw_unload_handler(struct work_struct *work)
5090{
5091 struct msm_vidc_core *core = NULL;
5092 struct hfi_device *hdev = NULL;
5093 int rc = 0;
5094
5095 core = container_of(work, struct msm_vidc_core, fw_unload_work.work);
5096 if (!core || !core->device) {
5097 dprintk(VIDC_ERR, "%s - invalid work or core handle\n",
5098 __func__);
5099 return;
5100 }
5101
5102 hdev = core->device;
5103
5104 mutex_lock(&core->lock);
5105 if (list_empty(&core->instances) &&
5106 core->state != VIDC_CORE_UNINIT) {
5107 if (core->state > VIDC_CORE_INIT) {
5108 dprintk(VIDC_DBG, "Calling vidc_hal_core_release\n");
5109 rc = call_hfi_op(hdev, core_release,
5110 hdev->hfi_device_data);
5111 if (rc) {
5112 dprintk(VIDC_ERR,
5113 "Failed to release core, id = %d\n",
5114 core->id);
5115 mutex_unlock(&core->lock);
5116 return;
5117 }
5118 }
5119 core->state = VIDC_CORE_UNINIT;
5120 kfree(core->capabilities);
5121 core->capabilities = NULL;
5122 }
5123 mutex_unlock(&core->lock);
5124}
5125
5126int msm_comm_set_color_format(struct msm_vidc_inst *inst,
5127 enum hal_buffer buffer_type, int fourcc)
5128{
5129 struct hal_uncompressed_format_select hal_fmt = {0};
5130 enum hal_uncompressed_format format = HAL_UNUSED_COLOR;
5131 int rc = 0;
5132 struct hfi_device *hdev;
5133
5134 if (!inst || !inst->core || !inst->core->device) {
5135 dprintk(VIDC_ERR, "%s - invalid param\n", __func__);
5136 return -EINVAL;
5137 }
5138
5139 hdev = inst->core->device;
5140
5141 format = get_hal_uncompressed(fourcc);
5142 if (format == HAL_UNUSED_COLOR) {
5143 dprintk(VIDC_ERR, "Using unsupported colorformat %#x\n",
5144 fourcc);
5145 rc = -ENOTSUPP;
5146 goto exit;
5147 }
5148
5149 hal_fmt.buffer_type = buffer_type;
5150 hal_fmt.format = format;
5151
5152 rc = call_hfi_op(hdev, session_set_property, inst->session,
5153 HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT, &hal_fmt);
5154 if (rc)
5155 dprintk(VIDC_ERR,
5156 "Failed to set input color format\n");
5157 else
5158 dprintk(VIDC_DBG, "Setting uncompressed colorformat to %#x\n",
5159 format);
5160
5161exit:
5162 return rc;
5163}
5164
5165int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
5166{
5167 u32 property_id = 0;
5168 u64 us_per_frame = 0;
5169 void *pdata;
5170 int rc = 0, fps = 0;
5171 struct hal_frame_rate frame_rate;
5172 struct hfi_device *hdev;
5173
5174 if (!inst || !inst->core || !inst->core->device || !a) {
5175 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
5176 return -EINVAL;
5177 }
5178
5179 hdev = inst->core->device;
5180 property_id = HAL_CONFIG_FRAME_RATE;
5181
5182 if (a->parm.output.timeperframe.denominator) {
5183 switch (a->type) {
5184 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
5185 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
5186 us_per_frame = a->parm.output.timeperframe.numerator *
5187 (u64)USEC_PER_SEC;
5188 do_div(us_per_frame, a->parm.output.
5189 timeperframe.denominator);
5190 break;
5191 default:
5192 dprintk(VIDC_ERR,
5193 "Scale clocks : Unknown buffer type %d\n",
5194 a->type);
5195 break;
5196 }
5197 }
5198
5199 if (!us_per_frame) {
5200 dprintk(VIDC_ERR,
5201 "Failed to scale clocks : time between frames is 0\n");
5202 rc = -EINVAL;
5203 goto exit;
5204 }
5205
5206 fps = USEC_PER_SEC;
5207 do_div(fps, us_per_frame);
5208
5209 if (fps % 15 == 14 || fps % 24 == 23)
5210 fps = fps + 1;
5211 else if ((fps > 1) && (fps % 24 == 1 || fps % 15 == 1))
5212 fps = fps - 1;
5213
5214 if (inst->prop.fps != fps) {
5215 dprintk(VIDC_PROF, "reported fps changed for %pK: %d->%d\n",
5216 inst, inst->prop.fps, fps);
5217 inst->prop.fps = fps;
5218 frame_rate.frame_rate = inst->prop.fps * BIT(16);
5219 frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
5220 pdata = &frame_rate;
5221 if (inst->session_type == MSM_VIDC_ENCODER) {
5222 rc = call_hfi_op(hdev, session_set_property,
5223 inst->session, property_id, pdata);
5224
5225 if (rc)
5226 dprintk(VIDC_WARN,
5227 "Failed to set frame rate %d\n", rc);
5228 } else {
5229 msm_dcvs_init_load(inst);
5230 }
5231 msm_comm_scale_clocks_and_bus(inst);
5232 msm_dcvs_try_enable(inst);
5233 }
5234exit:
5235 return rc;
5236}
5237
5238void msm_comm_print_inst_info(struct msm_vidc_inst *inst)
5239{
5240 struct buffer_info *temp;
5241 struct internal_buf *buf;
5242 int i = 0;
5243 bool is_decode = false;
5244 enum vidc_ports port;
5245 bool is_secure = false;
5246
5247 if (!inst) {
5248 dprintk(VIDC_ERR, "%s - invalid param %pK\n",
5249 __func__, inst);
5250 return;
5251 }
5252
5253 is_decode = inst->session_type == MSM_VIDC_DECODER;
5254 port = is_decode ? OUTPUT_PORT : CAPTURE_PORT;
5255 is_secure = inst->flags & VIDC_SECURE;
5256 dprintk(VIDC_ERR,
5257 "%s session, %s, Codec type: %s HxW: %d x %d fps: %d bitrate: %d bit-depth: %s\n",
5258 is_decode ? "Decode" : "Encode",
5259 is_secure ? "Secure" : "Non-Secure",
5260 inst->fmts[port].name,
5261 inst->prop.height[port], inst->prop.width[port],
5262 inst->prop.fps, inst->prop.bitrate,
5263 !inst->bit_depth ? "8" : "10");
5264
5265 dprintk(VIDC_ERR,
5266 "---Buffer details for inst: %pK of type: %d---\n",
5267 inst, inst->session_type);
5268 mutex_lock(&inst->registeredbufs.lock);
5269 dprintk(VIDC_ERR, "registered buffer list:\n");
5270 list_for_each_entry(temp, &inst->registeredbufs.list, list)
5271 for (i = 0; i < temp->num_planes; i++)
5272 dprintk(VIDC_ERR,
5273 "type: %d plane: %d addr: %pa size: %d\n",
5274 temp->type, i, &temp->device_addr[i],
5275 temp->size[i]);
5276
5277 mutex_unlock(&inst->registeredbufs.lock);
5278
5279 mutex_lock(&inst->scratchbufs.lock);
5280 dprintk(VIDC_ERR, "scratch buffer list:\n");
5281 list_for_each_entry(buf, &inst->scratchbufs.list, list)
5282 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5283 buf->buffer_type, &buf->handle->device_addr,
5284 buf->handle->size);
5285 mutex_unlock(&inst->scratchbufs.lock);
5286
5287 mutex_lock(&inst->persistbufs.lock);
5288 dprintk(VIDC_ERR, "persist buffer list:\n");
5289 list_for_each_entry(buf, &inst->persistbufs.list, list)
5290 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5291 buf->buffer_type, &buf->handle->device_addr,
5292 buf->handle->size);
5293 mutex_unlock(&inst->persistbufs.lock);
5294
5295 mutex_lock(&inst->outputbufs.lock);
5296 dprintk(VIDC_ERR, "dpb buffer list:\n");
5297 list_for_each_entry(buf, &inst->outputbufs.list, list)
5298 dprintk(VIDC_ERR, "type: %d addr: %pa size: %zu\n",
5299 buf->buffer_type, &buf->handle->device_addr,
5300 buf->handle->size);
5301 mutex_unlock(&inst->outputbufs.lock);
5302}
5303
5304static void msm_comm_print_debug_info(struct msm_vidc_inst *inst)
5305{
5306 struct msm_vidc_core *core = NULL;
5307 struct msm_vidc_inst *temp = NULL;
5308
5309 if (!inst || !inst->core) {
5310 dprintk(VIDC_ERR, "%s - invalid param %pK %pK\n",
5311 __func__, inst, core);
5312 return;
5313 }
5314 core = inst->core;
5315
5316 dprintk(VIDC_ERR, "Venus core frequency = %lu",
5317 msm_comm_get_clock_rate(core));
5318 mutex_lock(&core->lock);
5319 dprintk(VIDC_ERR, "Printing instance info that caused Error\n");
5320 msm_comm_print_inst_info(inst);
5321 dprintk(VIDC_ERR, "Printing remaining instances info\n");
5322 list_for_each_entry(temp, &core->instances, list) {
5323 /* inst already printed above. Hence don't repeat.*/
5324 if (temp == inst)
5325 continue;
5326 msm_comm_print_inst_info(temp);
5327 }
5328 mutex_unlock(&core->lock);
5329}