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