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 | |
27 | #include "hantro.h" |
28 | #include "hantro_hw.h" |
29 | #include "hantro_v4l2.h" |
30 | |
31 | #define HANTRO_DEFAULT_BIT_DEPTH 8 |
32 | |
33 | static int hantro_set_fmt_out(struct hantro_ctx *ctx, |
34 | struct v4l2_pix_format_mplane *pix_mp, |
35 | bool need_postproc); |
36 | static int hantro_set_fmt_cap(struct hantro_ctx *ctx, |
37 | struct v4l2_pix_format_mplane *pix_mp); |
38 | |
39 | static const struct hantro_fmt * |
40 | hantro_get_formats(const struct hantro_ctx *ctx, unsigned int *num_fmts, bool need_postproc) |
41 | { |
42 | const struct hantro_fmt *formats; |
43 | |
44 | if (need_postproc) { |
45 | *num_fmts = 0; |
46 | return NULL; |
47 | } |
48 | |
49 | if (ctx->is_encoder) { |
50 | formats = ctx->dev->variant->enc_fmts; |
51 | *num_fmts = ctx->dev->variant->num_enc_fmts; |
52 | } else { |
53 | formats = ctx->dev->variant->dec_fmts; |
54 | *num_fmts = ctx->dev->variant->num_dec_fmts; |
55 | } |
56 | |
57 | return formats; |
58 | } |
59 | |
60 | static const struct hantro_fmt * |
61 | hantro_get_postproc_formats(const struct hantro_ctx *ctx, |
62 | unsigned int *num_fmts) |
63 | { |
64 | struct hantro_dev *vpu = ctx->dev; |
65 | |
66 | if (ctx->is_encoder || !vpu->variant->postproc_fmts) { |
67 | *num_fmts = 0; |
68 | return NULL; |
69 | } |
70 | |
71 | *num_fmts = ctx->dev->variant->num_postproc_fmts; |
72 | return ctx->dev->variant->postproc_fmts; |
73 | } |
74 | |
75 | int hantro_get_format_depth(u32 fourcc) |
76 | { |
77 | switch (fourcc) { |
78 | case V4L2_PIX_FMT_P010: |
79 | case V4L2_PIX_FMT_P010_4L4: |
80 | case V4L2_PIX_FMT_NV15_4L4: |
81 | return 10; |
82 | default: |
83 | return 8; |
84 | } |
85 | } |
86 | |
87 | static bool |
88 | hantro_check_depth_match(const struct hantro_fmt *fmt, int bit_depth) |
89 | { |
90 | int fmt_depth; |
91 | |
92 | if (!fmt->match_depth && !fmt->postprocessed) |
93 | return true; |
94 | |
95 | /* 0 means default depth, which is 8 */ |
96 | if (!bit_depth) |
97 | bit_depth = HANTRO_DEFAULT_BIT_DEPTH; |
98 | |
99 | fmt_depth = hantro_get_format_depth(fourcc: fmt->fourcc); |
100 | |
101 | /* |
102 | * Allow only downconversion for postproc formats for now. |
103 | * It may be possible to relax that on some HW. |
104 | */ |
105 | if (!fmt->match_depth) |
106 | return fmt_depth <= bit_depth; |
107 | |
108 | return fmt_depth == bit_depth; |
109 | } |
110 | |
111 | static const struct hantro_fmt * |
112 | hantro_find_format(const struct hantro_ctx *ctx, u32 fourcc) |
113 | { |
114 | const struct hantro_fmt *formats; |
115 | unsigned int i, num_fmts; |
116 | |
117 | formats = hantro_get_formats(ctx, num_fmts: &num_fmts, HANTRO_AUTO_POSTPROC); |
118 | for (i = 0; i < num_fmts; i++) |
119 | if (formats[i].fourcc == fourcc) |
120 | return &formats[i]; |
121 | |
122 | formats = hantro_get_postproc_formats(ctx, num_fmts: &num_fmts); |
123 | for (i = 0; i < num_fmts; i++) |
124 | if (formats[i].fourcc == fourcc) |
125 | return &formats[i]; |
126 | return NULL; |
127 | } |
128 | |
129 | const struct hantro_fmt * |
130 | hantro_get_default_fmt(const struct hantro_ctx *ctx, bool bitstream, |
131 | int bit_depth, bool need_postproc) |
132 | { |
133 | const struct hantro_fmt *formats; |
134 | unsigned int i, num_fmts; |
135 | |
136 | formats = hantro_get_formats(ctx, num_fmts: &num_fmts, need_postproc); |
137 | for (i = 0; i < num_fmts; i++) { |
138 | if (bitstream == (formats[i].codec_mode != |
139 | HANTRO_MODE_NONE) && |
140 | hantro_check_depth_match(fmt: &formats[i], bit_depth)) |
141 | return &formats[i]; |
142 | } |
143 | |
144 | formats = hantro_get_postproc_formats(ctx, num_fmts: &num_fmts); |
145 | for (i = 0; i < num_fmts; i++) { |
146 | if (bitstream == (formats[i].codec_mode != |
147 | HANTRO_MODE_NONE) && |
148 | hantro_check_depth_match(fmt: &formats[i], bit_depth)) |
149 | return &formats[i]; |
150 | } |
151 | |
152 | return NULL; |
153 | } |
154 | |
155 | static int vidioc_querycap(struct file *file, void *priv, |
156 | struct v4l2_capability *cap) |
157 | { |
158 | struct hantro_dev *vpu = video_drvdata(file); |
159 | struct video_device *vdev = video_devdata(file); |
160 | |
161 | strscpy(cap->driver, vpu->dev->driver->name, sizeof(cap->driver)); |
162 | strscpy(cap->card, vdev->name, sizeof(cap->card)); |
163 | return 0; |
164 | } |
165 | |
166 | static int vidioc_enum_framesizes(struct file *file, void *priv, |
167 | struct v4l2_frmsizeenum *fsize) |
168 | { |
169 | struct hantro_ctx *ctx = fh_to_ctx(fh: priv); |
170 | const struct hantro_fmt *fmt; |
171 | |
172 | fmt = hantro_find_format(ctx, fourcc: fsize->pixel_format); |
173 | if (!fmt) { |
174 | vpu_debug(0, "unsupported bitstream format (%08x)\n" , |
175 | fsize->pixel_format); |
176 | return -EINVAL; |
177 | } |
178 | |
179 | /* For non-coded formats check if postprocessing scaling is possible */ |
180 | if (fmt->codec_mode == HANTRO_MODE_NONE) { |
181 | if (hantro_needs_postproc(ctx, fmt)) |
182 | return hanto_postproc_enum_framesizes(ctx, fsize); |
183 | else |
184 | return -ENOTTY; |
185 | } else if (fsize->index != 0) { |
186 | vpu_debug(0, "invalid frame size index (expected 0, got %d)\n" , |
187 | fsize->index); |
188 | return -EINVAL; |
189 | } |
190 | |
191 | fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; |
192 | fsize->stepwise = fmt->frmsize; |
193 | |
194 | return 0; |
195 | } |
196 | |
197 | static int vidioc_enum_fmt(struct file *file, void *priv, |
198 | struct v4l2_fmtdesc *f, bool capture) |
199 | |
200 | { |
201 | struct hantro_ctx *ctx = fh_to_ctx(fh: priv); |
202 | const struct hantro_fmt *fmt, *formats; |
203 | unsigned int num_fmts, i, j = 0; |
204 | bool skip_mode_none; |
205 | |
206 | /* |
207 | * When dealing with an encoder: |
208 | * - on the capture side we want to filter out all MODE_NONE formats. |
209 | * - on the output side we want to filter out all formats that are |
210 | * not MODE_NONE. |
211 | * When dealing with a decoder: |
212 | * - on the capture side we want to filter out all formats that are |
213 | * not MODE_NONE. |
214 | * - on the output side we want to filter out all MODE_NONE formats. |
215 | */ |
216 | skip_mode_none = capture == ctx->is_encoder; |
217 | |
218 | formats = hantro_get_formats(ctx, num_fmts: &num_fmts, HANTRO_AUTO_POSTPROC); |
219 | for (i = 0; i < num_fmts; i++) { |
220 | bool mode_none = formats[i].codec_mode == HANTRO_MODE_NONE; |
221 | fmt = &formats[i]; |
222 | |
223 | if (skip_mode_none == mode_none) |
224 | continue; |
225 | if (!hantro_check_depth_match(fmt, bit_depth: ctx->bit_depth)) |
226 | continue; |
227 | if (j == f->index) { |
228 | f->pixelformat = fmt->fourcc; |
229 | return 0; |
230 | } |
231 | ++j; |
232 | } |
233 | |
234 | /* |
235 | * Enumerate post-processed formats. As per the specification, |
236 | * we enumerated these formats after natively decoded formats |
237 | * as a hint for applications on what's the preferred fomat. |
238 | */ |
239 | if (!capture) |
240 | return -EINVAL; |
241 | formats = hantro_get_postproc_formats(ctx, num_fmts: &num_fmts); |
242 | for (i = 0; i < num_fmts; i++) { |
243 | fmt = &formats[i]; |
244 | |
245 | if (!hantro_check_depth_match(fmt, bit_depth: ctx->bit_depth)) |
246 | continue; |
247 | if (j == f->index) { |
248 | f->pixelformat = fmt->fourcc; |
249 | return 0; |
250 | } |
251 | ++j; |
252 | } |
253 | |
254 | return -EINVAL; |
255 | } |
256 | |
257 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, |
258 | struct v4l2_fmtdesc *f) |
259 | { |
260 | return vidioc_enum_fmt(file, priv, f, capture: true); |
261 | } |
262 | |
263 | static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, |
264 | struct v4l2_fmtdesc *f) |
265 | { |
266 | return vidioc_enum_fmt(file, priv, f, capture: false); |
267 | } |
268 | |
269 | static int vidioc_g_fmt_out_mplane(struct file *file, void *priv, |
270 | struct v4l2_format *f) |
271 | { |
272 | struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; |
273 | struct hantro_ctx *ctx = fh_to_ctx(fh: priv); |
274 | |
275 | vpu_debug(4, "f->type = %d\n" , f->type); |
276 | |
277 | *pix_mp = ctx->src_fmt; |
278 | |
279 | return 0; |
280 | } |
281 | |
282 | static int vidioc_g_fmt_cap_mplane(struct file *file, void *priv, |
283 | struct v4l2_format *f) |
284 | { |
285 | struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; |
286 | struct hantro_ctx *ctx = fh_to_ctx(fh: priv); |
287 | |
288 | vpu_debug(4, "f->type = %d\n" , f->type); |
289 | |
290 | *pix_mp = ctx->dst_fmt; |
291 | |
292 | return 0; |
293 | } |
294 | |
295 | static int hantro_try_fmt(const struct hantro_ctx *ctx, |
296 | struct v4l2_pix_format_mplane *pix_mp, |
297 | enum v4l2_buf_type type) |
298 | { |
299 | const struct hantro_fmt *fmt; |
300 | const struct hantro_fmt *vpu_fmt; |
301 | bool capture = V4L2_TYPE_IS_CAPTURE(type); |
302 | bool coded; |
303 | |
304 | coded = capture == ctx->is_encoder; |
305 | |
306 | vpu_debug(4, "trying format %c%c%c%c\n" , |
307 | (pix_mp->pixelformat & 0x7f), |
308 | (pix_mp->pixelformat >> 8) & 0x7f, |
309 | (pix_mp->pixelformat >> 16) & 0x7f, |
310 | (pix_mp->pixelformat >> 24) & 0x7f); |
311 | |
312 | fmt = hantro_find_format(ctx, fourcc: pix_mp->pixelformat); |
313 | if (!fmt) { |
314 | fmt = hantro_get_default_fmt(ctx, bitstream: coded, HANTRO_DEFAULT_BIT_DEPTH, HANTRO_AUTO_POSTPROC); |
315 | pix_mp->pixelformat = fmt->fourcc; |
316 | } |
317 | |
318 | if (coded) { |
319 | pix_mp->num_planes = 1; |
320 | vpu_fmt = fmt; |
321 | } else if (ctx->is_encoder) { |
322 | vpu_fmt = hantro_find_format(ctx, fourcc: ctx->dst_fmt.pixelformat); |
323 | } else { |
324 | /* |
325 | * Width/height on the CAPTURE end of a decoder are ignored and |
326 | * replaced by the OUTPUT ones. |
327 | */ |
328 | pix_mp->width = ctx->src_fmt.width; |
329 | pix_mp->height = ctx->src_fmt.height; |
330 | vpu_fmt = fmt; |
331 | } |
332 | |
333 | pix_mp->field = V4L2_FIELD_NONE; |
334 | |
335 | v4l2_apply_frmsize_constraints(width: &pix_mp->width, height: &pix_mp->height, |
336 | frmsize: &vpu_fmt->frmsize); |
337 | |
338 | if (!coded) { |
339 | /* Fill remaining fields */ |
340 | v4l2_fill_pixfmt_mp(pixfmt: pix_mp, pixelformat: fmt->fourcc, width: pix_mp->width, |
341 | height: pix_mp->height); |
342 | if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE && |
343 | !hantro_needs_postproc(ctx, fmt)) |
344 | pix_mp->plane_fmt[0].sizeimage += |
345 | hantro_h264_mv_size(width: pix_mp->width, |
346 | height: pix_mp->height); |
347 | else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME && |
348 | !hantro_needs_postproc(ctx, fmt)) |
349 | pix_mp->plane_fmt[0].sizeimage += |
350 | hantro_vp9_mv_size(width: pix_mp->width, |
351 | height: pix_mp->height); |
352 | else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE && |
353 | !hantro_needs_postproc(ctx, fmt)) |
354 | pix_mp->plane_fmt[0].sizeimage += |
355 | hantro_hevc_mv_size(width: pix_mp->width, |
356 | height: pix_mp->height); |
357 | else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_AV1_FRAME && |
358 | !hantro_needs_postproc(ctx, fmt)) |
359 | pix_mp->plane_fmt[0].sizeimage += |
360 | hantro_av1_mv_size(width: pix_mp->width, |
361 | height: pix_mp->height); |
362 | } else if (!pix_mp->plane_fmt[0].sizeimage) { |
363 | /* |
364 | * For coded formats the application can specify |
365 | * sizeimage. If the application passes a zero sizeimage, |
366 | * let's default to the maximum frame size. |
367 | */ |
368 | pix_mp->plane_fmt[0].sizeimage = fmt->header_size + |
369 | pix_mp->width * pix_mp->height * fmt->max_depth; |
370 | } |
371 | |
372 | return 0; |
373 | } |
374 | |
375 | static int vidioc_try_fmt_cap_mplane(struct file *file, void *priv, |
376 | struct v4l2_format *f) |
377 | { |
378 | return hantro_try_fmt(ctx: fh_to_ctx(fh: priv), pix_mp: &f->fmt.pix_mp, type: f->type); |
379 | } |
380 | |
381 | static int vidioc_try_fmt_out_mplane(struct file *file, void *priv, |
382 | struct v4l2_format *f) |
383 | { |
384 | return hantro_try_fmt(ctx: fh_to_ctx(fh: priv), pix_mp: &f->fmt.pix_mp, type: f->type); |
385 | } |
386 | |
387 | static void |
388 | hantro_reset_fmt(struct v4l2_pix_format_mplane *fmt, |
389 | const struct hantro_fmt *vpu_fmt) |
390 | { |
391 | memset(fmt, 0, sizeof(*fmt)); |
392 | |
393 | fmt->pixelformat = vpu_fmt->fourcc; |
394 | fmt->field = V4L2_FIELD_NONE; |
395 | fmt->colorspace = V4L2_COLORSPACE_JPEG; |
396 | fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; |
397 | fmt->quantization = V4L2_QUANTIZATION_DEFAULT; |
398 | fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; |
399 | } |
400 | |
401 | static void |
402 | hantro_reset_encoded_fmt(struct hantro_ctx *ctx) |
403 | { |
404 | const struct hantro_fmt *vpu_fmt; |
405 | struct v4l2_pix_format_mplane fmt; |
406 | |
407 | vpu_fmt = hantro_get_default_fmt(ctx, bitstream: true, HANTRO_DEFAULT_BIT_DEPTH, HANTRO_AUTO_POSTPROC); |
408 | if (!vpu_fmt) |
409 | return; |
410 | |
411 | hantro_reset_fmt(fmt: &fmt, vpu_fmt); |
412 | fmt.width = vpu_fmt->frmsize.min_width; |
413 | fmt.height = vpu_fmt->frmsize.min_height; |
414 | if (ctx->is_encoder) |
415 | hantro_set_fmt_cap(ctx, pix_mp: &fmt); |
416 | else |
417 | hantro_set_fmt_out(ctx, pix_mp: &fmt, HANTRO_AUTO_POSTPROC); |
418 | } |
419 | |
420 | int |
421 | hantro_reset_raw_fmt(struct hantro_ctx *ctx, int bit_depth, bool need_postproc) |
422 | { |
423 | const struct hantro_fmt *raw_vpu_fmt; |
424 | struct v4l2_pix_format_mplane raw_fmt, *encoded_fmt; |
425 | int ret; |
426 | |
427 | raw_vpu_fmt = hantro_get_default_fmt(ctx, bitstream: false, bit_depth, need_postproc); |
428 | if (!raw_vpu_fmt) |
429 | return -EINVAL; |
430 | |
431 | if (ctx->is_encoder) { |
432 | encoded_fmt = &ctx->dst_fmt; |
433 | ctx->vpu_src_fmt = raw_vpu_fmt; |
434 | } else { |
435 | encoded_fmt = &ctx->src_fmt; |
436 | } |
437 | |
438 | hantro_reset_fmt(fmt: &raw_fmt, vpu_fmt: raw_vpu_fmt); |
439 | raw_fmt.width = encoded_fmt->width; |
440 | raw_fmt.height = encoded_fmt->height; |
441 | if (ctx->is_encoder) |
442 | ret = hantro_set_fmt_out(ctx, pix_mp: &raw_fmt, need_postproc); |
443 | else |
444 | ret = hantro_set_fmt_cap(ctx, pix_mp: &raw_fmt); |
445 | |
446 | if (!ret) { |
447 | ctx->bit_depth = bit_depth; |
448 | ctx->need_postproc = need_postproc; |
449 | } |
450 | |
451 | return ret; |
452 | } |
453 | |
454 | void hantro_reset_fmts(struct hantro_ctx *ctx) |
455 | { |
456 | hantro_reset_encoded_fmt(ctx); |
457 | hantro_reset_raw_fmt(ctx, HANTRO_DEFAULT_BIT_DEPTH, HANTRO_AUTO_POSTPROC); |
458 | } |
459 | |
460 | static void |
461 | hantro_update_requires_request(struct hantro_ctx *ctx, u32 fourcc) |
462 | { |
463 | switch (fourcc) { |
464 | case V4L2_PIX_FMT_JPEG: |
465 | ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = false; |
466 | break; |
467 | case V4L2_PIX_FMT_MPEG2_SLICE: |
468 | case V4L2_PIX_FMT_VP8_FRAME: |
469 | case V4L2_PIX_FMT_H264_SLICE: |
470 | case V4L2_PIX_FMT_HEVC_SLICE: |
471 | case V4L2_PIX_FMT_VP9_FRAME: |
472 | ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = true; |
473 | break; |
474 | default: |
475 | break; |
476 | } |
477 | } |
478 | |
479 | static void |
480 | hantro_update_requires_hold_capture_buf(struct hantro_ctx *ctx, u32 fourcc) |
481 | { |
482 | struct vb2_queue *vq; |
483 | |
484 | vq = v4l2_m2m_get_vq(m2m_ctx: ctx->fh.m2m_ctx, |
485 | type: V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); |
486 | |
487 | switch (fourcc) { |
488 | case V4L2_PIX_FMT_JPEG: |
489 | case V4L2_PIX_FMT_MPEG2_SLICE: |
490 | case V4L2_PIX_FMT_VP8_FRAME: |
491 | case V4L2_PIX_FMT_HEVC_SLICE: |
492 | case V4L2_PIX_FMT_VP9_FRAME: |
493 | vq->subsystem_flags &= ~(VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF); |
494 | break; |
495 | case V4L2_PIX_FMT_H264_SLICE: |
496 | vq->subsystem_flags |= VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF; |
497 | break; |
498 | default: |
499 | break; |
500 | } |
501 | } |
502 | |
503 | static int hantro_set_fmt_out(struct hantro_ctx *ctx, |
504 | struct v4l2_pix_format_mplane *pix_mp, |
505 | bool need_postproc) |
506 | { |
507 | struct vb2_queue *vq; |
508 | int ret; |
509 | |
510 | vq = v4l2_m2m_get_vq(m2m_ctx: ctx->fh.m2m_ctx, |
511 | type: V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); |
512 | ret = hantro_try_fmt(ctx, pix_mp, type: V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); |
513 | if (ret) |
514 | return ret; |
515 | |
516 | if (!ctx->is_encoder) { |
517 | /* |
518 | * In order to support dynamic resolution change, |
519 | * the decoder admits a resolution change, as long |
520 | * as the pixelformat remains. |
521 | */ |
522 | if (vb2_is_streaming(q: vq) && pix_mp->pixelformat != ctx->src_fmt.pixelformat) { |
523 | return -EBUSY; |
524 | } |
525 | } else { |
526 | /* |
527 | * The encoder doesn't admit a format change if |
528 | * there are OUTPUT buffers allocated. |
529 | */ |
530 | if (vb2_is_busy(q: vq)) |
531 | return -EBUSY; |
532 | } |
533 | |
534 | ctx->vpu_src_fmt = hantro_find_format(ctx, fourcc: pix_mp->pixelformat); |
535 | ctx->src_fmt = *pix_mp; |
536 | |
537 | /* |
538 | * Current raw format might have become invalid with newly |
539 | * selected codec, so reset it to default just to be safe and |
540 | * keep internal driver state sane. User is mandated to set |
541 | * the raw format again after we return, so we don't need |
542 | * anything smarter. |
543 | * Note that hantro_reset_raw_fmt() also propagates size |
544 | * changes to the raw format. |
545 | */ |
546 | if (!ctx->is_encoder) |
547 | hantro_reset_raw_fmt(ctx, |
548 | bit_depth: hantro_get_format_depth(fourcc: pix_mp->pixelformat), |
549 | need_postproc); |
550 | |
551 | /* Colorimetry information are always propagated. */ |
552 | ctx->dst_fmt.colorspace = pix_mp->colorspace; |
553 | ctx->dst_fmt.ycbcr_enc = pix_mp->ycbcr_enc; |
554 | ctx->dst_fmt.xfer_func = pix_mp->xfer_func; |
555 | ctx->dst_fmt.quantization = pix_mp->quantization; |
556 | |
557 | hantro_update_requires_request(ctx, fourcc: pix_mp->pixelformat); |
558 | hantro_update_requires_hold_capture_buf(ctx, fourcc: pix_mp->pixelformat); |
559 | |
560 | vpu_debug(0, "OUTPUT codec mode: %d\n" , ctx->vpu_src_fmt->codec_mode); |
561 | vpu_debug(0, "fmt - w: %d, h: %d\n" , |
562 | pix_mp->width, pix_mp->height); |
563 | return 0; |
564 | } |
565 | |
566 | static int hantro_set_fmt_cap(struct hantro_ctx *ctx, |
567 | struct v4l2_pix_format_mplane *pix_mp) |
568 | { |
569 | int ret; |
570 | |
571 | if (ctx->is_encoder) { |
572 | struct vb2_queue *peer_vq; |
573 | |
574 | /* |
575 | * Since format change on the CAPTURE queue will reset |
576 | * the OUTPUT queue, we can't allow doing so |
577 | * when the OUTPUT queue has buffers allocated. |
578 | */ |
579 | peer_vq = v4l2_m2m_get_vq(m2m_ctx: ctx->fh.m2m_ctx, |
580 | type: V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); |
581 | if (vb2_is_busy(q: peer_vq) && |
582 | (pix_mp->pixelformat != ctx->dst_fmt.pixelformat || |
583 | pix_mp->height != ctx->dst_fmt.height || |
584 | pix_mp->width != ctx->dst_fmt.width)) |
585 | return -EBUSY; |
586 | } |
587 | |
588 | ret = hantro_try_fmt(ctx, pix_mp, type: V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); |
589 | if (ret) |
590 | return ret; |
591 | |
592 | ctx->vpu_dst_fmt = hantro_find_format(ctx, fourcc: pix_mp->pixelformat); |
593 | ctx->dst_fmt = *pix_mp; |
594 | |
595 | /* |
596 | * Current raw format might have become invalid with newly |
597 | * selected codec, so reset it to default just to be safe and |
598 | * keep internal driver state sane. User is mandated to set |
599 | * the raw format again after we return, so we don't need |
600 | * anything smarter. |
601 | * Note that hantro_reset_raw_fmt() also propagates size |
602 | * changes to the raw format. |
603 | */ |
604 | if (ctx->is_encoder) |
605 | hantro_reset_raw_fmt(ctx, HANTRO_DEFAULT_BIT_DEPTH, HANTRO_AUTO_POSTPROC); |
606 | |
607 | /* Colorimetry information are always propagated. */ |
608 | ctx->src_fmt.colorspace = pix_mp->colorspace; |
609 | ctx->src_fmt.ycbcr_enc = pix_mp->ycbcr_enc; |
610 | ctx->src_fmt.xfer_func = pix_mp->xfer_func; |
611 | ctx->src_fmt.quantization = pix_mp->quantization; |
612 | |
613 | vpu_debug(0, "CAPTURE codec mode: %d\n" , ctx->vpu_dst_fmt->codec_mode); |
614 | vpu_debug(0, "fmt - w: %d, h: %d\n" , |
615 | pix_mp->width, pix_mp->height); |
616 | |
617 | hantro_update_requires_request(ctx, fourcc: pix_mp->pixelformat); |
618 | |
619 | return 0; |
620 | } |
621 | |
622 | static int |
623 | vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f) |
624 | { |
625 | return hantro_set_fmt_out(ctx: fh_to_ctx(fh: priv), pix_mp: &f->fmt.pix_mp, HANTRO_AUTO_POSTPROC); |
626 | } |
627 | |
628 | static int |
629 | vidioc_s_fmt_cap_mplane(struct file *file, void *priv, struct v4l2_format *f) |
630 | { |
631 | return hantro_set_fmt_cap(ctx: fh_to_ctx(fh: priv), pix_mp: &f->fmt.pix_mp); |
632 | } |
633 | |
634 | static int vidioc_g_selection(struct file *file, void *priv, |
635 | struct v4l2_selection *sel) |
636 | { |
637 | struct hantro_ctx *ctx = fh_to_ctx(fh: priv); |
638 | |
639 | /* Crop only supported on source. */ |
640 | if (!ctx->is_encoder || |
641 | sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) |
642 | return -EINVAL; |
643 | |
644 | switch (sel->target) { |
645 | case V4L2_SEL_TGT_CROP_DEFAULT: |
646 | case V4L2_SEL_TGT_CROP_BOUNDS: |
647 | sel->r.top = 0; |
648 | sel->r.left = 0; |
649 | sel->r.width = ctx->src_fmt.width; |
650 | sel->r.height = ctx->src_fmt.height; |
651 | break; |
652 | case V4L2_SEL_TGT_CROP: |
653 | sel->r.top = 0; |
654 | sel->r.left = 0; |
655 | sel->r.width = ctx->dst_fmt.width; |
656 | sel->r.height = ctx->dst_fmt.height; |
657 | break; |
658 | default: |
659 | return -EINVAL; |
660 | } |
661 | |
662 | return 0; |
663 | } |
664 | |
665 | static int vidioc_s_selection(struct file *file, void *priv, |
666 | struct v4l2_selection *sel) |
667 | { |
668 | struct hantro_ctx *ctx = fh_to_ctx(fh: priv); |
669 | struct v4l2_rect *rect = &sel->r; |
670 | struct vb2_queue *vq; |
671 | |
672 | /* Crop only supported on source. */ |
673 | if (!ctx->is_encoder || |
674 | sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) |
675 | return -EINVAL; |
676 | |
677 | /* Change not allowed if the queue is streaming. */ |
678 | vq = v4l2_m2m_get_src_vq(m2m_ctx: ctx->fh.m2m_ctx); |
679 | if (vb2_is_streaming(q: vq)) |
680 | return -EBUSY; |
681 | |
682 | if (sel->target != V4L2_SEL_TGT_CROP) |
683 | return -EINVAL; |
684 | |
685 | /* |
686 | * We do not support offsets, and we can crop only inside |
687 | * right-most or bottom-most macroblocks. |
688 | */ |
689 | if (rect->left != 0 || rect->top != 0 || |
690 | round_up(rect->width, MB_DIM) != ctx->src_fmt.width || |
691 | round_up(rect->height, MB_DIM) != ctx->src_fmt.height) { |
692 | /* Default to full frame for incorrect settings. */ |
693 | rect->left = 0; |
694 | rect->top = 0; |
695 | rect->width = ctx->src_fmt.width; |
696 | rect->height = ctx->src_fmt.height; |
697 | } else { |
698 | /* We support widths aligned to 4 pixels and arbitrary heights. */ |
699 | rect->width = round_up(rect->width, 4); |
700 | } |
701 | |
702 | ctx->dst_fmt.width = rect->width; |
703 | ctx->dst_fmt.height = rect->height; |
704 | |
705 | return 0; |
706 | } |
707 | |
708 | static const struct v4l2_event hantro_eos_event = { |
709 | .type = V4L2_EVENT_EOS |
710 | }; |
711 | |
712 | static int vidioc_encoder_cmd(struct file *file, void *priv, |
713 | struct v4l2_encoder_cmd *ec) |
714 | { |
715 | struct hantro_ctx *ctx = fh_to_ctx(fh: priv); |
716 | int ret; |
717 | |
718 | ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh: priv, ec); |
719 | if (ret < 0) |
720 | return ret; |
721 | |
722 | if (!vb2_is_streaming(q: v4l2_m2m_get_src_vq(m2m_ctx: ctx->fh.m2m_ctx)) || |
723 | !vb2_is_streaming(q: v4l2_m2m_get_dst_vq(m2m_ctx: ctx->fh.m2m_ctx))) |
724 | return 0; |
725 | |
726 | ret = v4l2_m2m_ioctl_encoder_cmd(file, fh: priv, ec); |
727 | if (ret < 0) |
728 | return ret; |
729 | |
730 | if (ec->cmd == V4L2_ENC_CMD_STOP && |
731 | v4l2_m2m_has_stopped(m2m_ctx: ctx->fh.m2m_ctx)) |
732 | v4l2_event_queue_fh(fh: &ctx->fh, ev: &hantro_eos_event); |
733 | |
734 | if (ec->cmd == V4L2_ENC_CMD_START) |
735 | vb2_clear_last_buffer_dequeued(q: &ctx->fh.m2m_ctx->cap_q_ctx.q); |
736 | |
737 | return 0; |
738 | } |
739 | |
740 | const struct v4l2_ioctl_ops hantro_ioctl_ops = { |
741 | .vidioc_querycap = vidioc_querycap, |
742 | .vidioc_enum_framesizes = vidioc_enum_framesizes, |
743 | |
744 | .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_cap_mplane, |
745 | .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_out_mplane, |
746 | .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt_out_mplane, |
747 | .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt_cap_mplane, |
748 | .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt_out_mplane, |
749 | .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt_cap_mplane, |
750 | .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out, |
751 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, |
752 | |
753 | .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, |
754 | .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, |
755 | .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, |
756 | .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, |
757 | .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, |
758 | .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, |
759 | .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, |
760 | |
761 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, |
762 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, |
763 | |
764 | .vidioc_streamon = v4l2_m2m_ioctl_streamon, |
765 | .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, |
766 | |
767 | .vidioc_g_selection = vidioc_g_selection, |
768 | .vidioc_s_selection = vidioc_s_selection, |
769 | |
770 | .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, |
771 | .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, |
772 | |
773 | .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd, |
774 | .vidioc_encoder_cmd = vidioc_encoder_cmd, |
775 | }; |
776 | |
777 | static int |
778 | hantro_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, |
779 | unsigned int *num_planes, unsigned int sizes[], |
780 | struct device *alloc_devs[]) |
781 | { |
782 | struct hantro_ctx *ctx = vb2_get_drv_priv(q: vq); |
783 | struct v4l2_pix_format_mplane *pixfmt; |
784 | int i; |
785 | |
786 | switch (vq->type) { |
787 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
788 | pixfmt = &ctx->dst_fmt; |
789 | break; |
790 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
791 | pixfmt = &ctx->src_fmt; |
792 | break; |
793 | default: |
794 | vpu_err("invalid queue type: %d\n" , vq->type); |
795 | return -EINVAL; |
796 | } |
797 | |
798 | if (*num_planes) { |
799 | if (*num_planes != pixfmt->num_planes) |
800 | return -EINVAL; |
801 | for (i = 0; i < pixfmt->num_planes; ++i) |
802 | if (sizes[i] < pixfmt->plane_fmt[i].sizeimage) |
803 | return -EINVAL; |
804 | return 0; |
805 | } |
806 | |
807 | *num_planes = pixfmt->num_planes; |
808 | for (i = 0; i < pixfmt->num_planes; ++i) |
809 | sizes[i] = pixfmt->plane_fmt[i].sizeimage; |
810 | return 0; |
811 | } |
812 | |
813 | static int |
814 | hantro_buf_plane_check(struct vb2_buffer *vb, |
815 | struct v4l2_pix_format_mplane *pixfmt) |
816 | { |
817 | unsigned int sz; |
818 | int i; |
819 | |
820 | for (i = 0; i < pixfmt->num_planes; ++i) { |
821 | sz = pixfmt->plane_fmt[i].sizeimage; |
822 | vpu_debug(4, "plane %d size: %ld, sizeimage: %u\n" , |
823 | i, vb2_plane_size(vb, i), sz); |
824 | if (vb2_plane_size(vb, plane_no: i) < sz) { |
825 | vpu_err("plane %d is too small for output\n" , i); |
826 | return -EINVAL; |
827 | } |
828 | } |
829 | return 0; |
830 | } |
831 | |
832 | static int hantro_buf_prepare(struct vb2_buffer *vb) |
833 | { |
834 | struct vb2_queue *vq = vb->vb2_queue; |
835 | struct hantro_ctx *ctx = vb2_get_drv_priv(q: vq); |
836 | struct v4l2_pix_format_mplane *pix_fmt; |
837 | int ret; |
838 | |
839 | if (V4L2_TYPE_IS_OUTPUT(vq->type)) |
840 | pix_fmt = &ctx->src_fmt; |
841 | else |
842 | pix_fmt = &ctx->dst_fmt; |
843 | ret = hantro_buf_plane_check(vb, pixfmt: pix_fmt); |
844 | if (ret) |
845 | return ret; |
846 | /* |
847 | * Buffer's bytesused must be written by driver for CAPTURE buffers. |
848 | * (for OUTPUT buffers, if userspace passes 0 bytesused, v4l2-core sets |
849 | * it to buffer length). |
850 | */ |
851 | if (V4L2_TYPE_IS_CAPTURE(vq->type)) { |
852 | if (ctx->is_encoder) |
853 | vb2_set_plane_payload(vb, plane_no: 0, size: 0); |
854 | else |
855 | vb2_set_plane_payload(vb, plane_no: 0, size: pix_fmt->plane_fmt[0].sizeimage); |
856 | } |
857 | |
858 | return 0; |
859 | } |
860 | |
861 | static void hantro_buf_queue(struct vb2_buffer *vb) |
862 | { |
863 | struct hantro_ctx *ctx = vb2_get_drv_priv(q: vb->vb2_queue); |
864 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
865 | |
866 | if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && |
867 | vb2_is_streaming(q: vb->vb2_queue) && |
868 | v4l2_m2m_dst_buf_is_last(m2m_ctx: ctx->fh.m2m_ctx)) { |
869 | unsigned int i; |
870 | |
871 | for (i = 0; i < vb->num_planes; i++) |
872 | vb2_set_plane_payload(vb, plane_no: i, size: 0); |
873 | |
874 | vbuf->field = V4L2_FIELD_NONE; |
875 | vbuf->sequence = ctx->sequence_cap++; |
876 | |
877 | v4l2_m2m_last_buffer_done(m2m_ctx: ctx->fh.m2m_ctx, vbuf); |
878 | v4l2_event_queue_fh(fh: &ctx->fh, ev: &hantro_eos_event); |
879 | return; |
880 | } |
881 | |
882 | v4l2_m2m_buf_queue(m2m_ctx: ctx->fh.m2m_ctx, vbuf); |
883 | } |
884 | |
885 | static bool hantro_vq_is_coded(struct vb2_queue *q) |
886 | { |
887 | struct hantro_ctx *ctx = vb2_get_drv_priv(q); |
888 | |
889 | return ctx->is_encoder != V4L2_TYPE_IS_OUTPUT(q->type); |
890 | } |
891 | |
892 | static int hantro_start_streaming(struct vb2_queue *q, unsigned int count) |
893 | { |
894 | struct hantro_ctx *ctx = vb2_get_drv_priv(q); |
895 | int ret = 0; |
896 | |
897 | v4l2_m2m_update_start_streaming_state(m2m_ctx: ctx->fh.m2m_ctx, q); |
898 | |
899 | if (V4L2_TYPE_IS_OUTPUT(q->type)) |
900 | ctx->sequence_out = 0; |
901 | else |
902 | ctx->sequence_cap = 0; |
903 | |
904 | if (hantro_vq_is_coded(q)) { |
905 | enum hantro_codec_mode codec_mode; |
906 | |
907 | if (V4L2_TYPE_IS_OUTPUT(q->type)) |
908 | codec_mode = ctx->vpu_src_fmt->codec_mode; |
909 | else |
910 | codec_mode = ctx->vpu_dst_fmt->codec_mode; |
911 | |
912 | vpu_debug(4, "Codec mode = %d\n" , codec_mode); |
913 | ctx->codec_ops = &ctx->dev->variant->codec_ops[codec_mode]; |
914 | if (ctx->codec_ops->init) { |
915 | ret = ctx->codec_ops->init(ctx); |
916 | if (ret) |
917 | return ret; |
918 | } |
919 | |
920 | if (hantro_needs_postproc(ctx, fmt: ctx->vpu_dst_fmt)) { |
921 | ret = hantro_postproc_init(ctx); |
922 | if (ret) |
923 | goto err_codec_exit; |
924 | } |
925 | } |
926 | return ret; |
927 | |
928 | err_codec_exit: |
929 | if (ctx->codec_ops->exit) |
930 | ctx->codec_ops->exit(ctx); |
931 | return ret; |
932 | } |
933 | |
934 | static void |
935 | hantro_return_bufs(struct vb2_queue *q, |
936 | struct vb2_v4l2_buffer *(*buf_remove)(struct v4l2_m2m_ctx *)) |
937 | { |
938 | struct hantro_ctx *ctx = vb2_get_drv_priv(q); |
939 | |
940 | for (;;) { |
941 | struct vb2_v4l2_buffer *vbuf; |
942 | |
943 | vbuf = buf_remove(ctx->fh.m2m_ctx); |
944 | if (!vbuf) |
945 | break; |
946 | v4l2_ctrl_request_complete(req: vbuf->vb2_buf.req_obj.req, |
947 | parent: &ctx->ctrl_handler); |
948 | v4l2_m2m_buf_done(buf: vbuf, state: VB2_BUF_STATE_ERROR); |
949 | } |
950 | } |
951 | |
952 | static void hantro_stop_streaming(struct vb2_queue *q) |
953 | { |
954 | struct hantro_ctx *ctx = vb2_get_drv_priv(q); |
955 | |
956 | if (hantro_vq_is_coded(q)) { |
957 | hantro_postproc_free(ctx); |
958 | if (ctx->codec_ops && ctx->codec_ops->exit) |
959 | ctx->codec_ops->exit(ctx); |
960 | } |
961 | |
962 | /* |
963 | * The mem2mem framework calls v4l2_m2m_cancel_job before |
964 | * .stop_streaming, so there isn't any job running and |
965 | * it is safe to return all the buffers. |
966 | */ |
967 | if (V4L2_TYPE_IS_OUTPUT(q->type)) |
968 | hantro_return_bufs(q, buf_remove: v4l2_m2m_src_buf_remove); |
969 | else |
970 | hantro_return_bufs(q, buf_remove: v4l2_m2m_dst_buf_remove); |
971 | |
972 | v4l2_m2m_update_stop_streaming_state(m2m_ctx: ctx->fh.m2m_ctx, q); |
973 | |
974 | if (V4L2_TYPE_IS_OUTPUT(q->type) && |
975 | v4l2_m2m_has_stopped(m2m_ctx: ctx->fh.m2m_ctx)) |
976 | v4l2_event_queue_fh(fh: &ctx->fh, ev: &hantro_eos_event); |
977 | } |
978 | |
979 | static void hantro_buf_request_complete(struct vb2_buffer *vb) |
980 | { |
981 | struct hantro_ctx *ctx = vb2_get_drv_priv(q: vb->vb2_queue); |
982 | |
983 | v4l2_ctrl_request_complete(req: vb->req_obj.req, parent: &ctx->ctrl_handler); |
984 | } |
985 | |
986 | static int hantro_buf_out_validate(struct vb2_buffer *vb) |
987 | { |
988 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
989 | |
990 | vbuf->field = V4L2_FIELD_NONE; |
991 | return 0; |
992 | } |
993 | |
994 | const struct vb2_ops hantro_queue_ops = { |
995 | .queue_setup = hantro_queue_setup, |
996 | .buf_prepare = hantro_buf_prepare, |
997 | .buf_queue = hantro_buf_queue, |
998 | .buf_out_validate = hantro_buf_out_validate, |
999 | .buf_request_complete = hantro_buf_request_complete, |
1000 | .start_streaming = hantro_start_streaming, |
1001 | .stop_streaming = hantro_stop_streaming, |
1002 | .wait_prepare = vb2_ops_wait_prepare, |
1003 | .wait_finish = vb2_ops_wait_finish, |
1004 | }; |
1005 | |