1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2016 MediaTek Inc.
4  * Author: PC Chen <pc.chen@mediatek.com>
5  *         Tiffany Lin <tiffany.lin@mediatek.com>
6  */
7 
8 #include <media/v4l2-event.h>
9 #include <media/v4l2-mem2mem.h>
10 #include <media/videobuf2-dma-contig.h>
11 
12 #include "mtk_vcodec_drv.h"
13 #include "mtk_vcodec_dec.h"
14 #include "mtk_vcodec_intr.h"
15 #include "mtk_vcodec_util.h"
16 #include "vdec_drv_if.h"
17 #include "mtk_vcodec_dec_pm.h"
18 
19 #define DFT_CFG_WIDTH	MTK_VDEC_MIN_W
20 #define DFT_CFG_HEIGHT	MTK_VDEC_MIN_H
21 
22 static const struct mtk_video_fmt *
mtk_vdec_find_format(struct v4l2_format * f,const struct mtk_vcodec_dec_pdata * dec_pdata)23 mtk_vdec_find_format(struct v4l2_format *f,
24 		     const struct mtk_vcodec_dec_pdata *dec_pdata)
25 {
26 	const struct mtk_video_fmt *fmt;
27 	unsigned int k;
28 
29 	for (k = 0; k < *dec_pdata->num_formats; k++) {
30 		fmt = &dec_pdata->vdec_formats[k];
31 		if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
32 			return fmt;
33 	}
34 
35 	return NULL;
36 }
37 
mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx * ctx,int format_index)38 static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx *ctx, int format_index)
39 {
40 	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
41 	const struct mtk_video_fmt *fmt;
42 	struct mtk_q_data *q_data;
43 	int num_frame_count = 0, i;
44 	bool ret = true;
45 
46 	for (i = 0; i < *dec_pdata->num_formats; i++) {
47 		if (dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME)
48 			continue;
49 
50 		num_frame_count++;
51 	}
52 
53 	if (num_frame_count == 1)
54 		return true;
55 
56 	fmt = &dec_pdata->vdec_formats[format_index];
57 	q_data = &ctx->q_data[MTK_Q_DATA_SRC];
58 	switch (q_data->fmt->fourcc) {
59 	case V4L2_PIX_FMT_VP8_FRAME:
60 		if (fmt->fourcc == V4L2_PIX_FMT_MM21)
61 			ret = true;
62 		break;
63 	case V4L2_PIX_FMT_H264_SLICE:
64 	case V4L2_PIX_FMT_VP9_FRAME:
65 		if (fmt->fourcc == V4L2_PIX_FMT_MM21)
66 			ret = false;
67 		break;
68 	default:
69 		ret = true;
70 		break;
71 	}
72 
73 	return ret;
74 }
75 
mtk_vdec_get_q_data(struct mtk_vcodec_ctx * ctx,enum v4l2_buf_type type)76 static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx,
77 					      enum v4l2_buf_type type)
78 {
79 	if (V4L2_TYPE_IS_OUTPUT(type))
80 		return &ctx->q_data[MTK_Q_DATA_SRC];
81 
82 	return &ctx->q_data[MTK_Q_DATA_DST];
83 }
84 
vidioc_try_decoder_cmd(struct file * file,void * priv,struct v4l2_decoder_cmd * cmd)85 static int vidioc_try_decoder_cmd(struct file *file, void *priv,
86 				struct v4l2_decoder_cmd *cmd)
87 {
88 	return v4l2_m2m_ioctl_try_decoder_cmd(file, priv, cmd);
89 }
90 
91 
vidioc_decoder_cmd(struct file * file,void * priv,struct v4l2_decoder_cmd * cmd)92 static int vidioc_decoder_cmd(struct file *file, void *priv,
93 				struct v4l2_decoder_cmd *cmd)
94 {
95 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
96 	struct vb2_queue *src_vq, *dst_vq;
97 	int ret;
98 
99 	ret = vidioc_try_decoder_cmd(file, priv, cmd);
100 	if (ret)
101 		return ret;
102 
103 	mtk_v4l2_debug(1, "decoder cmd=%u", cmd->cmd);
104 	dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
105 				V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
106 	switch (cmd->cmd) {
107 	case V4L2_DEC_CMD_STOP:
108 		src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
109 				V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
110 		if (!vb2_is_streaming(src_vq)) {
111 			mtk_v4l2_debug(1, "Output stream is off. No need to flush.");
112 			return 0;
113 		}
114 		if (!vb2_is_streaming(dst_vq)) {
115 			mtk_v4l2_debug(1, "Capture stream is off. No need to flush.");
116 			return 0;
117 		}
118 		v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf.vb);
119 		v4l2_m2m_try_schedule(ctx->m2m_ctx);
120 		break;
121 
122 	case V4L2_DEC_CMD_START:
123 		vb2_clear_last_buffer_dequeued(dst_vq);
124 		break;
125 
126 	default:
127 		return -EINVAL;
128 	}
129 
130 	return 0;
131 }
132 
mtk_vdec_unlock(struct mtk_vcodec_ctx * ctx)133 void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx)
134 {
135 	mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]);
136 }
137 
mtk_vdec_lock(struct mtk_vcodec_ctx * ctx)138 void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx)
139 {
140 	mutex_lock(&ctx->dev->dec_mutex[ctx->hw_id]);
141 }
142 
mtk_vcodec_dec_release(struct mtk_vcodec_ctx * ctx)143 void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx)
144 {
145 	vdec_if_deinit(ctx);
146 	ctx->state = MTK_STATE_FREE;
147 }
148 
mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx * ctx)149 void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
150 {
151 	struct mtk_q_data *q_data;
152 
153 	ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
154 	ctx->fh.m2m_ctx = ctx->m2m_ctx;
155 	ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
156 	INIT_WORK(&ctx->decode_work, ctx->dev->vdec_pdata->worker);
157 	ctx->colorspace = V4L2_COLORSPACE_REC709;
158 	ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
159 	ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
160 	ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT;
161 
162 	q_data = &ctx->q_data[MTK_Q_DATA_SRC];
163 	memset(q_data, 0, sizeof(struct mtk_q_data));
164 	q_data->visible_width = DFT_CFG_WIDTH;
165 	q_data->visible_height = DFT_CFG_HEIGHT;
166 	q_data->fmt = ctx->dev->vdec_pdata->default_out_fmt;
167 	q_data->field = V4L2_FIELD_NONE;
168 
169 	q_data->sizeimage[0] = DFT_CFG_WIDTH * DFT_CFG_HEIGHT;
170 	q_data->bytesperline[0] = 0;
171 
172 	q_data = &ctx->q_data[MTK_Q_DATA_DST];
173 	memset(q_data, 0, sizeof(struct mtk_q_data));
174 	q_data->visible_width = DFT_CFG_WIDTH;
175 	q_data->visible_height = DFT_CFG_HEIGHT;
176 	q_data->coded_width = DFT_CFG_WIDTH;
177 	q_data->coded_height = DFT_CFG_HEIGHT;
178 	q_data->fmt = ctx->dev->vdec_pdata->default_cap_fmt;
179 	q_data->field = V4L2_FIELD_NONE;
180 
181 	q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height;
182 	q_data->bytesperline[0] = q_data->coded_width;
183 	q_data->sizeimage[1] = q_data->sizeimage[0] / 2;
184 	q_data->bytesperline[1] = q_data->coded_width;
185 }
186 
vidioc_vdec_qbuf(struct file * file,void * priv,struct v4l2_buffer * buf)187 static int vidioc_vdec_qbuf(struct file *file, void *priv,
188 			    struct v4l2_buffer *buf)
189 {
190 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
191 
192 	if (ctx->state == MTK_STATE_ABORT) {
193 		mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
194 				ctx->id);
195 		return -EIO;
196 	}
197 
198 	return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
199 }
200 
vidioc_vdec_dqbuf(struct file * file,void * priv,struct v4l2_buffer * buf)201 static int vidioc_vdec_dqbuf(struct file *file, void *priv,
202 			     struct v4l2_buffer *buf)
203 {
204 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
205 
206 	if (ctx->state == MTK_STATE_ABORT) {
207 		mtk_v4l2_err("[%d] Call on DQBUF after unrecoverable error",
208 				ctx->id);
209 		return -EIO;
210 	}
211 
212 	return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
213 }
214 
mtk_vcodec_dec_get_chip_name(void * priv)215 static int mtk_vcodec_dec_get_chip_name(void *priv)
216 {
217 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
218 	struct device *dev = &ctx->dev->plat_dev->dev;
219 
220 	if (of_device_is_compatible(dev->of_node, "mediatek,mt8173-vcodec-dec"))
221 		return 8173;
222 	else if (of_device_is_compatible(dev->of_node, "mediatek,mt8183-vcodec-dec"))
223 		return 8183;
224 	else if (of_device_is_compatible(dev->of_node, "mediatek,mt8192-vcodec-dec"))
225 		return 8192;
226 	else if (of_device_is_compatible(dev->of_node, "mediatek,mt8195-vcodec-dec"))
227 		return 8195;
228 	else if (of_device_is_compatible(dev->of_node, "mediatek,mt8186-vcodec-dec"))
229 		return 8186;
230 	else if (of_device_is_compatible(dev->of_node, "mediatek,mt8188-vcodec-dec"))
231 		return 8188;
232 	else
233 		return 8173;
234 }
235 
vidioc_vdec_querycap(struct file * file,void * priv,struct v4l2_capability * cap)236 static int vidioc_vdec_querycap(struct file *file, void *priv,
237 				struct v4l2_capability *cap)
238 {
239 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
240 	struct device *dev = &ctx->dev->plat_dev->dev;
241 	int platform_name = mtk_vcodec_dec_get_chip_name(priv);
242 
243 	strscpy(cap->driver, dev->driver->name, sizeof(cap->driver));
244 	snprintf(cap->card, sizeof(cap->card), "MT%d video decoder", platform_name);
245 
246 	return 0;
247 }
248 
vidioc_vdec_subscribe_evt(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)249 static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
250 				     const struct v4l2_event_subscription *sub)
251 {
252 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(fh);
253 
254 	if (ctx->dev->vdec_pdata->uses_stateless_api)
255 		return v4l2_ctrl_subscribe_event(fh, sub);
256 
257 	switch (sub->type) {
258 	case V4L2_EVENT_EOS:
259 		return v4l2_event_subscribe(fh, sub, 2, NULL);
260 	case V4L2_EVENT_SOURCE_CHANGE:
261 		return v4l2_src_change_event_subscribe(fh, sub);
262 	default:
263 		return v4l2_ctrl_subscribe_event(fh, sub);
264 	}
265 }
266 
vidioc_try_fmt(struct mtk_vcodec_ctx * ctx,struct v4l2_format * f,const struct mtk_video_fmt * fmt)267 static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f,
268 			  const struct mtk_video_fmt *fmt)
269 {
270 	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
271 	const struct v4l2_frmsize_stepwise *frmsize;
272 
273 	pix_fmt_mp->field = V4L2_FIELD_NONE;
274 
275 	/* Always apply frame size constraints from the coded side */
276 	if (V4L2_TYPE_IS_OUTPUT(f->type))
277 		frmsize = &fmt->frmsize;
278 	else
279 		frmsize = &ctx->q_data[MTK_Q_DATA_SRC].fmt->frmsize;
280 
281 	pix_fmt_mp->width = clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, frmsize->max_width);
282 	pix_fmt_mp->height = clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, frmsize->max_height);
283 
284 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
285 		pix_fmt_mp->num_planes = 1;
286 		pix_fmt_mp->plane_fmt[0].bytesperline = 0;
287 	} else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
288 		int tmp_w, tmp_h;
289 
290 		/*
291 		 * Find next closer width align 64, heign align 64, size align
292 		 * 64 rectangle
293 		 * Note: This only get default value, the real HW needed value
294 		 *       only available when ctx in MTK_STATE_HEADER state
295 		 */
296 		tmp_w = pix_fmt_mp->width;
297 		tmp_h = pix_fmt_mp->height;
298 		v4l_bound_align_image(&pix_fmt_mp->width, MTK_VDEC_MIN_W, frmsize->max_width, 6,
299 				      &pix_fmt_mp->height, MTK_VDEC_MIN_H, frmsize->max_height, 6,
300 				      9);
301 
302 		if (pix_fmt_mp->width < tmp_w &&
303 		    (pix_fmt_mp->width + 64) <= frmsize->max_width)
304 			pix_fmt_mp->width += 64;
305 		if (pix_fmt_mp->height < tmp_h &&
306 		    (pix_fmt_mp->height + 64) <= frmsize->max_height)
307 			pix_fmt_mp->height += 64;
308 
309 		mtk_v4l2_debug(0,
310 			"before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d",
311 			tmp_w, tmp_h, pix_fmt_mp->width,
312 			pix_fmt_mp->height,
313 			pix_fmt_mp->width * pix_fmt_mp->height);
314 
315 		pix_fmt_mp->num_planes = fmt->num_planes;
316 		pix_fmt_mp->plane_fmt[0].sizeimage =
317 				pix_fmt_mp->width * pix_fmt_mp->height;
318 		pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width;
319 
320 		if (pix_fmt_mp->num_planes == 2) {
321 			pix_fmt_mp->plane_fmt[1].sizeimage =
322 				(pix_fmt_mp->width * pix_fmt_mp->height) / 2;
323 			pix_fmt_mp->plane_fmt[1].bytesperline =
324 				pix_fmt_mp->width;
325 		}
326 	}
327 
328 	pix_fmt_mp->flags = 0;
329 	return 0;
330 }
331 
vidioc_try_fmt_vid_cap_mplane(struct file * file,void * priv,struct v4l2_format * f)332 static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
333 				struct v4l2_format *f)
334 {
335 	const struct mtk_video_fmt *fmt;
336 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
337 	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
338 
339 	fmt = mtk_vdec_find_format(f, dec_pdata);
340 	if (!fmt) {
341 		f->fmt.pix.pixelformat =
342 			ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc;
343 		fmt = mtk_vdec_find_format(f, dec_pdata);
344 	}
345 
346 	return vidioc_try_fmt(ctx, f, fmt);
347 }
348 
vidioc_try_fmt_vid_out_mplane(struct file * file,void * priv,struct v4l2_format * f)349 static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
350 				struct v4l2_format *f)
351 {
352 	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
353 	const struct mtk_video_fmt *fmt;
354 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
355 	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
356 
357 	fmt = mtk_vdec_find_format(f, dec_pdata);
358 	if (!fmt) {
359 		f->fmt.pix.pixelformat =
360 			ctx->q_data[MTK_Q_DATA_SRC].fmt->fourcc;
361 		fmt = mtk_vdec_find_format(f, dec_pdata);
362 	}
363 
364 	if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) {
365 		mtk_v4l2_err("sizeimage of output format must be given");
366 		return -EINVAL;
367 	}
368 
369 	return vidioc_try_fmt(ctx, f, fmt);
370 }
371 
vidioc_vdec_g_selection(struct file * file,void * priv,struct v4l2_selection * s)372 static int vidioc_vdec_g_selection(struct file *file, void *priv,
373 			struct v4l2_selection *s)
374 {
375 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
376 	struct mtk_q_data *q_data;
377 
378 	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
379 		return -EINVAL;
380 
381 	q_data = &ctx->q_data[MTK_Q_DATA_DST];
382 
383 	switch (s->target) {
384 	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
385 		s->r.left = 0;
386 		s->r.top = 0;
387 		s->r.width = ctx->picinfo.pic_w;
388 		s->r.height = ctx->picinfo.pic_h;
389 		break;
390 	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
391 		s->r.left = 0;
392 		s->r.top = 0;
393 		s->r.width = ctx->picinfo.buf_w;
394 		s->r.height = ctx->picinfo.buf_h;
395 		break;
396 	case V4L2_SEL_TGT_COMPOSE:
397 		if (vdec_if_get_param(ctx, GET_PARAM_CROP_INFO, &(s->r))) {
398 			/* set to default value if header info not ready yet*/
399 			s->r.left = 0;
400 			s->r.top = 0;
401 			s->r.width = q_data->visible_width;
402 			s->r.height = q_data->visible_height;
403 		}
404 		break;
405 	default:
406 		return -EINVAL;
407 	}
408 
409 	if (ctx->state < MTK_STATE_HEADER) {
410 		/* set to default value if header info not ready yet*/
411 		s->r.left = 0;
412 		s->r.top = 0;
413 		s->r.width = q_data->visible_width;
414 		s->r.height = q_data->visible_height;
415 		return 0;
416 	}
417 
418 	return 0;
419 }
420 
vidioc_vdec_s_selection(struct file * file,void * priv,struct v4l2_selection * s)421 static int vidioc_vdec_s_selection(struct file *file, void *priv,
422 				struct v4l2_selection *s)
423 {
424 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
425 
426 	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
427 		return -EINVAL;
428 
429 	switch (s->target) {
430 	case V4L2_SEL_TGT_COMPOSE:
431 		s->r.left = 0;
432 		s->r.top = 0;
433 		s->r.width = ctx->picinfo.pic_w;
434 		s->r.height = ctx->picinfo.pic_h;
435 		break;
436 	default:
437 		return -EINVAL;
438 	}
439 
440 	return 0;
441 }
442 
vidioc_vdec_s_fmt(struct file * file,void * priv,struct v4l2_format * f)443 static int vidioc_vdec_s_fmt(struct file *file, void *priv,
444 			     struct v4l2_format *f)
445 {
446 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
447 	struct v4l2_pix_format_mplane *pix_mp;
448 	struct mtk_q_data *q_data;
449 	int ret = 0;
450 	const struct mtk_video_fmt *fmt;
451 	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
452 
453 	mtk_v4l2_debug(3, "[%d]", ctx->id);
454 
455 	q_data = mtk_vdec_get_q_data(ctx, f->type);
456 	if (!q_data)
457 		return -EINVAL;
458 
459 	pix_mp = &f->fmt.pix_mp;
460 	/*
461 	 * Setting OUTPUT format after OUTPUT buffers are allocated is invalid
462 	 * if using the stateful API.
463 	 */
464 	if (!dec_pdata->uses_stateless_api &&
465 	    f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
466 	    vb2_is_busy(&ctx->m2m_ctx->out_q_ctx.q)) {
467 		mtk_v4l2_err("out_q_ctx buffers already requested");
468 		ret = -EBUSY;
469 	}
470 
471 	/*
472 	 * Setting CAPTURE format after CAPTURE buffers are allocated is
473 	 * invalid.
474 	 */
475 	if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
476 	    vb2_is_busy(&ctx->m2m_ctx->cap_q_ctx.q)) {
477 		mtk_v4l2_err("cap_q_ctx buffers already requested");
478 		ret = -EBUSY;
479 	}
480 
481 	fmt = mtk_vdec_find_format(f, dec_pdata);
482 	if (fmt == NULL) {
483 		if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
484 			f->fmt.pix.pixelformat =
485 				dec_pdata->default_out_fmt->fourcc;
486 			fmt = mtk_vdec_find_format(f, dec_pdata);
487 		} else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
488 			f->fmt.pix.pixelformat =
489 				dec_pdata->default_cap_fmt->fourcc;
490 			fmt = mtk_vdec_find_format(f, dec_pdata);
491 		}
492 	}
493 	if (fmt == NULL)
494 		return -EINVAL;
495 
496 	q_data->fmt = fmt;
497 	vidioc_try_fmt(ctx, f, q_data->fmt);
498 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
499 		q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
500 		q_data->coded_width = pix_mp->width;
501 		q_data->coded_height = pix_mp->height;
502 
503 		ctx->colorspace = pix_mp->colorspace;
504 		ctx->ycbcr_enc = pix_mp->ycbcr_enc;
505 		ctx->quantization = pix_mp->quantization;
506 		ctx->xfer_func = pix_mp->xfer_func;
507 
508 		ctx->current_codec = fmt->fourcc;
509 		if (ctx->state == MTK_STATE_FREE) {
510 			ret = vdec_if_init(ctx, q_data->fmt->fourcc);
511 			if (ret) {
512 				mtk_v4l2_err("[%d]: vdec_if_init() fail ret=%d",
513 					ctx->id, ret);
514 				return -EINVAL;
515 			}
516 			ctx->state = MTK_STATE_INIT;
517 		}
518 	} else {
519 		ctx->capture_fourcc = fmt->fourcc;
520 	}
521 
522 	/*
523 	 * If using the stateless API, S_FMT should have the effect of setting
524 	 * the CAPTURE queue resolution no matter which queue it was called on.
525 	 */
526 	if (dec_pdata->uses_stateless_api) {
527 		ctx->picinfo.pic_w = pix_mp->width;
528 		ctx->picinfo.pic_h = pix_mp->height;
529 
530 		/*
531 		 * If get pic info fail, need to use the default pic info params, or
532 		 * v4l2-compliance will fail
533 		 */
534 		ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo);
535 		if (ret) {
536 			mtk_v4l2_err("[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail",
537 				     ctx->id);
538 		}
539 
540 		ctx->last_decoded_picinfo = ctx->picinfo;
541 
542 		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1) {
543 			ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
544 				ctx->picinfo.fb_sz[0] +
545 				ctx->picinfo.fb_sz[1];
546 			ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] =
547 				ctx->picinfo.buf_w;
548 		} else {
549 			ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
550 				ctx->picinfo.fb_sz[0];
551 			ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] =
552 				ctx->picinfo.buf_w;
553 			ctx->q_data[MTK_Q_DATA_DST].sizeimage[1] =
554 				ctx->picinfo.fb_sz[1];
555 			ctx->q_data[MTK_Q_DATA_DST].bytesperline[1] =
556 				ctx->picinfo.buf_w;
557 		}
558 
559 		ctx->q_data[MTK_Q_DATA_DST].coded_width = ctx->picinfo.buf_w;
560 		ctx->q_data[MTK_Q_DATA_DST].coded_height = ctx->picinfo.buf_h;
561 		mtk_v4l2_debug(2, "[%d] vdec_if_init() num_plane = %d wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x",
562 			       ctx->id, pix_mp->num_planes, ctx->picinfo.buf_w, ctx->picinfo.buf_h,
563 			       ctx->picinfo.pic_w, ctx->picinfo.pic_h,
564 			       ctx->q_data[MTK_Q_DATA_DST].sizeimage[0],
565 			       ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]);
566 	}
567 	return 0;
568 }
569 
vidioc_enum_framesizes(struct file * file,void * priv,struct v4l2_frmsizeenum * fsize)570 static int vidioc_enum_framesizes(struct file *file, void *priv,
571 				struct v4l2_frmsizeenum *fsize)
572 {
573 	int i = 0;
574 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
575 	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
576 
577 	if (fsize->index != 0)
578 		return -EINVAL;
579 
580 	for (i = 0; i < *dec_pdata->num_formats; i++) {
581 		if (fsize->pixel_format != dec_pdata->vdec_formats[i].fourcc)
582 			continue;
583 
584 		/* Only coded formats have frame sizes set */
585 		if (!dec_pdata->vdec_formats[i].frmsize.max_width)
586 			return -ENOTTY;
587 
588 		fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
589 		fsize->stepwise = dec_pdata->vdec_formats[i].frmsize;
590 
591 		mtk_v4l2_debug(1, "%x, %d %d %d %d %d %d",
592 				ctx->dev->dec_capability,
593 				fsize->stepwise.min_width,
594 				fsize->stepwise.max_width,
595 				fsize->stepwise.step_width,
596 				fsize->stepwise.min_height,
597 				fsize->stepwise.max_height,
598 				fsize->stepwise.step_height);
599 
600 		return 0;
601 	}
602 
603 	return -EINVAL;
604 }
605 
vidioc_enum_fmt(struct v4l2_fmtdesc * f,void * priv,bool output_queue)606 static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
607 			   bool output_queue)
608 {
609 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
610 	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
611 	const struct mtk_video_fmt *fmt;
612 	int i, j = 0;
613 
614 	for (i = 0; i < *dec_pdata->num_formats; i++) {
615 		if (output_queue &&
616 		    dec_pdata->vdec_formats[i].type != MTK_FMT_DEC)
617 			continue;
618 		if (!output_queue &&
619 		    dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME)
620 			continue;
621 
622 		if (!output_queue && !mtk_vdec_get_cap_fmt(ctx, i))
623 			continue;
624 
625 		if (j == f->index)
626 			break;
627 		++j;
628 	}
629 
630 	if (i == *dec_pdata->num_formats)
631 		return -EINVAL;
632 
633 	fmt = &dec_pdata->vdec_formats[i];
634 	f->pixelformat = fmt->fourcc;
635 	f->flags = fmt->flags;
636 
637 	return 0;
638 }
639 
vidioc_vdec_enum_fmt_vid_cap(struct file * file,void * priv,struct v4l2_fmtdesc * f)640 static int vidioc_vdec_enum_fmt_vid_cap(struct file *file, void *priv,
641 					struct v4l2_fmtdesc *f)
642 {
643 	return vidioc_enum_fmt(f, priv, false);
644 }
645 
vidioc_vdec_enum_fmt_vid_out(struct file * file,void * priv,struct v4l2_fmtdesc * f)646 static int vidioc_vdec_enum_fmt_vid_out(struct file *file, void *priv,
647 					struct v4l2_fmtdesc *f)
648 {
649 	return vidioc_enum_fmt(f, priv, true);
650 }
651 
vidioc_vdec_g_fmt(struct file * file,void * priv,struct v4l2_format * f)652 static int vidioc_vdec_g_fmt(struct file *file, void *priv,
653 			     struct v4l2_format *f)
654 {
655 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
656 	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
657 	struct vb2_queue *vq;
658 	struct mtk_q_data *q_data;
659 
660 	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
661 	if (!vq) {
662 		mtk_v4l2_err("no vb2 queue for type=%d", f->type);
663 		return -EINVAL;
664 	}
665 
666 	q_data = mtk_vdec_get_q_data(ctx, f->type);
667 
668 	pix_mp->field = V4L2_FIELD_NONE;
669 	pix_mp->colorspace = ctx->colorspace;
670 	pix_mp->ycbcr_enc = ctx->ycbcr_enc;
671 	pix_mp->quantization = ctx->quantization;
672 	pix_mp->xfer_func = ctx->xfer_func;
673 
674 	if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
675 	    (ctx->state >= MTK_STATE_HEADER)) {
676 		/* Until STREAMOFF is called on the CAPTURE queue
677 		 * (acknowledging the event), the driver operates as if
678 		 * the resolution hasn't changed yet.
679 		 * So we just return picinfo yet, and update picinfo in
680 		 * stop_streaming hook function
681 		 */
682 		q_data->sizeimage[0] = ctx->picinfo.fb_sz[0];
683 		q_data->sizeimage[1] = ctx->picinfo.fb_sz[1];
684 		q_data->bytesperline[0] = ctx->last_decoded_picinfo.buf_w;
685 		q_data->bytesperline[1] = ctx->last_decoded_picinfo.buf_w;
686 		q_data->coded_width = ctx->picinfo.buf_w;
687 		q_data->coded_height = ctx->picinfo.buf_h;
688 		ctx->last_decoded_picinfo.cap_fourcc = q_data->fmt->fourcc;
689 
690 		/*
691 		 * Width and height are set to the dimensions
692 		 * of the movie, the buffer is bigger and
693 		 * further processing stages should crop to this
694 		 * rectangle.
695 		 */
696 		pix_mp->width = q_data->coded_width;
697 		pix_mp->height = q_data->coded_height;
698 
699 		/*
700 		 * Set pixelformat to the format in which mt vcodec
701 		 * outputs the decoded frame
702 		 */
703 		pix_mp->num_planes = q_data->fmt->num_planes;
704 		pix_mp->pixelformat = q_data->fmt->fourcc;
705 		pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
706 		pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
707 		pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1];
708 		pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1];
709 
710 	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
711 		/*
712 		 * This is run on OUTPUT
713 		 * The buffer contains compressed image
714 		 * so width and height have no meaning.
715 		 * Assign value here to pass v4l2-compliance test
716 		 */
717 		pix_mp->width = q_data->visible_width;
718 		pix_mp->height = q_data->visible_height;
719 		pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
720 		pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
721 		pix_mp->pixelformat = q_data->fmt->fourcc;
722 		pix_mp->num_planes = q_data->fmt->num_planes;
723 	} else {
724 		pix_mp->width = q_data->coded_width;
725 		pix_mp->height = q_data->coded_height;
726 		pix_mp->num_planes = q_data->fmt->num_planes;
727 		pix_mp->pixelformat = q_data->fmt->fourcc;
728 		pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
729 		pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
730 		pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1];
731 		pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1];
732 
733 		mtk_v4l2_debug(1, "[%d] type=%d state=%d Format information could not be read, not ready yet!",
734 				ctx->id, f->type, ctx->state);
735 	}
736 
737 	return 0;
738 }
739 
vb2ops_vdec_queue_setup(struct vb2_queue * vq,unsigned int * nbuffers,unsigned int * nplanes,unsigned int sizes[],struct device * alloc_devs[])740 int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
741 			    unsigned int *nplanes, unsigned int sizes[],
742 			    struct device *alloc_devs[])
743 {
744 	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq);
745 	struct mtk_q_data *q_data;
746 	unsigned int i;
747 
748 	q_data = mtk_vdec_get_q_data(ctx, vq->type);
749 
750 	if (q_data == NULL) {
751 		mtk_v4l2_err("vq->type=%d err\n", vq->type);
752 		return -EINVAL;
753 	}
754 
755 	if (*nplanes) {
756 		for (i = 0; i < *nplanes; i++) {
757 			if (sizes[i] < q_data->sizeimage[i])
758 				return -EINVAL;
759 		}
760 	} else {
761 		if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
762 			*nplanes = q_data->fmt->num_planes;
763 		else
764 			*nplanes = 1;
765 
766 		for (i = 0; i < *nplanes; i++)
767 			sizes[i] = q_data->sizeimage[i];
768 	}
769 
770 	mtk_v4l2_debug(1,
771 			"[%d]\t type = %d, get %d plane(s), %d buffer(s) of size 0x%x 0x%x ",
772 			ctx->id, vq->type, *nplanes, *nbuffers,
773 			sizes[0], sizes[1]);
774 
775 	return 0;
776 }
777 
vb2ops_vdec_buf_prepare(struct vb2_buffer * vb)778 int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb)
779 {
780 	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
781 	struct mtk_q_data *q_data;
782 	int i;
783 
784 	mtk_v4l2_debug(3, "[%d] (%d) id=%d",
785 			ctx->id, vb->vb2_queue->type, vb->index);
786 
787 	q_data = mtk_vdec_get_q_data(ctx, vb->vb2_queue->type);
788 
789 	for (i = 0; i < q_data->fmt->num_planes; i++) {
790 		if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) {
791 			mtk_v4l2_err("data will not fit into plane %d (%lu < %d)",
792 				i, vb2_plane_size(vb, i),
793 				q_data->sizeimage[i]);
794 			return -EINVAL;
795 		}
796 		if (!V4L2_TYPE_IS_OUTPUT(vb->type))
797 			vb2_set_plane_payload(vb, i, q_data->sizeimage[i]);
798 	}
799 
800 	return 0;
801 }
802 
vb2ops_vdec_buf_finish(struct vb2_buffer * vb)803 void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
804 {
805 	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
806 	struct vb2_v4l2_buffer *vb2_v4l2;
807 	struct mtk_video_dec_buf *buf;
808 	bool buf_error;
809 
810 	vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
811 	buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
812 	mutex_lock(&ctx->lock);
813 	if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
814 		buf->queued_in_v4l2 = false;
815 		buf->queued_in_vb2 = false;
816 	}
817 	buf_error = buf->error;
818 	mutex_unlock(&ctx->lock);
819 
820 	if (buf_error) {
821 		mtk_v4l2_err("Unrecoverable error on buffer.");
822 		ctx->state = MTK_STATE_ABORT;
823 	}
824 }
825 
vb2ops_vdec_buf_init(struct vb2_buffer * vb)826 int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
827 {
828 	struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
829 					struct vb2_v4l2_buffer, vb2_buf);
830 	struct mtk_video_dec_buf *buf = container_of(vb2_v4l2,
831 					struct mtk_video_dec_buf, m2m_buf.vb);
832 
833 	if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
834 		buf->used = false;
835 		buf->queued_in_v4l2 = false;
836 	}
837 
838 	return 0;
839 }
840 
vb2ops_vdec_start_streaming(struct vb2_queue * q,unsigned int count)841 int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
842 {
843 	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
844 
845 	if (ctx->state == MTK_STATE_FLUSH)
846 		ctx->state = MTK_STATE_HEADER;
847 
848 	return 0;
849 }
850 
vb2ops_vdec_stop_streaming(struct vb2_queue * q)851 void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
852 {
853 	struct vb2_v4l2_buffer *src_buf = NULL, *dst_buf = NULL;
854 	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
855 	int ret;
856 
857 	mtk_v4l2_debug(3, "[%d] (%d) state=(%x) ctx->decoded_frame_cnt=%d",
858 			ctx->id, q->type, ctx->state, ctx->decoded_frame_cnt);
859 
860 	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
861 		while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) {
862 			if (src_buf != &ctx->empty_flush_buf.vb) {
863 				struct media_request *req =
864 					src_buf->vb2_buf.req_obj.req;
865 				v4l2_m2m_buf_done(src_buf,
866 						VB2_BUF_STATE_ERROR);
867 				if (req)
868 					v4l2_ctrl_request_complete(req, &ctx->ctrl_hdl);
869 			}
870 		}
871 		return;
872 	}
873 
874 	if (ctx->state >= MTK_STATE_HEADER) {
875 
876 		/* Until STREAMOFF is called on the CAPTURE queue
877 		 * (acknowledging the event), the driver operates
878 		 * as if the resolution hasn't changed yet, i.e.
879 		 * VIDIOC_G_FMT< etc. return previous resolution.
880 		 * So we update picinfo here
881 		 */
882 		ctx->picinfo = ctx->last_decoded_picinfo;
883 
884 		mtk_v4l2_debug(2,
885 				"[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)",
886 				ctx->id, ctx->last_decoded_picinfo.pic_w,
887 				ctx->last_decoded_picinfo.pic_h,
888 				ctx->picinfo.pic_w, ctx->picinfo.pic_h,
889 				ctx->last_decoded_picinfo.buf_w,
890 				ctx->last_decoded_picinfo.buf_h);
891 
892 		ret = ctx->dev->vdec_pdata->flush_decoder(ctx);
893 		if (ret)
894 			mtk_v4l2_err("DecodeFinal failed, ret=%d", ret);
895 	}
896 	ctx->state = MTK_STATE_FLUSH;
897 
898 	while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) {
899 		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
900 		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
901 			vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0);
902 		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
903 	}
904 
905 }
906 
m2mops_vdec_device_run(void * priv)907 static void m2mops_vdec_device_run(void *priv)
908 {
909 	struct mtk_vcodec_ctx *ctx = priv;
910 	struct mtk_vcodec_dev *dev = ctx->dev;
911 
912 	queue_work(dev->decode_workqueue, &ctx->decode_work);
913 }
914 
m2mops_vdec_job_ready(void * m2m_priv)915 static int m2mops_vdec_job_ready(void *m2m_priv)
916 {
917 	struct mtk_vcodec_ctx *ctx = m2m_priv;
918 
919 	mtk_v4l2_debug(3, "[%d]", ctx->id);
920 
921 	if (ctx->state == MTK_STATE_ABORT)
922 		return 0;
923 
924 	if ((ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w) ||
925 	    (ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h))
926 		return 0;
927 
928 	if (ctx->state != MTK_STATE_HEADER)
929 		return 0;
930 
931 	return 1;
932 }
933 
m2mops_vdec_job_abort(void * priv)934 static void m2mops_vdec_job_abort(void *priv)
935 {
936 	struct mtk_vcodec_ctx *ctx = priv;
937 
938 	ctx->state = MTK_STATE_ABORT;
939 }
940 
941 const struct v4l2_m2m_ops mtk_vdec_m2m_ops = {
942 	.device_run	= m2mops_vdec_device_run,
943 	.job_ready	= m2mops_vdec_job_ready,
944 	.job_abort	= m2mops_vdec_job_abort,
945 };
946 
947 const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops = {
948 	.vidioc_streamon	= v4l2_m2m_ioctl_streamon,
949 	.vidioc_streamoff	= v4l2_m2m_ioctl_streamoff,
950 	.vidioc_reqbufs		= v4l2_m2m_ioctl_reqbufs,
951 	.vidioc_querybuf	= v4l2_m2m_ioctl_querybuf,
952 	.vidioc_expbuf		= v4l2_m2m_ioctl_expbuf,
953 
954 	.vidioc_qbuf		= vidioc_vdec_qbuf,
955 	.vidioc_dqbuf		= vidioc_vdec_dqbuf,
956 
957 	.vidioc_try_fmt_vid_cap_mplane	= vidioc_try_fmt_vid_cap_mplane,
958 	.vidioc_try_fmt_vid_out_mplane	= vidioc_try_fmt_vid_out_mplane,
959 
960 	.vidioc_s_fmt_vid_cap_mplane	= vidioc_vdec_s_fmt,
961 	.vidioc_s_fmt_vid_out_mplane	= vidioc_vdec_s_fmt,
962 	.vidioc_g_fmt_vid_cap_mplane	= vidioc_vdec_g_fmt,
963 	.vidioc_g_fmt_vid_out_mplane	= vidioc_vdec_g_fmt,
964 
965 	.vidioc_create_bufs		= v4l2_m2m_ioctl_create_bufs,
966 
967 	.vidioc_enum_fmt_vid_cap	= vidioc_vdec_enum_fmt_vid_cap,
968 	.vidioc_enum_fmt_vid_out	= vidioc_vdec_enum_fmt_vid_out,
969 	.vidioc_enum_framesizes	= vidioc_enum_framesizes,
970 
971 	.vidioc_querycap		= vidioc_vdec_querycap,
972 	.vidioc_subscribe_event		= vidioc_vdec_subscribe_evt,
973 	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
974 	.vidioc_g_selection             = vidioc_vdec_g_selection,
975 	.vidioc_s_selection             = vidioc_vdec_s_selection,
976 
977 	.vidioc_decoder_cmd = vidioc_decoder_cmd,
978 	.vidioc_try_decoder_cmd = vidioc_try_decoder_cmd,
979 };
980 
mtk_vcodec_dec_queue_init(void * priv,struct vb2_queue * src_vq,struct vb2_queue * dst_vq)981 int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
982 			   struct vb2_queue *dst_vq)
983 {
984 	struct mtk_vcodec_ctx *ctx = priv;
985 	int ret = 0;
986 
987 	mtk_v4l2_debug(3, "[%d]", ctx->id);
988 
989 	src_vq->type		= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
990 	src_vq->io_modes	= VB2_DMABUF | VB2_MMAP;
991 	src_vq->drv_priv	= ctx;
992 	src_vq->buf_struct_size = sizeof(struct mtk_video_dec_buf);
993 	src_vq->ops		= ctx->dev->vdec_pdata->vdec_vb2_ops;
994 	src_vq->mem_ops		= &vb2_dma_contig_memops;
995 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
996 	src_vq->lock		= &ctx->dev->dev_mutex;
997 	src_vq->dev             = &ctx->dev->plat_dev->dev;
998 	src_vq->allow_cache_hints = 1;
999 
1000 	ret = vb2_queue_init(src_vq);
1001 	if (ret) {
1002 		mtk_v4l2_err("Failed to initialize videobuf2 queue(output)");
1003 		return ret;
1004 	}
1005 	dst_vq->type		= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1006 	dst_vq->io_modes	= VB2_DMABUF | VB2_MMAP;
1007 	dst_vq->drv_priv	= ctx;
1008 	dst_vq->buf_struct_size = sizeof(struct mtk_video_dec_buf);
1009 	dst_vq->ops		= ctx->dev->vdec_pdata->vdec_vb2_ops;
1010 	dst_vq->mem_ops		= &vb2_dma_contig_memops;
1011 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1012 	dst_vq->lock		= &ctx->dev->dev_mutex;
1013 	dst_vq->dev             = &ctx->dev->plat_dev->dev;
1014 	dst_vq->allow_cache_hints = 1;
1015 
1016 	ret = vb2_queue_init(dst_vq);
1017 	if (ret)
1018 		mtk_v4l2_err("Failed to initialize videobuf2 queue(capture)");
1019 
1020 	return ret;
1021 }
1022