blob: 514908671ca4274022686d38698b15e9ce073c40 [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/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;
Vaibhav Deshu Venkateshf962e1c2017-07-24 16:19:01 -0700182 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
183 case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE:
184 case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE:
Vaibhav Deshu Venkateshb69518e2017-08-21 12:22:49 -0700185 case V4L2_CID_MPEG_VIDC_VIDEO_VP9_PROFILE:
Vaibhav Deshu Venkateshf962e1c2017-07-24 16:19:01 -0700186 {
187 prof_level_supported = &inst->capability.profile_level;
188 for (i = 0; i < prof_level_supported->profile_count; i++) {
189 v4l2_prof_value = msm_comm_hal_to_v4l2(ctrl->id,
190 prof_level_supported->profile_level[i].profile);
191 if (v4l2_prof_value == -EINVAL) {
192 dprintk(VIDC_WARN, "Invalid profile");
193 rc = -EINVAL;
194 }
195 profile_mask |= (1 << v4l2_prof_value);
196 }
197 ctrl->flags = profile_mask;
198 break;
199 }
200 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
201 case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL:
202 case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL:
203 case V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL:
Vaibhav Deshu Venkateshb69518e2017-08-21 12:22:49 -0700204 case V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL:
Vaibhav Deshu Venkateshf962e1c2017-07-24 16:19:01 -0700205 {
206 prof_level_supported = &inst->capability.profile_level;
207 for (i = 0; i < prof_level_supported->profile_count; i++) {
208 if (max_level < prof_level_supported->
209 profile_level[i].level) {
210 max_level = prof_level_supported->
211 profile_level[i].level;
212 }
213 }
214 ctrl->maximum = msm_comm_hal_to_v4l2(ctrl->id, max_level);
215 if (ctrl->maximum == -EINVAL) {
216 dprintk(VIDC_WARN, "Invalid max level");
217 rc = -EINVAL;
218 }
219 break;
220 }
Praneeth Paladugue1679112017-01-27 10:07:15 -0800221 default:
222 rc = -EINVAL;
223 }
224 return rc;
225}
226EXPORT_SYMBOL(msm_vidc_query_ctrl);
227
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800228int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
229{
230 struct msm_vidc_inst *inst = instance;
231
232 if (!inst || !f)
233 return -EINVAL;
234
235 if (inst->session_type == MSM_VIDC_DECODER)
236 return msm_vdec_s_fmt(instance, f);
237 if (inst->session_type == MSM_VIDC_ENCODER)
238 return msm_venc_s_fmt(instance, f);
239 return -EINVAL;
240}
241EXPORT_SYMBOL(msm_vidc_s_fmt);
242
243int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
244{
245 struct msm_vidc_inst *inst = instance;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800246 int i, rc = 0, color_format = 0;
247 enum vidc_ports port;
248 u32 num_planes;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800249
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800250 if (!inst || !f) {
251 dprintk(VIDC_ERR,
252 "Invalid input, inst = %pK, format = %pK\n", inst, f);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800253 return -EINVAL;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800254 }
255 if (inst->in_reconfig) {
256 inst->prop.height[OUTPUT_PORT] = inst->reconfig_height;
257 inst->prop.width[OUTPUT_PORT] = inst->reconfig_width;
258 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800259
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800260 port = f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
261 OUTPUT_PORT : CAPTURE_PORT;
262
263 f->fmt.pix_mp.pixelformat = inst->fmts[port].fourcc;
264 f->fmt.pix_mp.height = inst->prop.height[port];
265 f->fmt.pix_mp.width = inst->prop.width[port];
266 num_planes = f->fmt.pix_mp.num_planes = inst->bufq[port].num_planes;
267 for (i = 0; i < num_planes; ++i)
268 f->fmt.pix_mp.plane_fmt[i].sizeimage =
269 inst->bufq[port].plane_sizes[i];
270 switch (inst->fmts[port].fourcc) {
271 case V4L2_PIX_FMT_NV12:
272 color_format = COLOR_FMT_NV12;
273 break;
274 case V4L2_PIX_FMT_NV12_UBWC:
275 color_format = COLOR_FMT_NV12_UBWC;
276 break;
277 case V4L2_PIX_FMT_NV12_TP10_UBWC:
278 color_format = COLOR_FMT_NV12_BPP10_UBWC;
Zhongbo Shi6bd5f5f2017-08-16 17:20:08 +0800279 case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010:
280 color_format = COLOR_FMT_P010;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800281 break;
282 default:
283 dprintk(VIDC_DBG,
284 "Invalid : g_fmt called on %s port with Invalid fourcc 0x%x\n",
285 port == OUTPUT_PORT ? "OUTPUT" : "CAPTURE",
286 inst->fmts[port].fourcc);
287 goto exit;
288 }
289
290 f->fmt.pix_mp.plane_fmt[0].bytesperline = VENUS_Y_STRIDE(color_format,
291 inst->prop.width[port]);
292 f->fmt.pix_mp.plane_fmt[0].reserved[0] = VENUS_Y_SCANLINES(color_format,
293 inst->prop.height[port]);
294
295exit:
296 return rc;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800297}
298EXPORT_SYMBOL(msm_vidc_g_fmt);
299
300int msm_vidc_s_ctrl(void *instance, struct v4l2_control *control)
301{
302 struct msm_vidc_inst *inst = instance;
303
304 if (!inst || !control)
305 return -EINVAL;
306
307 return msm_comm_s_ctrl(instance, control);
308}
309EXPORT_SYMBOL(msm_vidc_s_ctrl);
310
Praneeth Paladugu72fa67b2017-05-30 11:20:01 -0700311int msm_vidc_g_crop(void *instance, struct v4l2_crop *crop)
312{
313 struct msm_vidc_inst *inst = instance;
314
315 if (!inst || !crop)
316 return -EINVAL;
317
318 if (inst->session_type == MSM_VIDC_ENCODER) {
319 dprintk(VIDC_ERR,
320 "Session = %pK : Encoder Crop is not implemented yet\n",
321 inst);
322 return -EPERM;
323 }
324
325 crop->c.left = inst->prop.crop_info.left;
326 crop->c.top = inst->prop.crop_info.top;
327 crop->c.width = inst->prop.crop_info.width;
328 crop->c.height = inst->prop.crop_info.height;
329
330 return 0;
331}
332EXPORT_SYMBOL(msm_vidc_g_crop);
333
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800334int msm_vidc_g_ctrl(void *instance, struct v4l2_control *control)
335{
336 struct msm_vidc_inst *inst = instance;
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700337 struct v4l2_ctrl *ctrl = NULL;
338 int rc = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800339
340 if (!inst || !control)
341 return -EINVAL;
342
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700343 ctrl = v4l2_ctrl_find(&inst->ctrl_handler, control->id);
344 if (ctrl) {
345 rc = try_get_ctrl(inst, ctrl);
346 if (!rc)
347 control->value = ctrl->val;
348 }
349
350 return rc;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800351}
352EXPORT_SYMBOL(msm_vidc_g_ctrl);
353
Praneeth Paladugu13c90962017-04-24 13:15:28 -0700354int msm_vidc_g_ext_ctrl(void *instance, struct v4l2_ext_controls *control)
355{
356 struct msm_vidc_inst *inst = instance;
357 struct v4l2_ext_control *ext_control;
358 struct v4l2_ctrl ctrl;
359 int i = 0, rc = 0;
360
361 if (!inst || !control)
362 return -EINVAL;
363
364 ext_control = control->controls;
365
366 for (i = 0; i < control->count; i++) {
367 switch (ext_control[i].id) {
368 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
369 case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
370 ctrl.id = ext_control[i].id;
371 ctrl.val = ext_control[i].value;
372
373 msm_vidc_get_count(inst, &ctrl);
374 ext_control->value = ctrl.val;
375 break;
376 default:
377 dprintk(VIDC_ERR,
378 "This control %x is not supported yet\n",
379 ext_control[i].id);
380 rc = -EINVAL;
381 break;
382 }
383 }
384 return rc;
385}
386EXPORT_SYMBOL(msm_vidc_g_ext_ctrl);
387
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800388int msm_vidc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *control)
389{
390 struct msm_vidc_inst *inst = instance;
391
392 if (!inst || !control)
393 return -EINVAL;
394
395 if (inst->session_type == MSM_VIDC_DECODER)
396 return msm_vdec_s_ext_ctrl(instance, control);
397 if (inst->session_type == MSM_VIDC_ENCODER)
398 return msm_venc_s_ext_ctrl(instance, control);
399 return -EINVAL;
400}
401EXPORT_SYMBOL(msm_vidc_s_ext_ctrl);
402
403int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
404{
405 struct msm_vidc_inst *inst = instance;
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700406 struct buf_queue *q = NULL;
407 int rc = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800408
409 if (!inst || !b)
410 return -EINVAL;
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700411 q = msm_comm_get_vb2q(inst, b->type);
412 if (!q) {
413 dprintk(VIDC_ERR,
414 "Failed to find buffer queue for type = %d\n",
415 b->type);
416 return -EINVAL;
417 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800418
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700419 mutex_lock(&q->lock);
420 rc = vb2_reqbufs(&q->vb2_bufq, b);
421 mutex_unlock(&q->lock);
422
423 if (rc)
424 dprintk(VIDC_ERR, "Failed to get reqbufs, %d\n", rc);
425 return rc;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800426}
427EXPORT_SYMBOL(msm_vidc_reqbufs);
428
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800429static bool valid_v4l2_buffer(struct v4l2_buffer *b,
430 struct msm_vidc_inst *inst) {
431 enum vidc_ports port =
432 !V4L2_TYPE_IS_MULTIPLANAR(b->type) ? MAX_PORT_NUM :
433 b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ? CAPTURE_PORT :
434 b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ? OUTPUT_PORT :
435 MAX_PORT_NUM;
436
437 return port != MAX_PORT_NUM &&
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800438 inst->bufq[port].num_planes == b->length;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800439}
440
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700441int msm_vidc_release_buffer(void *instance, int type, unsigned int index)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800442{
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700443 int rc = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800444 struct msm_vidc_inst *inst = instance;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700445 struct msm_vidc_buffer *mbuf, *dummy;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800446
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700447 if (!inst) {
448 dprintk(VIDC_ERR, "%s: invalid inst\n", __func__);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800449 return -EINVAL;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700450 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800451
452 if (!inst->in_reconfig &&
453 inst->state > MSM_VIDC_LOAD_RESOURCES &&
454 inst->state < MSM_VIDC_RELEASE_RESOURCES_DONE) {
455 rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
456 if (rc) {
457 dprintk(VIDC_ERR,
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700458 "%s: Failed to move inst: %pK to release res done\n",
459 __func__, inst);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800460 }
461 }
462
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800463 mutex_lock(&inst->registeredbufs.lock);
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700464 list_for_each_entry_safe(mbuf, dummy, &inst->registeredbufs.list,
465 list) {
466 struct vb2_buffer *vb2 = &mbuf->vvb.vb2_buf;
467
468 if (vb2->type != type || vb2->index != index)
469 continue;
470
Maheshwar Ajjae5765bd2017-08-08 11:59:38 -0700471 if (mbuf->flags & MSM_VIDC_FLAG_RBR_PENDING) {
472 print_vidc_buffer(VIDC_DBG,
473 "skip rel buf (rbr pending)", inst, mbuf);
474 continue;
475 }
476
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700477 print_vidc_buffer(VIDC_DBG, "release buf", inst, mbuf);
478 msm_comm_unmap_vidc_buffer(inst, mbuf);
479 list_del(&mbuf->list);
Maheshwar Ajjacca04052017-07-12 17:59:45 -0700480 kref_put_mbuf(mbuf);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800481 }
482 mutex_unlock(&inst->registeredbufs.lock);
Praneeth Paladuguceec6d82016-12-21 15:09:57 -0800483
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800484 return rc;
485}
Praneeth Paladuguceec6d82016-12-21 15:09:57 -0800486EXPORT_SYMBOL(msm_vidc_release_buffer);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800487
488int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
489{
490 struct msm_vidc_inst *inst = instance;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700491 int rc = 0, i = 0;
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700492 struct buf_queue *q = NULL;
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -0700493 u32 cr = 0;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800494
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700495 if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst)) {
496 dprintk(VIDC_ERR, "%s: invalid params, inst %pK\n",
497 __func__, inst);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800498 return -EINVAL;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800499 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800500
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700501 for (i = 0; i < b->length; i++) {
502 b->m.planes[i].m.fd = b->m.planes[i].reserved[0];
503 b->m.planes[i].data_offset = b->m.planes[i].reserved[1];
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800504 }
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -0700505
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700506 msm_comm_qbuf_cache_operations(inst, b);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800507
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -0700508 /* Compression ratio is valid only for Encoder YUV buffers. */
509 if (inst->session_type == MSM_VIDC_ENCODER &&
510 b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
511 cr = b->m.planes[0].reserved[2];
512 msm_comm_update_input_cr(inst, b->index, cr);
513 }
514
Qiwei Liu551a22222017-08-23 15:28:29 +0800515 if (inst->session_type == MSM_VIDC_DECODER &&
516 b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
517 msm_comm_store_mark_data(&inst->etb_data, b->index,
518 b->m.planes[0].reserved[3], b->m.planes[0].reserved[4]);
519 }
520
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700521 q = msm_comm_get_vb2q(inst, b->type);
522 if (!q) {
523 dprintk(VIDC_ERR,
524 "Failed to find buffer queue for type = %d\n", b->type);
525 return -EINVAL;
526 }
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700527
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700528 mutex_lock(&q->lock);
529 rc = vb2_qbuf(&q->vb2_bufq, b);
530 mutex_unlock(&q->lock);
531 if (rc)
532 dprintk(VIDC_ERR, "Failed to qbuf, %d\n", rc);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800533
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700534 return rc;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800535}
536EXPORT_SYMBOL(msm_vidc_qbuf);
537
538int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
539{
540 struct msm_vidc_inst *inst = instance;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700541 int rc = 0, i = 0;
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700542 struct buf_queue *q = NULL;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800543
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700544 if (!inst || !b || !valid_v4l2_buffer(b, inst)) {
545 dprintk(VIDC_ERR, "%s: invalid params, inst %pK\n",
546 __func__, inst);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800547 return -EINVAL;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700548 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800549
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700550 q = msm_comm_get_vb2q(inst, b->type);
551 if (!q) {
552 dprintk(VIDC_ERR,
553 "Failed to find buffer queue for type = %d\n", b->type);
554 return -EINVAL;
555 }
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700556
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700557 mutex_lock(&q->lock);
558 rc = vb2_dqbuf(&q->vb2_bufq, b, true);
559 mutex_unlock(&q->lock);
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700560 if (rc == -EAGAIN) {
561 return rc;
562 } else if (rc) {
563 dprintk(VIDC_ERR, "Failed to dqbuf, %d\n", rc);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800564 return rc;
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700565 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800566
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700567 msm_comm_dqbuf_cache_operations(inst, b);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800568 for (i = 0; i < b->length; i++) {
Maheshwar Ajjac6407c02017-06-09 18:53:20 -0700569 b->m.planes[i].reserved[0] = b->m.planes[i].m.fd;
570 b->m.planes[i].reserved[1] = b->m.planes[i].data_offset;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800571 }
572
Qiwei Liu551a22222017-08-23 15:28:29 +0800573 if (inst->session_type == MSM_VIDC_DECODER &&
574 b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
575 msm_comm_fetch_mark_data(&inst->fbd_data, b->index,
576 &b->m.planes[0].reserved[3],
577 &b->m.planes[0].reserved[4]);
578 }
579
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800580 return rc;
581}
582EXPORT_SYMBOL(msm_vidc_dqbuf);
583
584int msm_vidc_streamon(void *instance, enum v4l2_buf_type i)
585{
586 struct msm_vidc_inst *inst = instance;
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700587 int rc = 0;
588 struct buf_queue *q;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800589
590 if (!inst)
591 return -EINVAL;
592
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700593 q = msm_comm_get_vb2q(inst, i);
594 if (!q) {
595 dprintk(VIDC_ERR,
596 "Failed to find buffer queue for type = %d\n", i);
597 return -EINVAL;
598 }
599 dprintk(VIDC_DBG, "Calling streamon\n");
600 mutex_lock(&q->lock);
601 rc = vb2_streamon(&q->vb2_bufq, i);
602 mutex_unlock(&q->lock);
603 if (rc)
604 dprintk(VIDC_ERR, "streamon failed on port: %d\n", i);
605 return rc;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800606}
607EXPORT_SYMBOL(msm_vidc_streamon);
608
609int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i)
610{
611 struct msm_vidc_inst *inst = instance;
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700612 int rc = 0;
613 struct buf_queue *q;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800614
615 if (!inst)
616 return -EINVAL;
617
Praneeth Paladugube42cb22016-04-12 22:34:39 -0700618 q = msm_comm_get_vb2q(inst, i);
619 if (!q) {
620 dprintk(VIDC_ERR,
621 "Failed to find buffer queue for type = %d\n", i);
622 return -EINVAL;
623 }
624 dprintk(VIDC_DBG, "Calling streamoff\n");
625 mutex_lock(&q->lock);
626 rc = vb2_streamoff(&q->vb2_bufq, i);
627 mutex_unlock(&q->lock);
628 if (rc)
629 dprintk(VIDC_ERR, "streamoff failed on port: %d\n", i);
630 return rc;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -0800631}
632EXPORT_SYMBOL(msm_vidc_streamoff);
633
634int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize)
635{
636 struct msm_vidc_inst *inst = instance;
637 struct msm_vidc_capability *capability = NULL;
638
639 if (!inst || !fsize) {
640 dprintk(VIDC_ERR, "%s: invalid parameter: %pK %pK\n",
641 __func__, inst, fsize);
642 return -EINVAL;
643 }
644 if (!inst->core)
645 return -EINVAL;
646
647 capability = &inst->capability;
648 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
649 fsize->stepwise.min_width = capability->width.min;
650 fsize->stepwise.max_width = capability->width.max;
651 fsize->stepwise.step_width = capability->width.step_size;
652 fsize->stepwise.min_height = capability->height.min;
653 fsize->stepwise.max_height = capability->height.max;
654 fsize->stepwise.step_height = capability->height.step_size;
655 return 0;
656}
657EXPORT_SYMBOL(msm_vidc_enum_framesizes);
658
659static void *vidc_get_userptr(struct device *dev, unsigned long vaddr,
660 unsigned long size, enum dma_data_direction dma_dir)
661{
662 return (void *)0xdeadbeef;
663}
664
665static void vidc_put_userptr(void *buf_priv)
666{
667}
668
669static const struct vb2_mem_ops msm_vidc_vb2_mem_ops = {
670 .get_userptr = vidc_get_userptr,
671 .put_userptr = vidc_put_userptr,
672};
673
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800674static void msm_vidc_cleanup_buffer(struct vb2_buffer *vb)
675{
676 int rc = 0;
677 struct buf_queue *q = NULL;
678 struct msm_vidc_inst *inst = NULL;
679
680 if (!vb) {
681 dprintk(VIDC_ERR, "%s : Invalid vb pointer %pK",
682 __func__, vb);
683 return;
684 }
685
686 inst = vb2_get_drv_priv(vb->vb2_queue);
687 if (!inst) {
688 dprintk(VIDC_ERR, "%s : Invalid inst pointer",
689 __func__);
690 return;
691 }
692
693 q = msm_comm_get_vb2q(inst, vb->type);
694 if (!q) {
695 dprintk(VIDC_ERR,
696 "%s : Failed to find buffer queue for type = %d\n",
697 __func__, vb->type);
698 return;
699 }
700
701 if (q->vb2_bufq.streaming) {
702 dprintk(VIDC_DBG, "%d PORT is streaming\n",
703 vb->type);
704 return;
705 }
706
Praneeth Paladuguceec6d82016-12-21 15:09:57 -0800707 rc = msm_vidc_release_buffer(inst, vb->type, vb->index);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800708 if (rc)
709 dprintk(VIDC_ERR, "%s : Failed to release buffers : %d\n",
710 __func__, rc);
711}
712
713static int set_buffer_count(struct msm_vidc_inst *inst,
714 int host_count, int act_count, enum hal_buffer type)
715{
716 int rc = 0;
717 struct hfi_device *hdev;
718 struct hal_buffer_count_actual buf_count;
719
720 hdev = inst->core->device;
721
722 buf_count.buffer_type = type;
723 buf_count.buffer_count_actual = act_count;
724 buf_count.buffer_count_min_host = host_count;
Praneeth Paladugu13c90962017-04-24 13:15:28 -0700725 dprintk(VIDC_DBG, "%s : Act count = %d Host count = %d\n",
726 __func__, act_count, host_count);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800727 rc = call_hfi_op(hdev, session_set_property,
728 inst->session, HAL_PARAM_BUFFER_COUNT_ACTUAL, &buf_count);
729 if (rc)
730 dprintk(VIDC_ERR,
731 "Failed to set actual buffer count %d for buffer type %d\n",
732 act_count, type);
733 return rc;
734}
735
736static int msm_vidc_queue_setup(struct vb2_queue *q,
737 unsigned int *num_buffers, unsigned int *num_planes,
738 unsigned int sizes[], struct device *alloc_devs[])
739{
740 struct msm_vidc_inst *inst;
741 int i, rc = 0;
742 struct hal_buffer_requirements *bufreq;
743 enum hal_buffer buffer_type;
744
745 if (!q || !num_buffers || !num_planes
746 || !sizes || !q->drv_priv) {
747 dprintk(VIDC_ERR, "Invalid input, q = %pK, %pK, %pK\n",
748 q, num_buffers, num_planes);
749 return -EINVAL;
750 }
751 inst = q->drv_priv;
752
753 if (!inst || !inst->core || !inst->core->device) {
754 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
755 return -EINVAL;
756 }
757
758 switch (q->type) {
759 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: {
760 bufreq = get_buff_req_buffer(inst,
761 HAL_BUFFER_INPUT);
762 if (!bufreq) {
763 dprintk(VIDC_ERR,
764 "Failed : No buffer requirements : %x\n",
765 HAL_BUFFER_INPUT);
766 return -EINVAL;
767 }
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700768 if (*num_buffers < bufreq->buffer_count_min_host) {
Maheshwar Ajja78e4cd32017-05-19 17:39:51 -0700769 dprintk(VIDC_DBG,
770 "Client passed num buffers %d less than the min_host count %d\n",
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700771 *num_buffers, bufreq->buffer_count_min_host);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800772 }
773 *num_planes = inst->bufq[OUTPUT_PORT].num_planes;
774 if (*num_buffers < MIN_NUM_OUTPUT_BUFFERS ||
775 *num_buffers > MAX_NUM_OUTPUT_BUFFERS)
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700776 bufreq->buffer_count_actual = *num_buffers =
777 MIN_NUM_OUTPUT_BUFFERS;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800778 for (i = 0; i < *num_planes; i++)
779 sizes[i] = inst->bufq[OUTPUT_PORT].plane_sizes[i];
780
781 bufreq->buffer_count_actual = *num_buffers;
Praneeth Paladuguf4b15822017-06-27 15:39:24 -0700782 rc = set_buffer_count(inst, bufreq->buffer_count_min_host,
Maheshwar Ajjaec382932017-06-30 13:47:01 -0700783 bufreq->buffer_count_actual, HAL_BUFFER_INPUT);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800784 }
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800785 break;
786 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: {
787 buffer_type = msm_comm_get_hal_output_buffer(inst);
788 bufreq = get_buff_req_buffer(inst,
789 buffer_type);
790 if (!bufreq) {
791 dprintk(VIDC_ERR,
792 "Failed : No buffer requirements : %x\n",
793 buffer_type);
794 return -EINVAL;
795 }
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700796 if (inst->session_type != MSM_VIDC_DECODER &&
797 inst->state > MSM_VIDC_LOAD_RESOURCES_DONE) {
798 if (*num_buffers < bufreq->buffer_count_min_host) {
Maheshwar Ajja78e4cd32017-05-19 17:39:51 -0700799 dprintk(VIDC_DBG,
800 "Client passed num buffers %d less than the min_host count %d\n",
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700801 *num_buffers,
802 bufreq->buffer_count_min_host);
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700803 }
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800804 }
805 *num_planes = inst->bufq[CAPTURE_PORT].num_planes;
806 if (*num_buffers < MIN_NUM_CAPTURE_BUFFERS ||
807 *num_buffers > MAX_NUM_CAPTURE_BUFFERS)
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700808 bufreq->buffer_count_actual = *num_buffers =
809 MIN_NUM_CAPTURE_BUFFERS;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800810
811 for (i = 0; i < *num_planes; i++)
812 sizes[i] = inst->bufq[CAPTURE_PORT].plane_sizes[i];
813
814 bufreq->buffer_count_actual = *num_buffers;
Praneeth Paladuguf4b15822017-06-27 15:39:24 -0700815 rc = set_buffer_count(inst, bufreq->buffer_count_min_host,
Maheshwar Ajjaec382932017-06-30 13:47:01 -0700816 bufreq->buffer_count_actual, buffer_type);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800817 }
818 break;
819 default:
820 dprintk(VIDC_ERR, "Invalid q type = %d\n", q->type);
821 rc = -EINVAL;
822 break;
823 }
824 return rc;
825}
826
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800827static inline int msm_vidc_verify_buffer_counts(struct msm_vidc_inst *inst)
828{
829 int rc = 0, i = 0;
830
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700831 /* For decoder No need to sanity till LOAD_RESOURCES */
832 if (inst->session_type == MSM_VIDC_DECODER &&
833 inst->state < MSM_VIDC_LOAD_RESOURCES_DONE) {
834 dprintk(VIDC_DBG,
835 "No need to verify buffer counts : %pK\n", inst);
836 return 0;
837 }
838
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800839 for (i = 0; i < HAL_BUFFER_MAX; i++) {
840 struct hal_buffer_requirements *req = &inst->buff_req.buffer[i];
841
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -0700842 if (req && (msm_comm_get_hal_output_buffer(inst) ==
843 req->buffer_type)) {
844 dprintk(VIDC_DBG, "Verifying Buffer : %d\n",
845 req->buffer_type);
846 if (req->buffer_count_actual <
847 req->buffer_count_min_host ||
848 req->buffer_count_min_host <
849 req->buffer_count_min) {
850
851 dprintk(VIDC_ERR,
852 "Invalid data : Counts mismatch\n");
853 dprintk(VIDC_ERR,
854 "Min Count = %d ",
855 req->buffer_count_min);
856 dprintk(VIDC_ERR,
857 "Min Host Count = %d ",
858 req->buffer_count_min_host);
859 dprintk(VIDC_ERR,
860 "Min Actual Count = %d\n",
861 req->buffer_count_actual);
862 rc = -EINVAL;
863 break;
864 }
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800865 }
866 }
867 return rc;
868}
869
870static inline int start_streaming(struct msm_vidc_inst *inst)
871{
872 int rc = 0;
873 struct hfi_device *hdev;
874 struct hal_buffer_size_minimum b;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800875
876 hdev = inst->core->device;
877
878 /* Check if current session is under HW capability */
879 rc = msm_vidc_check_session_supported(inst);
880 if (rc) {
881 dprintk(VIDC_ERR,
882 "This session is not supported %pK\n", inst);
883 goto fail_start;
884 }
885
Maheshwar Ajja3cff01f2017-09-03 14:22:54 -0700886 rc = msm_vidc_check_scaling_supported(inst);
887 if (rc) {
888 dprintk(VIDC_ERR,
889 "This session scaling is not supported %pK\n", inst);
890 goto fail_start;
891 }
892
Praneeth Paladugu238977b2016-12-06 12:51:26 -0800893 /* Decide work mode for current session */
894 rc = msm_vidc_decide_work_mode(inst);
895 if (rc) {
896 dprintk(VIDC_ERR,
897 "Failed to decide work mode for session %pK\n", inst);
898 goto fail_start;
899 }
900
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800901 /* Assign Core and LP mode for current session */
902 rc = msm_vidc_decide_core_and_power_mode(inst);
903 if (rc) {
904 dprintk(VIDC_ERR,
Praneeth Paladugu238977b2016-12-06 12:51:26 -0800905 "This session can't be submitted to HW %pK\n", inst);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800906 goto fail_start;
907 }
908
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800909 if (msm_comm_get_stream_output_mode(inst) ==
910 HAL_VIDEO_DECODER_SECONDARY) {
911 b.buffer_type = HAL_BUFFER_OUTPUT2;
912 } else {
913 b.buffer_type = HAL_BUFFER_OUTPUT;
914 }
915
Chinmay Sawarkar02f8f852017-06-26 12:05:38 -0700916 rc = msm_comm_try_get_bufreqs(inst);
917
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800918 b.buffer_size = inst->bufq[CAPTURE_PORT].plane_sizes[0];
919 rc = call_hfi_op(hdev, session_set_property,
920 inst->session, HAL_PARAM_BUFFER_SIZE_MINIMUM,
921 &b);
922
Praneeth Paladugu238977b2016-12-06 12:51:26 -0800923 /* Verify if buffer counts are correct */
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800924 rc = msm_vidc_verify_buffer_counts(inst);
925 if (rc) {
926 dprintk(VIDC_ERR,
927 "This session has mis-match buffer counts%pK\n", inst);
928 goto fail_start;
929 }
930
931 rc = msm_comm_set_scratch_buffers(inst);
932 if (rc) {
933 dprintk(VIDC_ERR,
934 "Failed to set scratch buffers: %d\n", rc);
935 goto fail_start;
936 }
937 rc = msm_comm_set_persist_buffers(inst);
938 if (rc) {
939 dprintk(VIDC_ERR,
940 "Failed to set persist buffers: %d\n", rc);
941 goto fail_start;
942 }
943
Praneeth Paladugu319e7922017-03-16 11:09:06 -0700944 rc = msm_comm_set_recon_buffers(inst);
945 if (rc) {
946 dprintk(VIDC_ERR,
947 "Failed to set recon buffers: %d\n", rc);
948 goto fail_start;
949 }
950
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800951 if (msm_comm_get_stream_output_mode(inst) ==
952 HAL_VIDEO_DECODER_SECONDARY) {
953 rc = msm_comm_set_output_buffers(inst);
954 if (rc) {
955 dprintk(VIDC_ERR,
956 "Failed to set output buffers: %d\n", rc);
957 goto fail_start;
958 }
959 }
960
961 /*
962 * For seq_changed_insufficient, driver should set session_continue
963 * to firmware after the following sequence
964 * - driver raises insufficient event to v4l2 client
965 * - all output buffers have been flushed and freed
966 * - v4l2 client queries buffer requirements and splits/combines OPB-DPB
967 * - v4l2 client sets new set of buffers to firmware
968 * - v4l2 client issues CONTINUE to firmware to resume decoding of
969 * submitted ETBs.
970 */
Umesh Pandeybb3fad02017-03-31 16:49:42 -0700971 rc = msm_comm_session_continue(inst);
972 if (rc)
973 goto fail_start;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800974
975 msm_comm_scale_clocks_and_bus(inst);
976
977 rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE);
978 if (rc) {
979 dprintk(VIDC_ERR,
980 "Failed to move inst: %pK to start done state\n", inst);
981 goto fail_start;
982 }
Praneeth Paladugue5fd0872017-04-19 11:24:28 -0700983
984 msm_clock_data_reset(inst);
985
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800986 if (msm_comm_get_stream_output_mode(inst) ==
987 HAL_VIDEO_DECODER_SECONDARY) {
988 rc = msm_comm_queue_output_buffers(inst);
989 if (rc) {
990 dprintk(VIDC_ERR,
991 "Failed to queue output buffers: %d\n", rc);
992 goto fail_start;
993 }
994 }
995
996fail_start:
Maheshwar Ajja99422322017-07-07 17:31:15 -0700997 if (rc) {
998 dprintk(VIDC_ERR, "%s: kill session %pK\n", __func__, inst);
999 msm_comm_kill_session(inst);
1000 }
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001001 return rc;
1002}
1003
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001004static int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count)
1005{
1006 struct msm_vidc_inst *inst;
1007 int rc = 0;
1008 struct hfi_device *hdev;
1009
1010 if (!q || !q->drv_priv) {
1011 dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q);
1012 return -EINVAL;
1013 }
1014 inst = q->drv_priv;
1015 if (!inst || !inst->core || !inst->core->device) {
1016 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
1017 return -EINVAL;
1018 }
1019 hdev = inst->core->device;
1020 dprintk(VIDC_DBG, "Streamon called on: %d capability for inst: %pK\n",
1021 q->type, inst);
1022 switch (q->type) {
1023 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1024 if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
1025 rc = start_streaming(inst);
1026 break;
1027 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1028 if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
1029 rc = start_streaming(inst);
1030 break;
1031 default:
1032 dprintk(VIDC_ERR, "Queue type is not supported: %d\n", q->type);
1033 rc = -EINVAL;
1034 goto stream_start_failed;
1035 }
1036 if (rc) {
1037 dprintk(VIDC_ERR,
1038 "Streamon failed on: %d capability for inst: %pK\n",
1039 q->type, inst);
1040 goto stream_start_failed;
1041 }
1042
1043 rc = msm_comm_qbuf(inst, NULL);
1044 if (rc) {
1045 dprintk(VIDC_ERR,
1046 "Failed to commit buffers queued before STREAM_ON to hardware: %d\n",
1047 rc);
1048 goto stream_start_failed;
1049 }
1050
Praneeth Paladugu54865842017-08-18 01:45:27 -07001051 rc = msm_vidc_send_pending_eos_buffers(inst);
1052 if (rc) {
1053 dprintk(VIDC_ERR,
1054 "Failed : Send pending EOS buffs for Inst = %pK, %d\n",
1055 inst, rc);
1056 goto stream_start_failed;
1057 }
1058
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001059stream_start_failed:
Maheshwar Ajja884259c2017-06-28 11:22:54 -07001060 if (rc) {
1061 struct msm_vidc_buffer *temp, *next;
1062 struct vb2_buffer *vb;
1063
1064 mutex_lock(&inst->registeredbufs.lock);
1065 list_for_each_entry_safe(temp, next, &inst->registeredbufs.list,
1066 list) {
1067 if (temp->vvb.vb2_buf.type != q->type)
1068 continue;
1069 /*
1070 * queued_list lock is already acquired before
1071 * vb2_stream so no need to acquire it again.
1072 */
1073 list_for_each_entry(vb, &q->queued_list, queued_entry) {
1074 if (msm_comm_compare_vb2_planes(inst, temp,
1075 vb)) {
1076 print_vb2_buffer(VIDC_ERR, "return vb",
1077 inst, vb);
1078 vb2_buffer_done(vb,
1079 VB2_BUF_STATE_QUEUED);
1080 break;
1081 }
1082 }
1083 msm_comm_unmap_vidc_buffer(inst, temp);
1084 list_del(&temp->list);
Maheshwar Ajjacca04052017-07-12 17:59:45 -07001085 kref_put_mbuf(temp);
Maheshwar Ajja884259c2017-06-28 11:22:54 -07001086 }
1087 mutex_unlock(&inst->registeredbufs.lock);
1088 }
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001089 return rc;
1090}
1091
1092static inline int stop_streaming(struct msm_vidc_inst *inst)
1093{
1094 int rc = 0;
1095
1096 rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
1097 if (rc)
1098 dprintk(VIDC_ERR,
1099 "Failed to move inst: %pK to state %d\n",
1100 inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
Praneeth Paladugue5fd0872017-04-19 11:24:28 -07001101
1102 msm_clock_data_reset(inst);
1103
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001104 return rc;
1105}
1106
1107static void msm_vidc_stop_streaming(struct vb2_queue *q)
1108{
1109 struct msm_vidc_inst *inst;
1110 int rc = 0;
1111
1112 if (!q || !q->drv_priv) {
1113 dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q);
1114 return;
1115 }
1116
1117 inst = q->drv_priv;
1118 dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type);
1119 switch (q->type) {
1120 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1121 if (!inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
1122 rc = stop_streaming(inst);
1123 break;
1124 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1125 if (!inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
1126 rc = stop_streaming(inst);
1127 break;
1128 default:
1129 dprintk(VIDC_ERR,
1130 "Q-type is not supported: %d\n", q->type);
1131 rc = -EINVAL;
1132 break;
1133 }
1134
1135 msm_comm_scale_clocks_and_bus(inst);
1136
1137 if (rc)
1138 dprintk(VIDC_ERR,
1139 "Failed STOP Streaming inst = %pK on cap = %d\n",
1140 inst, q->type);
1141}
1142
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001143static void msm_vidc_buf_queue(struct vb2_buffer *vb2)
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001144{
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001145 int rc = 0;
1146 struct msm_vidc_inst *inst = NULL;
1147 struct msm_vidc_buffer *mbuf = NULL;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001148
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001149 inst = vb2_get_drv_priv(vb2->vb2_queue);
1150 if (!inst) {
1151 dprintk(VIDC_ERR, "%s: invalid inst\n", __func__);
1152 return;
1153 }
1154
1155 mbuf = msm_comm_get_vidc_buffer(inst, vb2);
1156 if (IS_ERR_OR_NULL(mbuf)) {
1157 if (PTR_ERR(mbuf) != -EEXIST)
1158 print_vb2_buffer(VIDC_ERR, "failed to get vidc-buf",
1159 inst, vb2);
1160 return;
1161 }
Maheshwar Ajjacca04052017-07-12 17:59:45 -07001162 if (!kref_get_mbuf(inst, mbuf)) {
1163 dprintk(VIDC_ERR, "%s: mbuf not found\n", __func__);
1164 return;
1165 }
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001166
1167 rc = msm_comm_qbuf(inst, mbuf);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001168 if (rc)
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001169 print_vidc_buffer(VIDC_ERR, "failed qbuf", inst, mbuf);
Maheshwar Ajjacca04052017-07-12 17:59:45 -07001170
1171 kref_put_mbuf(mbuf);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001172}
1173
1174static const struct vb2_ops msm_vidc_vb2q_ops = {
1175 .queue_setup = msm_vidc_queue_setup,
1176 .start_streaming = msm_vidc_start_streaming,
1177 .buf_queue = msm_vidc_buf_queue,
1178 .buf_cleanup = msm_vidc_cleanup_buffer,
1179 .stop_streaming = msm_vidc_stop_streaming,
1180};
1181
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001182static inline int vb2_bufq_init(struct msm_vidc_inst *inst,
1183 enum v4l2_buf_type type, enum session_type sess)
1184{
1185 struct vb2_queue *q = NULL;
1186
1187 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1188 q = &inst->bufq[CAPTURE_PORT].vb2_bufq;
1189 } else if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1190 q = &inst->bufq[OUTPUT_PORT].vb2_bufq;
1191 } else {
1192 dprintk(VIDC_ERR, "buf_type = %d not recognised\n", type);
1193 return -EINVAL;
1194 }
1195
1196 q->type = type;
1197 q->io_modes = VB2_MMAP | VB2_USERPTR;
1198 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001199 q->ops = &msm_vidc_vb2q_ops;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001200
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001201 q->mem_ops = &msm_vidc_vb2_mem_ops;
1202 q->drv_priv = inst;
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001203 q->allow_zero_bytesused = !V4L2_TYPE_IS_OUTPUT(type);
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08001204 q->copy_timestamp = 1;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001205 return vb2_queue_init(q);
1206}
1207
1208static int setup_event_queue(void *inst,
1209 struct video_device *pvdev)
1210{
1211 int rc = 0;
1212 struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
1213
1214 v4l2_fh_init(&vidc_inst->event_handler, pvdev);
1215 v4l2_fh_add(&vidc_inst->event_handler);
1216
1217 return rc;
1218}
1219
1220int msm_vidc_subscribe_event(void *inst,
1221 const struct v4l2_event_subscription *sub)
1222{
1223 int rc = 0;
1224 struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
1225
1226 if (!inst || !sub)
1227 return -EINVAL;
1228
1229 rc = v4l2_event_subscribe(&vidc_inst->event_handler,
1230 sub, MAX_EVENTS, NULL);
1231 return rc;
1232}
1233EXPORT_SYMBOL(msm_vidc_subscribe_event);
1234
1235int msm_vidc_unsubscribe_event(void *inst,
1236 const struct v4l2_event_subscription *sub)
1237{
1238 int rc = 0;
1239 struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
1240
1241 if (!inst || !sub)
1242 return -EINVAL;
1243
1244 rc = v4l2_event_unsubscribe(&vidc_inst->event_handler, sub);
1245 return rc;
1246}
1247EXPORT_SYMBOL(msm_vidc_unsubscribe_event);
1248
1249int msm_vidc_dqevent(void *inst, struct v4l2_event *event)
1250{
1251 int rc = 0;
1252 struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
1253
1254 if (!inst || !event)
1255 return -EINVAL;
1256
1257 rc = v4l2_event_dequeue(&vidc_inst->event_handler, event, false);
1258 return rc;
1259}
1260EXPORT_SYMBOL(msm_vidc_dqevent);
1261
1262static bool msm_vidc_check_for_inst_overload(struct msm_vidc_core *core)
1263{
1264 u32 instance_count = 0;
1265 u32 secure_instance_count = 0;
1266 struct msm_vidc_inst *inst = NULL;
1267 bool overload = false;
1268
1269 mutex_lock(&core->lock);
1270 list_for_each_entry(inst, &core->instances, list) {
1271 instance_count++;
1272 /* This flag is not updated yet for the current instance */
1273 if (inst->flags & VIDC_SECURE)
1274 secure_instance_count++;
1275 }
1276 mutex_unlock(&core->lock);
1277
1278 /* Instance count includes current instance as well. */
1279
1280 if ((instance_count > core->resources.max_inst_count) ||
1281 (secure_instance_count > core->resources.max_secure_inst_count))
1282 overload = true;
1283 return overload;
1284}
1285
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001286static int msm_vidc_try_set_ctrl(void *instance, struct v4l2_ctrl *ctrl)
1287{
1288 struct msm_vidc_inst *inst = instance;
1289
1290 if (inst->session_type == MSM_VIDC_DECODER)
1291 return msm_vdec_s_ctrl(instance, ctrl);
1292 else if (inst->session_type == MSM_VIDC_ENCODER)
1293 return msm_venc_s_ctrl(instance, ctrl);
1294 return -EINVAL;
1295}
1296
1297static int msm_vidc_op_s_ctrl(struct v4l2_ctrl *ctrl)
1298{
1299
1300 int rc = 0, c = 0;
1301 struct msm_vidc_inst *inst;
1302
1303 if (!ctrl) {
1304 dprintk(VIDC_ERR, "%s invalid parameters for ctrl\n", __func__);
1305 return -EINVAL;
1306 }
1307
1308 inst = container_of(ctrl->handler,
1309 struct msm_vidc_inst, ctrl_handler);
1310 if (!inst) {
1311 dprintk(VIDC_ERR, "%s invalid parameters for inst\n", __func__);
1312 return -EINVAL;
1313 }
1314
1315 for (c = 0; c < ctrl->ncontrols; ++c) {
1316 if (ctrl->cluster[c]->is_new) {
1317 rc = msm_vidc_try_set_ctrl(inst, ctrl->cluster[c]);
1318 if (rc) {
1319 dprintk(VIDC_ERR, "Failed setting %x\n",
1320 ctrl->cluster[c]->id);
1321 break;
1322 }
1323 }
1324 }
1325 if (rc)
1326 dprintk(VIDC_ERR, "Failed setting control: Inst = %pK (%s)\n",
1327 inst, v4l2_ctrl_get_name(ctrl->id));
1328 return rc;
1329}
1330
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001331static int msm_vidc_get_count(struct msm_vidc_inst *inst,
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001332 struct v4l2_ctrl *ctrl)
1333{
1334 int rc = 0;
Praneeth Paladugu6e637472017-05-16 16:06:46 -07001335 struct hal_buffer_requirements *bufreq;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001336 enum hal_buffer buffer_type;
1337
1338 if (ctrl->id == V4L2_CID_MIN_BUFFERS_FOR_OUTPUT) {
1339 bufreq = get_buff_req_buffer(inst, HAL_BUFFER_INPUT);
1340 if (!bufreq) {
1341 dprintk(VIDC_ERR,
1342 "Failed to find bufreqs for buffer type = %d\n",
1343 HAL_BUFFER_INPUT);
1344 return 0;
1345 }
1346 if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming) {
1347 ctrl->val = bufreq->buffer_count_min_host;
1348 return 0;
1349 }
1350 if (ctrl->val > bufreq->buffer_count_min_host) {
1351 dprintk(VIDC_DBG,
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001352 "Buffer count Host changed from %d to %d\n",
1353 bufreq->buffer_count_min_host,
1354 ctrl->val);
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001355 bufreq->buffer_count_actual =
1356 bufreq->buffer_count_min =
1357 bufreq->buffer_count_min_host =
1358 ctrl->val;
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001359 } else {
1360 ctrl->val = bufreq->buffer_count_min_host;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001361 }
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001362 rc = set_buffer_count(inst,
1363 bufreq->buffer_count_min_host,
1364 bufreq->buffer_count_actual,
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001365 HAL_BUFFER_INPUT);
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001366
1367 msm_vidc_update_host_buff_counts(inst);
1368 ctrl->val = bufreq->buffer_count_min_host;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001369 return rc;
1370
1371 } else if (ctrl->id == V4L2_CID_MIN_BUFFERS_FOR_CAPTURE) {
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001372
1373 buffer_type = msm_comm_get_hal_output_buffer(inst);
1374 bufreq = get_buff_req_buffer(inst,
1375 buffer_type);
1376 if (!bufreq) {
1377 dprintk(VIDC_ERR,
1378 "Failed to find bufreqs for buffer type = %d\n",
1379 buffer_type);
1380 return 0;
1381 }
1382 if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming) {
1383 if (ctrl->val != bufreq->buffer_count_min_host)
1384 return -EINVAL;
1385 else
1386 return 0;
1387 }
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001388
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001389 if (inst->session_type == MSM_VIDC_DECODER &&
1390 !inst->in_reconfig &&
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001391 inst->state < MSM_VIDC_LOAD_RESOURCES_DONE) {
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001392 dprintk(VIDC_DBG,
1393 "Clients updates Buffer count from %d to %d\n",
1394 bufreq->buffer_count_min_host, ctrl->val);
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001395 bufreq->buffer_count_actual =
1396 bufreq->buffer_count_min =
1397 bufreq->buffer_count_min_host =
1398 ctrl->val;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001399 }
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001400 if (ctrl->val > bufreq->buffer_count_min_host) {
1401 dprintk(VIDC_DBG,
1402 "Buffer count Host changed from %d to %d\n",
1403 bufreq->buffer_count_min_host,
1404 ctrl->val);
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001405 bufreq->buffer_count_actual =
1406 bufreq->buffer_count_min =
1407 bufreq->buffer_count_min_host =
1408 ctrl->val;
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001409 } else {
1410 ctrl->val = bufreq->buffer_count_min_host;
1411 }
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001412 rc = set_buffer_count(inst,
1413 bufreq->buffer_count_min_host,
1414 bufreq->buffer_count_actual,
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001415 HAL_BUFFER_OUTPUT);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001416
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001417 msm_vidc_update_host_buff_counts(inst);
1418 ctrl->val = bufreq->buffer_count_min_host;
1419
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001420 return rc;
1421 }
1422 return -EINVAL;
1423}
1424
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001425static int try_get_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
1426{
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001427 int rc = 0;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001428 struct hal_buffer_requirements *bufreq = NULL;
1429 enum hal_buffer buffer_type;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001430
1431 switch (ctrl->id) {
1432
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001433 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001434 ctrl->val = msm_comm_hal_to_v4l2(
1435 V4L2_CID_MPEG_VIDEO_H264_PROFILE,
1436 inst->profile);
1437 break;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001438 case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001439 ctrl->val = msm_comm_hal_to_v4l2(
1440 V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE,
1441 inst->profile);
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001442 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001443
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001444 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001445 ctrl->val = msm_comm_hal_to_v4l2(
1446 V4L2_CID_MPEG_VIDEO_H264_LEVEL,
1447 inst->level);
1448 break;
Chinmay Sawarkar7f1cc152017-05-05 18:16:36 -07001449 case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001450 ctrl->val = msm_comm_hal_to_v4l2(
1451 V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL,
1452 inst->level);
1453 break;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001454 case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001455 ctrl->val = msm_comm_hal_to_v4l2(
1456 V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL,
1457 inst->level);
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001458 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001459
1460 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
1461 ctrl->val = inst->entropy_mode;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001462 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001463
1464 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001465 if (inst->in_reconfig)
1466 msm_vidc_update_host_buff_counts(inst);
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001467 buffer_type = msm_comm_get_hal_output_buffer(inst);
1468 bufreq = get_buff_req_buffer(inst,
1469 buffer_type);
1470 if (!bufreq) {
1471 dprintk(VIDC_ERR,
1472 "Failed to find bufreqs for buffer type = %d\n",
1473 buffer_type);
1474 return -EINVAL;
1475 }
1476 ctrl->val = bufreq->buffer_count_min_host;
1477 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001478 case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001479 bufreq = get_buff_req_buffer(inst, HAL_BUFFER_INPUT);
1480 if (!bufreq) {
1481 dprintk(VIDC_ERR,
1482 "Failed to find bufreqs for buffer type = %d\n",
1483 HAL_BUFFER_INPUT);
1484 return -EINVAL;
1485 }
1486 ctrl->val = bufreq->buffer_count_min_host;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001487 break;
Surajit Poddere502daa2017-05-30 19:17:45 +05301488 case V4L2_CID_MPEG_VIDC_VIDEO_TME_PAYLOAD_VERSION:
1489 ctrl->val = inst->capability.tme_version;
1490 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001491 default:
1492 /*
1493 * Other controls aren't really volatile, shouldn't need to
1494 * modify ctrl->value
1495 */
1496 break;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001497 }
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001498
1499 return rc;
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001500}
1501
1502static int msm_vidc_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1503{
1504 int rc = 0, c = 0;
1505 struct msm_vidc_inst *inst;
1506 struct v4l2_ctrl *master;
1507
1508 if (!ctrl) {
1509 dprintk(VIDC_ERR, "%s invalid parameters for ctrl\n", __func__);
1510 return -EINVAL;
1511 }
1512
1513 inst = container_of(ctrl->handler,
1514 struct msm_vidc_inst, ctrl_handler);
1515 if (!inst) {
1516 dprintk(VIDC_ERR, "%s invalid parameters for inst\n", __func__);
1517 return -EINVAL;
1518 }
1519 master = ctrl->cluster[0];
1520 if (!master) {
1521 dprintk(VIDC_ERR, "%s invalid parameters for master\n",
1522 __func__);
1523 return -EINVAL;
1524 }
1525
1526 for (c = 0; c < master->ncontrols; ++c) {
1527 if (master->cluster[c]->flags & V4L2_CTRL_FLAG_VOLATILE) {
1528 rc = try_get_ctrl(inst, master->cluster[c]);
1529 if (rc) {
1530 dprintk(VIDC_ERR, "Failed getting %x\n",
1531 master->cluster[c]->id);
1532 return rc;
1533 }
1534 }
1535 }
1536 if (rc)
1537 dprintk(VIDC_ERR, "Failed getting control: Inst = %pK (%s)\n",
1538 inst, v4l2_ctrl_get_name(ctrl->id));
1539 return rc;
1540}
1541
1542static const struct v4l2_ctrl_ops msm_vidc_ctrl_ops = {
1543
1544 .s_ctrl = msm_vidc_op_s_ctrl,
1545 .g_volatile_ctrl = msm_vidc_op_g_volatile_ctrl,
1546};
1547
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001548void *msm_vidc_open(int core_id, int session_type)
1549{
1550 struct msm_vidc_inst *inst = NULL;
1551 struct msm_vidc_core *core = NULL;
1552 int rc = 0;
1553 int i = 0;
1554
1555 if (core_id >= MSM_VIDC_CORES_MAX ||
1556 session_type >= MSM_VIDC_MAX_DEVICES) {
1557 dprintk(VIDC_ERR, "Invalid input, core_id = %d, session = %d\n",
1558 core_id, session_type);
1559 goto err_invalid_core;
1560 }
1561 core = get_vidc_core(core_id);
1562 if (!core) {
1563 dprintk(VIDC_ERR,
1564 "Failed to find core for core_id = %d\n", core_id);
1565 goto err_invalid_core;
1566 }
1567
1568 inst = kzalloc(sizeof(*inst), GFP_KERNEL);
1569 if (!inst) {
1570 dprintk(VIDC_ERR, "Failed to allocate memory\n");
1571 rc = -ENOMEM;
1572 goto err_invalid_core;
1573 }
1574
1575 pr_info(VIDC_DBG_TAG "Opening video instance: %pK, %d\n",
1576 VIDC_MSG_PRIO2STRING(VIDC_INFO), inst, session_type);
1577 mutex_init(&inst->sync_lock);
1578 mutex_init(&inst->bufq[CAPTURE_PORT].lock);
1579 mutex_init(&inst->bufq[OUTPUT_PORT].lock);
1580 mutex_init(&inst->lock);
1581
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001582 INIT_MSM_VIDC_LIST(&inst->scratchbufs);
Praneeth Paladugub71968b2015-08-19 20:47:57 -07001583 INIT_MSM_VIDC_LIST(&inst->freqs);
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -07001584 INIT_MSM_VIDC_LIST(&inst->input_crs);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001585 INIT_MSM_VIDC_LIST(&inst->persistbufs);
1586 INIT_MSM_VIDC_LIST(&inst->pending_getpropq);
1587 INIT_MSM_VIDC_LIST(&inst->outputbufs);
1588 INIT_MSM_VIDC_LIST(&inst->registeredbufs);
Praneeth Paladugu319e7922017-03-16 11:09:06 -07001589 INIT_MSM_VIDC_LIST(&inst->reconbufs);
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001590 INIT_MSM_VIDC_LIST(&inst->eosbufs);
Qiwei Liu551a22222017-08-23 15:28:29 +08001591 INIT_MSM_VIDC_LIST(&inst->etb_data);
1592 INIT_MSM_VIDC_LIST(&inst->fbd_data);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001593
1594 kref_init(&inst->kref);
1595
1596 inst->session_type = session_type;
1597 inst->state = MSM_VIDC_CORE_UNINIT_DONE;
1598 inst->core = core;
Praneeth Paladugue5fd0872017-04-19 11:24:28 -07001599 inst->clk_data.min_freq = 0;
1600 inst->clk_data.curr_freq = 0;
1601 inst->clk_data.bitrate = 0;
1602 inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001603 inst->bit_depth = MSM_VIDC_BIT_DEPTH_8;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001604 inst->pic_struct = MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
1605 inst->colour_space = MSM_VIDC_BT601_6_525;
Chinmay Sawarkarb3c6ccb2017-02-23 18:01:32 -08001606 inst->profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
1607 inst->level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
1608 inst->entropy_mode = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001609
1610 for (i = SESSION_MSG_INDEX(SESSION_MSG_START);
1611 i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) {
1612 init_completion(&inst->completions[i]);
1613 }
1614 inst->mem_client = msm_smem_new_client(SMEM_ION,
1615 &inst->core->resources, session_type);
1616 if (!inst->mem_client) {
1617 dprintk(VIDC_ERR, "Failed to create memory client\n");
1618 goto fail_mem_client;
1619 }
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001620
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001621 if (session_type == MSM_VIDC_DECODER) {
1622 msm_vdec_inst_init(inst);
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001623 rc = msm_vdec_ctrl_init(inst, &msm_vidc_ctrl_ops);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001624 } else if (session_type == MSM_VIDC_ENCODER) {
1625 msm_venc_inst_init(inst);
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001626 rc = msm_venc_ctrl_init(inst, &msm_vidc_ctrl_ops);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001627 }
1628
1629 if (rc)
1630 goto fail_bufq_capture;
1631
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001632 rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
1633 session_type);
1634 if (rc) {
1635 dprintk(VIDC_ERR,
1636 "Failed to initialize vb2 queue on capture port\n");
1637 goto fail_bufq_capture;
1638 }
1639 rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
1640 session_type);
1641 if (rc) {
1642 dprintk(VIDC_ERR,
1643 "Failed to initialize vb2 queue on capture port\n");
1644 goto fail_bufq_output;
1645 }
1646
1647 setup_event_queue(inst, &core->vdev[session_type].vdev);
1648
1649 mutex_lock(&core->lock);
1650 list_add_tail(&inst->list, &core->instances);
1651 mutex_unlock(&core->lock);
1652
1653 rc = msm_comm_try_state(inst, MSM_VIDC_CORE_INIT_DONE);
1654 if (rc) {
1655 dprintk(VIDC_ERR,
1656 "Failed to move video instance to init state\n");
1657 goto fail_init;
1658 }
1659
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001660 msm_dcvs_try_enable(inst);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001661 if (msm_vidc_check_for_inst_overload(core)) {
1662 dprintk(VIDC_ERR,
1663 "Instance count reached Max limit, rejecting session");
1664 goto fail_init;
1665 }
1666
Praneeth Paladugue5fd0872017-04-19 11:24:28 -07001667 msm_comm_scale_clocks_and_bus(inst);
1668
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001669 inst->debugfs_root =
1670 msm_vidc_debugfs_init_inst(inst, core->debugfs_root);
1671
1672 return inst;
1673fail_init:
1674 mutex_lock(&core->lock);
1675 list_del(&inst->list);
1676 mutex_unlock(&core->lock);
1677
1678 v4l2_fh_del(&inst->event_handler);
1679 v4l2_fh_exit(&inst->event_handler);
1680 vb2_queue_release(&inst->bufq[OUTPUT_PORT].vb2_bufq);
1681fail_bufq_output:
1682 vb2_queue_release(&inst->bufq[CAPTURE_PORT].vb2_bufq);
1683fail_bufq_capture:
1684 msm_comm_ctrl_deinit(inst);
1685 msm_smem_delete_client(inst->mem_client);
1686fail_mem_client:
1687 mutex_destroy(&inst->sync_lock);
1688 mutex_destroy(&inst->bufq[CAPTURE_PORT].lock);
1689 mutex_destroy(&inst->bufq[OUTPUT_PORT].lock);
1690 mutex_destroy(&inst->lock);
1691
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001692 DEINIT_MSM_VIDC_LIST(&inst->scratchbufs);
1693 DEINIT_MSM_VIDC_LIST(&inst->persistbufs);
1694 DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq);
1695 DEINIT_MSM_VIDC_LIST(&inst->outputbufs);
1696 DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001697 DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -07001698 DEINIT_MSM_VIDC_LIST(&inst->freqs);
1699 DEINIT_MSM_VIDC_LIST(&inst->input_crs);
Qiwei Liu551a22222017-08-23 15:28:29 +08001700 DEINIT_MSM_VIDC_LIST(&inst->etb_data);
1701 DEINIT_MSM_VIDC_LIST(&inst->fbd_data);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001702
1703 kfree(inst);
1704 inst = NULL;
1705err_invalid_core:
1706 return inst;
1707}
1708EXPORT_SYMBOL(msm_vidc_open);
1709
Maheshwar Ajja99422322017-07-07 17:31:15 -07001710static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001711{
Maheshwar Ajja99422322017-07-07 17:31:15 -07001712 struct msm_vidc_buffer *temp, *dummy;
Surajit Podder29d7b342017-08-29 00:27:50 +05301713 struct getprop_buf *temp_prop, *dummy_prop;
Maheshwar Ajja99422322017-07-07 17:31:15 -07001714
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001715 if (!inst) {
1716 dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
1717 return;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001718 }
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001719
Maheshwar Ajja99422322017-07-07 17:31:15 -07001720 mutex_lock(&inst->registeredbufs.lock);
1721 list_for_each_entry_safe(temp, dummy, &inst->registeredbufs.list,
1722 list) {
1723 print_vidc_buffer(VIDC_ERR, "undequeud buf", inst, temp);
1724 msm_comm_unmap_vidc_buffer(inst, temp);
1725 list_del(&temp->list);
Maheshwar Ajjacca04052017-07-12 17:59:45 -07001726 kref_put_mbuf(temp);
Maheshwar Ajja99422322017-07-07 17:31:15 -07001727 }
1728 mutex_unlock(&inst->registeredbufs.lock);
1729
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001730 msm_comm_free_freq_table(inst);
1731
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -07001732 msm_comm_free_input_cr_table(inst);
1733
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001734 if (msm_comm_release_scratch_buffers(inst, false))
1735 dprintk(VIDC_ERR,
1736 "Failed to release scratch buffers\n");
1737
1738 if (msm_comm_release_recon_buffers(inst))
1739 dprintk(VIDC_ERR,
1740 "Failed to release recon buffers\n");
1741
1742 if (msm_comm_release_persist_buffers(inst))
1743 dprintk(VIDC_ERR,
1744 "Failed to release persist buffers\n");
1745
Qiwei Liu551a22222017-08-23 15:28:29 +08001746 if (msm_comm_release_mark_data(inst))
1747 dprintk(VIDC_ERR,
1748 "Failed to release mark_data buffers\n");
1749
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001750 /*
1751 * At this point all buffes should be with driver
1752 * irrespective of scenario
1753 */
1754 msm_comm_validate_output_buffers(inst);
1755
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001756 msm_comm_release_eos_buffers(inst);
1757
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001758 if (msm_comm_release_output_buffers(inst, true))
1759 dprintk(VIDC_ERR,
1760 "Failed to release output buffers\n");
1761
1762 if (inst->extradata_handle)
1763 msm_comm_smem_free(inst, inst->extradata_handle);
1764
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001765 mutex_lock(&inst->pending_getpropq.lock);
Surajit Podder29d7b342017-08-29 00:27:50 +05301766 if (!list_empty(&inst->pending_getpropq.list)) {
1767 dprintk(VIDC_ERR,
1768 "pending_getpropq not empty for instance %pK\n",
1769 inst);
1770 list_for_each_entry_safe(temp_prop, dummy_prop,
1771 &inst->pending_getpropq.list, list) {
1772 kfree(temp_prop->data);
1773 list_del(&temp_prop->list);
1774 kfree(temp_prop);
1775 }
1776 }
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001777 mutex_unlock(&inst->pending_getpropq.lock);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001778}
1779
1780int msm_vidc_destroy(struct msm_vidc_inst *inst)
1781{
1782 struct msm_vidc_core *core;
1783 int i = 0;
1784
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001785 if (!inst || !inst->core) {
1786 dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001787 return -EINVAL;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001788 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001789
1790 core = inst->core;
1791
1792 mutex_lock(&core->lock);
1793 /* inst->list lives in core->instances */
1794 list_del(&inst->list);
1795 mutex_unlock(&core->lock);
1796
1797 msm_comm_ctrl_deinit(inst);
1798
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001799 v4l2_fh_del(&inst->event_handler);
1800 v4l2_fh_exit(&inst->event_handler);
1801
1802 for (i = 0; i < MAX_PORT_NUM; i++)
1803 vb2_queue_release(&inst->bufq[i].vb2_bufq);
1804
Maheshwar Ajja99422322017-07-07 17:31:15 -07001805 DEINIT_MSM_VIDC_LIST(&inst->scratchbufs);
1806 DEINIT_MSM_VIDC_LIST(&inst->persistbufs);
1807 DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq);
1808 DEINIT_MSM_VIDC_LIST(&inst->outputbufs);
1809 DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001810 DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -07001811 DEINIT_MSM_VIDC_LIST(&inst->freqs);
1812 DEINIT_MSM_VIDC_LIST(&inst->input_crs);
Qiwei Liu551a22222017-08-23 15:28:29 +08001813 DEINIT_MSM_VIDC_LIST(&inst->etb_data);
1814 DEINIT_MSM_VIDC_LIST(&inst->fbd_data);
Maheshwar Ajja99422322017-07-07 17:31:15 -07001815
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001816 mutex_destroy(&inst->sync_lock);
1817 mutex_destroy(&inst->bufq[CAPTURE_PORT].lock);
1818 mutex_destroy(&inst->bufq[OUTPUT_PORT].lock);
1819 mutex_destroy(&inst->lock);
1820
Abdulla Anamed3c6532017-05-12 19:47:58 +05301821 msm_vidc_debugfs_deinit_inst(inst);
1822
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001823 pr_info(VIDC_DBG_TAG "Closed video instance: %pK\n",
1824 VIDC_MSG_PRIO2STRING(VIDC_INFO), inst);
1825 kfree(inst);
1826 return 0;
1827}
1828
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001829static void close_helper(struct kref *kref)
1830{
1831 struct msm_vidc_inst *inst = container_of(kref,
1832 struct msm_vidc_inst, kref);
1833
1834 msm_vidc_destroy(inst);
1835}
1836
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001837int msm_vidc_close(void *instance)
1838{
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001839 struct msm_vidc_inst *inst = instance;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001840 int rc = 0;
1841
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001842 if (!inst || !inst->core) {
1843 dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001844 return -EINVAL;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001845 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001846
Praneeth Paladuguceec6d82016-12-21 15:09:57 -08001847 /*
1848 * Make sure that HW stop working on these buffers that
1849 * we are going to free.
1850 */
Maheshwar Ajja99422322017-07-07 17:31:15 -07001851 rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001852 if (rc)
1853 dprintk(VIDC_ERR,
Maheshwar Ajja99422322017-07-07 17:31:15 -07001854 "Failed to move inst %pK to rel resource done state\n",
1855 inst);
1856
1857 msm_vidc_cleanup_instance(inst);
1858
1859 rc = msm_comm_try_state(inst, MSM_VIDC_CORE_UNINIT);
1860 if (rc) {
1861 dprintk(VIDC_ERR,
1862 "Failed to move inst %pK to uninit state\n", inst);
1863 rc = msm_comm_force_cleanup(inst);
1864 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001865
1866 msm_comm_session_clean(inst);
1867 msm_smem_delete_client(inst->mem_client);
1868
1869 kref_put(&inst->kref, close_helper);
1870 return 0;
1871}
1872EXPORT_SYMBOL(msm_vidc_close);
1873
1874int msm_vidc_suspend(int core_id)
1875{
1876 return msm_comm_suspend(core_id);
1877}
1878EXPORT_SYMBOL(msm_vidc_suspend);
1879