xref: /linux/drivers/staging/media/sunxi/cedrus/cedrus_video.c (revision cbdb1f163af2bb90d01be1f0263df1d8d5c9d9d3)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Cedrus VPU driver
4  *
5  * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
6  * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
7  * Copyright (C) 2018 Bootlin
8  *
9  * Based on the vim2m driver, that is:
10  *
11  * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
12  * Pawel Osciak, <pawel@osciak.com>
13  * Marek Szyprowski, <m.szyprowski@samsung.com>
14  */
15 
16 #include <linux/pm_runtime.h>
17 
18 #include <media/videobuf2-dma-contig.h>
19 #include <media/v4l2-device.h>
20 #include <media/v4l2-ioctl.h>
21 #include <media/v4l2-event.h>
22 #include <media/v4l2-mem2mem.h>
23 
24 #include "cedrus.h"
25 #include "cedrus_video.h"
26 #include "cedrus_dec.h"
27 #include "cedrus_hw.h"
28 
29 #define CEDRUS_DECODE_SRC	BIT(0)
30 #define CEDRUS_DECODE_DST	BIT(1)
31 
32 #define CEDRUS_MIN_WIDTH	16U
33 #define CEDRUS_MIN_HEIGHT	16U
34 #define CEDRUS_MAX_WIDTH	4096U
35 #define CEDRUS_MAX_HEIGHT	2304U
36 
37 static struct cedrus_format cedrus_formats[] = {
38 	{
39 		.pixelformat	= V4L2_PIX_FMT_MPEG2_SLICE,
40 		.directions	= CEDRUS_DECODE_SRC,
41 		.capabilities	= CEDRUS_CAPABILITY_MPEG2_DEC,
42 	},
43 	{
44 		.pixelformat	= V4L2_PIX_FMT_H264_SLICE,
45 		.directions	= CEDRUS_DECODE_SRC,
46 		.capabilities	= CEDRUS_CAPABILITY_H264_DEC,
47 	},
48 	{
49 		.pixelformat	= V4L2_PIX_FMT_HEVC_SLICE,
50 		.directions	= CEDRUS_DECODE_SRC,
51 		.capabilities	= CEDRUS_CAPABILITY_H265_DEC,
52 	},
53 	{
54 		.pixelformat	= V4L2_PIX_FMT_VP8_FRAME,
55 		.directions	= CEDRUS_DECODE_SRC,
56 		.capabilities	= CEDRUS_CAPABILITY_VP8_DEC,
57 	},
58 	{
59 		.pixelformat	= V4L2_PIX_FMT_NV12,
60 		.directions	= CEDRUS_DECODE_DST,
61 		.capabilities	= CEDRUS_CAPABILITY_UNTILED,
62 	},
63 	{
64 		.pixelformat	= V4L2_PIX_FMT_NV12_32L32,
65 		.directions	= CEDRUS_DECODE_DST,
66 	},
67 };
68 
69 #define CEDRUS_FORMATS_COUNT	ARRAY_SIZE(cedrus_formats)
70 
71 static inline struct cedrus_ctx *cedrus_file2ctx(struct file *file)
72 {
73 	return container_of(file->private_data, struct cedrus_ctx, fh);
74 }
75 
76 static struct cedrus_format *cedrus_find_format(struct cedrus_ctx *ctx,
77 						u32 pixelformat, u32 directions)
78 {
79 	struct cedrus_format *first_valid_fmt = NULL;
80 	struct cedrus_format *fmt;
81 	unsigned int i;
82 
83 	for (i = 0; i < CEDRUS_FORMATS_COUNT; i++) {
84 		fmt = &cedrus_formats[i];
85 
86 		if (!cedrus_is_capable(ctx, fmt->capabilities) ||
87 		    !(fmt->directions & directions))
88 			continue;
89 
90 		if (fmt->pixelformat == pixelformat)
91 			break;
92 
93 		if (!first_valid_fmt)
94 			first_valid_fmt = fmt;
95 	}
96 
97 	if (i == CEDRUS_FORMATS_COUNT)
98 		return first_valid_fmt;
99 
100 	return &cedrus_formats[i];
101 }
102 
103 void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
104 {
105 	unsigned int width = pix_fmt->width;
106 	unsigned int height = pix_fmt->height;
107 	unsigned int sizeimage = pix_fmt->sizeimage;
108 	unsigned int bytesperline = pix_fmt->bytesperline;
109 
110 	pix_fmt->field = V4L2_FIELD_NONE;
111 
112 	/* Limit to hardware min/max. */
113 	width = clamp(width, CEDRUS_MIN_WIDTH, CEDRUS_MAX_WIDTH);
114 	height = clamp(height, CEDRUS_MIN_HEIGHT, CEDRUS_MAX_HEIGHT);
115 
116 	switch (pix_fmt->pixelformat) {
117 	case V4L2_PIX_FMT_MPEG2_SLICE:
118 	case V4L2_PIX_FMT_H264_SLICE:
119 	case V4L2_PIX_FMT_HEVC_SLICE:
120 	case V4L2_PIX_FMT_VP8_FRAME:
121 		/* Zero bytes per line for encoded source. */
122 		bytesperline = 0;
123 		/* Choose some minimum size since this can't be 0 */
124 		sizeimage = max_t(u32, SZ_1K, sizeimage);
125 		break;
126 
127 	case V4L2_PIX_FMT_NV12_32L32:
128 		/* 32-aligned stride. */
129 		bytesperline = ALIGN(width, 32);
130 
131 		/* 32-aligned height. */
132 		height = ALIGN(height, 32);
133 
134 		/* Luma plane size. */
135 		sizeimage = bytesperline * height;
136 
137 		/* Chroma plane size. */
138 		sizeimage += bytesperline * ALIGN(height, 64) / 2;
139 
140 		break;
141 
142 	case V4L2_PIX_FMT_NV12:
143 		/* 16-aligned stride. */
144 		bytesperline = ALIGN(width, 16);
145 
146 		/* 16-aligned height. */
147 		height = ALIGN(height, 16);
148 
149 		/* Luma plane size. */
150 		sizeimage = bytesperline * height;
151 
152 		/* Chroma plane size. */
153 		sizeimage += bytesperline * height / 2;
154 
155 		break;
156 	}
157 
158 	pix_fmt->width = width;
159 	pix_fmt->height = height;
160 
161 	pix_fmt->bytesperline = bytesperline;
162 	pix_fmt->sizeimage = sizeimage;
163 }
164 
165 static int cedrus_querycap(struct file *file, void *priv,
166 			   struct v4l2_capability *cap)
167 {
168 	strscpy(cap->driver, CEDRUS_NAME, sizeof(cap->driver));
169 	strscpy(cap->card, CEDRUS_NAME, sizeof(cap->card));
170 	snprintf(cap->bus_info, sizeof(cap->bus_info),
171 		 "platform:%s", CEDRUS_NAME);
172 
173 	return 0;
174 }
175 
176 static int cedrus_enum_fmt(struct file *file, struct v4l2_fmtdesc *f,
177 			   u32 direction)
178 {
179 	struct cedrus_ctx *ctx = cedrus_file2ctx(file);
180 	unsigned int i, index;
181 
182 	/* Index among formats that match the requested direction. */
183 	index = 0;
184 
185 	for (i = 0; i < CEDRUS_FORMATS_COUNT; i++) {
186 		if (!cedrus_is_capable(ctx, cedrus_formats[i].capabilities))
187 			continue;
188 
189 		if (!(cedrus_formats[i].directions & direction))
190 			continue;
191 
192 		if (index == f->index)
193 			break;
194 
195 		index++;
196 	}
197 
198 	/* Matched format. */
199 	if (i < CEDRUS_FORMATS_COUNT) {
200 		f->pixelformat = cedrus_formats[i].pixelformat;
201 
202 		return 0;
203 	}
204 
205 	return -EINVAL;
206 }
207 
208 static int cedrus_enum_fmt_vid_cap(struct file *file, void *priv,
209 				   struct v4l2_fmtdesc *f)
210 {
211 	return cedrus_enum_fmt(file, f, CEDRUS_DECODE_DST);
212 }
213 
214 static int cedrus_enum_fmt_vid_out(struct file *file, void *priv,
215 				   struct v4l2_fmtdesc *f)
216 {
217 	return cedrus_enum_fmt(file, f, CEDRUS_DECODE_SRC);
218 }
219 
220 static int cedrus_g_fmt_vid_cap(struct file *file, void *priv,
221 				struct v4l2_format *f)
222 {
223 	struct cedrus_ctx *ctx = cedrus_file2ctx(file);
224 
225 	f->fmt.pix = ctx->dst_fmt;
226 	return 0;
227 }
228 
229 static int cedrus_g_fmt_vid_out(struct file *file, void *priv,
230 				struct v4l2_format *f)
231 {
232 	struct cedrus_ctx *ctx = cedrus_file2ctx(file);
233 
234 	f->fmt.pix = ctx->src_fmt;
235 	return 0;
236 }
237 
238 static int cedrus_try_fmt_vid_cap_p(struct cedrus_ctx *ctx,
239 				    struct v4l2_pix_format *pix_fmt)
240 {
241 	struct cedrus_format *fmt =
242 		cedrus_find_format(ctx, pix_fmt->pixelformat,
243 				   CEDRUS_DECODE_DST);
244 
245 	if (!fmt)
246 		return -EINVAL;
247 
248 	pix_fmt->pixelformat = fmt->pixelformat;
249 	pix_fmt->width = ctx->src_fmt.width;
250 	pix_fmt->height = ctx->src_fmt.height;
251 	cedrus_prepare_format(pix_fmt);
252 
253 	if (ctx->current_codec->extra_cap_size)
254 		pix_fmt->sizeimage +=
255 			ctx->current_codec->extra_cap_size(ctx, pix_fmt);
256 
257 	return 0;
258 }
259 
260 static int cedrus_try_fmt_vid_cap(struct file *file, void *priv,
261 				  struct v4l2_format *f)
262 {
263 	return cedrus_try_fmt_vid_cap_p(cedrus_file2ctx(file), &f->fmt.pix);
264 }
265 
266 static int cedrus_try_fmt_vid_out_p(struct cedrus_ctx *ctx,
267 				    struct v4l2_pix_format *pix_fmt)
268 {
269 	struct cedrus_format *fmt =
270 		cedrus_find_format(ctx, pix_fmt->pixelformat,
271 				   CEDRUS_DECODE_SRC);
272 
273 	if (!fmt)
274 		return -EINVAL;
275 
276 	pix_fmt->pixelformat = fmt->pixelformat;
277 	cedrus_prepare_format(pix_fmt);
278 
279 	return 0;
280 }
281 
282 static int cedrus_try_fmt_vid_out(struct file *file, void *priv,
283 				  struct v4l2_format *f)
284 {
285 	return cedrus_try_fmt_vid_out_p(cedrus_file2ctx(file), &f->fmt.pix);
286 }
287 
288 static int cedrus_s_fmt_vid_cap(struct file *file, void *priv,
289 				struct v4l2_format *f)
290 {
291 	struct cedrus_ctx *ctx = cedrus_file2ctx(file);
292 	struct vb2_queue *vq;
293 	int ret;
294 
295 	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
296 	if (vb2_is_busy(vq))
297 		return -EBUSY;
298 
299 	ret = cedrus_try_fmt_vid_cap(file, priv, f);
300 	if (ret)
301 		return ret;
302 
303 	ctx->dst_fmt = f->fmt.pix;
304 
305 	return 0;
306 }
307 
308 void cedrus_reset_cap_format(struct cedrus_ctx *ctx)
309 {
310 	ctx->dst_fmt.pixelformat = 0;
311 	cedrus_try_fmt_vid_cap_p(ctx, &ctx->dst_fmt);
312 }
313 
314 static int cedrus_s_fmt_vid_out_p(struct cedrus_ctx *ctx,
315 				  struct v4l2_pix_format *pix_fmt)
316 {
317 	struct vb2_queue *vq;
318 	int ret;
319 
320 	ret = cedrus_try_fmt_vid_out_p(ctx, pix_fmt);
321 	if (ret)
322 		return ret;
323 
324 	ctx->src_fmt = *pix_fmt;
325 
326 	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
327 
328 	switch (ctx->src_fmt.pixelformat) {
329 	case V4L2_PIX_FMT_H264_SLICE:
330 	case V4L2_PIX_FMT_HEVC_SLICE:
331 		vq->subsystem_flags |=
332 			VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF;
333 		break;
334 	default:
335 		vq->subsystem_flags &=
336 			~VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF;
337 		break;
338 	}
339 
340 	switch (ctx->src_fmt.pixelformat) {
341 	case V4L2_PIX_FMT_MPEG2_SLICE:
342 		ctx->current_codec = &cedrus_dec_ops_mpeg2;
343 		break;
344 	case V4L2_PIX_FMT_H264_SLICE:
345 		ctx->current_codec = &cedrus_dec_ops_h264;
346 		break;
347 	case V4L2_PIX_FMT_HEVC_SLICE:
348 		ctx->current_codec = &cedrus_dec_ops_h265;
349 		break;
350 	case V4L2_PIX_FMT_VP8_FRAME:
351 		ctx->current_codec = &cedrus_dec_ops_vp8;
352 		break;
353 	}
354 
355 	/* Propagate format information to capture. */
356 	ctx->dst_fmt.colorspace = pix_fmt->colorspace;
357 	ctx->dst_fmt.xfer_func = pix_fmt->xfer_func;
358 	ctx->dst_fmt.ycbcr_enc = pix_fmt->ycbcr_enc;
359 	ctx->dst_fmt.quantization = pix_fmt->quantization;
360 	cedrus_reset_cap_format(ctx);
361 
362 	return 0;
363 }
364 
365 void cedrus_reset_out_format(struct cedrus_ctx *ctx)
366 {
367 	ctx->src_fmt.pixelformat = 0;
368 	cedrus_s_fmt_vid_out_p(ctx, &ctx->src_fmt);
369 }
370 
371 static int cedrus_s_fmt_vid_out(struct file *file, void *priv,
372 				struct v4l2_format *f)
373 {
374 	struct cedrus_ctx *ctx = cedrus_file2ctx(file);
375 	struct vb2_queue *vq;
376 	struct vb2_queue *peer_vq;
377 
378 	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
379 	/*
380 	 * In order to support dynamic resolution change,
381 	 * the decoder admits a resolution change, as long
382 	 * as the pixelformat remains. Can't be done if streaming.
383 	 */
384 	if (vb2_is_streaming(vq) || (vb2_is_busy(vq) &&
385 	    f->fmt.pix.pixelformat != ctx->src_fmt.pixelformat))
386 		return -EBUSY;
387 	/*
388 	 * Since format change on the OUTPUT queue will reset
389 	 * the CAPTURE queue, we can't allow doing so
390 	 * when the CAPTURE queue has buffers allocated.
391 	 */
392 	peer_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
393 				  V4L2_BUF_TYPE_VIDEO_CAPTURE);
394 	if (vb2_is_busy(peer_vq))
395 		return -EBUSY;
396 
397 	return cedrus_s_fmt_vid_out_p(cedrus_file2ctx(file), &f->fmt.pix);
398 }
399 
400 const struct v4l2_ioctl_ops cedrus_ioctl_ops = {
401 	.vidioc_querycap		= cedrus_querycap,
402 
403 	.vidioc_enum_fmt_vid_cap	= cedrus_enum_fmt_vid_cap,
404 	.vidioc_g_fmt_vid_cap		= cedrus_g_fmt_vid_cap,
405 	.vidioc_try_fmt_vid_cap		= cedrus_try_fmt_vid_cap,
406 	.vidioc_s_fmt_vid_cap		= cedrus_s_fmt_vid_cap,
407 
408 	.vidioc_enum_fmt_vid_out	= cedrus_enum_fmt_vid_out,
409 	.vidioc_g_fmt_vid_out		= cedrus_g_fmt_vid_out,
410 	.vidioc_try_fmt_vid_out		= cedrus_try_fmt_vid_out,
411 	.vidioc_s_fmt_vid_out		= cedrus_s_fmt_vid_out,
412 
413 	.vidioc_reqbufs			= v4l2_m2m_ioctl_reqbufs,
414 	.vidioc_querybuf		= v4l2_m2m_ioctl_querybuf,
415 	.vidioc_qbuf			= v4l2_m2m_ioctl_qbuf,
416 	.vidioc_dqbuf			= v4l2_m2m_ioctl_dqbuf,
417 	.vidioc_prepare_buf		= v4l2_m2m_ioctl_prepare_buf,
418 	.vidioc_create_bufs		= v4l2_m2m_ioctl_create_bufs,
419 	.vidioc_expbuf			= v4l2_m2m_ioctl_expbuf,
420 
421 	.vidioc_streamon		= v4l2_m2m_ioctl_streamon,
422 	.vidioc_streamoff		= v4l2_m2m_ioctl_streamoff,
423 
424 	.vidioc_try_decoder_cmd		= v4l2_m2m_ioctl_stateless_try_decoder_cmd,
425 	.vidioc_decoder_cmd		= v4l2_m2m_ioctl_stateless_decoder_cmd,
426 
427 	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
428 	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
429 };
430 
431 static int cedrus_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
432 			      unsigned int *nplanes, unsigned int sizes[],
433 			      struct device *alloc_devs[])
434 {
435 	struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
436 	struct v4l2_pix_format *pix_fmt;
437 
438 	if (V4L2_TYPE_IS_OUTPUT(vq->type))
439 		pix_fmt = &ctx->src_fmt;
440 	else
441 		pix_fmt = &ctx->dst_fmt;
442 
443 	if (*nplanes) {
444 		if (sizes[0] < pix_fmt->sizeimage)
445 			return -EINVAL;
446 	} else {
447 		sizes[0] = pix_fmt->sizeimage;
448 		*nplanes = 1;
449 	}
450 
451 	return 0;
452 }
453 
454 static void cedrus_queue_cleanup(struct vb2_queue *vq, u32 state)
455 {
456 	struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
457 	struct vb2_v4l2_buffer *vbuf;
458 
459 	for (;;) {
460 		if (V4L2_TYPE_IS_OUTPUT(vq->type))
461 			vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
462 		else
463 			vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
464 
465 		if (!vbuf)
466 			return;
467 
468 		v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
469 					   &ctx->hdl);
470 		v4l2_m2m_buf_done(vbuf, state);
471 	}
472 }
473 
474 static int cedrus_buf_out_validate(struct vb2_buffer *vb)
475 {
476 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
477 
478 	vbuf->field = V4L2_FIELD_NONE;
479 	return 0;
480 }
481 
482 static int cedrus_buf_prepare(struct vb2_buffer *vb)
483 {
484 	struct vb2_queue *vq = vb->vb2_queue;
485 	struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
486 	struct v4l2_pix_format *pix_fmt;
487 
488 	if (V4L2_TYPE_IS_OUTPUT(vq->type))
489 		pix_fmt = &ctx->src_fmt;
490 	else
491 		pix_fmt = &ctx->dst_fmt;
492 
493 	if (vb2_plane_size(vb, 0) < pix_fmt->sizeimage)
494 		return -EINVAL;
495 
496 	/*
497 	 * Buffer's bytesused must be written by driver for CAPTURE buffers.
498 	 * (for OUTPUT buffers, if userspace passes 0 bytesused, v4l2-core sets
499 	 * it to buffer length).
500 	 */
501 	if (V4L2_TYPE_IS_CAPTURE(vq->type))
502 		vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage);
503 
504 	return 0;
505 }
506 
507 static int cedrus_start_streaming(struct vb2_queue *vq, unsigned int count)
508 {
509 	struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
510 	struct cedrus_dev *dev = ctx->dev;
511 	int ret = 0;
512 
513 	if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
514 		ret = pm_runtime_resume_and_get(dev->dev);
515 		if (ret < 0)
516 			goto err_cleanup;
517 
518 		if (ctx->current_codec->start) {
519 			ret = ctx->current_codec->start(ctx);
520 			if (ret)
521 				goto err_pm;
522 		}
523 	}
524 
525 	return 0;
526 
527 err_pm:
528 	pm_runtime_put(dev->dev);
529 err_cleanup:
530 	cedrus_queue_cleanup(vq, VB2_BUF_STATE_QUEUED);
531 
532 	return ret;
533 }
534 
535 static void cedrus_stop_streaming(struct vb2_queue *vq)
536 {
537 	struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
538 	struct cedrus_dev *dev = ctx->dev;
539 
540 	if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
541 		if (ctx->current_codec->stop)
542 			ctx->current_codec->stop(ctx);
543 
544 		pm_runtime_put(dev->dev);
545 	}
546 
547 	cedrus_queue_cleanup(vq, VB2_BUF_STATE_ERROR);
548 }
549 
550 static void cedrus_buf_queue(struct vb2_buffer *vb)
551 {
552 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
553 	struct cedrus_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
554 
555 	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
556 }
557 
558 static void cedrus_buf_request_complete(struct vb2_buffer *vb)
559 {
560 	struct cedrus_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
561 
562 	v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl);
563 }
564 
565 static const struct vb2_ops cedrus_qops = {
566 	.queue_setup		= cedrus_queue_setup,
567 	.buf_prepare		= cedrus_buf_prepare,
568 	.buf_queue		= cedrus_buf_queue,
569 	.buf_out_validate	= cedrus_buf_out_validate,
570 	.buf_request_complete	= cedrus_buf_request_complete,
571 	.start_streaming	= cedrus_start_streaming,
572 	.stop_streaming		= cedrus_stop_streaming,
573 	.wait_prepare		= vb2_ops_wait_prepare,
574 	.wait_finish		= vb2_ops_wait_finish,
575 };
576 
577 int cedrus_queue_init(void *priv, struct vb2_queue *src_vq,
578 		      struct vb2_queue *dst_vq)
579 {
580 	struct cedrus_ctx *ctx = priv;
581 	int ret;
582 
583 	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
584 	src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
585 	src_vq->drv_priv = ctx;
586 	src_vq->buf_struct_size = sizeof(struct cedrus_buffer);
587 	src_vq->ops = &cedrus_qops;
588 	src_vq->mem_ops = &vb2_dma_contig_memops;
589 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
590 	src_vq->lock = &ctx->dev->dev_mutex;
591 	src_vq->dev = ctx->dev->dev;
592 	src_vq->supports_requests = true;
593 	src_vq->requires_requests = true;
594 
595 	ret = vb2_queue_init(src_vq);
596 	if (ret)
597 		return ret;
598 
599 	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
600 	dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
601 	dst_vq->drv_priv = ctx;
602 	dst_vq->buf_struct_size = sizeof(struct cedrus_buffer);
603 	dst_vq->ops = &cedrus_qops;
604 	dst_vq->mem_ops = &vb2_dma_contig_memops;
605 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
606 	dst_vq->lock = &ctx->dev->dev_mutex;
607 	dst_vq->dev = ctx->dev->dev;
608 
609 	return vb2_queue_init(dst_vq);
610 }
611