1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Hantro VPU codec driver
4 *
5 * Copyright (C) 2018 Collabora, Ltd.
6 * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
7 * Alpha Lin <Alpha.Lin@rock-chips.com>
8 * Jeffy Chen <jeffy.chen@rock-chips.com>
9 *
10 * Copyright 2018 Google LLC.
11 * Tomasz Figa <tfiga@chromium.org>
12 *
13 * Based on s5p-mfc driver by Samsung Electronics Co., Ltd.
14 * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
15 */
16
17 #include <linux/interrupt.h>
18 #include <linux/io.h>
19 #include <linux/module.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/videodev2.h>
22 #include <linux/workqueue.h>
23 #include <media/v4l2-ctrls.h>
24 #include <media/v4l2-event.h>
25 #include <media/v4l2-mem2mem.h>
26 #include <media/videobuf2-core.h>
27 #include <media/videobuf2-dma-sg.h>
28
29 #include "hantro.h"
30 #include "hantro_hw.h"
31 #include "hantro_v4l2.h"
32
33 static const struct hantro_fmt *
hantro_get_formats(const struct hantro_ctx * ctx,unsigned int * num_fmts)34 hantro_get_formats(const struct hantro_ctx *ctx, unsigned int *num_fmts)
35 {
36 const struct hantro_fmt *formats;
37
38 if (hantro_is_encoder_ctx(ctx)) {
39 formats = ctx->dev->variant->enc_fmts;
40 *num_fmts = ctx->dev->variant->num_enc_fmts;
41 } else {
42 formats = ctx->dev->variant->dec_fmts;
43 *num_fmts = ctx->dev->variant->num_dec_fmts;
44 }
45
46 return formats;
47 }
48
49 static const struct hantro_fmt *
hantro_find_format(const struct hantro_fmt * formats,unsigned int num_fmts,u32 fourcc)50 hantro_find_format(const struct hantro_fmt *formats, unsigned int num_fmts,
51 u32 fourcc)
52 {
53 unsigned int i;
54
55 for (i = 0; i < num_fmts; i++)
56 if (formats[i].fourcc == fourcc)
57 return &formats[i];
58 return NULL;
59 }
60
61 static const struct hantro_fmt *
hantro_get_default_fmt(const struct hantro_fmt * formats,unsigned int num_fmts,bool bitstream)62 hantro_get_default_fmt(const struct hantro_fmt *formats, unsigned int num_fmts,
63 bool bitstream)
64 {
65 unsigned int i;
66
67 for (i = 0; i < num_fmts; i++) {
68 if (bitstream == (formats[i].codec_mode !=
69 HANTRO_MODE_NONE))
70 return &formats[i];
71 }
72 return NULL;
73 }
74
vidioc_querycap(struct file * file,void * priv,struct v4l2_capability * cap)75 static int vidioc_querycap(struct file *file, void *priv,
76 struct v4l2_capability *cap)
77 {
78 struct hantro_dev *vpu = video_drvdata(file);
79 struct video_device *vdev = video_devdata(file);
80
81 strscpy(cap->driver, vpu->dev->driver->name, sizeof(cap->driver));
82 strscpy(cap->card, vdev->name, sizeof(cap->card));
83 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform: %s",
84 vpu->dev->driver->name);
85 return 0;
86 }
87
vidioc_enum_framesizes(struct file * file,void * priv,struct v4l2_frmsizeenum * fsize)88 static int vidioc_enum_framesizes(struct file *file, void *priv,
89 struct v4l2_frmsizeenum *fsize)
90 {
91 struct hantro_ctx *ctx = fh_to_ctx(priv);
92 const struct hantro_fmt *formats, *fmt;
93 unsigned int num_fmts;
94
95 if (fsize->index != 0) {
96 vpu_debug(0, "invalid frame size index (expected 0, got %d)\n",
97 fsize->index);
98 return -EINVAL;
99 }
100
101 formats = hantro_get_formats(ctx, &num_fmts);
102 fmt = hantro_find_format(formats, num_fmts, fsize->pixel_format);
103 if (!fmt) {
104 vpu_debug(0, "unsupported bitstream format (%08x)\n",
105 fsize->pixel_format);
106 return -EINVAL;
107 }
108
109 /* This only makes sense for coded formats */
110 if (fmt->codec_mode == HANTRO_MODE_NONE)
111 return -EINVAL;
112
113 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
114 fsize->stepwise = fmt->frmsize;
115
116 return 0;
117 }
118
vidioc_enum_fmt(struct file * file,void * priv,struct v4l2_fmtdesc * f,bool capture)119 static int vidioc_enum_fmt(struct file *file, void *priv,
120 struct v4l2_fmtdesc *f, bool capture)
121
122 {
123 struct hantro_ctx *ctx = fh_to_ctx(priv);
124 const struct hantro_fmt *fmt, *formats;
125 unsigned int num_fmts, i, j = 0;
126 bool skip_mode_none;
127
128 /*
129 * When dealing with an encoder:
130 * - on the capture side we want to filter out all MODE_NONE formats.
131 * - on the output side we want to filter out all formats that are
132 * not MODE_NONE.
133 * When dealing with a decoder:
134 * - on the capture side we want to filter out all formats that are
135 * not MODE_NONE.
136 * - on the output side we want to filter out all MODE_NONE formats.
137 */
138 skip_mode_none = capture == hantro_is_encoder_ctx(ctx);
139
140 formats = hantro_get_formats(ctx, &num_fmts);
141 for (i = 0; i < num_fmts; i++) {
142 bool mode_none = formats[i].codec_mode == HANTRO_MODE_NONE;
143
144 if (skip_mode_none == mode_none)
145 continue;
146 if (j == f->index) {
147 fmt = &formats[i];
148 f->pixelformat = fmt->fourcc;
149 return 0;
150 }
151 ++j;
152 }
153 return -EINVAL;
154 }
155
vidioc_enum_fmt_vid_cap(struct file * file,void * priv,struct v4l2_fmtdesc * f)156 static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
157 struct v4l2_fmtdesc *f)
158 {
159 return vidioc_enum_fmt(file, priv, f, true);
160 }
161
vidioc_enum_fmt_vid_out(struct file * file,void * priv,struct v4l2_fmtdesc * f)162 static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
163 struct v4l2_fmtdesc *f)
164 {
165 return vidioc_enum_fmt(file, priv, f, false);
166 }
167
vidioc_g_fmt_out_mplane(struct file * file,void * priv,struct v4l2_format * f)168 static int vidioc_g_fmt_out_mplane(struct file *file, void *priv,
169 struct v4l2_format *f)
170 {
171 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
172 struct hantro_ctx *ctx = fh_to_ctx(priv);
173
174 vpu_debug(4, "f->type = %d\n", f->type);
175
176 *pix_mp = ctx->src_fmt;
177
178 return 0;
179 }
180
vidioc_g_fmt_cap_mplane(struct file * file,void * priv,struct v4l2_format * f)181 static int vidioc_g_fmt_cap_mplane(struct file *file, void *priv,
182 struct v4l2_format *f)
183 {
184 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
185 struct hantro_ctx *ctx = fh_to_ctx(priv);
186
187 vpu_debug(4, "f->type = %d\n", f->type);
188
189 *pix_mp = ctx->dst_fmt;
190
191 return 0;
192 }
193
vidioc_try_fmt(struct file * file,void * priv,struct v4l2_format * f,bool capture)194 static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f,
195 bool capture)
196 {
197 struct hantro_ctx *ctx = fh_to_ctx(priv);
198 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
199 const struct hantro_fmt *formats, *fmt, *vpu_fmt;
200 unsigned int num_fmts;
201 bool coded;
202
203 coded = capture == hantro_is_encoder_ctx(ctx);
204
205 vpu_debug(4, "trying format %c%c%c%c\n",
206 (pix_mp->pixelformat & 0x7f),
207 (pix_mp->pixelformat >> 8) & 0x7f,
208 (pix_mp->pixelformat >> 16) & 0x7f,
209 (pix_mp->pixelformat >> 24) & 0x7f);
210
211 formats = hantro_get_formats(ctx, &num_fmts);
212 fmt = hantro_find_format(formats, num_fmts, pix_mp->pixelformat);
213 if (!fmt) {
214 fmt = hantro_get_default_fmt(formats, num_fmts, coded);
215 f->fmt.pix_mp.pixelformat = fmt->fourcc;
216 }
217
218 if (coded) {
219 pix_mp->num_planes = 1;
220 vpu_fmt = fmt;
221 } else if (hantro_is_encoder_ctx(ctx)) {
222 vpu_fmt = ctx->vpu_dst_fmt;
223 } else {
224 vpu_fmt = ctx->vpu_src_fmt;
225 /*
226 * Width/height on the CAPTURE end of a decoder are ignored and
227 * replaced by the OUTPUT ones.
228 */
229 pix_mp->width = ctx->src_fmt.width;
230 pix_mp->height = ctx->src_fmt.height;
231 }
232
233 pix_mp->field = V4L2_FIELD_NONE;
234
235 v4l2_apply_frmsize_constraints(&pix_mp->width, &pix_mp->height,
236 &vpu_fmt->frmsize);
237
238 if (!coded) {
239 /* Fill remaining fields */
240 v4l2_fill_pixfmt_mp(pix_mp, fmt->fourcc, pix_mp->width,
241 pix_mp->height);
242 /*
243 * The H264 decoder needs extra space on the output buffers
244 * to store motion vectors. This is needed for reference
245 * frames.
246 */
247 if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE)
248 pix_mp->plane_fmt[0].sizeimage +=
249 128 * DIV_ROUND_UP(pix_mp->width, 16) *
250 DIV_ROUND_UP(pix_mp->height, 16);
251 } else if (!pix_mp->plane_fmt[0].sizeimage) {
252 /*
253 * For coded formats the application can specify
254 * sizeimage. If the application passes a zero sizeimage,
255 * let's default to the maximum frame size.
256 */
257 pix_mp->plane_fmt[0].sizeimage = fmt->header_size +
258 pix_mp->width * pix_mp->height * fmt->max_depth;
259 }
260
261 return 0;
262 }
263
vidioc_try_fmt_cap_mplane(struct file * file,void * priv,struct v4l2_format * f)264 static int vidioc_try_fmt_cap_mplane(struct file *file, void *priv,
265 struct v4l2_format *f)
266 {
267 return vidioc_try_fmt(file, priv, f, true);
268 }
269
vidioc_try_fmt_out_mplane(struct file * file,void * priv,struct v4l2_format * f)270 static int vidioc_try_fmt_out_mplane(struct file *file, void *priv,
271 struct v4l2_format *f)
272 {
273 return vidioc_try_fmt(file, priv, f, false);
274 }
275
276 static void
hantro_reset_fmt(struct v4l2_pix_format_mplane * fmt,const struct hantro_fmt * vpu_fmt)277 hantro_reset_fmt(struct v4l2_pix_format_mplane *fmt,
278 const struct hantro_fmt *vpu_fmt)
279 {
280 memset(fmt, 0, sizeof(*fmt));
281
282 fmt->pixelformat = vpu_fmt->fourcc;
283 fmt->field = V4L2_FIELD_NONE;
284 fmt->colorspace = V4L2_COLORSPACE_JPEG,
285 fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
286 fmt->quantization = V4L2_QUANTIZATION_DEFAULT;
287 fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT;
288 }
289
290 static void
hantro_reset_encoded_fmt(struct hantro_ctx * ctx)291 hantro_reset_encoded_fmt(struct hantro_ctx *ctx)
292 {
293 const struct hantro_fmt *vpu_fmt, *formats;
294 struct v4l2_pix_format_mplane *fmt;
295 unsigned int num_fmts;
296
297 formats = hantro_get_formats(ctx, &num_fmts);
298 vpu_fmt = hantro_get_default_fmt(formats, num_fmts, true);
299
300 if (hantro_is_encoder_ctx(ctx)) {
301 ctx->vpu_dst_fmt = vpu_fmt;
302 fmt = &ctx->dst_fmt;
303 } else {
304 ctx->vpu_src_fmt = vpu_fmt;
305 fmt = &ctx->src_fmt;
306 }
307
308 hantro_reset_fmt(fmt, vpu_fmt);
309 fmt->num_planes = 1;
310 fmt->width = vpu_fmt->frmsize.min_width;
311 fmt->height = vpu_fmt->frmsize.min_height;
312 fmt->plane_fmt[0].sizeimage = vpu_fmt->header_size +
313 fmt->width * fmt->height * vpu_fmt->max_depth;
314 }
315
316 static void
hantro_reset_raw_fmt(struct hantro_ctx * ctx)317 hantro_reset_raw_fmt(struct hantro_ctx *ctx)
318 {
319 const struct hantro_fmt *raw_vpu_fmt, *formats;
320 struct v4l2_pix_format_mplane *raw_fmt, *encoded_fmt;
321 unsigned int num_fmts;
322
323 formats = hantro_get_formats(ctx, &num_fmts);
324 raw_vpu_fmt = hantro_get_default_fmt(formats, num_fmts, false);
325
326 if (hantro_is_encoder_ctx(ctx)) {
327 ctx->vpu_src_fmt = raw_vpu_fmt;
328 raw_fmt = &ctx->src_fmt;
329 encoded_fmt = &ctx->dst_fmt;
330 } else {
331 ctx->vpu_dst_fmt = raw_vpu_fmt;
332 raw_fmt = &ctx->dst_fmt;
333 encoded_fmt = &ctx->src_fmt;
334 }
335
336 hantro_reset_fmt(raw_fmt, raw_vpu_fmt);
337 v4l2_fill_pixfmt_mp(raw_fmt, raw_vpu_fmt->fourcc,
338 encoded_fmt->width,
339 encoded_fmt->height);
340 }
341
hantro_reset_fmts(struct hantro_ctx * ctx)342 void hantro_reset_fmts(struct hantro_ctx *ctx)
343 {
344 hantro_reset_encoded_fmt(ctx);
345 hantro_reset_raw_fmt(ctx);
346 }
347
348 static void
hantro_update_requires_request(struct hantro_ctx * ctx,u32 fourcc)349 hantro_update_requires_request(struct hantro_ctx *ctx, u32 fourcc)
350 {
351 switch (fourcc) {
352 case V4L2_PIX_FMT_JPEG:
353 ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = false;
354 break;
355 case V4L2_PIX_FMT_MPEG2_SLICE:
356 case V4L2_PIX_FMT_VP8_FRAME:
357 case V4L2_PIX_FMT_H264_SLICE:
358 ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = true;
359 break;
360 default:
361 break;
362 }
363 }
364
365 static int
vidioc_s_fmt_out_mplane(struct file * file,void * priv,struct v4l2_format * f)366 vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f)
367 {
368 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
369 struct hantro_ctx *ctx = fh_to_ctx(priv);
370 const struct hantro_fmt *formats;
371 unsigned int num_fmts;
372 struct vb2_queue *vq;
373 int ret;
374
375 /* Change not allowed if queue is busy. */
376 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
377 if (vb2_is_busy(vq))
378 return -EBUSY;
379
380 if (!hantro_is_encoder_ctx(ctx)) {
381 struct vb2_queue *peer_vq;
382
383 /*
384 * Since format change on the OUTPUT queue will reset
385 * the CAPTURE queue, we can't allow doing so
386 * when the CAPTURE queue has buffers allocated.
387 */
388 peer_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
389 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
390 if (vb2_is_busy(peer_vq))
391 return -EBUSY;
392 }
393
394 ret = vidioc_try_fmt_out_mplane(file, priv, f);
395 if (ret)
396 return ret;
397
398 formats = hantro_get_formats(ctx, &num_fmts);
399 ctx->vpu_src_fmt = hantro_find_format(formats, num_fmts,
400 pix_mp->pixelformat);
401 ctx->src_fmt = *pix_mp;
402
403 /*
404 * Current raw format might have become invalid with newly
405 * selected codec, so reset it to default just to be safe and
406 * keep internal driver state sane. User is mandated to set
407 * the raw format again after we return, so we don't need
408 * anything smarter.
409 * Note that hantro_reset_raw_fmt() also propagates size
410 * changes to the raw format.
411 */
412 if (!hantro_is_encoder_ctx(ctx))
413 hantro_reset_raw_fmt(ctx);
414
415 /* Colorimetry information are always propagated. */
416 ctx->dst_fmt.colorspace = pix_mp->colorspace;
417 ctx->dst_fmt.ycbcr_enc = pix_mp->ycbcr_enc;
418 ctx->dst_fmt.xfer_func = pix_mp->xfer_func;
419 ctx->dst_fmt.quantization = pix_mp->quantization;
420
421 hantro_update_requires_request(ctx, pix_mp->pixelformat);
422
423 vpu_debug(0, "OUTPUT codec mode: %d\n", ctx->vpu_src_fmt->codec_mode);
424 vpu_debug(0, "fmt - w: %d, h: %d\n",
425 pix_mp->width, pix_mp->height);
426 return 0;
427 }
428
vidioc_s_fmt_cap_mplane(struct file * file,void * priv,struct v4l2_format * f)429 static int vidioc_s_fmt_cap_mplane(struct file *file, void *priv,
430 struct v4l2_format *f)
431 {
432 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
433 struct hantro_ctx *ctx = fh_to_ctx(priv);
434 const struct hantro_fmt *formats;
435 struct vb2_queue *vq;
436 unsigned int num_fmts;
437 int ret;
438
439 /* Change not allowed if queue is busy. */
440 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
441 if (vb2_is_busy(vq))
442 return -EBUSY;
443
444 if (hantro_is_encoder_ctx(ctx)) {
445 struct vb2_queue *peer_vq;
446
447 /*
448 * Since format change on the CAPTURE queue will reset
449 * the OUTPUT queue, we can't allow doing so
450 * when the OUTPUT queue has buffers allocated.
451 */
452 peer_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
453 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
454 if (vb2_is_busy(peer_vq) &&
455 (pix_mp->pixelformat != ctx->dst_fmt.pixelformat ||
456 pix_mp->height != ctx->dst_fmt.height ||
457 pix_mp->width != ctx->dst_fmt.width))
458 return -EBUSY;
459 }
460
461 ret = vidioc_try_fmt_cap_mplane(file, priv, f);
462 if (ret)
463 return ret;
464
465 formats = hantro_get_formats(ctx, &num_fmts);
466 ctx->vpu_dst_fmt = hantro_find_format(formats, num_fmts,
467 pix_mp->pixelformat);
468 ctx->dst_fmt = *pix_mp;
469
470 /*
471 * Current raw format might have become invalid with newly
472 * selected codec, so reset it to default just to be safe and
473 * keep internal driver state sane. User is mandated to set
474 * the raw format again after we return, so we don't need
475 * anything smarter.
476 * Note that hantro_reset_raw_fmt() also propagates size
477 * changes to the raw format.
478 */
479 if (hantro_is_encoder_ctx(ctx))
480 hantro_reset_raw_fmt(ctx);
481
482 /* Colorimetry information are always propagated. */
483 ctx->src_fmt.colorspace = pix_mp->colorspace;
484 ctx->src_fmt.ycbcr_enc = pix_mp->ycbcr_enc;
485 ctx->src_fmt.xfer_func = pix_mp->xfer_func;
486 ctx->src_fmt.quantization = pix_mp->quantization;
487
488 vpu_debug(0, "CAPTURE codec mode: %d\n", ctx->vpu_dst_fmt->codec_mode);
489 vpu_debug(0, "fmt - w: %d, h: %d\n",
490 pix_mp->width, pix_mp->height);
491
492 hantro_update_requires_request(ctx, pix_mp->pixelformat);
493
494 return 0;
495 }
496
497 const struct v4l2_ioctl_ops hantro_ioctl_ops = {
498 .vidioc_querycap = vidioc_querycap,
499 .vidioc_enum_framesizes = vidioc_enum_framesizes,
500
501 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_cap_mplane,
502 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_out_mplane,
503 .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt_out_mplane,
504 .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt_cap_mplane,
505 .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt_out_mplane,
506 .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt_cap_mplane,
507 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
508 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
509
510 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
511 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
512 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
513 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
514 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
515 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
516 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
517
518 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
519 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
520
521 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
522 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
523 };
524
525 static int
hantro_queue_setup(struct vb2_queue * vq,unsigned int * num_buffers,unsigned int * num_planes,unsigned int sizes[],struct device * alloc_devs[])526 hantro_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
527 unsigned int *num_planes, unsigned int sizes[],
528 struct device *alloc_devs[])
529 {
530 struct hantro_ctx *ctx = vb2_get_drv_priv(vq);
531 struct v4l2_pix_format_mplane *pixfmt;
532 int i;
533
534 switch (vq->type) {
535 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
536 pixfmt = &ctx->dst_fmt;
537 break;
538 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
539 pixfmt = &ctx->src_fmt;
540 break;
541 default:
542 vpu_err("invalid queue type: %d\n", vq->type);
543 return -EINVAL;
544 }
545
546 if (*num_planes) {
547 if (*num_planes != pixfmt->num_planes)
548 return -EINVAL;
549 for (i = 0; i < pixfmt->num_planes; ++i)
550 if (sizes[i] < pixfmt->plane_fmt[i].sizeimage)
551 return -EINVAL;
552 return 0;
553 }
554
555 *num_planes = pixfmt->num_planes;
556 for (i = 0; i < pixfmt->num_planes; ++i)
557 sizes[i] = pixfmt->plane_fmt[i].sizeimage;
558 return 0;
559 }
560
561 static int
hantro_buf_plane_check(struct vb2_buffer * vb,const struct hantro_fmt * vpu_fmt,struct v4l2_pix_format_mplane * pixfmt)562 hantro_buf_plane_check(struct vb2_buffer *vb, const struct hantro_fmt *vpu_fmt,
563 struct v4l2_pix_format_mplane *pixfmt)
564 {
565 unsigned int sz;
566 int i;
567
568 for (i = 0; i < pixfmt->num_planes; ++i) {
569 sz = pixfmt->plane_fmt[i].sizeimage;
570 vpu_debug(4, "plane %d size: %ld, sizeimage: %u\n",
571 i, vb2_plane_size(vb, i), sz);
572 if (vb2_plane_size(vb, i) < sz) {
573 vpu_err("plane %d is too small for output\n", i);
574 return -EINVAL;
575 }
576 }
577 return 0;
578 }
579
hantro_buf_prepare(struct vb2_buffer * vb)580 static int hantro_buf_prepare(struct vb2_buffer *vb)
581 {
582 struct vb2_queue *vq = vb->vb2_queue;
583 struct hantro_ctx *ctx = vb2_get_drv_priv(vq);
584
585 if (V4L2_TYPE_IS_OUTPUT(vq->type))
586 return hantro_buf_plane_check(vb, ctx->vpu_src_fmt,
587 &ctx->src_fmt);
588
589 return hantro_buf_plane_check(vb, ctx->vpu_dst_fmt, &ctx->dst_fmt);
590 }
591
hantro_buf_queue(struct vb2_buffer * vb)592 static void hantro_buf_queue(struct vb2_buffer *vb)
593 {
594 struct hantro_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
595 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
596
597 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
598 }
599
hantro_vq_is_coded(struct vb2_queue * q)600 static bool hantro_vq_is_coded(struct vb2_queue *q)
601 {
602 struct hantro_ctx *ctx = vb2_get_drv_priv(q);
603
604 return hantro_is_encoder_ctx(ctx) != V4L2_TYPE_IS_OUTPUT(q->type);
605 }
606
hantro_start_streaming(struct vb2_queue * q,unsigned int count)607 static int hantro_start_streaming(struct vb2_queue *q, unsigned int count)
608 {
609 struct hantro_ctx *ctx = vb2_get_drv_priv(q);
610 int ret = 0;
611
612 if (V4L2_TYPE_IS_OUTPUT(q->type))
613 ctx->sequence_out = 0;
614 else
615 ctx->sequence_cap = 0;
616
617 if (hantro_vq_is_coded(q)) {
618 enum hantro_codec_mode codec_mode;
619
620 if (V4L2_TYPE_IS_OUTPUT(q->type))
621 codec_mode = ctx->vpu_src_fmt->codec_mode;
622 else
623 codec_mode = ctx->vpu_dst_fmt->codec_mode;
624
625 vpu_debug(4, "Codec mode = %d\n", codec_mode);
626 ctx->codec_ops = &ctx->dev->variant->codec_ops[codec_mode];
627 if (ctx->codec_ops->init)
628 ret = ctx->codec_ops->init(ctx);
629 }
630
631 return ret;
632 }
633
634 static void
hantro_return_bufs(struct vb2_queue * q,struct vb2_v4l2_buffer * (* buf_remove)(struct v4l2_m2m_ctx *))635 hantro_return_bufs(struct vb2_queue *q,
636 struct vb2_v4l2_buffer *(*buf_remove)(struct v4l2_m2m_ctx *))
637 {
638 struct hantro_ctx *ctx = vb2_get_drv_priv(q);
639
640 for (;;) {
641 struct vb2_v4l2_buffer *vbuf;
642
643 vbuf = buf_remove(ctx->fh.m2m_ctx);
644 if (!vbuf)
645 break;
646 v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
647 &ctx->ctrl_handler);
648 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
649 }
650 }
651
hantro_stop_streaming(struct vb2_queue * q)652 static void hantro_stop_streaming(struct vb2_queue *q)
653 {
654 struct hantro_ctx *ctx = vb2_get_drv_priv(q);
655
656 if (hantro_vq_is_coded(q)) {
657 if (ctx->codec_ops && ctx->codec_ops->exit)
658 ctx->codec_ops->exit(ctx);
659 }
660
661 /*
662 * The mem2mem framework calls v4l2_m2m_cancel_job before
663 * .stop_streaming, so there isn't any job running and
664 * it is safe to return all the buffers.
665 */
666 if (V4L2_TYPE_IS_OUTPUT(q->type))
667 hantro_return_bufs(q, v4l2_m2m_src_buf_remove);
668 else
669 hantro_return_bufs(q, v4l2_m2m_dst_buf_remove);
670 }
671
hantro_buf_request_complete(struct vb2_buffer * vb)672 static void hantro_buf_request_complete(struct vb2_buffer *vb)
673 {
674 struct hantro_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
675
676 v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->ctrl_handler);
677 }
678
hantro_buf_out_validate(struct vb2_buffer * vb)679 static int hantro_buf_out_validate(struct vb2_buffer *vb)
680 {
681 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
682
683 vbuf->field = V4L2_FIELD_NONE;
684 return 0;
685 }
686
687 const struct vb2_ops hantro_queue_ops = {
688 .queue_setup = hantro_queue_setup,
689 .buf_prepare = hantro_buf_prepare,
690 .buf_queue = hantro_buf_queue,
691 .buf_out_validate = hantro_buf_out_validate,
692 .buf_request_complete = hantro_buf_request_complete,
693 .start_streaming = hantro_start_streaming,
694 .stop_streaming = hantro_stop_streaming,
695 .wait_prepare = vb2_ops_wait_prepare,
696 .wait_finish = vb2_ops_wait_finish,
697 };
698