blob: 6a7588cc9311c9449b333f0ed0fc398962f5ae82 [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
Praneeth Paladugu238977b2016-12-06 12:51:26 -0800886 /* Decide work mode for current session */
887 rc = msm_vidc_decide_work_mode(inst);
888 if (rc) {
889 dprintk(VIDC_ERR,
890 "Failed to decide work mode for session %pK\n", inst);
891 goto fail_start;
892 }
893
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800894 /* Assign Core and LP mode for current session */
895 rc = msm_vidc_decide_core_and_power_mode(inst);
896 if (rc) {
897 dprintk(VIDC_ERR,
Praneeth Paladugu238977b2016-12-06 12:51:26 -0800898 "This session can't be submitted to HW %pK\n", inst);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800899 goto fail_start;
900 }
901
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800902 if (msm_comm_get_stream_output_mode(inst) ==
903 HAL_VIDEO_DECODER_SECONDARY) {
904 b.buffer_type = HAL_BUFFER_OUTPUT2;
905 } else {
906 b.buffer_type = HAL_BUFFER_OUTPUT;
907 }
908
Chinmay Sawarkar02f8f852017-06-26 12:05:38 -0700909 rc = msm_comm_try_get_bufreqs(inst);
910
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800911 b.buffer_size = inst->bufq[CAPTURE_PORT].plane_sizes[0];
912 rc = call_hfi_op(hdev, session_set_property,
913 inst->session, HAL_PARAM_BUFFER_SIZE_MINIMUM,
914 &b);
915
Praneeth Paladugu238977b2016-12-06 12:51:26 -0800916 /* Verify if buffer counts are correct */
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800917 rc = msm_vidc_verify_buffer_counts(inst);
918 if (rc) {
919 dprintk(VIDC_ERR,
920 "This session has mis-match buffer counts%pK\n", inst);
921 goto fail_start;
922 }
923
924 rc = msm_comm_set_scratch_buffers(inst);
925 if (rc) {
926 dprintk(VIDC_ERR,
927 "Failed to set scratch buffers: %d\n", rc);
928 goto fail_start;
929 }
930 rc = msm_comm_set_persist_buffers(inst);
931 if (rc) {
932 dprintk(VIDC_ERR,
933 "Failed to set persist buffers: %d\n", rc);
934 goto fail_start;
935 }
936
Praneeth Paladugu319e7922017-03-16 11:09:06 -0700937 rc = msm_comm_set_recon_buffers(inst);
938 if (rc) {
939 dprintk(VIDC_ERR,
940 "Failed to set recon buffers: %d\n", rc);
941 goto fail_start;
942 }
943
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800944 if (msm_comm_get_stream_output_mode(inst) ==
945 HAL_VIDEO_DECODER_SECONDARY) {
946 rc = msm_comm_set_output_buffers(inst);
947 if (rc) {
948 dprintk(VIDC_ERR,
949 "Failed to set output buffers: %d\n", rc);
950 goto fail_start;
951 }
952 }
953
954 /*
955 * For seq_changed_insufficient, driver should set session_continue
956 * to firmware after the following sequence
957 * - driver raises insufficient event to v4l2 client
958 * - all output buffers have been flushed and freed
959 * - v4l2 client queries buffer requirements and splits/combines OPB-DPB
960 * - v4l2 client sets new set of buffers to firmware
961 * - v4l2 client issues CONTINUE to firmware to resume decoding of
962 * submitted ETBs.
963 */
Umesh Pandeybb3fad02017-03-31 16:49:42 -0700964 rc = msm_comm_session_continue(inst);
965 if (rc)
966 goto fail_start;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800967
968 msm_comm_scale_clocks_and_bus(inst);
969
970 rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE);
971 if (rc) {
972 dprintk(VIDC_ERR,
973 "Failed to move inst: %pK to start done state\n", inst);
974 goto fail_start;
975 }
Praneeth Paladugue5fd0872017-04-19 11:24:28 -0700976
977 msm_clock_data_reset(inst);
978
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800979 if (msm_comm_get_stream_output_mode(inst) ==
980 HAL_VIDEO_DECODER_SECONDARY) {
981 rc = msm_comm_queue_output_buffers(inst);
982 if (rc) {
983 dprintk(VIDC_ERR,
984 "Failed to queue output buffers: %d\n", rc);
985 goto fail_start;
986 }
987 }
988
989fail_start:
Maheshwar Ajja99422322017-07-07 17:31:15 -0700990 if (rc) {
991 dprintk(VIDC_ERR, "%s: kill session %pK\n", __func__, inst);
992 msm_comm_kill_session(inst);
993 }
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800994 return rc;
995}
996
Praneeth Paladugudefea4e2017-02-09 23:44:08 -0800997static int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count)
998{
999 struct msm_vidc_inst *inst;
1000 int rc = 0;
1001 struct hfi_device *hdev;
1002
1003 if (!q || !q->drv_priv) {
1004 dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q);
1005 return -EINVAL;
1006 }
1007 inst = q->drv_priv;
1008 if (!inst || !inst->core || !inst->core->device) {
1009 dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
1010 return -EINVAL;
1011 }
1012 hdev = inst->core->device;
1013 dprintk(VIDC_DBG, "Streamon called on: %d capability for inst: %pK\n",
1014 q->type, inst);
1015 switch (q->type) {
1016 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1017 if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
1018 rc = start_streaming(inst);
1019 break;
1020 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1021 if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
1022 rc = start_streaming(inst);
1023 break;
1024 default:
1025 dprintk(VIDC_ERR, "Queue type is not supported: %d\n", q->type);
1026 rc = -EINVAL;
1027 goto stream_start_failed;
1028 }
1029 if (rc) {
1030 dprintk(VIDC_ERR,
1031 "Streamon failed on: %d capability for inst: %pK\n",
1032 q->type, inst);
1033 goto stream_start_failed;
1034 }
1035
1036 rc = msm_comm_qbuf(inst, NULL);
1037 if (rc) {
1038 dprintk(VIDC_ERR,
1039 "Failed to commit buffers queued before STREAM_ON to hardware: %d\n",
1040 rc);
1041 goto stream_start_failed;
1042 }
1043
Praneeth Paladugu54865842017-08-18 01:45:27 -07001044 rc = msm_vidc_send_pending_eos_buffers(inst);
1045 if (rc) {
1046 dprintk(VIDC_ERR,
1047 "Failed : Send pending EOS buffs for Inst = %pK, %d\n",
1048 inst, rc);
1049 goto stream_start_failed;
1050 }
1051
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001052stream_start_failed:
Maheshwar Ajja884259c2017-06-28 11:22:54 -07001053 if (rc) {
1054 struct msm_vidc_buffer *temp, *next;
1055 struct vb2_buffer *vb;
1056
1057 mutex_lock(&inst->registeredbufs.lock);
1058 list_for_each_entry_safe(temp, next, &inst->registeredbufs.list,
1059 list) {
1060 if (temp->vvb.vb2_buf.type != q->type)
1061 continue;
1062 /*
1063 * queued_list lock is already acquired before
1064 * vb2_stream so no need to acquire it again.
1065 */
1066 list_for_each_entry(vb, &q->queued_list, queued_entry) {
1067 if (msm_comm_compare_vb2_planes(inst, temp,
1068 vb)) {
1069 print_vb2_buffer(VIDC_ERR, "return vb",
1070 inst, vb);
1071 vb2_buffer_done(vb,
1072 VB2_BUF_STATE_QUEUED);
1073 break;
1074 }
1075 }
1076 msm_comm_unmap_vidc_buffer(inst, temp);
1077 list_del(&temp->list);
Maheshwar Ajjacca04052017-07-12 17:59:45 -07001078 kref_put_mbuf(temp);
Maheshwar Ajja884259c2017-06-28 11:22:54 -07001079 }
1080 mutex_unlock(&inst->registeredbufs.lock);
1081 }
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001082 return rc;
1083}
1084
1085static inline int stop_streaming(struct msm_vidc_inst *inst)
1086{
1087 int rc = 0;
1088
1089 rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
1090 if (rc)
1091 dprintk(VIDC_ERR,
1092 "Failed to move inst: %pK to state %d\n",
1093 inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
Praneeth Paladugue5fd0872017-04-19 11:24:28 -07001094
1095 msm_clock_data_reset(inst);
1096
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001097 return rc;
1098}
1099
1100static void msm_vidc_stop_streaming(struct vb2_queue *q)
1101{
1102 struct msm_vidc_inst *inst;
1103 int rc = 0;
1104
1105 if (!q || !q->drv_priv) {
1106 dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q);
1107 return;
1108 }
1109
1110 inst = q->drv_priv;
1111 dprintk(VIDC_DBG, "Streamoff called on: %d capability\n", q->type);
1112 switch (q->type) {
1113 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1114 if (!inst->bufq[CAPTURE_PORT].vb2_bufq.streaming)
1115 rc = stop_streaming(inst);
1116 break;
1117 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1118 if (!inst->bufq[OUTPUT_PORT].vb2_bufq.streaming)
1119 rc = stop_streaming(inst);
1120 break;
1121 default:
1122 dprintk(VIDC_ERR,
1123 "Q-type is not supported: %d\n", q->type);
1124 rc = -EINVAL;
1125 break;
1126 }
1127
1128 msm_comm_scale_clocks_and_bus(inst);
1129
1130 if (rc)
1131 dprintk(VIDC_ERR,
1132 "Failed STOP Streaming inst = %pK on cap = %d\n",
1133 inst, q->type);
1134}
1135
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001136static void msm_vidc_buf_queue(struct vb2_buffer *vb2)
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001137{
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001138 int rc = 0;
1139 struct msm_vidc_inst *inst = NULL;
1140 struct msm_vidc_buffer *mbuf = NULL;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001141
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001142 inst = vb2_get_drv_priv(vb2->vb2_queue);
1143 if (!inst) {
1144 dprintk(VIDC_ERR, "%s: invalid inst\n", __func__);
1145 return;
1146 }
1147
1148 mbuf = msm_comm_get_vidc_buffer(inst, vb2);
1149 if (IS_ERR_OR_NULL(mbuf)) {
1150 if (PTR_ERR(mbuf) != -EEXIST)
1151 print_vb2_buffer(VIDC_ERR, "failed to get vidc-buf",
1152 inst, vb2);
1153 return;
1154 }
Maheshwar Ajjacca04052017-07-12 17:59:45 -07001155 if (!kref_get_mbuf(inst, mbuf)) {
1156 dprintk(VIDC_ERR, "%s: mbuf not found\n", __func__);
1157 return;
1158 }
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001159
1160 rc = msm_comm_qbuf(inst, mbuf);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001161 if (rc)
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001162 print_vidc_buffer(VIDC_ERR, "failed qbuf", inst, mbuf);
Maheshwar Ajjacca04052017-07-12 17:59:45 -07001163
1164 kref_put_mbuf(mbuf);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001165}
1166
1167static const struct vb2_ops msm_vidc_vb2q_ops = {
1168 .queue_setup = msm_vidc_queue_setup,
1169 .start_streaming = msm_vidc_start_streaming,
1170 .buf_queue = msm_vidc_buf_queue,
1171 .buf_cleanup = msm_vidc_cleanup_buffer,
1172 .stop_streaming = msm_vidc_stop_streaming,
1173};
1174
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001175static inline int vb2_bufq_init(struct msm_vidc_inst *inst,
1176 enum v4l2_buf_type type, enum session_type sess)
1177{
1178 struct vb2_queue *q = NULL;
1179
1180 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1181 q = &inst->bufq[CAPTURE_PORT].vb2_bufq;
1182 } else if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1183 q = &inst->bufq[OUTPUT_PORT].vb2_bufq;
1184 } else {
1185 dprintk(VIDC_ERR, "buf_type = %d not recognised\n", type);
1186 return -EINVAL;
1187 }
1188
1189 q->type = type;
1190 q->io_modes = VB2_MMAP | VB2_USERPTR;
1191 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001192 q->ops = &msm_vidc_vb2q_ops;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001193
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001194 q->mem_ops = &msm_vidc_vb2_mem_ops;
1195 q->drv_priv = inst;
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001196 q->allow_zero_bytesused = !V4L2_TYPE_IS_OUTPUT(type);
Vaibhav Deshu Venkatesh362d0922017-03-02 14:16:11 -08001197 q->copy_timestamp = 1;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001198 return vb2_queue_init(q);
1199}
1200
1201static int setup_event_queue(void *inst,
1202 struct video_device *pvdev)
1203{
1204 int rc = 0;
1205 struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
1206
1207 v4l2_fh_init(&vidc_inst->event_handler, pvdev);
1208 v4l2_fh_add(&vidc_inst->event_handler);
1209
1210 return rc;
1211}
1212
1213int msm_vidc_subscribe_event(void *inst,
1214 const struct v4l2_event_subscription *sub)
1215{
1216 int rc = 0;
1217 struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
1218
1219 if (!inst || !sub)
1220 return -EINVAL;
1221
1222 rc = v4l2_event_subscribe(&vidc_inst->event_handler,
1223 sub, MAX_EVENTS, NULL);
1224 return rc;
1225}
1226EXPORT_SYMBOL(msm_vidc_subscribe_event);
1227
1228int msm_vidc_unsubscribe_event(void *inst,
1229 const struct v4l2_event_subscription *sub)
1230{
1231 int rc = 0;
1232 struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
1233
1234 if (!inst || !sub)
1235 return -EINVAL;
1236
1237 rc = v4l2_event_unsubscribe(&vidc_inst->event_handler, sub);
1238 return rc;
1239}
1240EXPORT_SYMBOL(msm_vidc_unsubscribe_event);
1241
1242int msm_vidc_dqevent(void *inst, struct v4l2_event *event)
1243{
1244 int rc = 0;
1245 struct msm_vidc_inst *vidc_inst = (struct msm_vidc_inst *)inst;
1246
1247 if (!inst || !event)
1248 return -EINVAL;
1249
1250 rc = v4l2_event_dequeue(&vidc_inst->event_handler, event, false);
1251 return rc;
1252}
1253EXPORT_SYMBOL(msm_vidc_dqevent);
1254
1255static bool msm_vidc_check_for_inst_overload(struct msm_vidc_core *core)
1256{
1257 u32 instance_count = 0;
1258 u32 secure_instance_count = 0;
1259 struct msm_vidc_inst *inst = NULL;
1260 bool overload = false;
1261
1262 mutex_lock(&core->lock);
1263 list_for_each_entry(inst, &core->instances, list) {
1264 instance_count++;
1265 /* This flag is not updated yet for the current instance */
1266 if (inst->flags & VIDC_SECURE)
1267 secure_instance_count++;
1268 }
1269 mutex_unlock(&core->lock);
1270
1271 /* Instance count includes current instance as well. */
1272
1273 if ((instance_count > core->resources.max_inst_count) ||
1274 (secure_instance_count > core->resources.max_secure_inst_count))
1275 overload = true;
1276 return overload;
1277}
1278
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001279static int msm_vidc_try_set_ctrl(void *instance, struct v4l2_ctrl *ctrl)
1280{
1281 struct msm_vidc_inst *inst = instance;
1282
1283 if (inst->session_type == MSM_VIDC_DECODER)
1284 return msm_vdec_s_ctrl(instance, ctrl);
1285 else if (inst->session_type == MSM_VIDC_ENCODER)
1286 return msm_venc_s_ctrl(instance, ctrl);
1287 return -EINVAL;
1288}
1289
1290static int msm_vidc_op_s_ctrl(struct v4l2_ctrl *ctrl)
1291{
1292
1293 int rc = 0, c = 0;
1294 struct msm_vidc_inst *inst;
1295
1296 if (!ctrl) {
1297 dprintk(VIDC_ERR, "%s invalid parameters for ctrl\n", __func__);
1298 return -EINVAL;
1299 }
1300
1301 inst = container_of(ctrl->handler,
1302 struct msm_vidc_inst, ctrl_handler);
1303 if (!inst) {
1304 dprintk(VIDC_ERR, "%s invalid parameters for inst\n", __func__);
1305 return -EINVAL;
1306 }
1307
1308 for (c = 0; c < ctrl->ncontrols; ++c) {
1309 if (ctrl->cluster[c]->is_new) {
1310 rc = msm_vidc_try_set_ctrl(inst, ctrl->cluster[c]);
1311 if (rc) {
1312 dprintk(VIDC_ERR, "Failed setting %x\n",
1313 ctrl->cluster[c]->id);
1314 break;
1315 }
1316 }
1317 }
1318 if (rc)
1319 dprintk(VIDC_ERR, "Failed setting control: Inst = %pK (%s)\n",
1320 inst, v4l2_ctrl_get_name(ctrl->id));
1321 return rc;
1322}
1323
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001324static int msm_vidc_get_count(struct msm_vidc_inst *inst,
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001325 struct v4l2_ctrl *ctrl)
1326{
1327 int rc = 0;
Praneeth Paladugu6e637472017-05-16 16:06:46 -07001328 struct hal_buffer_requirements *bufreq;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001329 enum hal_buffer buffer_type;
1330
1331 if (ctrl->id == V4L2_CID_MIN_BUFFERS_FOR_OUTPUT) {
1332 bufreq = get_buff_req_buffer(inst, HAL_BUFFER_INPUT);
1333 if (!bufreq) {
1334 dprintk(VIDC_ERR,
1335 "Failed to find bufreqs for buffer type = %d\n",
1336 HAL_BUFFER_INPUT);
1337 return 0;
1338 }
1339 if (inst->bufq[OUTPUT_PORT].vb2_bufq.streaming) {
1340 ctrl->val = bufreq->buffer_count_min_host;
1341 return 0;
1342 }
1343 if (ctrl->val > bufreq->buffer_count_min_host) {
1344 dprintk(VIDC_DBG,
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001345 "Buffer count Host changed from %d to %d\n",
1346 bufreq->buffer_count_min_host,
1347 ctrl->val);
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001348 bufreq->buffer_count_actual =
1349 bufreq->buffer_count_min =
1350 bufreq->buffer_count_min_host =
1351 ctrl->val;
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001352 } else {
1353 ctrl->val = bufreq->buffer_count_min_host;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001354 }
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001355 rc = set_buffer_count(inst,
1356 bufreq->buffer_count_min_host,
1357 bufreq->buffer_count_actual,
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001358 HAL_BUFFER_INPUT);
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001359
1360 msm_vidc_update_host_buff_counts(inst);
1361 ctrl->val = bufreq->buffer_count_min_host;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001362 return rc;
1363
1364 } else if (ctrl->id == V4L2_CID_MIN_BUFFERS_FOR_CAPTURE) {
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001365
1366 buffer_type = msm_comm_get_hal_output_buffer(inst);
1367 bufreq = get_buff_req_buffer(inst,
1368 buffer_type);
1369 if (!bufreq) {
1370 dprintk(VIDC_ERR,
1371 "Failed to find bufreqs for buffer type = %d\n",
1372 buffer_type);
1373 return 0;
1374 }
1375 if (inst->bufq[CAPTURE_PORT].vb2_bufq.streaming) {
1376 if (ctrl->val != bufreq->buffer_count_min_host)
1377 return -EINVAL;
1378 else
1379 return 0;
1380 }
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001381
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001382 if (inst->session_type == MSM_VIDC_DECODER &&
1383 !inst->in_reconfig &&
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001384 inst->state < MSM_VIDC_LOAD_RESOURCES_DONE) {
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001385 dprintk(VIDC_DBG,
1386 "Clients updates Buffer count from %d to %d\n",
1387 bufreq->buffer_count_min_host, ctrl->val);
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001388 bufreq->buffer_count_actual =
1389 bufreq->buffer_count_min =
1390 bufreq->buffer_count_min_host =
1391 ctrl->val;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001392 }
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001393 if (ctrl->val > bufreq->buffer_count_min_host) {
1394 dprintk(VIDC_DBG,
1395 "Buffer count Host changed from %d to %d\n",
1396 bufreq->buffer_count_min_host,
1397 ctrl->val);
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001398 bufreq->buffer_count_actual =
1399 bufreq->buffer_count_min =
1400 bufreq->buffer_count_min_host =
1401 ctrl->val;
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001402 } else {
1403 ctrl->val = bufreq->buffer_count_min_host;
1404 }
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001405 rc = set_buffer_count(inst,
1406 bufreq->buffer_count_min_host,
1407 bufreq->buffer_count_actual,
Praneeth Paladugu1f9d1d92017-04-11 10:36:16 -07001408 HAL_BUFFER_OUTPUT);
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001409
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001410 msm_vidc_update_host_buff_counts(inst);
1411 ctrl->val = bufreq->buffer_count_min_host;
1412
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001413 return rc;
1414 }
1415 return -EINVAL;
1416}
1417
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001418static int try_get_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
1419{
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001420 int rc = 0;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001421 struct hal_buffer_requirements *bufreq = NULL;
1422 enum hal_buffer buffer_type;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001423
1424 switch (ctrl->id) {
1425
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001426 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001427 ctrl->val = msm_comm_hal_to_v4l2(
1428 V4L2_CID_MPEG_VIDEO_H264_PROFILE,
1429 inst->profile);
1430 break;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001431 case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001432 ctrl->val = msm_comm_hal_to_v4l2(
1433 V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE,
1434 inst->profile);
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001435 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001436
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001437 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001438 ctrl->val = msm_comm_hal_to_v4l2(
1439 V4L2_CID_MPEG_VIDEO_H264_LEVEL,
1440 inst->level);
1441 break;
Chinmay Sawarkar7f1cc152017-05-05 18:16:36 -07001442 case V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001443 ctrl->val = msm_comm_hal_to_v4l2(
1444 V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL,
1445 inst->level);
1446 break;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001447 case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL:
Vaibhav Deshu Venkateshce585582017-05-18 13:45:33 -07001448 ctrl->val = msm_comm_hal_to_v4l2(
1449 V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL,
1450 inst->level);
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001451 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001452
1453 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
1454 ctrl->val = inst->entropy_mode;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001455 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001456
1457 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
Praneeth Paladuguf4b15822017-06-27 15:39:24 -07001458 if (inst->in_reconfig)
1459 msm_vidc_update_host_buff_counts(inst);
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001460 buffer_type = msm_comm_get_hal_output_buffer(inst);
1461 bufreq = get_buff_req_buffer(inst,
1462 buffer_type);
1463 if (!bufreq) {
1464 dprintk(VIDC_ERR,
1465 "Failed to find bufreqs for buffer type = %d\n",
1466 buffer_type);
1467 return -EINVAL;
1468 }
1469 ctrl->val = bufreq->buffer_count_min_host;
1470 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001471 case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001472 bufreq = get_buff_req_buffer(inst, HAL_BUFFER_INPUT);
1473 if (!bufreq) {
1474 dprintk(VIDC_ERR,
1475 "Failed to find bufreqs for buffer type = %d\n",
1476 HAL_BUFFER_INPUT);
1477 return -EINVAL;
1478 }
1479 ctrl->val = bufreq->buffer_count_min_host;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001480 break;
Surajit Poddere502daa2017-05-30 19:17:45 +05301481 case V4L2_CID_MPEG_VIDC_VIDEO_TME_PAYLOAD_VERSION:
1482 ctrl->val = inst->capability.tme_version;
1483 break;
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001484 default:
1485 /*
1486 * Other controls aren't really volatile, shouldn't need to
1487 * modify ctrl->value
1488 */
1489 break;
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001490 }
Praneeth Paladugudefea4e2017-02-09 23:44:08 -08001491
1492 return rc;
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001493}
1494
1495static int msm_vidc_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1496{
1497 int rc = 0, c = 0;
1498 struct msm_vidc_inst *inst;
1499 struct v4l2_ctrl *master;
1500
1501 if (!ctrl) {
1502 dprintk(VIDC_ERR, "%s invalid parameters for ctrl\n", __func__);
1503 return -EINVAL;
1504 }
1505
1506 inst = container_of(ctrl->handler,
1507 struct msm_vidc_inst, ctrl_handler);
1508 if (!inst) {
1509 dprintk(VIDC_ERR, "%s invalid parameters for inst\n", __func__);
1510 return -EINVAL;
1511 }
1512 master = ctrl->cluster[0];
1513 if (!master) {
1514 dprintk(VIDC_ERR, "%s invalid parameters for master\n",
1515 __func__);
1516 return -EINVAL;
1517 }
1518
1519 for (c = 0; c < master->ncontrols; ++c) {
1520 if (master->cluster[c]->flags & V4L2_CTRL_FLAG_VOLATILE) {
1521 rc = try_get_ctrl(inst, master->cluster[c]);
1522 if (rc) {
1523 dprintk(VIDC_ERR, "Failed getting %x\n",
1524 master->cluster[c]->id);
1525 return rc;
1526 }
1527 }
1528 }
1529 if (rc)
1530 dprintk(VIDC_ERR, "Failed getting control: Inst = %pK (%s)\n",
1531 inst, v4l2_ctrl_get_name(ctrl->id));
1532 return rc;
1533}
1534
1535static const struct v4l2_ctrl_ops msm_vidc_ctrl_ops = {
1536
1537 .s_ctrl = msm_vidc_op_s_ctrl,
1538 .g_volatile_ctrl = msm_vidc_op_g_volatile_ctrl,
1539};
1540
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001541void *msm_vidc_open(int core_id, int session_type)
1542{
1543 struct msm_vidc_inst *inst = NULL;
1544 struct msm_vidc_core *core = NULL;
1545 int rc = 0;
1546 int i = 0;
1547
1548 if (core_id >= MSM_VIDC_CORES_MAX ||
1549 session_type >= MSM_VIDC_MAX_DEVICES) {
1550 dprintk(VIDC_ERR, "Invalid input, core_id = %d, session = %d\n",
1551 core_id, session_type);
1552 goto err_invalid_core;
1553 }
1554 core = get_vidc_core(core_id);
1555 if (!core) {
1556 dprintk(VIDC_ERR,
1557 "Failed to find core for core_id = %d\n", core_id);
1558 goto err_invalid_core;
1559 }
1560
1561 inst = kzalloc(sizeof(*inst), GFP_KERNEL);
1562 if (!inst) {
1563 dprintk(VIDC_ERR, "Failed to allocate memory\n");
1564 rc = -ENOMEM;
1565 goto err_invalid_core;
1566 }
1567
1568 pr_info(VIDC_DBG_TAG "Opening video instance: %pK, %d\n",
1569 VIDC_MSG_PRIO2STRING(VIDC_INFO), inst, session_type);
1570 mutex_init(&inst->sync_lock);
1571 mutex_init(&inst->bufq[CAPTURE_PORT].lock);
1572 mutex_init(&inst->bufq[OUTPUT_PORT].lock);
1573 mutex_init(&inst->lock);
1574
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001575 INIT_MSM_VIDC_LIST(&inst->scratchbufs);
Praneeth Paladugub71968b2015-08-19 20:47:57 -07001576 INIT_MSM_VIDC_LIST(&inst->freqs);
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -07001577 INIT_MSM_VIDC_LIST(&inst->input_crs);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001578 INIT_MSM_VIDC_LIST(&inst->persistbufs);
1579 INIT_MSM_VIDC_LIST(&inst->pending_getpropq);
1580 INIT_MSM_VIDC_LIST(&inst->outputbufs);
1581 INIT_MSM_VIDC_LIST(&inst->registeredbufs);
Praneeth Paladugu319e7922017-03-16 11:09:06 -07001582 INIT_MSM_VIDC_LIST(&inst->reconbufs);
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001583 INIT_MSM_VIDC_LIST(&inst->eosbufs);
Qiwei Liu551a22222017-08-23 15:28:29 +08001584 INIT_MSM_VIDC_LIST(&inst->etb_data);
1585 INIT_MSM_VIDC_LIST(&inst->fbd_data);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001586
1587 kref_init(&inst->kref);
1588
1589 inst->session_type = session_type;
1590 inst->state = MSM_VIDC_CORE_UNINIT_DONE;
1591 inst->core = core;
Praneeth Paladugue5fd0872017-04-19 11:24:28 -07001592 inst->clk_data.min_freq = 0;
1593 inst->clk_data.curr_freq = 0;
1594 inst->clk_data.bitrate = 0;
1595 inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001596 inst->bit_depth = MSM_VIDC_BIT_DEPTH_8;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001597 inst->pic_struct = MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
1598 inst->colour_space = MSM_VIDC_BT601_6_525;
Chinmay Sawarkarb3c6ccb2017-02-23 18:01:32 -08001599 inst->profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
1600 inst->level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
1601 inst->entropy_mode = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001602
1603 for (i = SESSION_MSG_INDEX(SESSION_MSG_START);
1604 i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) {
1605 init_completion(&inst->completions[i]);
1606 }
1607 inst->mem_client = msm_smem_new_client(SMEM_ION,
1608 &inst->core->resources, session_type);
1609 if (!inst->mem_client) {
1610 dprintk(VIDC_ERR, "Failed to create memory client\n");
1611 goto fail_mem_client;
1612 }
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001613
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001614 if (session_type == MSM_VIDC_DECODER) {
1615 msm_vdec_inst_init(inst);
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001616 rc = msm_vdec_ctrl_init(inst, &msm_vidc_ctrl_ops);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001617 } else if (session_type == MSM_VIDC_ENCODER) {
1618 msm_venc_inst_init(inst);
Praneeth Paladugube42cb22016-04-12 22:34:39 -07001619 rc = msm_venc_ctrl_init(inst, &msm_vidc_ctrl_ops);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001620 }
1621
1622 if (rc)
1623 goto fail_bufq_capture;
1624
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001625 rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
1626 session_type);
1627 if (rc) {
1628 dprintk(VIDC_ERR,
1629 "Failed to initialize vb2 queue on capture port\n");
1630 goto fail_bufq_capture;
1631 }
1632 rc = vb2_bufq_init(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_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_output;
1638 }
1639
1640 setup_event_queue(inst, &core->vdev[session_type].vdev);
1641
1642 mutex_lock(&core->lock);
1643 list_add_tail(&inst->list, &core->instances);
1644 mutex_unlock(&core->lock);
1645
1646 rc = msm_comm_try_state(inst, MSM_VIDC_CORE_INIT_DONE);
1647 if (rc) {
1648 dprintk(VIDC_ERR,
1649 "Failed to move video instance to init state\n");
1650 goto fail_init;
1651 }
1652
Praneeth Paladugu13c90962017-04-24 13:15:28 -07001653 msm_dcvs_try_enable(inst);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001654 if (msm_vidc_check_for_inst_overload(core)) {
1655 dprintk(VIDC_ERR,
1656 "Instance count reached Max limit, rejecting session");
1657 goto fail_init;
1658 }
1659
Praneeth Paladugue5fd0872017-04-19 11:24:28 -07001660 msm_comm_scale_clocks_and_bus(inst);
1661
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001662 inst->debugfs_root =
1663 msm_vidc_debugfs_init_inst(inst, core->debugfs_root);
1664
1665 return inst;
1666fail_init:
1667 mutex_lock(&core->lock);
1668 list_del(&inst->list);
1669 mutex_unlock(&core->lock);
1670
1671 v4l2_fh_del(&inst->event_handler);
1672 v4l2_fh_exit(&inst->event_handler);
1673 vb2_queue_release(&inst->bufq[OUTPUT_PORT].vb2_bufq);
1674fail_bufq_output:
1675 vb2_queue_release(&inst->bufq[CAPTURE_PORT].vb2_bufq);
1676fail_bufq_capture:
1677 msm_comm_ctrl_deinit(inst);
1678 msm_smem_delete_client(inst->mem_client);
1679fail_mem_client:
1680 mutex_destroy(&inst->sync_lock);
1681 mutex_destroy(&inst->bufq[CAPTURE_PORT].lock);
1682 mutex_destroy(&inst->bufq[OUTPUT_PORT].lock);
1683 mutex_destroy(&inst->lock);
1684
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001685 DEINIT_MSM_VIDC_LIST(&inst->scratchbufs);
1686 DEINIT_MSM_VIDC_LIST(&inst->persistbufs);
1687 DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq);
1688 DEINIT_MSM_VIDC_LIST(&inst->outputbufs);
1689 DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001690 DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -07001691 DEINIT_MSM_VIDC_LIST(&inst->freqs);
1692 DEINIT_MSM_VIDC_LIST(&inst->input_crs);
Qiwei Liu551a22222017-08-23 15:28:29 +08001693 DEINIT_MSM_VIDC_LIST(&inst->etb_data);
1694 DEINIT_MSM_VIDC_LIST(&inst->fbd_data);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001695
1696 kfree(inst);
1697 inst = NULL;
1698err_invalid_core:
1699 return inst;
1700}
1701EXPORT_SYMBOL(msm_vidc_open);
1702
Maheshwar Ajja99422322017-07-07 17:31:15 -07001703static void msm_vidc_cleanup_instance(struct msm_vidc_inst *inst)
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001704{
Maheshwar Ajja99422322017-07-07 17:31:15 -07001705 struct msm_vidc_buffer *temp, *dummy;
Surajit Podder29d7b342017-08-29 00:27:50 +05301706 struct getprop_buf *temp_prop, *dummy_prop;
Maheshwar Ajja99422322017-07-07 17:31:15 -07001707
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001708 if (!inst) {
1709 dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
1710 return;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001711 }
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001712
Maheshwar Ajja99422322017-07-07 17:31:15 -07001713 mutex_lock(&inst->registeredbufs.lock);
1714 list_for_each_entry_safe(temp, dummy, &inst->registeredbufs.list,
1715 list) {
1716 print_vidc_buffer(VIDC_ERR, "undequeud buf", inst, temp);
1717 msm_comm_unmap_vidc_buffer(inst, temp);
1718 list_del(&temp->list);
Maheshwar Ajjacca04052017-07-12 17:59:45 -07001719 kref_put_mbuf(temp);
Maheshwar Ajja99422322017-07-07 17:31:15 -07001720 }
1721 mutex_unlock(&inst->registeredbufs.lock);
1722
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001723 msm_comm_free_freq_table(inst);
1724
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -07001725 msm_comm_free_input_cr_table(inst);
1726
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001727 if (msm_comm_release_scratch_buffers(inst, false))
1728 dprintk(VIDC_ERR,
1729 "Failed to release scratch buffers\n");
1730
1731 if (msm_comm_release_recon_buffers(inst))
1732 dprintk(VIDC_ERR,
1733 "Failed to release recon buffers\n");
1734
1735 if (msm_comm_release_persist_buffers(inst))
1736 dprintk(VIDC_ERR,
1737 "Failed to release persist buffers\n");
1738
Qiwei Liu551a22222017-08-23 15:28:29 +08001739 if (msm_comm_release_mark_data(inst))
1740 dprintk(VIDC_ERR,
1741 "Failed to release mark_data buffers\n");
1742
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001743 /*
1744 * At this point all buffes should be with driver
1745 * irrespective of scenario
1746 */
1747 msm_comm_validate_output_buffers(inst);
1748
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001749 msm_comm_release_eos_buffers(inst);
1750
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001751 if (msm_comm_release_output_buffers(inst, true))
1752 dprintk(VIDC_ERR,
1753 "Failed to release output buffers\n");
1754
1755 if (inst->extradata_handle)
1756 msm_comm_smem_free(inst, inst->extradata_handle);
1757
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001758 mutex_lock(&inst->pending_getpropq.lock);
Surajit Podder29d7b342017-08-29 00:27:50 +05301759 if (!list_empty(&inst->pending_getpropq.list)) {
1760 dprintk(VIDC_ERR,
1761 "pending_getpropq not empty for instance %pK\n",
1762 inst);
1763 list_for_each_entry_safe(temp_prop, dummy_prop,
1764 &inst->pending_getpropq.list, list) {
1765 kfree(temp_prop->data);
1766 list_del(&temp_prop->list);
1767 kfree(temp_prop);
1768 }
1769 }
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001770 mutex_unlock(&inst->pending_getpropq.lock);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001771}
1772
1773int msm_vidc_destroy(struct msm_vidc_inst *inst)
1774{
1775 struct msm_vidc_core *core;
1776 int i = 0;
1777
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001778 if (!inst || !inst->core) {
1779 dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001780 return -EINVAL;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001781 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001782
1783 core = inst->core;
1784
1785 mutex_lock(&core->lock);
1786 /* inst->list lives in core->instances */
1787 list_del(&inst->list);
1788 mutex_unlock(&core->lock);
1789
1790 msm_comm_ctrl_deinit(inst);
1791
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001792 v4l2_fh_del(&inst->event_handler);
1793 v4l2_fh_exit(&inst->event_handler);
1794
1795 for (i = 0; i < MAX_PORT_NUM; i++)
1796 vb2_queue_release(&inst->bufq[i].vb2_bufq);
1797
Maheshwar Ajja99422322017-07-07 17:31:15 -07001798 DEINIT_MSM_VIDC_LIST(&inst->scratchbufs);
1799 DEINIT_MSM_VIDC_LIST(&inst->persistbufs);
1800 DEINIT_MSM_VIDC_LIST(&inst->pending_getpropq);
1801 DEINIT_MSM_VIDC_LIST(&inst->outputbufs);
1802 DEINIT_MSM_VIDC_LIST(&inst->registeredbufs);
Praneeth Paladuguf9ef8172017-07-18 22:55:59 -07001803 DEINIT_MSM_VIDC_LIST(&inst->eosbufs);
Praneeth Paladugu7722b4e2017-07-07 11:01:56 -07001804 DEINIT_MSM_VIDC_LIST(&inst->freqs);
1805 DEINIT_MSM_VIDC_LIST(&inst->input_crs);
Qiwei Liu551a22222017-08-23 15:28:29 +08001806 DEINIT_MSM_VIDC_LIST(&inst->etb_data);
1807 DEINIT_MSM_VIDC_LIST(&inst->fbd_data);
Maheshwar Ajja99422322017-07-07 17:31:15 -07001808
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001809 mutex_destroy(&inst->sync_lock);
1810 mutex_destroy(&inst->bufq[CAPTURE_PORT].lock);
1811 mutex_destroy(&inst->bufq[OUTPUT_PORT].lock);
1812 mutex_destroy(&inst->lock);
1813
Abdulla Anamed3c6532017-05-12 19:47:58 +05301814 msm_vidc_debugfs_deinit_inst(inst);
1815
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001816 pr_info(VIDC_DBG_TAG "Closed video instance: %pK\n",
1817 VIDC_MSG_PRIO2STRING(VIDC_INFO), inst);
1818 kfree(inst);
1819 return 0;
1820}
1821
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001822static void close_helper(struct kref *kref)
1823{
1824 struct msm_vidc_inst *inst = container_of(kref,
1825 struct msm_vidc_inst, kref);
1826
1827 msm_vidc_destroy(inst);
1828}
1829
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001830int msm_vidc_close(void *instance)
1831{
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001832 struct msm_vidc_inst *inst = instance;
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001833 int rc = 0;
1834
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001835 if (!inst || !inst->core) {
1836 dprintk(VIDC_ERR, "%s: invalid params\n", __func__);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001837 return -EINVAL;
Maheshwar Ajjac6407c02017-06-09 18:53:20 -07001838 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001839
Praneeth Paladuguceec6d82016-12-21 15:09:57 -08001840 /*
1841 * Make sure that HW stop working on these buffers that
1842 * we are going to free.
1843 */
Maheshwar Ajja99422322017-07-07 17:31:15 -07001844 rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001845 if (rc)
1846 dprintk(VIDC_ERR,
Maheshwar Ajja99422322017-07-07 17:31:15 -07001847 "Failed to move inst %pK to rel resource done state\n",
1848 inst);
1849
1850 msm_vidc_cleanup_instance(inst);
1851
1852 rc = msm_comm_try_state(inst, MSM_VIDC_CORE_UNINIT);
1853 if (rc) {
1854 dprintk(VIDC_ERR,
1855 "Failed to move inst %pK to uninit state\n", inst);
1856 rc = msm_comm_force_cleanup(inst);
1857 }
Praneeth Paladugu6e6fbdb2017-01-16 15:43:01 -08001858
1859 msm_comm_session_clean(inst);
1860 msm_smem_delete_client(inst->mem_client);
1861
1862 kref_put(&inst->kref, close_helper);
1863 return 0;
1864}
1865EXPORT_SYMBOL(msm_vidc_close);
1866
1867int msm_vidc_suspend(int core_id)
1868{
1869 return msm_comm_suspend(core_id);
1870}
1871EXPORT_SYMBOL(msm_vidc_suspend);
1872