blob: e7ae5791a4d8b8d8a002ed265b95f2ae10b9f01f [file] [log] [blame]
Surajit Podder0d812bf2018-02-02 13:37:24 +05301/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08002 *
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/dma-direction.h>
15#include <linux/sched.h>
16#include <linux/slab.h>
17#include <media/msm_vidc.h>
18#include "msm_vidc_internal.h"
19#include "msm_vidc_debug.h"
20#include "msm_vdec.h"
21#include "msm_venc.h"
22#include "msm_vidc_common.h"
23#include <linux/delay.h>
24#include "vidc_hfi_api.h"
25#include "msm_vidc_clocks.h"
Maheshwar Ajjac6407c02017-06-09 18:53:20 -070026#include <linux/dma-buf.h>
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -080027
28#define MAX_EVENTS 30
29
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -070030static int try_get_ctrl(struct msm_vidc_inst *inst,
31 struct v4l2_ctrl *ctrl);
Praneeth Paladugu13c90962017-04-24 13:15:28 -070032static int msm_vidc_get_count(struct msm_vidc_inst *inst,
33 struct v4l2_ctrl *ctrl);
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -070034
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -080035static int get_poll_flags(void *instance)
36{
37 struct msm_vidc_inst *inst = instance;
38 struct vb2_queue *outq = &inst->bufq[OUTPUT_PORT].vb2_bufq;
39 struct vb2_queue *capq = &inst->bufq[CAPTURE_PORT].vb2_bufq;
40 struct vb2_buffer *out_vb = NULL;
41 struct vb2_buffer *cap_vb = NULL;
42 unsigned long flags;
43 int rc = 0;
44
45 if (v4l2_event_pending(&inst->event_handler))
46 rc |= POLLPRI;
47
48 spin_lock_irqsave(&capq->done_lock, flags);
49 if (!list_empty(&capq->done_list))
50 cap_vb = list_first_entry(&capq->done_list, struct vb2_buffer,
51 done_entry);
52 if (cap_vb && (cap_vb->state == VB2_BUF_STATE_DONE
53 || cap_vb->state == VB2_BUF_STATE_ERROR))
54 rc |= POLLIN | POLLRDNORM;
55 spin_unlock_irqrestore(&capq->done_lock, flags);
56
57 spin_lock_irqsave(&outq->done_lock, flags);
58 if (!list_empty(&outq->done_list))
59 out_vb = list_first_entry(&outq->done_list, struct vb2_buffer,
60 done_entry);
61 if (out_vb && (out_vb->state == VB2_BUF_STATE_DONE
62 || out_vb->state == VB2_BUF_STATE_ERROR))
63 rc |= POLLOUT | POLLWRNORM;
64 spin_unlock_irqrestore(&outq->done_lock, flags);
65
66 return rc;
67}
68
69int msm_vidc_poll(void *instance, struct file *filp,
70 struct poll_table_struct *wait)
71{
72 struct msm_vidc_inst *inst = instance;
73 struct vb2_queue *outq = NULL;
74 struct vb2_queue *capq = NULL;
75
76 if (!inst)
77 return -EINVAL;
78
79 outq = &inst->bufq[OUTPUT_PORT].vb2_bufq;
80 capq = &inst->bufq[CAPTURE_PORT].vb2_bufq;
81
82 poll_wait(filp, &inst->event_handler.wait, wait);
83 poll_wait(filp, &capq->done_wq, wait);
84 poll_wait(filp, &outq->done_wq, wait);
85 return get_poll_flags(inst);
86}
87EXPORT_SYMBOL(msm_vidc_poll);
88
89int msm_vidc_querycap(void *instance, struct v4l2_capability *cap)
90{
91 struct msm_vidc_inst *inst = instance;
92
93 if (!inst || !cap)
94 return -EINVAL;
95
Praneeth Paladugube42cb22016-04-12 22:34:39 -070096 strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver));
97 cap->bus_info[0] = 0;
98 cap->version = MSM_VIDC_VERSION;
99 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
100 V4L2_CAP_VIDEO_OUTPUT_MPLANE |
101 V4L2_CAP_STREAMING;
102 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
103
104 memset(cap->reserved, 0, sizeof(cap->reserved));
105
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800106 if (inst->session_type == MSM_VIDC_DECODER)
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700107 strlcpy(cap->card, MSM_VDEC_DVC_NAME, sizeof(cap->card));
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800108 else if (inst->session_type == MSM_VIDC_ENCODER)
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700109 strlcpy(cap->card, MSM_VENC_DVC_NAME, sizeof(cap->card));
110 else
111 return -EINVAL;
112
113 return 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800114}
115EXPORT_SYMBOL(msm_vidc_querycap);
116
117int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f)
118{
119 struct msm_vidc_inst *inst = instance;
120
121 if (!inst || !f)
122 return -EINVAL;
123
124 if (inst->session_type == MSM_VIDC_DECODER)
125 return msm_vdec_enum_fmt(instance, f);
126 else if (inst->session_type == MSM_VIDC_ENCODER)
127 return msm_venc_enum_fmt(instance, f);
128 return -EINVAL;
129}
130EXPORT_SYMBOL(msm_vidc_enum_fmt);
131
Praneeth Paladugue1679112017-01-27 10:07:15 -0800132static void msm_vidc_ctrl_get_range(struct v4l2_queryctrl *ctrl,
133 struct hal_capability_supported *capability)
134
135{
136 ctrl->maximum = capability->max;
137 ctrl->minimum = capability->min;
138}
139
140int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *ctrl)
141{
142 struct msm_vidc_inst *inst = instance;
Vaibhav Deshu Venkateshf962e1c2017-07-24 16:19:01 -0700143 struct hal_profile_level_supported *prof_level_supported;
144 int rc = 0, i = 0, profile_mask = 0, v4l2_prof_value = 0, max_level = 0;
Praneeth Paladugue1679112017-01-27 10:07:15 -0800145
146 if (!inst || !ctrl)
147 return -EINVAL;
148
149 switch (ctrl->id) {
150 case V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE:
151 msm_vidc_ctrl_get_range(ctrl,
152 &inst->capability.hier_p_hybrid);
153 break;
154 case V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS:
155 msm_vidc_ctrl_get_range(ctrl, &inst->capability.hier_b);
156 break;
157 case V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS:
158 msm_vidc_ctrl_get_range(ctrl, &inst->capability.hier_p);
159 break;
Vaibhav Deshu Venkatesh2c072532017-04-07 17:50:18 -0700160 case V4L2_CID_MPEG_VIDC_VENC_PARAM_LAYER_BITRATE:
Praneeth Paladugue1679112017-01-27 10:07:15 -0800161 case V4L2_CID_MPEG_VIDEO_BITRATE:
162 msm_vidc_ctrl_get_range(ctrl, &inst->capability.bitrate);
163 break;
164 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
165 msm_vidc_ctrl_get_range(ctrl, &inst->capability.peakbitrate);
166 break;
167 case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_WIDTH:
168 msm_vidc_ctrl_get_range(ctrl, &inst->capability.blur_width);
169 break;
170 case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_HEIGHT:
171 msm_vidc_ctrl_get_range(ctrl, &inst->capability.blur_height);
172 break;
Saurabh Kothawadeb11d81c2017-05-18 19:07:17 -0700173 case V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES:
174 msm_vidc_ctrl_get_range(ctrl, &inst->capability.bframe);
175 break;
Saurabh Kothawade0425f242017-05-25 11:19:30 -0700176 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
177 msm_vidc_ctrl_get_range(ctrl, &inst->capability.slice_mbs);
178 break;
179 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
180 msm_vidc_ctrl_get_range(ctrl, &inst->capability.slice_bytes);
181 break;
Saurabh Kothawade501be792017-08-29 11:41:38 -0700182 case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE:
183 case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE:
184 msm_vidc_ctrl_get_range(ctrl, &inst->capability.frame_rate);
185 break;
Vaibhav Deshu Venkateshf962e1c2017-07-24 16:19:01 -0700186 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
187 case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE:
188 case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE:
Vaibhav Deshu Venkateshb69518e2017-08-21 12:22:49 -0700189 case V4L2_CID_MPEG_VIDC_VIDEO_VP9_PROFILE:
Vaibhav Deshu Venkateshf962e1c2017-07-24 16:19:01 -0700190 {
191 prof_level_supported = &inst->capability.profile_level;
192 for (i = 0; i < prof_level_supported->profile_count; i++) {
193 v4l2_prof_value = msm_comm_hal_to_v4l2(ctrl->id,
194 prof_level_supported->profile_level[i].profile);
195 if (v4l2_prof_value == -EINVAL) {
196 dprintk(VIDC_WARN, "Invalid profile");
197 rc = -EINVAL;
198 }
199 profile_mask |= (1 << v4l2_prof_value);
200 }
201 ctrl->flags = profile_mask;
202 break;
203 }
204 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
205 case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL:
206 case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL:
207 case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL:
Vaibhav Deshu Venkateshb69518e2017-08-21 12:22:49 -0700208 case V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL:
Vaibhav Deshu Venkateshf962e1c2017-07-24 16:19:01 -0700209 {
210 prof_level_supported = &inst->capability.profile_level;
211 for (i = 0; i < prof_level_supported->profile_count; i++) {
212 if (max_level < prof_level_supported->
213 profile_level[i].level) {
214 max_level = prof_level_supported->
215 profile_level[i].level;
216 }
217 }
218 ctrl->maximum = msm_comm_hal_to_v4l2(ctrl->id, max_level);
219 if (ctrl->maximum == -EINVAL) {
220 dprintk(VIDC_WARN, "Invalid max level");
221 rc = -EINVAL;
222 }
223 break;
224 }
Praneeth Paladugue1679112017-01-27 10:07:15 -0800225 default:
226 rc = -EINVAL;
227 }
228 return rc;
229}
230EXPORT_SYMBOL(msm_vidc_query_ctrl);
231
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800232int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
233{
234 struct msm_vidc_inst *inst = instance;
235
236 if (!inst || !f)
237 return -EINVAL;
238
239 if (inst->session_type == MSM_VIDC_DECODER)
240 return msm_vdec_s_fmt(instance, f);
241 if (inst->session_type == MSM_VIDC_ENCODER)
242 return msm_venc_s_fmt(instance, f);
243 return -EINVAL;
244}
245EXPORT_SYMBOL(msm_vidc_s_fmt);
246
247int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
248{
249 struct msm_vidc_inst *inst = instance;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800250 int i, rc = 0, color_format = 0;
251 enum vidc_ports port;
252 u32 num_planes;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800253
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800254 if (!inst || !f) {
255 dprintk(VIDC_ERR,
256 "Invalid input, inst = %pK, format = %pK\n", inst, f);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800257 return -EINVAL;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800258 }
259 if (inst->in_reconfig) {
260 inst->prop.height[OUTPUT_PORT] = inst->reconfig_height;
261 inst->prop.width[OUTPUT_PORT] = inst->reconfig_width;
262 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800263
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800264 port = f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
265 OUTPUT_PORT : CAPTURE_PORT;
266
267 f->fmt.pix_mp.pixelformat = inst->fmts[port].fourcc;
268 f->fmt.pix_mp.height = inst->prop.height[port];
269 f->fmt.pix_mp.width = inst->prop.width[port];
270 num_planes = f->fmt.pix_mp.num_planes = inst->bufq[port].num_planes;
271 for (i = 0; i < num_planes; ++i)
272 f->fmt.pix_mp.plane_fmt[i].sizeimage =
273 inst->bufq[port].plane_sizes[i];
274 switch (inst->fmts[port].fourcc) {
275 case V4L2_PIX_FMT_NV12:
276 color_format = COLOR_FMT_NV12;
277 break;
278 case V4L2_PIX_FMT_NV12_UBWC:
279 color_format = COLOR_FMT_NV12_UBWC;
280 break;
281 case V4L2_PIX_FMT_NV12_TP10_UBWC:
282 color_format = COLOR_FMT_NV12_BPP10_UBWC;
Zhongbo Shic527b822017-09-15 09:46:36 +0800283 break;
Zhongbo Shie4e1fbc2017-11-20 14:15:45 +0800284 case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS:
Zhongbo Shi6bd5f5f2017-08-16 17:20:08 +0800285 color_format = COLOR_FMT_P010;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800286 break;
287 default:
288 dprintk(VIDC_DBG,
289 "Invalid : g_fmt called on %s port with Invalid fourcc 0x%x\n",
290 port == OUTPUT_PORT ? "OUTPUT" : "CAPTURE",
291 inst->fmts[port].fourcc);
292 goto exit;
293 }
294
295 f->fmt.pix_mp.plane_fmt[0].bytesperline = VENUS_Y_STRIDE(color_format,
296 inst->prop.width[port]);
297 f->fmt.pix_mp.plane_fmt[0].reserved[0] = VENUS_Y_SCANLINES(color_format,
298 inst->prop.height[port]);
299
300exit:
301 return rc;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800302}
303EXPORT_SYMBOL(msm_vidc_g_fmt);
304
305int msm_vidc_s_ctrl(void *instance, struct v4l2_control *control)
306{
307 struct msm_vidc_inst *inst = instance;
308
309 if (!inst || !control)
310 return -EINVAL;
311
312 return msm_comm_s_ctrl(instance, control);
313}
314EXPORT_SYMBOL(msm_vidc_s_ctrl);
315
Praneeth Paladugu72fa67b2017-05-30 11:20:01 -0700316int msm_vidc_g_crop(void *instance, struct v4l2_crop *crop)
317{
318 struct msm_vidc_inst *inst = instance;
319
320 if (!inst || !crop)
321 return -EINVAL;
322
323 if (inst->session_type == MSM_VIDC_ENCODER) {
324 dprintk(VIDC_ERR,
325 "Session = %pK : Encoder Crop is not implemented yet\n",
326 inst);
327 return -EPERM;
328 }
329
330 crop->c.left = inst->prop.crop_info.left;
331 crop->c.top = inst->prop.crop_info.top;
332 crop->c.width = inst->prop.crop_info.width;
333 crop->c.height = inst->prop.crop_info.height;
334
335 return 0;
336}
337EXPORT_SYMBOL(msm_vidc_g_crop);
338
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800339int msm_vidc_g_ctrl(void *instance, struct v4l2_control *control)
340{
341 struct msm_vidc_inst *inst = instance;
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700342 struct v4l2_ctrl *ctrl = NULL;
343 int rc = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800344
345 if (!inst || !control)
346 return -EINVAL;
347
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700348 ctrl = v4l2_ctrl_find(&inst->ctrl_handler, control->id);
349 if (ctrl) {
350 rc = try_get_ctrl(inst, ctrl);
351 if (!rc)
352 control->value = ctrl->val;
353 }
354
355 return rc;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800356}
357EXPORT_SYMBOL(msm_vidc_g_ctrl);
358
Praneeth Paladugu13c90962017-04-24 13:15:28 -0700359int msm_vidc_g_ext_ctrl(void *instance, struct v4l2_ext_controls *control)
360{
361 struct msm_vidc_inst *inst = instance;
362 struct v4l2_ext_control *ext_control;
363 struct v4l2_ctrl ctrl;
364 int i = 0, rc = 0;
365
366 if (!inst || !control)
367 return -EINVAL;
368
369 ext_control = control->controls;
370
371 for (i = 0; i < control->count; i++) {
372 switch (ext_control[i].id) {
373 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
374 case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
375 ctrl.id = ext_control[i].id;
376 ctrl.val = ext_control[i].value;
377
378 msm_vidc_get_count(inst, &ctrl);
379 ext_control->value = ctrl.val;
380 break;
381 default:
382 dprintk(VIDC_ERR,
383 "This control %x is not supported yet\n",
384 ext_control[i].id);
385 rc = -EINVAL;
386 break;
387 }
388 }
389 return rc;
390}
391EXPORT_SYMBOL(msm_vidc_g_ext_ctrl);
392
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800393int msm_vidc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *control)
394{
395 struct msm_vidc_inst *inst = instance;
396
397 if (!inst || !control)
398 return -EINVAL;
399
400 if (inst->session_type == MSM_VIDC_DECODER)
401 return msm_vdec_s_ext_ctrl(instance, control);
402 if (inst->session_type == MSM_VIDC_ENCODER)
403 return msm_venc_s_ext_ctrl(instance, control);
404 return -EINVAL;
405}
406EXPORT_SYMBOL(msm_vidc_s_ext_ctrl);
407
408int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
409{
410 struct msm_vidc_inst *inst = instance;
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700411 struct buf_queue *q = NULL;
412 int rc = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800413
414 if (!inst || !b)
415 return -EINVAL;
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700416 q = msm_comm_get_vb2q(inst, b->type);
417 if (!q) {
418 dprintk(VIDC_ERR,
419 "Failed to find buffer queue for type = %d\n",
420 b->type);
421 return -EINVAL;
422 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800423
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700424 mutex_lock(&q->lock);
425 rc = vb2_reqbufs(&q->vb2_bufq, b);
426 mutex_unlock(&q->lock);
427
428 if (rc)
429 dprintk(VIDC_ERR, "Failed to get reqbufs, %d\n", rc);
430 return rc;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800431}
432EXPORT_SYMBOL(msm_vidc_reqbufs);
433
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800434static bool valid_v4l2_buffer(struct v4l2_buffer *b,
435 struct msm_vidc_inst *inst) {
436 enum vidc_ports port =
437 !V4L2_TYPE_IS_MULTIPLANAR(b->type) ? MAX_PORT_NUM :
438 b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ? CAPTURE_PORT :
439 b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ? OUTPUT_PORT :
440 MAX_PORT_NUM;
441
442 return port != MAX_PORT_NUM &&
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800443 inst->bufq[port].num_planes == b->length;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800444}
445
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700446int msm_vidc_release_buffer(void *instance, int type, unsigned int index)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800447{
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700448 int rc = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800449 struct msm_vidc_inst *inst = instance;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700450 struct msm_vidc_buffer *mbuf, *dummy;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800451
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700452 if (!inst) {
453 dprintk(VIDC_ERR, "%s: invalid inst\n", __func__);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800454 return -EINVAL;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700455 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800456
457 if (!inst->in_reconfig &&
458 inst->state > MSM_VIDC_LOAD_RESOURCES &&
459 inst->state < MSM_VIDC_RELEASE_RESOURCES_DONE) {
460 rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
461 if (rc) {
462 dprintk(VIDC_ERR,
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700463 "%s: Failed to move inst: %pK to release res done\n",
464 __func__, inst);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800465 }
466 }
467
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800468 mutex_lock(&inst->registeredbufs.lock);
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700469 list_for_each_entry_safe(mbuf, dummy, &inst->registeredbufs.list,
470 list) {
471 struct vb2_buffer *vb2 = &mbuf->vvb.vb2_buf;
472
473 if (vb2->type != type || vb2->index != index)
474 continue;
475
Maheshwar Ajjae5765bd2017-08-08 11:59:38 -0700476 if (mbuf->flags & MSM_VIDC_FLAG_RBR_PENDING) {
477 print_vidc_buffer(VIDC_DBG,
478 "skip rel buf (rbr pending)", inst, mbuf);
479 continue;
480 }
481
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700482 print_vidc_buffer(VIDC_DBG, "release buf", inst, mbuf);
483 msm_comm_unmap_vidc_buffer(inst, mbuf);
484 list_del(&mbuf->list);
Maheshwar Ajjacca04052017-07-12 17:59:45 -0700485 kref_put_mbuf(mbuf);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800486 }
487 mutex_unlock(&inst->registeredbufs.lock);
Praneeth Paladuguceec6d82016-12-21 15:09:57 -0800488
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800489 return rc;
490}
Praneeth Paladuguceec6d82016-12-21 15:09:57 -0800491EXPORT_SYMBOL(msm_vidc_release_buffer);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800492
493int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
494{
495 struct msm_vidc_inst *inst = instance;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700496 int rc = 0, i = 0;
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700497 struct buf_queue *q = NULL;
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -0700498 u32 cr = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800499
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700500 if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) {
501 dprintk(VIDC_ERR, "%s: invalid params, inst %pK\n",
502 __func__, inst);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800503 return -EINVAL;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800504 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800505
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700506 for (i = 0; i < b->length; i++) {
507 b->m.planes[i].m.fd = b->m.planes[i].reserved[0];
508 b->m.planes[i].data_offset = b->m.planes[i].reserved[1];
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800509 }
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -0700510
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700511 msm_comm_qbuf_cache_operations(inst, b);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800512
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -0700513 /* Compression ratio is valid only for Encoder YUV buffers. */
514 if (inst->session_type == MSM_VIDC_ENCODER &&
515 b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
516 cr = b->m.planes[0].reserved[2];
517 msm_comm_update_input_cr(inst, b->index, cr);
518 }
519
Qiwei Liu551a22222017-08-23 15:28:29 +0800520 if (inst->session_type == MSM_VIDC_DECODER &&
521 b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
522 msm_comm_store_mark_data(&inst->etb_data, b->index,
523 b->m.planes[0].reserved[3], b->m.planes[0].reserved[4]);
524 }
525
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700526 q = msm_comm_get_vb2q(inst, b->type);
527 if (!q) {
528 dprintk(VIDC_ERR,
529 "Failed to find buffer queue for type = %d\n", b->type);
530 return -EINVAL;
531 }
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700532
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700533 mutex_lock(&q->lock);
534 rc = vb2_qbuf(&q->vb2_bufq, b);
535 mutex_unlock(&q->lock);
536 if (rc)
537 dprintk(VIDC_ERR, "Failed to qbuf, %d\n", rc);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800538
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700539 return rc;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800540}
541EXPORT_SYMBOL(msm_vidc_qbuf);
542
543int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
544{
545 struct msm_vidc_inst *inst = instance;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700546 int rc = 0, i = 0;
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700547 struct buf_queue *q = NULL;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800548
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700549 if (!inst || !b || !valid_v4l2_buffer(b, inst)) {
550 dprintk(VIDC_ERR, "%s: invalid params, inst %pK\n",
551 __func__, inst);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800552 return -EINVAL;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700553 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800554
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700555 q = msm_comm_get_vb2q(inst, b->type);
556 if (!q) {
557 dprintk(VIDC_ERR,
558 "Failed to find buffer queue for type = %d\n", b->type);
559 return -EINVAL;
560 }
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700561
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700562 mutex_lock(&q->lock);
563 rc = vb2_dqbuf(&q->vb2_bufq, b, true);
564 mutex_unlock(&q->lock);
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700565 if (rc == -EAGAIN) {
566 return rc;
567 } else if (rc) {
568 dprintk(VIDC_ERR, "Failed to dqbuf, %d\n", rc);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800569 return rc;
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700570 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800571
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700572 msm_comm_dqbuf_cache_operations(inst, b);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800573 for (i = 0; i < b->length; i++) {
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700574 b->m.planes[i].reserved[0] = b->m.planes[i].m.fd;
575 b->m.planes[i].reserved[1] = b->m.planes[i].data_offset;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800576 }
577
Qiwei Liu551a22222017-08-23 15:28:29 +0800578 if (inst->session_type == MSM_VIDC_DECODER &&
579 b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
580 msm_comm_fetch_mark_data(&inst->fbd_data, b->index,
581 &b->m.planes[0].reserved[3],
582 &b->m.planes[0].reserved[4]);
583 }
584
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800585 return rc;
586}
587EXPORT_SYMBOL(msm_vidc_dqbuf);
588
589int msm_vidc_streamon(void *instance, enum v4l2_buf_type i)
590{
591 struct msm_vidc_inst *inst = instance;
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700592 int rc = 0;
593 struct buf_queue *q;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800594
595 if (!inst)
596 return -EINVAL;
597
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700598 q = msm_comm_get_vb2q(inst, i);
599 if (!q) {
600 dprintk(VIDC_ERR,
601 "Failed to find buffer queue for type = %d\n", i);
602 return -EINVAL;
603 }
604 dprintk(VIDC_DBG, "Calling streamon\n");
605 mutex_lock(&q->lock);
606 rc = vb2_streamon(&q->vb2_bufq, i);
607 mutex_unlock(&q->lock);
Maheshwar Ajja47f80b32017-10-30 08:59:07 -0700608 if (rc) {
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700609 dprintk(VIDC_ERR, "streamon failed on port: %d\n", i);
Maheshwar Ajja47f80b32017-10-30 08:59:07 -0700610 msm_comm_kill_session(inst);
611 }
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700612 return rc;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800613}
614EXPORT_SYMBOL(msm_vidc_streamon);
615
616int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i)
617{
618 struct msm_vidc_inst *inst = instance;
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700619 int rc = 0;
620 struct buf_queue *q;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800621
622 if (!inst)
623 return -EINVAL;
624
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700625 q = msm_comm_get_vb2q(inst, i);
626 if (!q) {
627 dprintk(VIDC_ERR,
628 "Failed to find buffer queue for type = %d\n", i);
629 return -EINVAL;
630 }
Maheshwar Ajja03d7bb02017-10-03 15:14:54 -0700631
632 if (!inst->in_reconfig) {
633 dprintk(VIDC_DBG, "%s: inst %pK release resources\n",
634 __func__, inst);
635 rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
636 if (rc)
637 dprintk(VIDC_ERR,
638 "%s: inst %pK move to rel res done failed\n",
639 __func__, inst);
640 }
641
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700642 dprintk(VIDC_DBG, "Calling streamoff\n");
643 mutex_lock(&q->lock);
644 rc = vb2_streamoff(&q->vb2_bufq, i);
645 mutex_unlock(&q->lock);
646 if (rc)
647 dprintk(VIDC_ERR, "streamoff failed on port: %d\n", i);
648 return rc;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800649}
650EXPORT_SYMBOL(msm_vidc_streamoff);
651
652int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize)
653{
654 struct msm_vidc_inst *inst = instance;
655 struct msm_vidc_capability *capability = NULL;
656
657 if (!inst || !fsize) {
658 dprintk(VIDC_ERR, "%s: invalid parameter: %pK %pK\n",
659 __func__, inst, fsize);
660 return -EINVAL;
661 }
662 if (!inst->core)
663 return -EINVAL;
664
665 capability = &inst->capability;
666 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
667 fsize->stepwise.min_width = capability->width.min;
668 fsize->stepwise.max_width = capability->width.max;
669 fsize->stepwise.step_width = capability->width.step_size;
670 fsize->stepwise.min_height = capability->height.min;
671 fsize->stepwise.max_height = capability->height.max;
672 fsize->stepwise.step_height = capability->height.step_size;
673 return 0;
674}
675EXPORT_SYMBOL(msm_vidc_enum_framesizes);
676
677static void *vidc_get_userptr(struct device *dev, unsigned long vaddr,
678 unsigned long size, enum dma_data_direction dma_dir)
679{
680 return (void *)0xdeadbeef;
681}
682
683static void vidc_put_userptr(void *buf_priv)
684{
685}
686
687static const struct vb2_mem_ops msm_vidc_vb2_mem_ops = {
688 .get_userptr = vidc_get_userptr,
689 .put_userptr = vidc_put_userptr,
690};
691
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800692static void msm_vidc_cleanup_buffer(struct vb2_buffer *vb)
693{
694 int rc = 0;
695 struct buf_queue *q = NULL;
696 struct msm_vidc_inst *inst = NULL;
697
698 if (!vb) {
699 dprintk(VIDC_ERR, "%s : Invalid vb pointer %pK",
700 __func__, vb);
701 return;
702 }
703
704 inst = vb2_get_drv_priv(vb->vb2_queue);
705 if (!inst) {
706 dprintk(VIDC_ERR, "%s : Invalid inst pointer",
707 __func__);
708 return;
709 }
710
711 q = msm_comm_get_vb2q(inst, vb->type);
712 if (!q) {
713 dprintk(VIDC_ERR,
714 "%s : Failed to find buffer queue for type = %d\n",
715 __func__, vb->type);
716 return;
717 }
718
719 if (q->vb2_bufq.streaming) {
720 dprintk(VIDC_DBG, "%d PORT is streaming\n",
721 vb->type);
722 return;
723 }
724
Praneeth Paladuguceec6d82016-12-21 15:09:57 -0800725 rc = msm_vidc_release_buffer(inst, vb->type, vb->index);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800726 if (rc)
727 dprintk(VIDC_ERR, "%s : Failed to release buffers : %d\n",
728 __func__, rc);
729}
730
731static int set_buffer_count(struct msm_vidc_inst *inst,
732 int host_count, int act_count, enum hal_buffer type)
733{
734 int rc = 0;
735 struct hfi_device *hdev;
736 struct hal_buffer_count_actual buf_count;
737
738 hdev = inst->core->device;
739
740 buf_count.buffer_type = type;
741 buf_count.buffer_count_actual = act_count;
742 buf_count.buffer_count_min_host = host_count;
Praneeth Paladugu13c90962017-04-24 13:15:28 -0700743 dprintk(VIDC_DBG, "%s : Act count = %d Host count = %d\n",
744 __func__, act_count, host_count);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800745 rc = call_hfi_op(hdev, session_set_property,
746 inst->session, HAL_PARAM_BUFFER_COUNT_ACTUAL, &buf_count);
747 if (rc)
748 dprintk(VIDC_ERR,
749 "Failed to set actual buffer count %d for buffer type %d\n",
750 act_count, type);
751 return rc;
752}
753
754static int msm_vidc_queue_setup(struct vb2_queue *q,
755 unsigned int *num_buffers, unsigned int *num_planes,
756 unsigned int sizes[], struct device *alloc_devs[])
757{
758 struct msm_vidc_inst *inst;
759 int i, rc = 0;
760 struct hal_buffer_requirements *bufreq;
761 enum hal_buffer buffer_type;
762
763 if (!q || !num_buffers || !num_planes
764 || !sizes || !q->drv_priv) {
765 dprintk(VIDC_ERR, "Invalid input, q = %pK, %pK, %pK\n",
766 q, num_buffers, num_planes);
767 return -EINVAL;
768 }
769 inst = q->drv_priv;
770
771 if (!inst || !inst->core || !inst->core->device) {
772 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
773 return -EINVAL;
774 }
775
776 switch (q->type) {
777 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: {
778 bufreq = get_buff_req_buffer(inst,
779 HAL_BUFFER_INPUT);
780 if (!bufreq) {
781 dprintk(VIDC_ERR,
782 "Failed : No buffer requirements : %x\n",
783 HAL_BUFFER_INPUT);
784 return -EINVAL;
785 }
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700786 if (*num_buffers < bufreq->buffer_count_min_host) {
Maheshwar Ajja78e4cd32017-05-19 17:39:51 -0700787 dprintk(VIDC_DBG,
788 "Client passed num buffers %d less than the min_host count %d\n",
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700789 *num_buffers, bufreq->buffer_count_min_host);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800790 }
791 *num_planes = inst->bufq[OUTPUT_PORT].num_planes;
792 if (*num_buffers < MIN_NUM_OUTPUT_BUFFERS ||
793 *num_buffers > MAX_NUM_OUTPUT_BUFFERS)
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700794 bufreq->buffer_count_actual = *num_buffers =
795 MIN_NUM_OUTPUT_BUFFERS;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800796 for (i = 0; i < *num_planes; i++)
797 sizes[i] = inst->bufq[OUTPUT_PORT].plane_sizes[i];
798
799 bufreq->buffer_count_actual = *num_buffers;
Praneeth Paladuguf4b15822017-06-27 15:39:24 -0700800 rc = set_buffer_count(inst, bufreq->buffer_count_min_host,
Maheshwar Ajjaec382932017-06-30 13:47:01 -0700801 bufreq->buffer_count_actual, HAL_BUFFER_INPUT);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800802 }
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800803 break;
804 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: {
805 buffer_type = msm_comm_get_hal_output_buffer(inst);
806 bufreq = get_buff_req_buffer(inst,
807 buffer_type);
808 if (!bufreq) {
809 dprintk(VIDC_ERR,
810 "Failed : No buffer requirements : %x\n",
811 buffer_type);
812 return -EINVAL;
813 }
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700814 if (inst->session_type != MSM_VIDC_DECODER &&
815 inst->state > MSM_VIDC_LOAD_RESOURCES_DONE) {
816 if (*num_buffers < bufreq->buffer_count_min_host) {
Maheshwar Ajja78e4cd32017-05-19 17:39:51 -0700817 dprintk(VIDC_DBG,
818 "Client passed num buffers %d less than the min_host count %d\n",
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700819 *num_buffers,
820 bufreq->buffer_count_min_host);
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700821 }
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800822 }
823 *num_planes = inst->bufq[CAPTURE_PORT].num_planes;
824 if (*num_buffers < MIN_NUM_CAPTURE_BUFFERS ||
825 *num_buffers > MAX_NUM_CAPTURE_BUFFERS)
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700826 bufreq->buffer_count_actual = *num_buffers =
827 MIN_NUM_CAPTURE_BUFFERS;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800828
829 for (i = 0; i < *num_planes; i++)
830 sizes[i] = inst->bufq[CAPTURE_PORT].plane_sizes[i];
831
832 bufreq->buffer_count_actual = *num_buffers;
Praneeth Paladuguf4b15822017-06-27 15:39:24 -0700833 rc = set_buffer_count(inst, bufreq->buffer_count_min_host,
Maheshwar Ajjaec382932017-06-30 13:47:01 -0700834 bufreq->buffer_count_actual, buffer_type);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800835 }
836 break;
837 default:
838 dprintk(VIDC_ERR, "Invalid q type = %d\n", q->type);
839 rc = -EINVAL;
840 break;
841 }
842 return rc;
843}
844
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800845static inline int msm_vidc_verify_buffer_counts(struct msm_vidc_inst *inst)
846{
847 int rc = 0, i = 0;
848
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700849 /* For decoder No need to sanity till LOAD_RESOURCES */
850 if (inst->session_type == MSM_VIDC_DECODER &&
Karthikeyan Periasamyc316e382017-10-07 12:04:54 -0700851 (inst->state < MSM_VIDC_LOAD_RESOURCES_DONE ||
852 inst->state >= MSM_VIDC_RELEASE_RESOURCES_DONE)) {
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700853 dprintk(VIDC_DBG,
854 "No need to verify buffer counts : %pK\n", inst);
855 return 0;
856 }
857
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800858 for (i = 0; i < HAL_BUFFER_MAX; i++) {
859 struct hal_buffer_requirements *req = &inst->buff_req.buffer[i];
860
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700861 if (req && (msm_comm_get_hal_output_buffer(inst) ==
862 req->buffer_type)) {
863 dprintk(VIDC_DBG, "Verifying Buffer : %d\n",
864 req->buffer_type);
865 if (req->buffer_count_actual <
866 req->buffer_count_min_host ||
867 req->buffer_count_min_host <
868 req->buffer_count_min) {
869
870 dprintk(VIDC_ERR,
871 "Invalid data : Counts mismatch\n");
872 dprintk(VIDC_ERR,
873 "Min Count = %d ",
874 req->buffer_count_min);
875 dprintk(VIDC_ERR,
876 "Min Host Count = %d ",
877 req->buffer_count_min_host);
878 dprintk(VIDC_ERR,
879 "Min Actual Count = %d\n",
880 req->buffer_count_actual);
881 rc = -EINVAL;
882 break;
883 }
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800884 }
885 }
886 return rc;
887}
888
889static inline int start_streaming(struct msm_vidc_inst *inst)
890{
891 int rc = 0;
892 struct hfi_device *hdev;
893 struct hal_buffer_size_minimum b;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800894
895 hdev = inst->core->device;
896
897 /* Check if current session is under HW capability */
898 rc = msm_vidc_check_session_supported(inst);
899 if (rc) {
900 dprintk(VIDC_ERR,
901 "This session is not supported %pK\n", inst);
902 goto fail_start;
903 }
904
Maheshwar Ajja3cff01f2017-09-03 14:22:54 -0700905 rc = msm_vidc_check_scaling_supported(inst);
906 if (rc) {
907 dprintk(VIDC_ERR,
908 "This session scaling is not supported %pK\n", inst);
909 goto fail_start;
910 }
911
Praneeth Paladugu238977b2016-12-06 12:51:26 -0800912 /* Decide work mode for current session */
913 rc = msm_vidc_decide_work_mode(inst);
914 if (rc) {
915 dprintk(VIDC_ERR,
916 "Failed to decide work mode for session %pK\n", inst);
917 goto fail_start;
918 }
919
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800920 /* Assign Core and LP mode for current session */
921 rc = msm_vidc_decide_core_and_power_mode(inst);
922 if (rc) {
923 dprintk(VIDC_ERR,
Praneeth Paladugu238977b2016-12-06 12:51:26 -0800924 "This session can't be submitted to HW %pK\n", inst);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800925 goto fail_start;
926 }
927
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800928 if (msm_comm_get_stream_output_mode(inst) ==
929 HAL_VIDEO_DECODER_SECONDARY) {
930 b.buffer_type = HAL_BUFFER_OUTPUT2;
931 } else {
932 b.buffer_type = HAL_BUFFER_OUTPUT;
933 }
934
Chinmay Sawarkar02f8f852017-06-26 12:05:38 -0700935 rc = msm_comm_try_get_bufreqs(inst);
936
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800937 b.buffer_size = inst->bufq[CAPTURE_PORT].plane_sizes[0];
938 rc = call_hfi_op(hdev, session_set_property,
939 inst->session, HAL_PARAM_BUFFER_SIZE_MINIMUM,
940 &b);
941
Praneeth Paladugu238977b2016-12-06 12:51:26 -0800942 /* Verify if buffer counts are correct */
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800943 rc = msm_vidc_verify_buffer_counts(inst);
944 if (rc) {
945 dprintk(VIDC_ERR,
946 "This session has mis-match buffer counts%pK\n", inst);
947 goto fail_start;
948 }
949
950 rc = msm_comm_set_scratch_buffers(inst);
951 if (rc) {
952 dprintk(VIDC_ERR,
953 "Failed to set scratch buffers: %d\n", rc);
954 goto fail_start;
955 }
956 rc = msm_comm_set_persist_buffers(inst);
957 if (rc) {
958 dprintk(VIDC_ERR,
959 "Failed to set persist buffers: %d\n", rc);
960 goto fail_start;
961 }
962
Praneeth Paladugu319e7922017-03-16 11:09:06 -0700963 rc = msm_comm_set_recon_buffers(inst);
964 if (rc) {
965 dprintk(VIDC_ERR,
966 "Failed to set recon buffers: %d\n", rc);
967 goto fail_start;
968 }
969
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800970 if (msm_comm_get_stream_output_mode(inst) ==
971 HAL_VIDEO_DECODER_SECONDARY) {
972 rc = msm_comm_set_output_buffers(inst);
973 if (rc) {
974 dprintk(VIDC_ERR,
975 "Failed to set output buffers: %d\n", rc);
976 goto fail_start;
977 }
978 }
979
980 /*
981 * For seq_changed_insufficient, driver should set session_continue
982 * to firmware after the following sequence
983 * - driver raises insufficient event to v4l2 client
984 * - all output buffers have been flushed and freed
985 * - v4l2 client queries buffer requirements and splits/combines OPB-DPB
986 * - v4l2 client sets new set of buffers to firmware
987 * - v4l2 client issues CONTINUE to firmware to resume decoding of
988 * submitted ETBs.
989 */
Umesh Pandeybb3fad02017-03-31 16:49:42 -0700990 rc = msm_comm_session_continue(inst);
991 if (rc)
992 goto fail_start;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800993
994 msm_comm_scale_clocks_and_bus(inst);
995
996 rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE);
997 if (rc) {
998 dprintk(VIDC_ERR,
999 "Failed to move inst: %pK to start done state\n", inst);
1000 goto fail_start;
1001 }
Praneeth Paladugue5fd0872017-04-19 11:24:28 -07001002
1003 msm_clock_data_reset(inst);
1004
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001005 if (msm_comm_get_stream_output_mode(inst) ==
1006 HAL_VIDEO_DECODER_SECONDARY) {
1007 rc = msm_comm_queue_output_buffers(inst);
1008 if (rc) {
1009 dprintk(VIDC_ERR,
1010 "Failed to queue output buffers: %d\n", rc);
1011 goto fail_start;
1012 }
1013 }
1014
1015fail_start:
Maheshwar Ajja47f80b32017-10-30 08:59:07 -07001016 if (rc)
1017 dprintk(VIDC_ERR, "%s: inst %pK session %x failed to start\n",
1018 __func__, inst, hash32_ptr(inst->session));
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001019 return rc;
1020}
1021
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001022static int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count)
1023{
1024 struct msm_vidc_inst *inst;
1025 int rc = 0;
1026 struct hfi_device *hdev;
1027
1028 if (!q || !q->drv_priv) {
1029 dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q);
1030 return -EINVAL;
1031 }
1032 inst = q->drv_priv;
1033 if (!inst || !inst->core || !inst->core->device) {
1034 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
1035 return -EINVAL;
1036 }
1037 hdev = inst->core->device;
1038 dprintk(VIDC_DBG, "Streamon called on: %d capability for inst: %pK\n",
1039 q->type, inst);
1040 switch (q->type) {
1041 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1042 if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
1043 rc = start_streaming(inst);
1044 break;
1045 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1046 if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
1047 rc = start_streaming(inst);
1048 break;
1049 default:
1050 dprintk(VIDC_ERR, "Queue type is not supported: %d\n", q->type);
1051 rc = -EINVAL;
1052 goto stream_start_failed;
1053 }
1054 if (rc) {
1055 dprintk(VIDC_ERR,
1056 "Streamon failed on: %d capability for inst: %pK\n",
1057 q->type, inst);
1058 goto stream_start_failed;
1059 }
1060
1061 rc = msm_comm_qbuf(inst, NULL);
1062 if (rc) {
1063 dprintk(VIDC_ERR,
1064 "Failed to commit buffers queued before STREAM_ON to hardware: %d\n",
1065 rc);
1066 goto stream_start_failed;
1067 }
1068
Praneeth Paladugu54865842017-08-18 01:45:27 -07001069 rc = msm_vidc_send_pending_eos_buffers(inst);
1070 if (rc) {
1071 dprintk(VIDC_ERR,
1072 "Failed : Send pending EOS buffs for Inst = %pK, %d\n",
1073 inst, rc);
1074 goto stream_start_failed;
1075 }
1076
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001077stream_start_failed:
Maheshwar Ajja884259c2017-06-28 11:22:54 -07001078 if (rc) {
1079 struct msm_vidc_buffer *temp, *next;
1080 struct vb2_buffer *vb;
1081
1082 mutex_lock(&inst->registeredbufs.lock);
1083 list_for_each_entry_safe(temp, next, &inst->registeredbufs.list,
1084 list) {
1085 if (temp->vvb.vb2_buf.type != q->type)
1086 continue;
1087 /*
1088 * queued_list lock is already acquired before
1089 * vb2_stream so no need to acquire it again.
1090 */
1091 list_for_each_entry(vb, &q->queued_list, queued_entry) {
1092 if (msm_comm_compare_vb2_planes(inst, temp,
1093 vb)) {
1094 print_vb2_buffer(VIDC_ERR, "return vb",
1095 inst, vb);
1096 vb2_buffer_done(vb,
1097 VB2_BUF_STATE_QUEUED);
1098 break;
1099 }
1100 }
1101 msm_comm_unmap_vidc_buffer(inst, temp);
1102 list_del(&temp->list);
Maheshwar Ajjacca04052017-07-12 17:59:45 -07001103 kref_put_mbuf(temp);
Maheshwar Ajja884259c2017-06-28 11:22:54 -07001104 }
1105 mutex_unlock(&inst->registeredbufs.lock);
1106 }
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001107 return rc;
1108}
1109
1110static inline int stop_streaming(struct msm_vidc_inst *inst)
1111{
1112 int rc = 0;
1113
1114 rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
1115 if (rc)
1116 dprintk(VIDC_ERR,
1117 "Failed to move inst: %pK to state %d\n",
1118 inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
Praneeth Paladugue5fd0872017-04-19 11:24:28 -07001119
1120 msm_clock_data_reset(inst);
1121
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001122 return rc;
1123}
1124
1125static void msm_vidc_stop_streaming(struct vb2_queue *q)
1126{
1127 struct msm_vidc_inst *inst;
1128 int rc = 0;
1129
1130 if (!q || !q->drv_priv) {
1131 dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q);
1132 return;
1133 }
1134
1135 inst = q->drv_priv;
1136 dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type);
1137 switch (q->type) {
1138 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1139 if (!inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
1140 rc = stop_streaming(inst);
1141 break;
1142 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1143 if (!inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
1144 rc = stop_streaming(inst);
1145 break;
1146 default:
1147 dprintk(VIDC_ERR,
1148 "Q-type is not supported: %d\n", q->type);
1149 rc = -EINVAL;
1150 break;
1151 }
1152
1153 msm_comm_scale_clocks_and_bus(inst);
1154
1155 if (rc)
1156 dprintk(VIDC_ERR,
1157 "Failed STOP Streaming inst = %pK on cap = %d\n",
1158 inst, q->type);
1159}
1160
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001161static void msm_vidc_buf_queue(struct vb2_buffer *vb2)
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001162{
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001163 int rc = 0;
1164 struct msm_vidc_inst *inst = NULL;
1165 struct msm_vidc_buffer *mbuf = NULL;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001166
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001167 inst = vb2_get_drv_priv(vb2->vb2_queue);
1168 if (!inst) {
1169 dprintk(VIDC_ERR, "%s: invalid inst\n", __func__);
1170 return;
1171 }
1172
1173 mbuf = msm_comm_get_vidc_buffer(inst, vb2);
1174 if (IS_ERR_OR_NULL(mbuf)) {
Maheshwar Ajja279da4a2017-10-17 21:40:46 -07001175 if (PTR_ERR(mbuf) == -EEXIST)
1176 return;
1177 print_vb2_buffer(VIDC_ERR, "failed to get vidc-buf",
1178 inst, vb2);
1179 rc = -EINVAL;
1180 goto error;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001181 }
Maheshwar Ajjacca04052017-07-12 17:59:45 -07001182 if (!kref_get_mbuf(inst, mbuf)) {
1183 dprintk(VIDC_ERR, "%s: mbuf not found\n", __func__);
Maheshwar Ajja279da4a2017-10-17 21:40:46 -07001184 rc = -EINVAL;
1185 goto error;
Maheshwar Ajjacca04052017-07-12 17:59:45 -07001186 }
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001187
1188 rc = msm_comm_qbuf(inst, mbuf);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001189 if (rc)
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001190 print_vidc_buffer(VIDC_ERR, "failed qbuf", inst, mbuf);
Maheshwar Ajjacca04052017-07-12 17:59:45 -07001191
1192 kref_put_mbuf(mbuf);
Maheshwar Ajja279da4a2017-10-17 21:40:46 -07001193
1194error:
1195 if (rc)
1196 msm_comm_generate_session_error(inst);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001197}
1198
1199static const struct vb2_ops msm_vidc_vb2q_ops = {
1200 .queue_setup = msm_vidc_queue_setup,
1201 .start_streaming = msm_vidc_start_streaming,
1202 .buf_queue = msm_vidc_buf_queue,
1203 .buf_cleanup = msm_vidc_cleanup_buffer,
1204 .stop_streaming = msm_vidc_stop_streaming,
1205};
1206
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001207static inline int vb2_bufq_init(struct msm_vidc_inst *inst,
1208 enum v4l2_buf_type type, enum session_type sess)
1209{
1210 struct vb2_queue *q = NULL;
1211
1212 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1213 q = &inst->bufq[CAPTURE_PORT].vb2_bufq;
1214 } else if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1215 q = &inst->bufq[OUTPUT_PORT].vb2_bufq;
1216 } else {
1217 dprintk(VIDC_ERR, "buf_type = %d not recognised\n", type);
1218 return -EINVAL;
1219 }
1220
1221 q->type = type;
1222 q->io_modes = VB2_MMAP | VB2_USERPTR;
1223 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001224 q->ops = &msm_vidc_vb2q_ops;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001225
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001226 q->mem_ops = &msm_vidc_vb2_mem_ops;
1227 q->drv_priv = inst;
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001228 q->allow_zero_bytesused = !V4L2_TYPE_IS_OUTPUT(type);
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08001229 q->copy_timestamp = 1;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001230 return vb2_queue_init(q);
1231}
1232
1233static int setup_event_queue(void *inst,
1234 struct video_device *pvdev)
1235{
1236 int rc = 0;
1237 struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
1238
1239 v4l2_fh_init(&vidc_inst->event_handler, pvdev);
1240 v4l2_fh_add(&vidc_inst->event_handler);
1241
1242 return rc;
1243}
1244
1245int msm_vidc_subscribe_event(void *inst,
1246 const struct v4l2_event_subscription *sub)
1247{
1248 int rc = 0;
1249 struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
1250
1251 if (!inst || !sub)
1252 return -EINVAL;
1253
1254 rc = v4l2_event_subscribe(&vidc_inst->event_handler,
1255 sub, MAX_EVENTS, NULL);
1256 return rc;
1257}
1258EXPORT_SYMBOL(msm_vidc_subscribe_event);
1259
1260int msm_vidc_unsubscribe_event(void *inst,
1261 const struct v4l2_event_subscription *sub)
1262{
1263 int rc = 0;
1264 struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
1265
1266 if (!inst || !sub)
1267 return -EINVAL;
1268
1269 rc = v4l2_event_unsubscribe(&vidc_inst->event_handler, sub);
1270 return rc;
1271}
1272EXPORT_SYMBOL(msm_vidc_unsubscribe_event);
1273
1274int msm_vidc_dqevent(void *inst, struct v4l2_event *event)
1275{
1276 int rc = 0;
1277 struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
1278
1279 if (!inst || !event)
1280 return -EINVAL;
1281
1282 rc = v4l2_event_dequeue(&vidc_inst->event_handler, event, false);
1283 return rc;
1284}
1285EXPORT_SYMBOL(msm_vidc_dqevent);
1286
1287static bool msm_vidc_check_for_inst_overload(struct msm_vidc_core *core)
1288{
1289 u32 instance_count = 0;
1290 u32 secure_instance_count = 0;
1291 struct msm_vidc_inst *inst = NULL;
1292 bool overload = false;
1293
1294 mutex_lock(&core->lock);
1295 list_for_each_entry(inst, &core->instances, list) {
1296 instance_count++;
1297 /* This flag is not updated yet for the current instance */
1298 if (inst->flags & VIDC_SECURE)
1299 secure_instance_count++;
1300 }
1301 mutex_unlock(&core->lock);
1302
1303 /* Instance count includes current instance as well. */
1304
1305 if ((instance_count > core->resources.max_inst_count) ||
1306 (secure_instance_count > core->resources.max_secure_inst_count))
1307 overload = true;
1308 return overload;
1309}
1310
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001311static int msm_vidc_try_set_ctrl(void *instance, struct v4l2_ctrl *ctrl)
1312{
1313 struct msm_vidc_inst *inst = instance;
1314
1315 if (inst->session_type == MSM_VIDC_DECODER)
1316 return msm_vdec_s_ctrl(instance, ctrl);
1317 else if (inst->session_type == MSM_VIDC_ENCODER)
1318 return msm_venc_s_ctrl(instance, ctrl);
1319 return -EINVAL;
1320}
1321
1322static int msm_vidc_op_s_ctrl(struct v4l2_ctrl *ctrl)
1323{
1324
1325 int rc = 0, c = 0;
1326 struct msm_vidc_inst *inst;
1327
1328 if (!ctrl) {
1329 dprintk(VIDC_ERR, "%s invalid parameters for ctrl\n", __func__);
1330 return -EINVAL;
1331 }
1332
1333 inst = container_of(ctrl->handler,
1334 struct msm_vidc_inst, ctrl_handler);
1335 if (!inst) {
1336 dprintk(VIDC_ERR, "%s invalid parameters for inst\n", __func__);
1337 return -EINVAL;
1338 }
1339
1340 for (c = 0; c < ctrl->ncontrols; ++c) {
1341 if (ctrl->cluster[c]->is_new) {
1342 rc = msm_vidc_try_set_ctrl(inst, ctrl->cluster[c]);
1343 if (rc) {
1344 dprintk(VIDC_ERR, "Failed setting %x\n",
1345 ctrl->cluster[c]->id);
1346 break;
1347 }
1348 }
1349 }
1350 if (rc)
1351 dprintk(VIDC_ERR, "Failed setting control: Inst = %pK (%s)\n",
1352 inst, v4l2_ctrl_get_name(ctrl->id));
1353 return rc;
1354}
1355
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001356static int msm_vidc_get_count(struct msm_vidc_inst *inst,
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001357 struct v4l2_ctrl *ctrl)
1358{
1359 int rc = 0;
Praneeth Paladugu6e637472017-05-16 16:06:46 -07001360 struct hal_buffer_requirements *bufreq;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001361 enum hal_buffer buffer_type;
1362
1363 if (ctrl->id == V4L2_CID_MIN_BUFFERS_FOR_OUTPUT) {
1364 bufreq = get_buff_req_buffer(inst, HAL_BUFFER_INPUT);
1365 if (!bufreq) {
1366 dprintk(VIDC_ERR,
1367 "Failed to find bufreqs for buffer type = %d\n",
1368 HAL_BUFFER_INPUT);
1369 return 0;
1370 }
1371 if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming) {
1372 ctrl->val = bufreq->buffer_count_min_host;
1373 return 0;
1374 }
1375 if (ctrl->val > bufreq->buffer_count_min_host) {
1376 dprintk(VIDC_DBG,
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001377 "Buffer count Host changed from %d to %d\n",
1378 bufreq->buffer_count_min_host,
1379 ctrl->val);
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001380 bufreq->buffer_count_actual =
1381 bufreq->buffer_count_min =
1382 bufreq->buffer_count_min_host =
1383 ctrl->val;
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001384 } else {
1385 ctrl->val = bufreq->buffer_count_min_host;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001386 }
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001387 rc = set_buffer_count(inst,
1388 bufreq->buffer_count_min_host,
1389 bufreq->buffer_count_actual,
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001390 HAL_BUFFER_INPUT);
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001391
1392 msm_vidc_update_host_buff_counts(inst);
1393 ctrl->val = bufreq->buffer_count_min_host;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001394 return rc;
1395
1396 } else if (ctrl->id == V4L2_CID_MIN_BUFFERS_FOR_CAPTURE) {
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001397
1398 buffer_type = msm_comm_get_hal_output_buffer(inst);
1399 bufreq = get_buff_req_buffer(inst,
1400 buffer_type);
1401 if (!bufreq) {
1402 dprintk(VIDC_ERR,
1403 "Failed to find bufreqs for buffer type = %d\n",
1404 buffer_type);
1405 return 0;
1406 }
1407 if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming) {
1408 if (ctrl->val != bufreq->buffer_count_min_host)
1409 return -EINVAL;
1410 else
1411 return 0;
1412 }
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001413
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001414 if (inst->session_type == MSM_VIDC_DECODER &&
1415 !inst->in_reconfig &&
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001416 inst->state < MSM_VIDC_LOAD_RESOURCES_DONE) {
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001417 dprintk(VIDC_DBG,
1418 "Clients updates Buffer count from %d to %d\n",
1419 bufreq->buffer_count_min_host, ctrl->val);
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001420 bufreq->buffer_count_actual =
1421 bufreq->buffer_count_min =
1422 bufreq->buffer_count_min_host =
1423 ctrl->val;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001424 }
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001425 if (ctrl->val > bufreq->buffer_count_min_host) {
1426 dprintk(VIDC_DBG,
1427 "Buffer count Host changed from %d to %d\n",
1428 bufreq->buffer_count_min_host,
1429 ctrl->val);
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001430 bufreq->buffer_count_actual =
1431 bufreq->buffer_count_min =
1432 bufreq->buffer_count_min_host =
1433 ctrl->val;
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001434 } else {
1435 ctrl->val = bufreq->buffer_count_min_host;
1436 }
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001437 rc = set_buffer_count(inst,
1438 bufreq->buffer_count_min_host,
1439 bufreq->buffer_count_actual,
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001440 HAL_BUFFER_OUTPUT);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001441
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001442 msm_vidc_update_host_buff_counts(inst);
1443 ctrl->val = bufreq->buffer_count_min_host;
1444
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001445 return rc;
1446 }
1447 return -EINVAL;
1448}
1449
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001450static int try_get_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
1451{
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001452 int rc = 0;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001453 struct hal_buffer_requirements *bufreq = NULL;
1454 enum hal_buffer buffer_type;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001455
1456 switch (ctrl->id) {
1457
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001458 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001459 ctrl->val = msm_comm_hal_to_v4l2(
1460 V4L2_CID_MPEG_VIDEO_H264_PROFILE,
1461 inst->profile);
1462 break;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001463 case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001464 ctrl->val = msm_comm_hal_to_v4l2(
1465 V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE,
1466 inst->profile);
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001467 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001468
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001469 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001470 ctrl->val = msm_comm_hal_to_v4l2(
1471 V4L2_CID_MPEG_VIDEO_H264_LEVEL,
1472 inst->level);
1473 break;
Chinmay Sawarkar7f1cc152017-05-05 18:16:36 -07001474 case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001475 ctrl->val = msm_comm_hal_to_v4l2(
1476 V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL,
1477 inst->level);
1478 break;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001479 case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001480 ctrl->val = msm_comm_hal_to_v4l2(
1481 V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL,
1482 inst->level);
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001483 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001484
1485 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
1486 ctrl->val = inst->entropy_mode;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001487 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001488
1489 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001490 if (inst->in_reconfig)
1491 msm_vidc_update_host_buff_counts(inst);
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001492 buffer_type = msm_comm_get_hal_output_buffer(inst);
1493 bufreq = get_buff_req_buffer(inst,
1494 buffer_type);
1495 if (!bufreq) {
1496 dprintk(VIDC_ERR,
1497 "Failed to find bufreqs for buffer type = %d\n",
1498 buffer_type);
1499 return -EINVAL;
1500 }
1501 ctrl->val = bufreq->buffer_count_min_host;
1502 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001503 case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001504 bufreq = get_buff_req_buffer(inst, HAL_BUFFER_INPUT);
1505 if (!bufreq) {
1506 dprintk(VIDC_ERR,
1507 "Failed to find bufreqs for buffer type = %d\n",
1508 HAL_BUFFER_INPUT);
1509 return -EINVAL;
1510 }
Surajit Podder26e12f8a2017-10-13 14:11:42 +05301511
1512 if (inst->session_type == MSM_VIDC_DECODER &&
1513 !(inst->flags & VIDC_THUMBNAIL) &&
1514 inst->fmts[OUTPUT_PORT].fourcc ==
1515 V4L2_PIX_FMT_VP9 &&
1516 bufreq->buffer_count_min_host <
1517 MIN_NUM_OUTPUT_BUFFERS_VP9)
1518 bufreq->buffer_count_min_host =
1519 MIN_NUM_OUTPUT_BUFFERS_VP9;
1520
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001521 ctrl->val = bufreq->buffer_count_min_host;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001522 break;
Surajit Poddere502daa2017-05-30 19:17:45 +05301523 case V4L2_CID_MPEG_VIDC_VIDEO_TME_PAYLOAD_VERSION:
1524 ctrl->val = inst->capability.tme_version;
1525 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001526 default:
1527 /*
1528 * Other controls aren't really volatile, shouldn't need to
1529 * modify ctrl->value
1530 */
1531 break;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001532 }
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001533
1534 return rc;
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001535}
1536
1537static int msm_vidc_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1538{
1539 int rc = 0, c = 0;
1540 struct msm_vidc_inst *inst;
1541 struct v4l2_ctrl *master;
1542
1543 if (!ctrl) {
1544 dprintk(VIDC_ERR, "%s invalid parameters for ctrl\n", __func__);
1545 return -EINVAL;
1546 }
1547
1548 inst = container_of(ctrl->handler,
1549 struct msm_vidc_inst, ctrl_handler);
1550 if (!inst) {
1551 dprintk(VIDC_ERR, "%s invalid parameters for inst\n", __func__);
1552 return -EINVAL;
1553 }
1554 master = ctrl->cluster[0];
1555 if (!master) {
1556 dprintk(VIDC_ERR, "%s invalid parameters for master\n",
1557 __func__);
1558 return -EINVAL;
1559 }
1560
1561 for (c = 0; c < master->ncontrols; ++c) {
1562 if (master->cluster[c]->flags & V4L2_CTRL_FLAG_VOLATILE) {
1563 rc = try_get_ctrl(inst, master->cluster[c]);
1564 if (rc) {
1565 dprintk(VIDC_ERR, "Failed getting %x\n",
1566 master->cluster[c]->id);
1567 return rc;
1568 }
1569 }
1570 }
1571 if (rc)
1572 dprintk(VIDC_ERR, "Failed getting control: Inst = %pK (%s)\n",
1573 inst, v4l2_ctrl_get_name(ctrl->id));
1574 return rc;
1575}
1576
1577static const struct v4l2_ctrl_ops msm_vidc_ctrl_ops = {
1578
1579 .s_ctrl = msm_vidc_op_s_ctrl,
1580 .g_volatile_ctrl = msm_vidc_op_g_volatile_ctrl,
1581};
1582
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001583void *msm_vidc_open(int core_id, int session_type)
1584{
1585 struct msm_vidc_inst *inst = NULL;
1586 struct msm_vidc_core *core = NULL;
1587 int rc = 0;
1588 int i = 0;
1589
1590 if (core_id >= MSM_VIDC_CORES_MAX ||
1591 session_type >= MSM_VIDC_MAX_DEVICES) {
1592 dprintk(VIDC_ERR, "Invalid input, core_id = %d, session = %d\n",
1593 core_id, session_type);
1594 goto err_invalid_core;
1595 }
1596 core = get_vidc_core(core_id);
1597 if (!core) {
1598 dprintk(VIDC_ERR,
1599 "Failed to find core for core_id = %d\n", core_id);
1600 goto err_invalid_core;
1601 }
1602
1603 inst = kzalloc(sizeof(*inst), GFP_KERNEL);
1604 if (!inst) {
1605 dprintk(VIDC_ERR, "Failed to allocate memory\n");
1606 rc = -ENOMEM;
1607 goto err_invalid_core;
1608 }
1609
1610 pr_info(VIDC_DBG_TAG "Opening video instance: %pK, %d\n",
1611 VIDC_MSG_PRIO2STRING(VIDC_INFO), inst, session_type);
1612 mutex_init(&inst->sync_lock);
1613 mutex_init(&inst->bufq[CAPTURE_PORT].lock);
1614 mutex_init(&inst->bufq[OUTPUT_PORT].lock);
1615 mutex_init(&inst->lock);
Surajit Podder0d812bf2018-02-02 13:37:24 +05301616 mutex_init(&inst->flush_lock);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001617
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001618 INIT_MSM_VIDC_LIST(&inst->scratchbufs);
Praneeth Paladugub71968b2015-08-19 20:47:57 -07001619 INIT_MSM_VIDC_LIST(&inst->freqs);
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -07001620 INIT_MSM_VIDC_LIST(&inst->input_crs);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001621 INIT_MSM_VIDC_LIST(&inst->persistbufs);
1622 INIT_MSM_VIDC_LIST(&inst->pending_getpropq);
1623 INIT_MSM_VIDC_LIST(&inst->outputbufs);
1624 INIT_MSM_VIDC_LIST(&inst->registeredbufs);
Praneeth Paladugu319e7922017-03-16 11:09:06 -07001625 INIT_MSM_VIDC_LIST(&inst->reconbufs);
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001626 INIT_MSM_VIDC_LIST(&inst->eosbufs);
Qiwei Liu551a22222017-08-23 15:28:29 +08001627 INIT_MSM_VIDC_LIST(&inst->etb_data);
1628 INIT_MSM_VIDC_LIST(&inst->fbd_data);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001629
1630 kref_init(&inst->kref);
1631
1632 inst->session_type = session_type;
1633 inst->state = MSM_VIDC_CORE_UNINIT_DONE;
1634 inst->core = core;
Praneeth Paladugue5fd0872017-04-19 11:24:28 -07001635 inst->clk_data.min_freq = 0;
1636 inst->clk_data.curr_freq = 0;
1637 inst->clk_data.bitrate = 0;
1638 inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001639 inst->bit_depth = MSM_VIDC_BIT_DEPTH_8;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001640 inst->pic_struct = MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
1641 inst->colour_space = MSM_VIDC_BT601_6_525;
Chinmay Sawarkarb3c6ccb2017-02-23 18:01:32 -08001642 inst->profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
1643 inst->level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
1644 inst->entropy_mode = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001645
1646 for (i = SESSION_MSG_INDEX(SESSION_MSG_START);
1647 i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) {
1648 init_completion(&inst->completions[i]);
1649 }
1650 inst->mem_client = msm_smem_new_client(SMEM_ION,
1651 &inst->core->resources, session_type);
1652 if (!inst->mem_client) {
1653 dprintk(VIDC_ERR, "Failed to create memory client\n");
1654 goto fail_mem_client;
1655 }
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001656
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001657 if (session_type == MSM_VIDC_DECODER) {
1658 msm_vdec_inst_init(inst);
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001659 rc = msm_vdec_ctrl_init(inst, &msm_vidc_ctrl_ops);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001660 } else if (session_type == MSM_VIDC_ENCODER) {
1661 msm_venc_inst_init(inst);
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001662 rc = msm_venc_ctrl_init(inst, &msm_vidc_ctrl_ops);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001663 }
1664
1665 if (rc)
1666 goto fail_bufq_capture;
1667
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001668 rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
1669 session_type);
1670 if (rc) {
1671 dprintk(VIDC_ERR,
1672 "Failed to initialize vb2 queue on capture port\n");
1673 goto fail_bufq_capture;
1674 }
1675 rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
1676 session_type);
1677 if (rc) {
1678 dprintk(VIDC_ERR,
1679 "Failed to initialize vb2 queue on capture port\n");
1680 goto fail_bufq_output;
1681 }
1682
1683 setup_event_queue(inst, &core->vdev[session_type].vdev);
1684
1685 mutex_lock(&core->lock);
1686 list_add_tail(&inst->list, &core->instances);
1687 mutex_unlock(&core->lock);
1688
1689 rc = msm_comm_try_state(inst, MSM_VIDC_CORE_INIT_DONE);
1690 if (rc) {
1691 dprintk(VIDC_ERR,
1692 "Failed to move video instance to init state\n");
1693 goto fail_init;
1694 }
1695
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001696 msm_dcvs_try_enable(inst);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001697 if (msm_vidc_check_for_inst_overload(core)) {
1698 dprintk(VIDC_ERR,
1699 "Instance count reached Max limit, rejecting session");
1700 goto fail_init;
1701 }
1702
Praneeth Paladugue5fd0872017-04-19 11:24:28 -07001703 msm_comm_scale_clocks_and_bus(inst);
1704
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001705 inst->debugfs_root =
1706 msm_vidc_debugfs_init_inst(inst, core->debugfs_root);
1707
1708 return inst;
1709fail_init:
1710 mutex_lock(&core->lock);
1711 list_del(&inst->list);
1712 mutex_unlock(&core->lock);
1713
1714 v4l2_fh_del(&inst->event_handler);
1715 v4l2_fh_exit(&inst->event_handler);
1716 vb2_queue_release(&inst->bufq[OUTPUT_PORT].vb2_bufq);
1717fail_bufq_output:
1718 vb2_queue_release(&inst->bufq[CAPTURE_PORT].vb2_bufq);
1719fail_bufq_capture:
1720 msm_comm_ctrl_deinit(inst);
1721 msm_smem_delete_client(inst->mem_client);
1722fail_mem_client:
1723 mutex_destroy(&inst->sync_lock);
1724 mutex_destroy(&inst->bufq[CAPTURE_PORT].lock);
1725 mutex_destroy(&inst->bufq[OUTPUT_PORT].lock);
1726 mutex_destroy(&inst->lock);
Surajit Podder0d812bf2018-02-02 13:37:24 +05301727 mutex_destroy(&inst->flush_lock);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001728
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001729 DEINIT_MSM_VIDC_LIST(&inst->scratchbufs);
1730 DEINIT_MSM_VIDC_LIST(&inst->persistbufs);
1731 DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq);
1732 DEINIT_MSM_VIDC_LIST(&inst->outputbufs);
1733 DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001734 DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -07001735 DEINIT_MSM_VIDC_LIST(&inst->freqs);
1736 DEINIT_MSM_VIDC_LIST(&inst->input_crs);
Qiwei Liu551a22222017-08-23 15:28:29 +08001737 DEINIT_MSM_VIDC_LIST(&inst->etb_data);
1738 DEINIT_MSM_VIDC_LIST(&inst->fbd_data);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001739
1740 kfree(inst);
1741 inst = NULL;
1742err_invalid_core:
1743 return inst;
1744}
1745EXPORT_SYMBOL(msm_vidc_open);
1746
Maheshwar Ajja99422322017-07-07 17:31:15 -07001747static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001748{
Maheshwar Ajja99422322017-07-07 17:31:15 -07001749 struct msm_vidc_buffer *temp, *dummy;
Surajit Podder29d7b342017-08-29 00:27:50 +05301750 struct getprop_buf *temp_prop, *dummy_prop;
Maheshwar Ajja99422322017-07-07 17:31:15 -07001751
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001752 if (!inst) {
1753 dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
1754 return;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001755 }
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001756
Maheshwar Ajja99422322017-07-07 17:31:15 -07001757 mutex_lock(&inst->registeredbufs.lock);
1758 list_for_each_entry_safe(temp, dummy, &inst->registeredbufs.list,
1759 list) {
1760 print_vidc_buffer(VIDC_ERR, "undequeud buf", inst, temp);
1761 msm_comm_unmap_vidc_buffer(inst, temp);
1762 list_del(&temp->list);
Maheshwar Ajjacca04052017-07-12 17:59:45 -07001763 kref_put_mbuf(temp);
Maheshwar Ajja99422322017-07-07 17:31:15 -07001764 }
1765 mutex_unlock(&inst->registeredbufs.lock);
1766
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001767 msm_comm_free_freq_table(inst);
1768
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -07001769 msm_comm_free_input_cr_table(inst);
1770
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001771 if (msm_comm_release_scratch_buffers(inst, false))
1772 dprintk(VIDC_ERR,
1773 "Failed to release scratch buffers\n");
1774
1775 if (msm_comm_release_recon_buffers(inst))
1776 dprintk(VIDC_ERR,
1777 "Failed to release recon buffers\n");
1778
1779 if (msm_comm_release_persist_buffers(inst))
1780 dprintk(VIDC_ERR,
1781 "Failed to release persist buffers\n");
1782
Qiwei Liu551a22222017-08-23 15:28:29 +08001783 if (msm_comm_release_mark_data(inst))
1784 dprintk(VIDC_ERR,
1785 "Failed to release mark_data buffers\n");
1786
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001787 msm_comm_release_eos_buffers(inst);
1788
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001789 if (msm_comm_release_output_buffers(inst, true))
1790 dprintk(VIDC_ERR,
1791 "Failed to release output buffers\n");
1792
1793 if (inst->extradata_handle)
1794 msm_comm_smem_free(inst, inst->extradata_handle);
1795
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001796 mutex_lock(&inst->pending_getpropq.lock);
Surajit Podder29d7b342017-08-29 00:27:50 +05301797 if (!list_empty(&inst->pending_getpropq.list)) {
1798 dprintk(VIDC_ERR,
1799 "pending_getpropq not empty for instance %pK\n",
1800 inst);
1801 list_for_each_entry_safe(temp_prop, dummy_prop,
1802 &inst->pending_getpropq.list, list) {
1803 kfree(temp_prop->data);
1804 list_del(&temp_prop->list);
1805 kfree(temp_prop);
1806 }
1807 }
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001808 mutex_unlock(&inst->pending_getpropq.lock);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001809}
1810
1811int msm_vidc_destroy(struct msm_vidc_inst *inst)
1812{
1813 struct msm_vidc_core *core;
1814 int i = 0;
1815
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001816 if (!inst || !inst->core) {
1817 dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001818 return -EINVAL;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001819 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001820
1821 core = inst->core;
1822
1823 mutex_lock(&core->lock);
1824 /* inst->list lives in core->instances */
1825 list_del(&inst->list);
1826 mutex_unlock(&core->lock);
1827
1828 msm_comm_ctrl_deinit(inst);
1829
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001830 v4l2_fh_del(&inst->event_handler);
1831 v4l2_fh_exit(&inst->event_handler);
1832
1833 for (i = 0; i < MAX_PORT_NUM; i++)
1834 vb2_queue_release(&inst->bufq[i].vb2_bufq);
1835
Maheshwar Ajja99422322017-07-07 17:31:15 -07001836 DEINIT_MSM_VIDC_LIST(&inst->scratchbufs);
1837 DEINIT_MSM_VIDC_LIST(&inst->persistbufs);
1838 DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq);
1839 DEINIT_MSM_VIDC_LIST(&inst->outputbufs);
1840 DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001841 DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -07001842 DEINIT_MSM_VIDC_LIST(&inst->freqs);
1843 DEINIT_MSM_VIDC_LIST(&inst->input_crs);
Qiwei Liu551a22222017-08-23 15:28:29 +08001844 DEINIT_MSM_VIDC_LIST(&inst->etb_data);
1845 DEINIT_MSM_VIDC_LIST(&inst->fbd_data);
Maheshwar Ajja99422322017-07-07 17:31:15 -07001846
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001847 mutex_destroy(&inst->sync_lock);
1848 mutex_destroy(&inst->bufq[CAPTURE_PORT].lock);
1849 mutex_destroy(&inst->bufq[OUTPUT_PORT].lock);
1850 mutex_destroy(&inst->lock);
Surajit Podder0d812bf2018-02-02 13:37:24 +05301851 mutex_destroy(&inst->flush_lock);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001852
Abdulla Anamed3c6532017-05-12 19:47:58 +05301853 msm_vidc_debugfs_deinit_inst(inst);
1854
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001855 pr_info(VIDC_DBG_TAG "Closed video instance: %pK\n",
1856 VIDC_MSG_PRIO2STRING(VIDC_INFO), inst);
1857 kfree(inst);
1858 return 0;
1859}
1860
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001861static void close_helper(struct kref *kref)
1862{
1863 struct msm_vidc_inst *inst = container_of(kref,
1864 struct msm_vidc_inst, kref);
1865
1866 msm_vidc_destroy(inst);
1867}
1868
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001869int msm_vidc_close(void *instance)
1870{
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001871 struct msm_vidc_inst *inst = instance;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001872 int rc = 0;
1873
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001874 if (!inst || !inst->core) {
1875 dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001876 return -EINVAL;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001877 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001878
Praneeth Paladuguceec6d82016-12-21 15:09:57 -08001879 /*
1880 * Make sure that HW stop working on these buffers that
1881 * we are going to free.
1882 */
Maheshwar Ajja99422322017-07-07 17:31:15 -07001883 rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001884 if (rc)
1885 dprintk(VIDC_ERR,
Maheshwar Ajja99422322017-07-07 17:31:15 -07001886 "Failed to move inst %pK to rel resource done state\n",
1887 inst);
1888
1889 msm_vidc_cleanup_instance(inst);
1890
1891 rc = msm_comm_try_state(inst, MSM_VIDC_CORE_UNINIT);
1892 if (rc) {
1893 dprintk(VIDC_ERR,
1894 "Failed to move inst %pK to uninit state\n", inst);
1895 rc = msm_comm_force_cleanup(inst);
1896 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001897
1898 msm_comm_session_clean(inst);
1899 msm_smem_delete_client(inst->mem_client);
1900
1901 kref_put(&inst->kref, close_helper);
1902 return 0;
1903}
1904EXPORT_SYMBOL(msm_vidc_close);
1905
1906int msm_vidc_suspend(int core_id)
1907{
1908 return msm_comm_suspend(core_id);
1909}
1910EXPORT_SYMBOL(msm_vidc_suspend);
1911