2937ecb21b31cf32ea5d45d3009ff549de8c39ea
[openwrt/staging/pepe2k.git] /
1 From 3b23f733feed28d440ba63c111e4c9a91c14fb42 Mon Sep 17 00:00:00 2001
2 From: John Cox <jc@kynesim.co.uk>
3 Date: Thu, 5 Mar 2020 18:30:41 +0000
4 Subject: [PATCH 0203/1085] staging: media: rpivid: Add Raspberry Pi V4L2 H265
5 decoder
6
7 This driver is for the HEVC/H265 decoder block on the Raspberry
8 Pi 4, and conforms to the V4L2 stateless decoder API.
9
10 Signed-off-by: John Cox <jc@kynesim.co.uk>
11
12 staging: media: rpivid: Select MEDIA_CONTROLLER and MEDIA_CONTROLLER_REQUEST_API
13
14 MEDIA_CONTROLLER_REQUEST_API is a hidden option. If rpivid depends on it,
15 the user would need to first enable another driver that selects
16 MEDIA_CONTROLLER_REQUEST_API, and only then rpivid would become available.
17
18 By selecting it instead of depending on it, it becomes possible to enable
19 rpivid without having to enable other potentially unnecessary drivers.
20
21 Signed-off-by: Hristo Venev <hristo@venev.name>
22
23 rpivid_h265: Fix width/height typo
24
25 Signed-off-by: popcornmix <popcornmix@gmail.com>
26
27 rpivid_h625: Fix build warnings
28
29 Signed-off-by: Phil Elwell <phil@raspberrypi.com>
30
31 staging: rpivid: Fix crash when CMA alloc fails
32
33 If realloc to increase coeff size fails then attempt to re-allocate
34 the original size. If that also fails then flag a fatal error to abort
35 all further decode.
36
37 Signed-off-by: John Cox <jc@kynesim.co.uk>
38
39 rpivid: Request maximum hevc clock
40
41 Query maximum and minimum clock from driver
42 and use those
43
44 Signed-off-by: Dom Cobley <popcornmix@gmail.com>
45
46 rpivid: Switch to new clock api
47
48 Signed-off-by: Dom Cobley <popcornmix@gmail.com>
49
50 rpivid: Only clk_request_done once
51
52 Fixes: 25486f49bfe2e3ae13b90478d1eebd91413136ad
53 Signed-off-by: Dom Cobley <popcornmix@gmail.com>
54
55 media: rpivid: Remove the need to have num_entry_points set
56
57 VAAPI H265 has num entry points but never sets it. Allow a VAAPI
58 shim to work without requiring rewriting the VAAPI driver.
59 num_entry_points can be calculated from the slice_segment_addr
60 of the next slice so delay processing until we have that.
61
62 Also includes some minor cosmetics.
63
64 Signed-off-by: John Cox <jc@kynesim.co.uk>
65
66 media: rpivid: Convert to MPLANE
67
68 Use multi-planar interface rather than single plane interface. This
69 allows dmabufs holding compressed data to be resized.
70
71 Signed-off-by: John Cox <jc@kynesim.co.uk>
72
73 media: rpivid: Add an enable count to irq claim Qs
74
75 Add an enable count to the irq Q structures to allow the irq logic to
76 block further callbacks if resources associated with the irq are not
77 yet available.
78
79 Signed-off-by: John Cox <jc@kynesim.co.uk>
80
81 media: rpivid: Add a Pass0 to accumulate slices and rework job finish
82
83 Due to overheads in assembling controls and requests it is worth having
84 the slice assembly phase separate from the h/w pass1 processing. Create
85 a queue to service pass1 rather than have the pass1 finished callback
86 trigger the next slice job.
87
88 This requires a rework of the logic that splits up the buffer and
89 request done events. This code contains two ways of doing that, we use
90 Ezequiel Garcias <ezequiel@collabora.com> solution, but expect that
91 in the future this will be handled by the framework in a cleaner manner.
92
93 Fix up the handling of some of the memory exhaustion crashes uncovered
94 in the process of writing this code.
95
96 Signed-off-by: John Cox <jc@kynesim.co.uk>
97
98 media: rpivid: Map cmd buffer directly
99
100 It is unnecessary to have a separate dmabuf to hold the cmd buffer.
101 Map it directly from the kmalloc.
102
103 Signed-off-by: John Cox <jc@kynesim.co.uk>
104
105 media: rpivid: Improve values returned when setting output format
106
107 Guess a better value for the compressed bitstream buffer size
108
109 Signed-off-by: John Cox <jc@kynesim.co.uk>
110
111 media: rpivid: Improve stream_on/off conformance & clock setup
112
113 Fix stream on & off such that failures leave the driver in the correct
114 state. Ensure that the clock is on when we are streaming and off when
115 all contexts attached to this device have stopped streaming.
116
117 Signed-off-by: John Cox <jc@kynesim.co.uk>
118
119 media: rpivid: Improve SPS/PPS error handling/validation
120
121 Move size and width checking from bitstream processing to control
122 validation
123
124 Signed-off-by: John Cox <jc@kynesim.co.uk>
125
126 media: rpivid: Fix H265 aux ent reuse of the same slot
127
128 It is legitimate, though unusual, for an aux ent associated with a slot
129 to be selected in phase 0 before a previous selection has been used and
130 released in phase 2. Fix such that if the slot is found to be in use
131 that the aux ent associated with it is reused rather than an new aux
132 ent being created. This fixes a problem where when the first aux ent
133 was released the second was lost track of.
134
135 This bug spotted in Nick's testing. It may explain some other occasional,
136 unreliable decode error reports where dmesg included "Missing DPB AUX
137 ent" logging.
138
139 Signed-off-by: John Cox <jc@kynesim.co.uk>
140
141 media: rpivid: Update to compile with new hevc decode params
142
143 DPB entries have moved from slice params to the new decode params
144 attribute - update to deal with this. Also fixes fallthrough
145 warnings which seem to be new in 5.14.
146
147 Signed-off-by: John Cox <jc@kynesim.co.uk>
148
149 media: rpivid: Make slice ctrl dynamic
150
151 Allows the user to submit a whole frames worth of slice headers in
152 one lump along with a single bitstream dmabuf for the whole lot.
153 This saves potentially a lot of bitstream copying.
154
155 Signed-off-by: John Cox <jc@kynesim.co.uk>
156
157 media: rpivid: Only create aux entries for H265 if needed
158
159 Only create aux entries of mv info for frames where that info might
160 be used by a later frame. This saves some memory bandwidth and
161 potentially some memory.
162
163 Signed-off-by: John Cox <jc@kynesim.co.uk>
164
165 media: rpivid: Avoid returning EINVAL to a G_FMT ioctl
166
167 V4L2 spec says that G/S/TRY_FMT IOCTLs should never return errors for
168 anything other than wrong buffer types. Improve the capture format
169 function such that this is so and unsupported values get converted
170 to supported ones properly.
171
172 Signed-off-by: John Cox <jc@kynesim.co.uk>
173
174 media: rpivid: Remove unused ctx state variable and defines
175
176 Remove unused ctx state tracking variable and associated defines.
177 Their presence implies they might be used, but they aren't.
178
179 Signed-off-by: John Cox <jc@kynesim.co.uk>
180
181 media: rpivid: Ensure IRQs have completed before uniniting context
182
183 Before uniniting the decode context sync with the IRQ queues to ensure
184 that decode no longer has any buffers in use. This fixes a problem that
185 manifested as ffmpeg leaking CMA buffers when it did a stream off on
186 OUTPUT before CAPTURE, though in reality it was probably much more
187 dangerous than that.
188
189 Signed-off-by: John Cox <jc@kynesim.co.uk>
190
191 media: rpivid: remove min_buffers_needed from src queue
192
193 Remove min_buffers_needed=1 from src queue init. Src buffers are bound
194 to media requests therefore this setting is not needed and generates
195 a WARN in kernel 5.16.
196
197 Signed-off-by: John Cox <jc@kynesim.co.uk>
198
199 rpivid: Use clk_get_max_rate()
200
201 The driver was using clk_round_rate() to figure out the maximum clock
202 rate that was allowed for the HEVC clock.
203
204 Since we have a function to return it directly now, let's use it.
205
206 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
207
208 media: rpivid: Apply V4L2 stateless API changes
209
210 media: rpivid: Fix fallthrough warning
211
212 Replace old-style /* FALLTHRU */ with fallthrough;
213
214 Signed-off-by: John Cox <jc@kynesim.co.uk>
215
216 media: rpivid: Set min value as well as max for HEVC_DECODE_MODE
217
218 As only one value can be accepted set both min and max to that value.
219
220 Signed-off-by: John Cox <jc@kynesim.co.uk>
221
222 media: rpivid: Accept ANNEX_B start codes
223
224 Allow the START_CODE control to take ANNEX_B as a value. This makes no
225 difference to any part of the decode process as the added bytes are in
226 data that we ignore. This helps my testing and may help userland code
227 that expects to send those bytes.
228
229 Signed-off-by: John Cox <jc@kynesim.co.uk>
230
231 rpivid: Convert to new clock rate API
232
233 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
234 ---
235 drivers/media/v4l2-core/v4l2-mem2mem.c | 2 -
236 drivers/staging/media/Kconfig | 2 +
237 drivers/staging/media/Makefile | 1 +
238 drivers/staging/media/rpivid/Kconfig | 16 +
239 drivers/staging/media/rpivid/Makefile | 5 +
240 drivers/staging/media/rpivid/rpivid.c | 459 ++++
241 drivers/staging/media/rpivid/rpivid.h | 203 ++
242 drivers/staging/media/rpivid/rpivid_dec.c | 96 +
243 drivers/staging/media/rpivid/rpivid_dec.h | 19 +
244 drivers/staging/media/rpivid/rpivid_h265.c | 2698 +++++++++++++++++++
245 drivers/staging/media/rpivid/rpivid_hw.c | 383 +++
246 drivers/staging/media/rpivid/rpivid_hw.h | 303 +++
247 drivers/staging/media/rpivid/rpivid_video.c | 696 +++++
248 drivers/staging/media/rpivid/rpivid_video.h | 33 +
249 14 files changed, 4914 insertions(+), 2 deletions(-)
250 create mode 100644 drivers/staging/media/rpivid/Kconfig
251 create mode 100644 drivers/staging/media/rpivid/Makefile
252 create mode 100644 drivers/staging/media/rpivid/rpivid.c
253 create mode 100644 drivers/staging/media/rpivid/rpivid.h
254 create mode 100644 drivers/staging/media/rpivid/rpivid_dec.c
255 create mode 100644 drivers/staging/media/rpivid/rpivid_dec.h
256 create mode 100644 drivers/staging/media/rpivid/rpivid_h265.c
257 create mode 100644 drivers/staging/media/rpivid/rpivid_hw.c
258 create mode 100644 drivers/staging/media/rpivid/rpivid_hw.h
259 create mode 100644 drivers/staging/media/rpivid/rpivid_video.c
260 create mode 100644 drivers/staging/media/rpivid/rpivid_video.h
261
262 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
263 +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
264 @@ -492,8 +492,6 @@ void v4l2_m2m_job_finish(struct v4l2_m2m
265 * holding capture buffers. Those should use
266 * v4l2_m2m_buf_done_and_job_finish() instead.
267 */
268 - WARN_ON(m2m_ctx->out_q_ctx.q.subsystem_flags &
269 - VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF);
270 spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
271 schedule_next = _v4l2_m2m_job_finish(m2m_dev, m2m_ctx);
272 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
273 --- a/drivers/staging/media/Kconfig
274 +++ b/drivers/staging/media/Kconfig
275 @@ -36,6 +36,8 @@ source "drivers/staging/media/omap4iss/K
276
277 source "drivers/staging/media/rkvdec/Kconfig"
278
279 +source "drivers/staging/media/rpivid/Kconfig"
280 +
281 source "drivers/staging/media/sunxi/Kconfig"
282
283 source "drivers/staging/media/tegra-video/Kconfig"
284 --- a/drivers/staging/media/Makefile
285 +++ b/drivers/staging/media/Makefile
286 @@ -6,6 +6,7 @@ obj-$(CONFIG_VIDEO_MAX96712) += max96712
287 obj-$(CONFIG_VIDEO_MESON_VDEC) += meson/vdec/
288 obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/
289 obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rkvdec/
290 +obj-$(CONFIG_VIDEO_RPIVID) += rpivid/
291 obj-$(CONFIG_VIDEO_SUNXI) += sunxi/
292 obj-$(CONFIG_VIDEO_TEGRA) += tegra-video/
293 obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/
294 --- /dev/null
295 +++ b/drivers/staging/media/rpivid/Kconfig
296 @@ -0,0 +1,16 @@
297 +# SPDX-License-Identifier: GPL-2.0
298 +
299 +config VIDEO_RPIVID
300 + tristate "Rpi H265 driver"
301 + depends on VIDEO_DEV && VIDEO_DEV
302 + depends on OF
303 + select MEDIA_CONTROLLER
304 + select MEDIA_CONTROLLER_REQUEST_API
305 + select VIDEOBUF2_DMA_CONTIG
306 + select V4L2_MEM2MEM_DEV
307 + help
308 + Support for the Rpi H265 h/w decoder.
309 +
310 + To compile this driver as a module, choose M here: the module
311 + will be called rpivid-hevc.
312 +
313 --- /dev/null
314 +++ b/drivers/staging/media/rpivid/Makefile
315 @@ -0,0 +1,5 @@
316 +# SPDX-License-Identifier: GPL-2.0
317 +obj-$(CONFIG_VIDEO_RPIVID) += rpivid-hevc.o
318 +
319 +rpivid-hevc-y = rpivid.o rpivid_video.o rpivid_dec.o \
320 + rpivid_hw.o rpivid_h265.o
321 --- /dev/null
322 +++ b/drivers/staging/media/rpivid/rpivid.c
323 @@ -0,0 +1,459 @@
324 +// SPDX-License-Identifier: GPL-2.0
325 +/*
326 + * Raspberry Pi HEVC driver
327 + *
328 + * Copyright (C) 2020 Raspberry Pi (Trading) Ltd
329 + *
330 + * Based on the Cedrus VPU driver, that is:
331 + *
332 + * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
333 + * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
334 + * Copyright (C) 2018 Bootlin
335 + */
336 +
337 +#include <linux/platform_device.h>
338 +#include <linux/module.h>
339 +#include <linux/of.h>
340 +
341 +#include <media/v4l2-device.h>
342 +#include <media/v4l2-ioctl.h>
343 +#include <media/v4l2-ctrls.h>
344 +#include <media/v4l2-mem2mem.h>
345 +
346 +#include "rpivid.h"
347 +#include "rpivid_video.h"
348 +#include "rpivid_hw.h"
349 +#include "rpivid_dec.h"
350 +
351 +/*
352 + * Default /dev/videoN node number.
353 + * Deliberately avoid the very low numbers as these are often taken by webcams
354 + * etc, and simple apps tend to only go for /dev/video0.
355 + */
356 +static int video_nr = 19;
357 +module_param(video_nr, int, 0644);
358 +MODULE_PARM_DESC(video_nr, "decoder video device number");
359 +
360 +static const struct rpivid_control rpivid_ctrls[] = {
361 + {
362 + .cfg = {
363 + .id = V4L2_CID_STATELESS_HEVC_SPS,
364 + .ops = &rpivid_hevc_sps_ctrl_ops,
365 + },
366 + .required = true,
367 + },
368 + {
369 + .cfg = {
370 + .id = V4L2_CID_STATELESS_HEVC_PPS,
371 + .ops = &rpivid_hevc_pps_ctrl_ops,
372 + },
373 + .required = true,
374 + },
375 + {
376 + .cfg = {
377 + .id = V4L2_CID_STATELESS_HEVC_SCALING_MATRIX,
378 + },
379 + .required = false,
380 + },
381 + {
382 + .cfg = {
383 + .id = V4L2_CID_STATELESS_HEVC_DECODE_PARAMS,
384 + },
385 + .required = true,
386 + },
387 + {
388 + .cfg = {
389 + .name = "Slice param array",
390 + .id = V4L2_CID_STATELESS_HEVC_SLICE_PARAMS,
391 + .type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS,
392 + .flags = V4L2_CTRL_FLAG_DYNAMIC_ARRAY,
393 + .dims = { 0x1000 },
394 + },
395 + .required = true,
396 + },
397 + {
398 + .cfg = {
399 + .id = V4L2_CID_STATELESS_HEVC_DECODE_MODE,
400 + .min = V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED,
401 + .max = V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED,
402 + .def = V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED,
403 + },
404 + .required = false,
405 + },
406 + {
407 + .cfg = {
408 + .id = V4L2_CID_STATELESS_HEVC_START_CODE,
409 + .min = V4L2_STATELESS_HEVC_START_CODE_NONE,
410 + .max = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
411 + .def = V4L2_STATELESS_HEVC_START_CODE_NONE,
412 + },
413 + .required = false,
414 + },
415 +};
416 +
417 +#define rpivid_ctrls_COUNT ARRAY_SIZE(rpivid_ctrls)
418 +
419 +struct v4l2_ctrl *rpivid_find_ctrl(struct rpivid_ctx *ctx, u32 id)
420 +{
421 + unsigned int i;
422 +
423 + for (i = 0; ctx->ctrls[i]; i++)
424 + if (ctx->ctrls[i]->id == id)
425 + return ctx->ctrls[i];
426 +
427 + return NULL;
428 +}
429 +
430 +void *rpivid_find_control_data(struct rpivid_ctx *ctx, u32 id)
431 +{
432 + struct v4l2_ctrl *const ctrl = rpivid_find_ctrl(ctx, id);
433 +
434 + return !ctrl ? NULL : ctrl->p_cur.p;
435 +}
436 +
437 +static int rpivid_init_ctrls(struct rpivid_dev *dev, struct rpivid_ctx *ctx)
438 +{
439 + struct v4l2_ctrl_handler *hdl = &ctx->hdl;
440 + struct v4l2_ctrl *ctrl;
441 + unsigned int ctrl_size;
442 + unsigned int i;
443 +
444 + v4l2_ctrl_handler_init(hdl, rpivid_ctrls_COUNT);
445 + if (hdl->error) {
446 + v4l2_err(&dev->v4l2_dev,
447 + "Failed to initialize control handler\n");
448 + return hdl->error;
449 + }
450 +
451 + ctrl_size = sizeof(ctrl) * rpivid_ctrls_COUNT + 1;
452 +
453 + ctx->ctrls = kzalloc(ctrl_size, GFP_KERNEL);
454 + if (!ctx->ctrls)
455 + return -ENOMEM;
456 +
457 + for (i = 0; i < rpivid_ctrls_COUNT; i++) {
458 + ctrl = v4l2_ctrl_new_custom(hdl, &rpivid_ctrls[i].cfg,
459 + ctx);
460 + if (hdl->error) {
461 + v4l2_err(&dev->v4l2_dev,
462 + "Failed to create new custom control id=%#x\n",
463 + rpivid_ctrls[i].cfg.id);
464 +
465 + v4l2_ctrl_handler_free(hdl);
466 + kfree(ctx->ctrls);
467 + return hdl->error;
468 + }
469 +
470 + ctx->ctrls[i] = ctrl;
471 + }
472 +
473 + ctx->fh.ctrl_handler = hdl;
474 + v4l2_ctrl_handler_setup(hdl);
475 +
476 + return 0;
477 +}
478 +
479 +static int rpivid_request_validate(struct media_request *req)
480 +{
481 + struct media_request_object *obj;
482 + struct v4l2_ctrl_handler *parent_hdl, *hdl;
483 + struct rpivid_ctx *ctx = NULL;
484 + struct v4l2_ctrl *ctrl_test;
485 + unsigned int count;
486 + unsigned int i;
487 +
488 + list_for_each_entry(obj, &req->objects, list) {
489 + struct vb2_buffer *vb;
490 +
491 + if (vb2_request_object_is_buffer(obj)) {
492 + vb = container_of(obj, struct vb2_buffer, req_obj);
493 + ctx = vb2_get_drv_priv(vb->vb2_queue);
494 +
495 + break;
496 + }
497 + }
498 +
499 + if (!ctx)
500 + return -ENOENT;
501 +
502 + count = vb2_request_buffer_cnt(req);
503 + if (!count) {
504 + v4l2_info(&ctx->dev->v4l2_dev,
505 + "No buffer was provided with the request\n");
506 + return -ENOENT;
507 + } else if (count > 1) {
508 + v4l2_info(&ctx->dev->v4l2_dev,
509 + "More than one buffer was provided with the request\n");
510 + return -EINVAL;
511 + }
512 +
513 + parent_hdl = &ctx->hdl;
514 +
515 + hdl = v4l2_ctrl_request_hdl_find(req, parent_hdl);
516 + if (!hdl) {
517 + v4l2_info(&ctx->dev->v4l2_dev, "Missing codec control(s)\n");
518 + return -ENOENT;
519 + }
520 +
521 + for (i = 0; i < rpivid_ctrls_COUNT; i++) {
522 + if (!rpivid_ctrls[i].required)
523 + continue;
524 +
525 + ctrl_test =
526 + v4l2_ctrl_request_hdl_ctrl_find(hdl,
527 + rpivid_ctrls[i].cfg.id);
528 + if (!ctrl_test) {
529 + v4l2_info(&ctx->dev->v4l2_dev,
530 + "Missing required codec control\n");
531 + v4l2_ctrl_request_hdl_put(hdl);
532 + return -ENOENT;
533 + }
534 + }
535 +
536 + v4l2_ctrl_request_hdl_put(hdl);
537 +
538 + return vb2_request_validate(req);
539 +}
540 +
541 +static int rpivid_open(struct file *file)
542 +{
543 + struct rpivid_dev *dev = video_drvdata(file);
544 + struct rpivid_ctx *ctx = NULL;
545 + int ret;
546 +
547 + if (mutex_lock_interruptible(&dev->dev_mutex))
548 + return -ERESTARTSYS;
549 +
550 + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
551 + if (!ctx) {
552 + mutex_unlock(&dev->dev_mutex);
553 + ret = -ENOMEM;
554 + goto err_unlock;
555 + }
556 +
557 + mutex_init(&ctx->ctx_mutex);
558 +
559 + v4l2_fh_init(&ctx->fh, video_devdata(file));
560 + file->private_data = &ctx->fh;
561 + ctx->dev = dev;
562 +
563 + ret = rpivid_init_ctrls(dev, ctx);
564 + if (ret)
565 + goto err_free;
566 +
567 + ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
568 + &rpivid_queue_init);
569 + if (IS_ERR(ctx->fh.m2m_ctx)) {
570 + ret = PTR_ERR(ctx->fh.m2m_ctx);
571 + goto err_ctrls;
572 + }
573 +
574 + /* The only bit of format info that we can guess now is H265 src
575 + * Everything else we need more info for
576 + */
577 + rpivid_prepare_src_format(&ctx->src_fmt);
578 +
579 + v4l2_fh_add(&ctx->fh);
580 +
581 + mutex_unlock(&dev->dev_mutex);
582 +
583 + return 0;
584 +
585 +err_ctrls:
586 + v4l2_ctrl_handler_free(&ctx->hdl);
587 +err_free:
588 + mutex_destroy(&ctx->ctx_mutex);
589 + kfree(ctx);
590 +err_unlock:
591 + mutex_unlock(&dev->dev_mutex);
592 +
593 + return ret;
594 +}
595 +
596 +static int rpivid_release(struct file *file)
597 +{
598 + struct rpivid_dev *dev = video_drvdata(file);
599 + struct rpivid_ctx *ctx = container_of(file->private_data,
600 + struct rpivid_ctx, fh);
601 +
602 + mutex_lock(&dev->dev_mutex);
603 +
604 + v4l2_fh_del(&ctx->fh);
605 + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
606 +
607 + v4l2_ctrl_handler_free(&ctx->hdl);
608 + kfree(ctx->ctrls);
609 +
610 + v4l2_fh_exit(&ctx->fh);
611 + mutex_destroy(&ctx->ctx_mutex);
612 +
613 + kfree(ctx);
614 +
615 + mutex_unlock(&dev->dev_mutex);
616 +
617 + return 0;
618 +}
619 +
620 +static const struct v4l2_file_operations rpivid_fops = {
621 + .owner = THIS_MODULE,
622 + .open = rpivid_open,
623 + .release = rpivid_release,
624 + .poll = v4l2_m2m_fop_poll,
625 + .unlocked_ioctl = video_ioctl2,
626 + .mmap = v4l2_m2m_fop_mmap,
627 +};
628 +
629 +static const struct video_device rpivid_video_device = {
630 + .name = RPIVID_NAME,
631 + .vfl_dir = VFL_DIR_M2M,
632 + .fops = &rpivid_fops,
633 + .ioctl_ops = &rpivid_ioctl_ops,
634 + .minor = -1,
635 + .release = video_device_release_empty,
636 + .device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING,
637 +};
638 +
639 +static const struct v4l2_m2m_ops rpivid_m2m_ops = {
640 + .device_run = rpivid_device_run,
641 +};
642 +
643 +static const struct media_device_ops rpivid_m2m_media_ops = {
644 + .req_validate = rpivid_request_validate,
645 + .req_queue = v4l2_m2m_request_queue,
646 +};
647 +
648 +static int rpivid_probe(struct platform_device *pdev)
649 +{
650 + struct rpivid_dev *dev;
651 + struct video_device *vfd;
652 + int ret;
653 +
654 + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
655 + if (!dev)
656 + return -ENOMEM;
657 +
658 + dev->vfd = rpivid_video_device;
659 + dev->dev = &pdev->dev;
660 + dev->pdev = pdev;
661 +
662 + ret = 0;
663 + ret = rpivid_hw_probe(dev);
664 + if (ret) {
665 + dev_err(&pdev->dev, "Failed to probe hardware\n");
666 + return ret;
667 + }
668 +
669 + dev->dec_ops = &rpivid_dec_ops_h265;
670 +
671 + mutex_init(&dev->dev_mutex);
672 +
673 + ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
674 + if (ret) {
675 + dev_err(&pdev->dev, "Failed to register V4L2 device\n");
676 + return ret;
677 + }
678 +
679 + vfd = &dev->vfd;
680 + vfd->lock = &dev->dev_mutex;
681 + vfd->v4l2_dev = &dev->v4l2_dev;
682 +
683 + snprintf(vfd->name, sizeof(vfd->name), "%s", rpivid_video_device.name);
684 + video_set_drvdata(vfd, dev);
685 +
686 + dev->m2m_dev = v4l2_m2m_init(&rpivid_m2m_ops);
687 + if (IS_ERR(dev->m2m_dev)) {
688 + v4l2_err(&dev->v4l2_dev,
689 + "Failed to initialize V4L2 M2M device\n");
690 + ret = PTR_ERR(dev->m2m_dev);
691 +
692 + goto err_v4l2;
693 + }
694 +
695 + dev->mdev.dev = &pdev->dev;
696 + strscpy(dev->mdev.model, RPIVID_NAME, sizeof(dev->mdev.model));
697 + strscpy(dev->mdev.bus_info, "platform:" RPIVID_NAME,
698 + sizeof(dev->mdev.bus_info));
699 +
700 + media_device_init(&dev->mdev);
701 + dev->mdev.ops = &rpivid_m2m_media_ops;
702 + dev->v4l2_dev.mdev = &dev->mdev;
703 +
704 + ret = video_register_device(vfd, VFL_TYPE_VIDEO, video_nr);
705 + if (ret) {
706 + v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
707 + goto err_m2m;
708 + }
709 +
710 + v4l2_info(&dev->v4l2_dev,
711 + "Device registered as /dev/video%d\n", vfd->num);
712 +
713 + ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd,
714 + MEDIA_ENT_F_PROC_VIDEO_DECODER);
715 + if (ret) {
716 + v4l2_err(&dev->v4l2_dev,
717 + "Failed to initialize V4L2 M2M media controller\n");
718 + goto err_video;
719 + }
720 +
721 + ret = media_device_register(&dev->mdev);
722 + if (ret) {
723 + v4l2_err(&dev->v4l2_dev, "Failed to register media device\n");
724 + goto err_m2m_mc;
725 + }
726 +
727 + platform_set_drvdata(pdev, dev);
728 +
729 + return 0;
730 +
731 +err_m2m_mc:
732 + v4l2_m2m_unregister_media_controller(dev->m2m_dev);
733 +err_video:
734 + video_unregister_device(&dev->vfd);
735 +err_m2m:
736 + v4l2_m2m_release(dev->m2m_dev);
737 +err_v4l2:
738 + v4l2_device_unregister(&dev->v4l2_dev);
739 +
740 + return ret;
741 +}
742 +
743 +static int rpivid_remove(struct platform_device *pdev)
744 +{
745 + struct rpivid_dev *dev = platform_get_drvdata(pdev);
746 +
747 + if (media_devnode_is_registered(dev->mdev.devnode)) {
748 + media_device_unregister(&dev->mdev);
749 + v4l2_m2m_unregister_media_controller(dev->m2m_dev);
750 + media_device_cleanup(&dev->mdev);
751 + }
752 +
753 + v4l2_m2m_release(dev->m2m_dev);
754 + video_unregister_device(&dev->vfd);
755 + v4l2_device_unregister(&dev->v4l2_dev);
756 +
757 + rpivid_hw_remove(dev);
758 +
759 + return 0;
760 +}
761 +
762 +static const struct of_device_id rpivid_dt_match[] = {
763 + {
764 + .compatible = "raspberrypi,rpivid-vid-decoder",
765 + },
766 + { /* sentinel */ }
767 +};
768 +MODULE_DEVICE_TABLE(of, rpivid_dt_match);
769 +
770 +static struct platform_driver rpivid_driver = {
771 + .probe = rpivid_probe,
772 + .remove = rpivid_remove,
773 + .driver = {
774 + .name = RPIVID_NAME,
775 + .of_match_table = of_match_ptr(rpivid_dt_match),
776 + },
777 +};
778 +module_platform_driver(rpivid_driver);
779 +
780 +MODULE_LICENSE("GPL v2");
781 +MODULE_AUTHOR("John Cox <jc@kynesim.co.uk>");
782 +MODULE_DESCRIPTION("Raspberry Pi HEVC V4L2 driver");
783 --- /dev/null
784 +++ b/drivers/staging/media/rpivid/rpivid.h
785 @@ -0,0 +1,203 @@
786 +/* SPDX-License-Identifier: GPL-2.0 */
787 +/*
788 + * Raspberry Pi HEVC driver
789 + *
790 + * Copyright (C) 2020 Raspberry Pi (Trading) Ltd
791 + *
792 + * Based on the Cedrus VPU driver, that is:
793 + *
794 + * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
795 + * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
796 + * Copyright (C) 2018 Bootlin
797 + */
798 +
799 +#ifndef _RPIVID_H_
800 +#define _RPIVID_H_
801 +
802 +#include <linux/clk.h>
803 +#include <linux/platform_device.h>
804 +#include <media/v4l2-ctrls.h>
805 +#include <media/v4l2-device.h>
806 +#include <media/v4l2-mem2mem.h>
807 +#include <media/videobuf2-v4l2.h>
808 +#include <media/videobuf2-dma-contig.h>
809 +
810 +#define OPT_DEBUG_POLL_IRQ 0
811 +
812 +#define RPIVID_DEC_ENV_COUNT 6
813 +#define RPIVID_P1BUF_COUNT 3
814 +#define RPIVID_P2BUF_COUNT 3
815 +
816 +#define RPIVID_NAME "rpivid"
817 +
818 +#define RPIVID_CAPABILITY_UNTILED BIT(0)
819 +#define RPIVID_CAPABILITY_H265_DEC BIT(1)
820 +
821 +#define RPIVID_QUIRK_NO_DMA_OFFSET BIT(0)
822 +
823 +enum rpivid_irq_status {
824 + RPIVID_IRQ_NONE,
825 + RPIVID_IRQ_ERROR,
826 + RPIVID_IRQ_OK,
827 +};
828 +
829 +struct rpivid_control {
830 + struct v4l2_ctrl_config cfg;
831 + unsigned char required:1;
832 +};
833 +
834 +struct rpivid_h265_run {
835 + u32 slice_ents;
836 + const struct v4l2_ctrl_hevc_sps *sps;
837 + const struct v4l2_ctrl_hevc_pps *pps;
838 + const struct v4l2_ctrl_hevc_decode_params *dec;
839 + const struct v4l2_ctrl_hevc_slice_params *slice_params;
840 + const struct v4l2_ctrl_hevc_scaling_matrix *scaling_matrix;
841 +};
842 +
843 +struct rpivid_run {
844 + struct vb2_v4l2_buffer *src;
845 + struct vb2_v4l2_buffer *dst;
846 +
847 + struct rpivid_h265_run h265;
848 +};
849 +
850 +struct rpivid_buffer {
851 + struct v4l2_m2m_buffer m2m_buf;
852 +};
853 +
854 +struct rpivid_dec_state;
855 +struct rpivid_dec_env;
856 +
857 +struct rpivid_gptr {
858 + size_t size;
859 + __u8 *ptr;
860 + dma_addr_t addr;
861 + unsigned long attrs;
862 +};
863 +
864 +struct rpivid_dev;
865 +typedef void (*rpivid_irq_callback)(struct rpivid_dev *dev, void *ctx);
866 +
867 +struct rpivid_q_aux;
868 +#define RPIVID_AUX_ENT_COUNT VB2_MAX_FRAME
869 +
870 +struct rpivid_ctx {
871 + struct v4l2_fh fh;
872 + struct rpivid_dev *dev;
873 +
874 + struct v4l2_pix_format_mplane src_fmt;
875 + struct v4l2_pix_format_mplane dst_fmt;
876 + int dst_fmt_set;
877 +
878 + int src_stream_on;
879 + int dst_stream_on;
880 +
881 + // fatal_err is set if an error has occurred s.t. decode cannot
882 + // continue (such as running out of CMA)
883 + int fatal_err;
884 +
885 + /* Lock for queue operations */
886 + struct mutex ctx_mutex;
887 +
888 + struct v4l2_ctrl_handler hdl;
889 + struct v4l2_ctrl **ctrls;
890 +
891 + /* Decode state - stateless decoder my *** */
892 + /* state contains stuff that is only needed in phase0
893 + * it could be held in dec_env but that would be wasteful
894 + */
895 + struct rpivid_dec_state *state;
896 + struct rpivid_dec_env *dec0;
897 +
898 + /* Spinlock protecting dec_free */
899 + spinlock_t dec_lock;
900 + struct rpivid_dec_env *dec_free;
901 +
902 + struct rpivid_dec_env *dec_pool;
903 +
904 + unsigned int p1idx;
905 + atomic_t p1out;
906 + struct rpivid_gptr bitbufs[RPIVID_P1BUF_COUNT];
907 +
908 + /* *** Should be in dev *** */
909 + unsigned int p2idx;
910 + struct rpivid_gptr pu_bufs[RPIVID_P2BUF_COUNT];
911 + struct rpivid_gptr coeff_bufs[RPIVID_P2BUF_COUNT];
912 +
913 + /* Spinlock protecting aux_free */
914 + spinlock_t aux_lock;
915 + struct rpivid_q_aux *aux_free;
916 +
917 + struct rpivid_q_aux *aux_ents[RPIVID_AUX_ENT_COUNT];
918 +
919 + unsigned int colmv_stride;
920 + unsigned int colmv_picsize;
921 +};
922 +
923 +struct rpivid_dec_ops {
924 + void (*setup)(struct rpivid_ctx *ctx, struct rpivid_run *run);
925 + int (*start)(struct rpivid_ctx *ctx);
926 + void (*stop)(struct rpivid_ctx *ctx);
927 + void (*trigger)(struct rpivid_ctx *ctx);
928 +};
929 +
930 +struct rpivid_variant {
931 + unsigned int capabilities;
932 + unsigned int quirks;
933 + unsigned int mod_rate;
934 +};
935 +
936 +struct rpivid_hw_irq_ent;
937 +
938 +#define RPIVID_ICTL_ENABLE_UNLIMITED (-1)
939 +
940 +struct rpivid_hw_irq_ctrl {
941 + /* Spinlock protecting claim and tail */
942 + spinlock_t lock;
943 + struct rpivid_hw_irq_ent *claim;
944 + struct rpivid_hw_irq_ent *tail;
945 +
946 + /* Ent for pending irq - also prevents sched */
947 + struct rpivid_hw_irq_ent *irq;
948 + /* Non-zero => do not start a new job - outer layer sched pending */
949 + int no_sched;
950 + /* Enable count. -1 always OK, 0 do not sched, +ve shed & count down */
951 + int enable;
952 + /* Thread CB requested */
953 + bool thread_reqed;
954 +};
955 +
956 +struct rpivid_dev {
957 + struct v4l2_device v4l2_dev;
958 + struct video_device vfd;
959 + struct media_device mdev;
960 + struct media_pad pad[2];
961 + struct platform_device *pdev;
962 + struct device *dev;
963 + struct v4l2_m2m_dev *m2m_dev;
964 + const struct rpivid_dec_ops *dec_ops;
965 +
966 + /* Device file mutex */
967 + struct mutex dev_mutex;
968 +
969 + void __iomem *base_irq;
970 + void __iomem *base_h265;
971 +
972 + struct clk *clock;
973 + unsigned long max_clock_rate;
974 +
975 + int cache_align;
976 +
977 + struct rpivid_hw_irq_ctrl ic_active1;
978 + struct rpivid_hw_irq_ctrl ic_active2;
979 +};
980 +
981 +extern const struct rpivid_dec_ops rpivid_dec_ops_h265;
982 +extern const struct v4l2_ctrl_ops rpivid_hevc_sps_ctrl_ops;
983 +extern const struct v4l2_ctrl_ops rpivid_hevc_pps_ctrl_ops;
984 +
985 +struct v4l2_ctrl *rpivid_find_ctrl(struct rpivid_ctx *ctx, u32 id);
986 +void *rpivid_find_control_data(struct rpivid_ctx *ctx, u32 id);
987 +
988 +#endif
989 --- /dev/null
990 +++ b/drivers/staging/media/rpivid/rpivid_dec.c
991 @@ -0,0 +1,96 @@
992 +// SPDX-License-Identifier: GPL-2.0
993 +/*
994 + * Raspberry Pi HEVC driver
995 + *
996 + * Copyright (C) 2020 Raspberry Pi (Trading) Ltd
997 + *
998 + * Based on the Cedrus VPU driver, that is:
999 + *
1000 + * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
1001 + * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
1002 + * Copyright (C) 2018 Bootlin
1003 + */
1004 +
1005 +#include <media/v4l2-device.h>
1006 +#include <media/v4l2-ioctl.h>
1007 +#include <media/v4l2-event.h>
1008 +#include <media/v4l2-mem2mem.h>
1009 +
1010 +#include "rpivid.h"
1011 +#include "rpivid_dec.h"
1012 +
1013 +void rpivid_device_run(void *priv)
1014 +{
1015 + struct rpivid_ctx *const ctx = priv;
1016 + struct rpivid_dev *const dev = ctx->dev;
1017 + struct rpivid_run run = {};
1018 + struct media_request *src_req;
1019 +
1020 + run.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1021 + run.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1022 +
1023 + if (!run.src || !run.dst) {
1024 + v4l2_err(&dev->v4l2_dev, "%s: Missing buffer: src=%p, dst=%p\n",
1025 + __func__, run.src, run.dst);
1026 + goto fail;
1027 + }
1028 +
1029 + /* Apply request(s) controls */
1030 + src_req = run.src->vb2_buf.req_obj.req;
1031 + if (!src_req) {
1032 + v4l2_err(&dev->v4l2_dev, "%s: Missing request\n", __func__);
1033 + goto fail;
1034 + }
1035 +
1036 + v4l2_ctrl_request_setup(src_req, &ctx->hdl);
1037 +
1038 + switch (ctx->src_fmt.pixelformat) {
1039 + case V4L2_PIX_FMT_HEVC_SLICE:
1040 + {
1041 + const struct v4l2_ctrl *ctrl;
1042 +
1043 + run.h265.sps =
1044 + rpivid_find_control_data(ctx,
1045 + V4L2_CID_STATELESS_HEVC_SPS);
1046 + run.h265.pps =
1047 + rpivid_find_control_data(ctx,
1048 + V4L2_CID_STATELESS_HEVC_PPS);
1049 + run.h265.dec =
1050 + rpivid_find_control_data(ctx,
1051 + V4L2_CID_STATELESS_HEVC_DECODE_PARAMS);
1052 +
1053 + ctrl = rpivid_find_ctrl(ctx,
1054 + V4L2_CID_STATELESS_HEVC_SLICE_PARAMS);
1055 + if (!ctrl || !ctrl->elems) {
1056 + v4l2_err(&dev->v4l2_dev, "%s: Missing slice params\n",
1057 + __func__);
1058 + goto fail;
1059 + }
1060 + run.h265.slice_ents = ctrl->elems;
1061 + run.h265.slice_params = ctrl->p_cur.p;
1062 +
1063 + run.h265.scaling_matrix =
1064 + rpivid_find_control_data(ctx,
1065 + V4L2_CID_STATELESS_HEVC_SCALING_MATRIX);
1066 + break;
1067 + }
1068 +
1069 + default:
1070 + break;
1071 + }
1072 +
1073 + v4l2_m2m_buf_copy_metadata(run.src, run.dst, true);
1074 +
1075 + dev->dec_ops->setup(ctx, &run);
1076 +
1077 + /* Complete request(s) controls */
1078 + v4l2_ctrl_request_complete(src_req, &ctx->hdl);
1079 +
1080 + dev->dec_ops->trigger(ctx);
1081 + return;
1082 +
1083 +fail:
1084 + /* We really shouldn't get here but tidy up what we can */
1085 + v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx,
1086 + VB2_BUF_STATE_ERROR);
1087 +}
1088 --- /dev/null
1089 +++ b/drivers/staging/media/rpivid/rpivid_dec.h
1090 @@ -0,0 +1,19 @@
1091 +/* SPDX-License-Identifier: GPL-2.0 */
1092 +/*
1093 + * Raspberry Pi HEVC driver
1094 + *
1095 + * Copyright (C) 2020 Raspberry Pi (Trading) Ltd
1096 + *
1097 + * Based on the Cedrus VPU driver, that is:
1098 + *
1099 + * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
1100 + * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
1101 + * Copyright (C) 2018 Bootlin
1102 + */
1103 +
1104 +#ifndef _RPIVID_DEC_H_
1105 +#define _RPIVID_DEC_H_
1106 +
1107 +void rpivid_device_run(void *priv);
1108 +
1109 +#endif
1110 --- /dev/null
1111 +++ b/drivers/staging/media/rpivid/rpivid_h265.c
1112 @@ -0,0 +1,2698 @@
1113 +// SPDX-License-Identifier: GPL-2.0-or-later
1114 +/*
1115 + * Raspberry Pi HEVC driver
1116 + *
1117 + * Copyright (C) 2020 Raspberry Pi (Trading) Ltd
1118 + *
1119 + * Based on the Cedrus VPU driver, that is:
1120 + *
1121 + * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
1122 + * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
1123 + * Copyright (C) 2018 Bootlin
1124 + */
1125 +
1126 +#include <linux/delay.h>
1127 +#include <linux/types.h>
1128 +
1129 +#include <media/videobuf2-dma-contig.h>
1130 +
1131 +#include "rpivid.h"
1132 +#include "rpivid_hw.h"
1133 +#include "rpivid_video.h"
1134 +
1135 +#define DEBUG_TRACE_P1_CMD 0
1136 +#define DEBUG_TRACE_EXECUTION 0
1137 +
1138 +#define USE_REQUEST_PIN 1
1139 +
1140 +#if DEBUG_TRACE_EXECUTION
1141 +#define xtrace_in(dev_, de_)\
1142 + v4l2_info(&(dev_)->v4l2_dev, "%s[%d]: in\n", __func__,\
1143 + (de_) == NULL ? -1 : (de_)->decode_order)
1144 +#define xtrace_ok(dev_, de_)\
1145 + v4l2_info(&(dev_)->v4l2_dev, "%s[%d]: ok\n", __func__,\
1146 + (de_) == NULL ? -1 : (de_)->decode_order)
1147 +#define xtrace_fin(dev_, de_)\
1148 + v4l2_info(&(dev_)->v4l2_dev, "%s[%d]: finish\n", __func__,\
1149 + (de_) == NULL ? -1 : (de_)->decode_order)
1150 +#define xtrace_fail(dev_, de_)\
1151 + v4l2_info(&(dev_)->v4l2_dev, "%s[%d]: FAIL\n", __func__,\
1152 + (de_) == NULL ? -1 : (de_)->decode_order)
1153 +#else
1154 +#define xtrace_in(dev_, de_)
1155 +#define xtrace_ok(dev_, de_)
1156 +#define xtrace_fin(dev_, de_)
1157 +#define xtrace_fail(dev_, de_)
1158 +#endif
1159 +
1160 +enum hevc_slice_type {
1161 + HEVC_SLICE_B = 0,
1162 + HEVC_SLICE_P = 1,
1163 + HEVC_SLICE_I = 2,
1164 +};
1165 +
1166 +enum hevc_layer { L0 = 0, L1 = 1 };
1167 +
1168 +static int gptr_alloc(struct rpivid_dev *const dev, struct rpivid_gptr *gptr,
1169 + size_t size, unsigned long attrs)
1170 +{
1171 + gptr->size = size;
1172 + gptr->attrs = attrs;
1173 + gptr->addr = 0;
1174 + gptr->ptr = dma_alloc_attrs(dev->dev, gptr->size, &gptr->addr,
1175 + GFP_KERNEL, gptr->attrs);
1176 + return !gptr->ptr ? -ENOMEM : 0;
1177 +}
1178 +
1179 +static void gptr_free(struct rpivid_dev *const dev,
1180 + struct rpivid_gptr *const gptr)
1181 +{
1182 + if (gptr->ptr)
1183 + dma_free_attrs(dev->dev, gptr->size, gptr->ptr, gptr->addr,
1184 + gptr->attrs);
1185 + gptr->size = 0;
1186 + gptr->ptr = NULL;
1187 + gptr->addr = 0;
1188 + gptr->attrs = 0;
1189 +}
1190 +
1191 +/* Realloc but do not copy
1192 + *
1193 + * Frees then allocs.
1194 + * If the alloc fails then it attempts to re-allocote the old size
1195 + * On error then check gptr->ptr to determine if anything is currently
1196 + * allocated.
1197 + */
1198 +static int gptr_realloc_new(struct rpivid_dev * const dev,
1199 + struct rpivid_gptr * const gptr, size_t size)
1200 +{
1201 + const size_t old_size = gptr->size;
1202 +
1203 + if (size == gptr->size)
1204 + return 0;
1205 +
1206 + if (gptr->ptr)
1207 + dma_free_attrs(dev->dev, gptr->size, gptr->ptr,
1208 + gptr->addr, gptr->attrs);
1209 +
1210 + gptr->addr = 0;
1211 + gptr->size = size;
1212 + gptr->ptr = dma_alloc_attrs(dev->dev, gptr->size,
1213 + &gptr->addr, GFP_KERNEL, gptr->attrs);
1214 +
1215 + if (!gptr->ptr) {
1216 + gptr->addr = 0;
1217 + gptr->size = old_size;
1218 + gptr->ptr = dma_alloc_attrs(dev->dev, gptr->size,
1219 + &gptr->addr, GFP_KERNEL, gptr->attrs);
1220 + if (!gptr->ptr) {
1221 + gptr->size = 0;
1222 + gptr->addr = 0;
1223 + gptr->attrs = 0;
1224 + }
1225 + return -ENOMEM;
1226 + }
1227 +
1228 + return 0;
1229 +}
1230 +
1231 +static size_t next_size(const size_t x)
1232 +{
1233 + return rpivid_round_up_size(x + 1);
1234 +}
1235 +
1236 +#define NUM_SCALING_FACTORS 4064 /* Not a typo = 0xbe0 + 0x400 */
1237 +
1238 +#define AXI_BASE64 0
1239 +
1240 +#define PROB_BACKUP ((20 << 12) + (20 << 6) + (0 << 0))
1241 +#define PROB_RELOAD ((20 << 12) + (20 << 0) + (0 << 6))
1242 +
1243 +#define HEVC_MAX_REFS V4L2_HEVC_DPB_ENTRIES_NUM_MAX
1244 +
1245 +//////////////////////////////////////////////////////////////////////////////
1246 +
1247 +struct rpi_cmd {
1248 + u32 addr;
1249 + u32 data;
1250 +} __packed;
1251 +
1252 +struct rpivid_q_aux {
1253 + unsigned int refcount;
1254 + unsigned int q_index;
1255 + struct rpivid_q_aux *next;
1256 + struct rpivid_gptr col;
1257 +};
1258 +
1259 +//////////////////////////////////////////////////////////////////////////////
1260 +
1261 +enum rpivid_decode_state {
1262 + RPIVID_DECODE_SLICE_START,
1263 + RPIVID_DECODE_SLICE_CONTINUE,
1264 + RPIVID_DECODE_ERROR_CONTINUE,
1265 + RPIVID_DECODE_ERROR_DONE,
1266 + RPIVID_DECODE_PHASE1,
1267 + RPIVID_DECODE_END,
1268 +};
1269 +
1270 +struct rpivid_dec_env {
1271 + struct rpivid_ctx *ctx;
1272 + struct rpivid_dec_env *next;
1273 +
1274 + enum rpivid_decode_state state;
1275 + unsigned int decode_order;
1276 + int p1_status; /* P1 status - what to realloc */
1277 +
1278 + struct rpi_cmd *cmd_fifo;
1279 + unsigned int cmd_len, cmd_max;
1280 + unsigned int num_slice_msgs;
1281 + unsigned int pic_width_in_ctbs_y;
1282 + unsigned int pic_height_in_ctbs_y;
1283 + unsigned int dpbno_col;
1284 + u32 reg_slicestart;
1285 + int collocated_from_l0_flag;
1286 + /*
1287 + * Last CTB/Tile X,Y processed by (wpp_)entry_point
1288 + * Could be in _state as P0 only but needs updating where _state
1289 + * is const
1290 + */
1291 + unsigned int entry_ctb_x;
1292 + unsigned int entry_ctb_y;
1293 + unsigned int entry_tile_x;
1294 + unsigned int entry_tile_y;
1295 + unsigned int entry_qp;
1296 + u32 entry_slice;
1297 +
1298 + u32 rpi_config2;
1299 + u32 rpi_framesize;
1300 + u32 rpi_currpoc;
1301 +
1302 + struct vb2_v4l2_buffer *frame_buf; // Detached dest buffer
1303 + struct vb2_v4l2_buffer *src_buf; // Detached src buffer
1304 + unsigned int frame_c_offset;
1305 + unsigned int frame_stride;
1306 + dma_addr_t frame_addr;
1307 + dma_addr_t ref_addrs[16];
1308 + struct rpivid_q_aux *frame_aux;
1309 + struct rpivid_q_aux *col_aux;
1310 +
1311 + dma_addr_t cmd_addr;
1312 + size_t cmd_size;
1313 +
1314 + dma_addr_t pu_base_vc;
1315 + dma_addr_t coeff_base_vc;
1316 + u32 pu_stride;
1317 + u32 coeff_stride;
1318 +
1319 + struct rpivid_gptr *bit_copy_gptr;
1320 + size_t bit_copy_len;
1321 +
1322 +#define SLICE_MSGS_MAX (2 * HEVC_MAX_REFS * 8 + 3)
1323 + u16 slice_msgs[SLICE_MSGS_MAX];
1324 + u8 scaling_factors[NUM_SCALING_FACTORS];
1325 +
1326 +#if USE_REQUEST_PIN
1327 + struct media_request *req_pin;
1328 +#else
1329 + struct media_request_object *req_obj;
1330 +#endif
1331 + struct rpivid_hw_irq_ent irq_ent;
1332 +};
1333 +
1334 +#define member_size(type, member) sizeof(((type *)0)->member)
1335 +
1336 +struct rpivid_dec_state {
1337 + struct v4l2_ctrl_hevc_sps sps;
1338 + struct v4l2_ctrl_hevc_pps pps;
1339 +
1340 + // Helper vars & tables derived from sps/pps
1341 + unsigned int log2_ctb_size; /* log2 width of a CTB */
1342 + unsigned int ctb_width; /* Width in CTBs */
1343 + unsigned int ctb_height; /* Height in CTBs */
1344 + unsigned int ctb_size; /* Pic area in CTBs */
1345 + unsigned int tile_width; /* Width in tiles */
1346 + unsigned int tile_height; /* Height in tiles */
1347 +
1348 + int *col_bd;
1349 + int *row_bd;
1350 + int *ctb_addr_rs_to_ts;
1351 + int *ctb_addr_ts_to_rs;
1352 +
1353 + // Aux starage for DPB
1354 + // Hold refs
1355 + struct rpivid_q_aux *ref_aux[HEVC_MAX_REFS];
1356 + struct rpivid_q_aux *frame_aux;
1357 +
1358 + // Slice vars
1359 + unsigned int slice_idx;
1360 + bool slice_temporal_mvp; /* Slice flag but constant for frame */
1361 + bool use_aux;
1362 + bool mk_aux;
1363 +
1364 + // Temp vars per run - don't actually need to persist
1365 + u8 *src_buf;
1366 + dma_addr_t src_addr;
1367 + const struct v4l2_ctrl_hevc_slice_params *sh;
1368 + const struct v4l2_ctrl_hevc_decode_params *dec;
1369 + unsigned int nb_refs[2];
1370 + unsigned int slice_qp;
1371 + unsigned int max_num_merge_cand; // 0 if I-slice
1372 + bool dependent_slice_segment_flag;
1373 +
1374 + unsigned int start_ts; /* slice_segment_addr -> ts */
1375 + unsigned int start_ctb_x; /* CTB X,Y of start_ts */
1376 + unsigned int start_ctb_y;
1377 + unsigned int prev_ctb_x; /* CTB X,Y of start_ts - 1 */
1378 + unsigned int prev_ctb_y;
1379 +};
1380 +
1381 +#if !USE_REQUEST_PIN
1382 +static void dst_req_obj_release(struct media_request_object *object)
1383 +{
1384 + kfree(object);
1385 +}
1386 +
1387 +static const struct media_request_object_ops dst_req_obj_ops = {
1388 + .release = dst_req_obj_release,
1389 +};
1390 +#endif
1391 +
1392 +static inline int clip_int(const int x, const int lo, const int hi)
1393 +{
1394 + return x < lo ? lo : x > hi ? hi : x;
1395 +}
1396 +
1397 +//////////////////////////////////////////////////////////////////////////////
1398 +// Phase 1 command and bit FIFOs
1399 +
1400 +#if DEBUG_TRACE_P1_CMD
1401 +static int p1_z;
1402 +#endif
1403 +
1404 +static int cmds_check_space(struct rpivid_dec_env *const de, unsigned int n)
1405 +{
1406 + struct rpi_cmd *a;
1407 + unsigned int newmax;
1408 +
1409 + if (n > 0x100000) {
1410 + v4l2_err(&de->ctx->dev->v4l2_dev,
1411 + "%s: n %u implausible\n", __func__, n);
1412 + return -ENOMEM;
1413 + }
1414 +
1415 + if (de->cmd_len + n <= de->cmd_max)
1416 + return 0;
1417 +
1418 + newmax = roundup_pow_of_two(de->cmd_len + n);
1419 +
1420 + a = krealloc(de->cmd_fifo, newmax * sizeof(struct rpi_cmd),
1421 + GFP_KERNEL);
1422 + if (!a) {
1423 + v4l2_err(&de->ctx->dev->v4l2_dev,
1424 + "Failed cmd buffer realloc from %u to %u\n",
1425 + de->cmd_max, newmax);
1426 + return -ENOMEM;
1427 + }
1428 + v4l2_info(&de->ctx->dev->v4l2_dev,
1429 + "cmd buffer realloc from %u to %u\n", de->cmd_max, newmax);
1430 +
1431 + de->cmd_fifo = a;
1432 + de->cmd_max = newmax;
1433 + return 0;
1434 +}
1435 +
1436 +// ???? u16 addr - put in u32
1437 +static void p1_apb_write(struct rpivid_dec_env *const de, const u16 addr,
1438 + const u32 data)
1439 +{
1440 + if (de->cmd_len >= de->cmd_max) {
1441 + v4l2_err(&de->ctx->dev->v4l2_dev,
1442 + "%s: Overflow @ %d\n", __func__, de->cmd_len);
1443 + return;
1444 + }
1445 +
1446 + de->cmd_fifo[de->cmd_len].addr = addr;
1447 + de->cmd_fifo[de->cmd_len].data = data;
1448 +
1449 +#if DEBUG_TRACE_P1_CMD
1450 + if (++p1_z < 256) {
1451 + v4l2_info(&de->ctx->dev->v4l2_dev, "[%02x] %x %x\n",
1452 + de->cmd_len, addr, data);
1453 + }
1454 +#endif
1455 + de->cmd_len++;
1456 +}
1457 +
1458 +static int ctb_to_tile(unsigned int ctb, unsigned int *bd, int num)
1459 +{
1460 + int i;
1461 +
1462 + for (i = 1; ctb >= bd[i]; i++)
1463 + ; // bd[] has num+1 elements; bd[0]=0;
1464 + return i - 1;
1465 +}
1466 +
1467 +static unsigned int ctb_to_tile_x(const struct rpivid_dec_state *const s,
1468 + const unsigned int ctb_x)
1469 +{
1470 + return ctb_to_tile(ctb_x, s->col_bd, s->tile_width);
1471 +}
1472 +
1473 +static unsigned int ctb_to_tile_y(const struct rpivid_dec_state *const s,
1474 + const unsigned int ctb_y)
1475 +{
1476 + return ctb_to_tile(ctb_y, s->row_bd, s->tile_height);
1477 +}
1478 +
1479 +static void aux_q_free(struct rpivid_ctx *const ctx,
1480 + struct rpivid_q_aux *const aq)
1481 +{
1482 + struct rpivid_dev *const dev = ctx->dev;
1483 +
1484 + gptr_free(dev, &aq->col);
1485 + kfree(aq);
1486 +}
1487 +
1488 +static struct rpivid_q_aux *aux_q_alloc(struct rpivid_ctx *const ctx,
1489 + const unsigned int q_index)
1490 +{
1491 + struct rpivid_dev *const dev = ctx->dev;
1492 + struct rpivid_q_aux *const aq = kzalloc(sizeof(*aq), GFP_KERNEL);
1493 +
1494 + if (!aq)
1495 + return NULL;
1496 +
1497 + if (gptr_alloc(dev, &aq->col, ctx->colmv_picsize,
1498 + DMA_ATTR_FORCE_CONTIGUOUS | DMA_ATTR_NO_KERNEL_MAPPING))
1499 + goto fail;
1500 +
1501 + /*
1502 + * Spinlock not required as called in P0 only and
1503 + * aux checks done by _new
1504 + */
1505 + aq->refcount = 1;
1506 + aq->q_index = q_index;
1507 + ctx->aux_ents[q_index] = aq;
1508 + return aq;
1509 +
1510 +fail:
1511 + kfree(aq);
1512 + return NULL;
1513 +}
1514 +
1515 +static struct rpivid_q_aux *aux_q_new(struct rpivid_ctx *const ctx,
1516 + const unsigned int q_index)
1517 +{
1518 + struct rpivid_q_aux *aq;
1519 + unsigned long lockflags;
1520 +
1521 + spin_lock_irqsave(&ctx->aux_lock, lockflags);
1522 + /*
1523 + * If we already have this allocated to a slot then use that
1524 + * and assume that it will all work itself out in the pipeline
1525 + */
1526 + if ((aq = ctx->aux_ents[q_index]) != NULL) {
1527 + ++aq->refcount;
1528 + } else if ((aq = ctx->aux_free) != NULL) {
1529 + ctx->aux_free = aq->next;
1530 + aq->next = NULL;
1531 + aq->refcount = 1;
1532 + aq->q_index = q_index;
1533 + ctx->aux_ents[q_index] = aq;
1534 + }
1535 + spin_unlock_irqrestore(&ctx->aux_lock, lockflags);
1536 +
1537 + if (!aq)
1538 + aq = aux_q_alloc(ctx, q_index);
1539 +
1540 + return aq;
1541 +}
1542 +
1543 +static struct rpivid_q_aux *aux_q_ref_idx(struct rpivid_ctx *const ctx,
1544 + const int q_index)
1545 +{
1546 + unsigned long lockflags;
1547 + struct rpivid_q_aux *aq;
1548 +
1549 + spin_lock_irqsave(&ctx->aux_lock, lockflags);
1550 + if ((aq = ctx->aux_ents[q_index]) != NULL)
1551 + ++aq->refcount;
1552 + spin_unlock_irqrestore(&ctx->aux_lock, lockflags);
1553 +
1554 + return aq;
1555 +}
1556 +
1557 +static struct rpivid_q_aux *aux_q_ref(struct rpivid_ctx *const ctx,
1558 + struct rpivid_q_aux *const aq)
1559 +{
1560 + if (aq) {
1561 + unsigned long lockflags;
1562 +
1563 + spin_lock_irqsave(&ctx->aux_lock, lockflags);
1564 +
1565 + ++aq->refcount;
1566 +
1567 + spin_unlock_irqrestore(&ctx->aux_lock, lockflags);
1568 + }
1569 + return aq;
1570 +}
1571 +
1572 +static void aux_q_release(struct rpivid_ctx *const ctx,
1573 + struct rpivid_q_aux **const paq)
1574 +{
1575 + struct rpivid_q_aux *const aq = *paq;
1576 + unsigned long lockflags;
1577 +
1578 + if (!aq)
1579 + return;
1580 +
1581 + *paq = NULL;
1582 +
1583 + spin_lock_irqsave(&ctx->aux_lock, lockflags);
1584 + if (--aq->refcount == 0) {
1585 + aq->next = ctx->aux_free;
1586 + ctx->aux_free = aq;
1587 + ctx->aux_ents[aq->q_index] = NULL;
1588 + aq->q_index = ~0U;
1589 + }
1590 + spin_unlock_irqrestore(&ctx->aux_lock, lockflags);
1591 +}
1592 +
1593 +static void aux_q_init(struct rpivid_ctx *const ctx)
1594 +{
1595 + spin_lock_init(&ctx->aux_lock);
1596 + ctx->aux_free = NULL;
1597 +}
1598 +
1599 +static void aux_q_uninit(struct rpivid_ctx *const ctx)
1600 +{
1601 + struct rpivid_q_aux *aq;
1602 +
1603 + ctx->colmv_picsize = 0;
1604 + ctx->colmv_stride = 0;
1605 + while ((aq = ctx->aux_free) != NULL) {
1606 + ctx->aux_free = aq->next;
1607 + aux_q_free(ctx, aq);
1608 + }
1609 +}
1610 +
1611 +//////////////////////////////////////////////////////////////////////////////
1612 +
1613 +/*
1614 + * Initialisation process for context variables (CABAC init)
1615 + * see H.265 9.3.2.2
1616 + *
1617 + * N.B. If comparing with FFmpeg note that this h/w uses slightly different
1618 + * offsets to FFmpegs array
1619 + */
1620 +
1621 +/* Actual number of values */
1622 +#define RPI_PROB_VALS 154U
1623 +/* Rounded up as we copy words */
1624 +#define RPI_PROB_ARRAY_SIZE ((154 + 3) & ~3)
1625 +
1626 +/* Initialiser values - see tables H.265 9-4 through 9-42 */
1627 +static const u8 prob_init[3][156] = {
1628 + {
1629 + 153, 200, 139, 141, 157, 154, 154, 154, 154, 154, 184, 154, 154,
1630 + 154, 184, 63, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
1631 + 154, 154, 154, 153, 138, 138, 111, 141, 94, 138, 182, 154, 154,
1632 + 154, 140, 92, 137, 138, 140, 152, 138, 139, 153, 74, 149, 92,
1633 + 139, 107, 122, 152, 140, 179, 166, 182, 140, 227, 122, 197, 110,
1634 + 110, 124, 125, 140, 153, 125, 127, 140, 109, 111, 143, 127, 111,
1635 + 79, 108, 123, 63, 110, 110, 124, 125, 140, 153, 125, 127, 140,
1636 + 109, 111, 143, 127, 111, 79, 108, 123, 63, 91, 171, 134, 141,
1637 + 138, 153, 136, 167, 152, 152, 139, 139, 111, 111, 125, 110, 110,
1638 + 94, 124, 108, 124, 107, 125, 141, 179, 153, 125, 107, 125, 141,
1639 + 179, 153, 125, 107, 125, 141, 179, 153, 125, 140, 139, 182, 182,
1640 + 152, 136, 152, 136, 153, 136, 139, 111, 136, 139, 111, 0, 0,
1641 + },
1642 + {
1643 + 153, 185, 107, 139, 126, 197, 185, 201, 154, 149, 154, 139, 154,
1644 + 154, 154, 152, 110, 122, 95, 79, 63, 31, 31, 153, 153, 168,
1645 + 140, 198, 79, 124, 138, 94, 153, 111, 149, 107, 167, 154, 154,
1646 + 154, 154, 196, 196, 167, 154, 152, 167, 182, 182, 134, 149, 136,
1647 + 153, 121, 136, 137, 169, 194, 166, 167, 154, 167, 137, 182, 125,
1648 + 110, 94, 110, 95, 79, 125, 111, 110, 78, 110, 111, 111, 95,
1649 + 94, 108, 123, 108, 125, 110, 94, 110, 95, 79, 125, 111, 110,
1650 + 78, 110, 111, 111, 95, 94, 108, 123, 108, 121, 140, 61, 154,
1651 + 107, 167, 91, 122, 107, 167, 139, 139, 155, 154, 139, 153, 139,
1652 + 123, 123, 63, 153, 166, 183, 140, 136, 153, 154, 166, 183, 140,
1653 + 136, 153, 154, 166, 183, 140, 136, 153, 154, 170, 153, 123, 123,
1654 + 107, 121, 107, 121, 167, 151, 183, 140, 151, 183, 140, 0, 0,
1655 + },
1656 + {
1657 + 153, 160, 107, 139, 126, 197, 185, 201, 154, 134, 154, 139, 154,
1658 + 154, 183, 152, 154, 137, 95, 79, 63, 31, 31, 153, 153, 168,
1659 + 169, 198, 79, 224, 167, 122, 153, 111, 149, 92, 167, 154, 154,
1660 + 154, 154, 196, 167, 167, 154, 152, 167, 182, 182, 134, 149, 136,
1661 + 153, 121, 136, 122, 169, 208, 166, 167, 154, 152, 167, 182, 125,
1662 + 110, 124, 110, 95, 94, 125, 111, 111, 79, 125, 126, 111, 111,
1663 + 79, 108, 123, 93, 125, 110, 124, 110, 95, 94, 125, 111, 111,
1664 + 79, 125, 126, 111, 111, 79, 108, 123, 93, 121, 140, 61, 154,
1665 + 107, 167, 91, 107, 107, 167, 139, 139, 170, 154, 139, 153, 139,
1666 + 123, 123, 63, 124, 166, 183, 140, 136, 153, 154, 166, 183, 140,
1667 + 136, 153, 154, 166, 183, 140, 136, 153, 154, 170, 153, 138, 138,
1668 + 122, 121, 122, 121, 167, 151, 183, 140, 151, 183, 140, 0, 0,
1669 + },
1670 +};
1671 +
1672 +#define CMDS_WRITE_PROB ((RPI_PROB_ARRAY_SIZE / 4) + 1)
1673 +static void write_prob(struct rpivid_dec_env *const de,
1674 + const struct rpivid_dec_state *const s)
1675 +{
1676 + u8 dst[RPI_PROB_ARRAY_SIZE];
1677 +
1678 + const unsigned int init_type =
1679 + ((s->sh->flags & V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT) != 0 &&
1680 + s->sh->slice_type != HEVC_SLICE_I) ?
1681 + s->sh->slice_type + 1 :
1682 + 2 - s->sh->slice_type;
1683 + const u8 *p = prob_init[init_type];
1684 + const int q = clip_int(s->slice_qp, 0, 51);
1685 + unsigned int i;
1686 +
1687 + for (i = 0; i < RPI_PROB_VALS; i++) {
1688 + int init_value = p[i];
1689 + int m = (init_value >> 4) * 5 - 45;
1690 + int n = ((init_value & 15) << 3) - 16;
1691 + int pre = 2 * (((m * q) >> 4) + n) - 127;
1692 +
1693 + pre ^= pre >> 31;
1694 + if (pre > 124)
1695 + pre = 124 + (pre & 1);
1696 + dst[i] = pre;
1697 + }
1698 + for (i = RPI_PROB_VALS; i != RPI_PROB_ARRAY_SIZE; ++i)
1699 + dst[i] = 0;
1700 +
1701 + for (i = 0; i < RPI_PROB_ARRAY_SIZE; i += 4)
1702 + p1_apb_write(de, 0x1000 + i,
1703 + dst[i] + (dst[i + 1] << 8) + (dst[i + 2] << 16) +
1704 + (dst[i + 3] << 24));
1705 +
1706 + /*
1707 + * Having written the prob array back it up
1708 + * This is not always needed but is a small overhead that simplifies
1709 + * (and speeds up) some multi-tile & WPP scenarios
1710 + * There are no scenarios where having written a prob we ever want
1711 + * a previous (non-initial) state back
1712 + */
1713 + p1_apb_write(de, RPI_TRANSFER, PROB_BACKUP);
1714 +}
1715 +
1716 +#define CMDS_WRITE_SCALING_FACTORS NUM_SCALING_FACTORS
1717 +static void write_scaling_factors(struct rpivid_dec_env *const de)
1718 +{
1719 + int i;
1720 + const u8 *p = (u8 *)de->scaling_factors;
1721 +
1722 + for (i = 0; i < NUM_SCALING_FACTORS; i += 4, p += 4)
1723 + p1_apb_write(de, 0x2000 + i,
1724 + p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24));
1725 +}
1726 +
1727 +static inline __u32 dma_to_axi_addr(dma_addr_t a)
1728 +{
1729 + return (__u32)(a >> 6);
1730 +}
1731 +
1732 +#define CMDS_WRITE_BITSTREAM 4
1733 +static int write_bitstream(struct rpivid_dec_env *const de,
1734 + const struct rpivid_dec_state *const s)
1735 +{
1736 + // Note that FFmpeg V4L2 does not remove emulation prevention bytes,
1737 + // so this is matched in the configuration here.
1738 + // Whether that is the correct behaviour or not is not clear in the
1739 + // spec.
1740 + const int rpi_use_emu = 1;
1741 + unsigned int offset = s->sh->data_byte_offset;
1742 + const unsigned int len = (s->sh->bit_size + 7) / 8 - offset;
1743 + dma_addr_t addr;
1744 +
1745 + if (s->src_addr != 0) {
1746 + addr = s->src_addr + offset;
1747 + } else {
1748 + if (len + de->bit_copy_len > de->bit_copy_gptr->size) {
1749 + v4l2_warn(&de->ctx->dev->v4l2_dev,
1750 + "Bit copy buffer overflow: size=%zu, offset=%zu, len=%u\n",
1751 + de->bit_copy_gptr->size,
1752 + de->bit_copy_len, len);
1753 + return -ENOMEM;
1754 + }
1755 + memcpy(de->bit_copy_gptr->ptr + de->bit_copy_len,
1756 + s->src_buf + offset, len);
1757 + addr = de->bit_copy_gptr->addr + de->bit_copy_len;
1758 + de->bit_copy_len += (len + 63) & ~63;
1759 + }
1760 + offset = addr & 63;
1761 +
1762 + p1_apb_write(de, RPI_BFBASE, dma_to_axi_addr(addr));
1763 + p1_apb_write(de, RPI_BFNUM, len);
1764 + p1_apb_write(de, RPI_BFCONTROL, offset + (1 << 7)); // Stop
1765 + p1_apb_write(de, RPI_BFCONTROL, offset + (rpi_use_emu << 6));
1766 + return 0;
1767 +}
1768 +
1769 +//////////////////////////////////////////////////////////////////////////////
1770 +
1771 +/*
1772 + * The slice constant part of the slice register - width and height need to
1773 + * be ORed in later as they are per-tile / WPP-row
1774 + */
1775 +static u32 slice_reg_const(const struct rpivid_dec_state *const s)
1776 +{
1777 + u32 x = (s->max_num_merge_cand << 0) |
1778 + (s->nb_refs[L0] << 4) |
1779 + (s->nb_refs[L1] << 8) |
1780 + (s->sh->slice_type << 12);
1781 +
1782 + if (s->sh->flags & V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA)
1783 + x |= BIT(14);
1784 + if (s->sh->flags & V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA)
1785 + x |= BIT(15);
1786 + if (s->sh->slice_type == HEVC_SLICE_B &&
1787 + (s->sh->flags & V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO))
1788 + x |= BIT(16);
1789 +
1790 + return x;
1791 +}
1792 +
1793 +//////////////////////////////////////////////////////////////////////////////
1794 +
1795 +#define CMDS_NEW_SLICE_SEGMENT (4 + CMDS_WRITE_SCALING_FACTORS)
1796 +static void new_slice_segment(struct rpivid_dec_env *const de,
1797 + const struct rpivid_dec_state *const s)
1798 +{
1799 + const struct v4l2_ctrl_hevc_sps *const sps = &s->sps;
1800 + const struct v4l2_ctrl_hevc_pps *const pps = &s->pps;
1801 +
1802 + p1_apb_write(de,
1803 + RPI_SPS0,
1804 + ((sps->log2_min_luma_coding_block_size_minus3 + 3) << 0) |
1805 + (s->log2_ctb_size << 4) |
1806 + ((sps->log2_min_luma_transform_block_size_minus2 + 2)
1807 + << 8) |
1808 + ((sps->log2_min_luma_transform_block_size_minus2 + 2 +
1809 + sps->log2_diff_max_min_luma_transform_block_size)
1810 + << 12) |
1811 + ((sps->bit_depth_luma_minus8 + 8) << 16) |
1812 + ((sps->bit_depth_chroma_minus8 + 8) << 20) |
1813 + (sps->max_transform_hierarchy_depth_intra << 24) |
1814 + (sps->max_transform_hierarchy_depth_inter << 28));
1815 +
1816 + p1_apb_write(de,
1817 + RPI_SPS1,
1818 + ((sps->pcm_sample_bit_depth_luma_minus1 + 1) << 0) |
1819 + ((sps->pcm_sample_bit_depth_chroma_minus1 + 1) << 4) |
1820 + ((sps->log2_min_pcm_luma_coding_block_size_minus3 + 3)
1821 + << 8) |
1822 + ((sps->log2_min_pcm_luma_coding_block_size_minus3 + 3 +
1823 + sps->log2_diff_max_min_pcm_luma_coding_block_size)
1824 + << 12) |
1825 + (((sps->flags & V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE) ?
1826 + 0 : sps->chroma_format_idc) << 16) |
1827 + ((!!(sps->flags & V4L2_HEVC_SPS_FLAG_AMP_ENABLED)) << 18) |
1828 + ((!!(sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED)) << 19) |
1829 + ((!!(sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED))
1830 + << 20) |
1831 + ((!!(sps->flags &
1832 + V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED))
1833 + << 21));
1834 +
1835 + p1_apb_write(de,
1836 + RPI_PPS,
1837 + ((s->log2_ctb_size - pps->diff_cu_qp_delta_depth) << 0) |
1838 + ((!!(pps->flags & V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED))
1839 + << 4) |
1840 + ((!!(pps->flags &
1841 + V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED))
1842 + << 5) |
1843 + ((!!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED))
1844 + << 6) |
1845 + ((!!(pps->flags &
1846 + V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED))
1847 + << 7) |
1848 + (((pps->pps_cb_qp_offset + s->sh->slice_cb_qp_offset) & 255)
1849 + << 8) |
1850 + (((pps->pps_cr_qp_offset + s->sh->slice_cr_qp_offset) & 255)
1851 + << 16) |
1852 + ((!!(pps->flags &
1853 + V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED))
1854 + << 24));
1855 +
1856 + if (!s->start_ts &&
1857 + (sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED) != 0)
1858 + write_scaling_factors(de);
1859 +
1860 + if (!s->dependent_slice_segment_flag) {
1861 + int ctb_col = s->sh->slice_segment_addr %
1862 + de->pic_width_in_ctbs_y;
1863 + int ctb_row = s->sh->slice_segment_addr /
1864 + de->pic_width_in_ctbs_y;
1865 +
1866 + de->reg_slicestart = (ctb_col << 0) + (ctb_row << 16);
1867 + }
1868 +
1869 + p1_apb_write(de, RPI_SLICESTART, de->reg_slicestart);
1870 +}
1871 +
1872 +//////////////////////////////////////////////////////////////////////////////
1873 +// Slice messages
1874 +
1875 +static void msg_slice(struct rpivid_dec_env *const de, const u16 msg)
1876 +{
1877 + de->slice_msgs[de->num_slice_msgs++] = msg;
1878 +}
1879 +
1880 +#define CMDS_PROGRAM_SLICECMDS (1 + SLICE_MSGS_MAX)
1881 +static void program_slicecmds(struct rpivid_dec_env *const de,
1882 + const int sliceid)
1883 +{
1884 + int i;
1885 +
1886 + p1_apb_write(de, RPI_SLICECMDS, de->num_slice_msgs + (sliceid << 8));
1887 +
1888 + for (i = 0; i < de->num_slice_msgs; i++)
1889 + p1_apb_write(de, 0x4000 + 4 * i, de->slice_msgs[i] & 0xffff);
1890 +}
1891 +
1892 +// NoBackwardPredictionFlag 8.3.5
1893 +// Simply checks POCs
1894 +static int has_backward(const struct v4l2_hevc_dpb_entry *const dpb,
1895 + const __u8 *const idx, const unsigned int n,
1896 + const s32 cur_poc)
1897 +{
1898 + unsigned int i;
1899 +
1900 + for (i = 0; i < n; ++i) {
1901 + if (cur_poc < dpb[idx[i]].pic_order_cnt_val)
1902 + return 0;
1903 + }
1904 + return 1;
1905 +}
1906 +
1907 +static void pre_slice_decode(struct rpivid_dec_env *const de,
1908 + const struct rpivid_dec_state *const s)
1909 +{
1910 + const struct v4l2_ctrl_hevc_slice_params *const sh = s->sh;
1911 + const struct v4l2_ctrl_hevc_decode_params *const dec = s->dec;
1912 + int weighted_pred_flag, idx;
1913 + u16 cmd_slice;
1914 + unsigned int collocated_from_l0_flag;
1915 +
1916 + de->num_slice_msgs = 0;
1917 +
1918 + cmd_slice = 0;
1919 + if (sh->slice_type == HEVC_SLICE_I)
1920 + cmd_slice = 1;
1921 + if (sh->slice_type == HEVC_SLICE_P)
1922 + cmd_slice = 2;
1923 + if (sh->slice_type == HEVC_SLICE_B)
1924 + cmd_slice = 3;
1925 +
1926 + cmd_slice |= (s->nb_refs[L0] << 2) | (s->nb_refs[L1] << 6) |
1927 + (s->max_num_merge_cand << 11);
1928 +
1929 + collocated_from_l0_flag =
1930 + !s->slice_temporal_mvp ||
1931 + sh->slice_type != HEVC_SLICE_B ||
1932 + (sh->flags & V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0);
1933 + cmd_slice |= collocated_from_l0_flag << 14;
1934 +
1935 + if (sh->slice_type == HEVC_SLICE_P || sh->slice_type == HEVC_SLICE_B) {
1936 + // Flag to say all reference pictures are from the past
1937 + const int no_backward_pred_flag =
1938 + has_backward(dec->dpb, sh->ref_idx_l0, s->nb_refs[L0],
1939 + sh->slice_pic_order_cnt) &&
1940 + has_backward(dec->dpb, sh->ref_idx_l1, s->nb_refs[L1],
1941 + sh->slice_pic_order_cnt);
1942 + cmd_slice |= no_backward_pred_flag << 10;
1943 + msg_slice(de, cmd_slice);
1944 +
1945 + if (s->slice_temporal_mvp) {
1946 + const __u8 *const rpl = collocated_from_l0_flag ?
1947 + sh->ref_idx_l0 : sh->ref_idx_l1;
1948 + de->dpbno_col = rpl[sh->collocated_ref_idx];
1949 + //v4l2_info(&de->ctx->dev->v4l2_dev,
1950 + // "L0=%d col_ref_idx=%d,
1951 + // dpb_no=%d\n", collocated_from_l0_flag,
1952 + // sh->collocated_ref_idx, de->dpbno_col);
1953 + }
1954 +
1955 + // Write reference picture descriptions
1956 + weighted_pred_flag =
1957 + sh->slice_type == HEVC_SLICE_P ?
1958 + !!(s->pps.flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED) :
1959 + !!(s->pps.flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED);
1960 +
1961 + for (idx = 0; idx < s->nb_refs[L0]; ++idx) {
1962 + unsigned int dpb_no = sh->ref_idx_l0[idx];
1963 + //v4l2_info(&de->ctx->dev->v4l2_dev,
1964 + // "L0[%d]=dpb[%d]\n", idx, dpb_no);
1965 +
1966 + msg_slice(de,
1967 + dpb_no |
1968 + ((dec->dpb[dpb_no].flags &
1969 + V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE) ?
1970 + (1 << 4) : 0) |
1971 + (weighted_pred_flag ? (3 << 5) : 0));
1972 + msg_slice(de, dec->dpb[dpb_no].pic_order_cnt_val & 0xffff);
1973 +
1974 + if (weighted_pred_flag) {
1975 + const struct v4l2_hevc_pred_weight_table
1976 + *const w = &sh->pred_weight_table;
1977 + const int luma_weight_denom =
1978 + (1 << w->luma_log2_weight_denom);
1979 + const unsigned int chroma_log2_weight_denom =
1980 + (w->luma_log2_weight_denom +
1981 + w->delta_chroma_log2_weight_denom);
1982 + const int chroma_weight_denom =
1983 + (1 << chroma_log2_weight_denom);
1984 +
1985 + msg_slice(de,
1986 + w->luma_log2_weight_denom |
1987 + (((w->delta_luma_weight_l0[idx] +
1988 + luma_weight_denom) & 0x1ff)
1989 + << 3));
1990 + msg_slice(de, w->luma_offset_l0[idx] & 0xff);
1991 + msg_slice(de,
1992 + chroma_log2_weight_denom |
1993 + (((w->delta_chroma_weight_l0[idx][0] +
1994 + chroma_weight_denom) & 0x1ff)
1995 + << 3));
1996 + msg_slice(de,
1997 + w->chroma_offset_l0[idx][0] & 0xff);
1998 + msg_slice(de,
1999 + chroma_log2_weight_denom |
2000 + (((w->delta_chroma_weight_l0[idx][1] +
2001 + chroma_weight_denom) & 0x1ff)
2002 + << 3));
2003 + msg_slice(de,
2004 + w->chroma_offset_l0[idx][1] & 0xff);
2005 + }
2006 + }
2007 +
2008 + for (idx = 0; idx < s->nb_refs[L1]; ++idx) {
2009 + unsigned int dpb_no = sh->ref_idx_l1[idx];
2010 + //v4l2_info(&de->ctx->dev->v4l2_dev,
2011 + // "L1[%d]=dpb[%d]\n", idx, dpb_no);
2012 + msg_slice(de,
2013 + dpb_no |
2014 + ((dec->dpb[dpb_no].flags &
2015 + V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE) ?
2016 + (1 << 4) : 0) |
2017 + (weighted_pred_flag ? (3 << 5) : 0));
2018 + msg_slice(de, dec->dpb[dpb_no].pic_order_cnt_val & 0xffff);
2019 + if (weighted_pred_flag) {
2020 + const struct v4l2_hevc_pred_weight_table
2021 + *const w = &sh->pred_weight_table;
2022 + const int luma_weight_denom =
2023 + (1 << w->luma_log2_weight_denom);
2024 + const unsigned int chroma_log2_weight_denom =
2025 + (w->luma_log2_weight_denom +
2026 + w->delta_chroma_log2_weight_denom);
2027 + const int chroma_weight_denom =
2028 + (1 << chroma_log2_weight_denom);
2029 +
2030 + msg_slice(de,
2031 + w->luma_log2_weight_denom |
2032 + (((w->delta_luma_weight_l1[idx] +
2033 + luma_weight_denom) & 0x1ff) << 3));
2034 + msg_slice(de, w->luma_offset_l1[idx] & 0xff);
2035 + msg_slice(de,
2036 + chroma_log2_weight_denom |
2037 + (((w->delta_chroma_weight_l1[idx][0] +
2038 + chroma_weight_denom) & 0x1ff)
2039 + << 3));
2040 + msg_slice(de,
2041 + w->chroma_offset_l1[idx][0] & 0xff);
2042 + msg_slice(de,
2043 + chroma_log2_weight_denom |
2044 + (((w->delta_chroma_weight_l1[idx][1] +
2045 + chroma_weight_denom) & 0x1ff)
2046 + << 3));
2047 + msg_slice(de,
2048 + w->chroma_offset_l1[idx][1] & 0xff);
2049 + }
2050 + }
2051 + } else {
2052 + msg_slice(de, cmd_slice);
2053 + }
2054 +
2055 + msg_slice(de,
2056 + (sh->slice_beta_offset_div2 & 15) |
2057 + ((sh->slice_tc_offset_div2 & 15) << 4) |
2058 + ((sh->flags &
2059 + V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED) ?
2060 + 1 << 8 : 0) |
2061 + ((sh->flags &
2062 + V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED) ?
2063 + 1 << 9 : 0) |
2064 + ((s->pps.flags &
2065 + V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED) ?
2066 + 1 << 10 : 0));
2067 +
2068 + msg_slice(de, ((sh->slice_cr_qp_offset & 31) << 5) +
2069 + (sh->slice_cb_qp_offset & 31)); // CMD_QPOFF
2070 +}
2071 +
2072 +#define CMDS_WRITE_SLICE 1
2073 +static void write_slice(struct rpivid_dec_env *const de,
2074 + const struct rpivid_dec_state *const s,
2075 + const u32 slice_const,
2076 + const unsigned int ctb_col,
2077 + const unsigned int ctb_row)
2078 +{
2079 + const unsigned int cs = (1 << s->log2_ctb_size);
2080 + const unsigned int w_last = s->sps.pic_width_in_luma_samples & (cs - 1);
2081 + const unsigned int h_last = s->sps.pic_height_in_luma_samples & (cs - 1);
2082 +
2083 + p1_apb_write(de, RPI_SLICE,
2084 + slice_const |
2085 + ((ctb_col + 1 < s->ctb_width || !w_last ?
2086 + cs : w_last) << 17) |
2087 + ((ctb_row + 1 < s->ctb_height || !h_last ?
2088 + cs : h_last) << 24));
2089 +}
2090 +
2091 +#define PAUSE_MODE_WPP 1
2092 +#define PAUSE_MODE_TILE 0xffff
2093 +
2094 +/*
2095 + * N.B. This can be called to fill in data from the previous slice so must not
2096 + * use any state data that may change from slice to slice (e.g. qp)
2097 + */
2098 +#define CMDS_NEW_ENTRY_POINT (6 + CMDS_WRITE_SLICE)
2099 +static void new_entry_point(struct rpivid_dec_env *const de,
2100 + const struct rpivid_dec_state *const s,
2101 + const bool do_bte,
2102 + const bool reset_qp_y,
2103 + const u32 pause_mode,
2104 + const unsigned int tile_x,
2105 + const unsigned int tile_y,
2106 + const unsigned int ctb_col,
2107 + const unsigned int ctb_row,
2108 + const unsigned int slice_qp,
2109 + const u32 slice_const)
2110 +{
2111 + const unsigned int endx = s->col_bd[tile_x + 1] - 1;
2112 + const unsigned int endy = (pause_mode == PAUSE_MODE_WPP) ?
2113 + ctb_row : s->row_bd[tile_y + 1] - 1;
2114 +
2115 + p1_apb_write(de, RPI_TILESTART,
2116 + s->col_bd[tile_x] | (s->row_bd[tile_y] << 16));
2117 + p1_apb_write(de, RPI_TILEEND, endx | (endy << 16));
2118 +
2119 + if (do_bte)
2120 + p1_apb_write(de, RPI_BEGINTILEEND, endx | (endy << 16));
2121 +
2122 + write_slice(de, s, slice_const, endx, endy);
2123 +
2124 + if (reset_qp_y) {
2125 + unsigned int sps_qp_bd_offset =
2126 + 6 * s->sps.bit_depth_luma_minus8;
2127 +
2128 + p1_apb_write(de, RPI_QP, sps_qp_bd_offset + slice_qp);
2129 + }
2130 +
2131 + p1_apb_write(de, RPI_MODE,
2132 + pause_mode |
2133 + ((endx == s->ctb_width - 1) << 17) |
2134 + ((endy == s->ctb_height - 1) << 18));
2135 +
2136 + p1_apb_write(de, RPI_CONTROL, (ctb_col << 0) | (ctb_row << 16));
2137 +
2138 + de->entry_tile_x = tile_x;
2139 + de->entry_tile_y = tile_y;
2140 + de->entry_ctb_x = ctb_col;
2141 + de->entry_ctb_y = ctb_row;
2142 + de->entry_qp = slice_qp;
2143 + de->entry_slice = slice_const;
2144 +}
2145 +
2146 +//////////////////////////////////////////////////////////////////////////////
2147 +// Wavefront mode
2148 +
2149 +#define CMDS_WPP_PAUSE 4
2150 +static void wpp_pause(struct rpivid_dec_env *const de, int ctb_row)
2151 +{
2152 + p1_apb_write(de, RPI_STATUS, (ctb_row << 18) | 0x25);
2153 + p1_apb_write(de, RPI_TRANSFER, PROB_BACKUP);
2154 + p1_apb_write(de, RPI_MODE,
2155 + ctb_row == de->pic_height_in_ctbs_y - 1 ?
2156 + 0x70000 : 0x30000);
2157 + p1_apb_write(de, RPI_CONTROL, (ctb_row << 16) + 2);
2158 +}
2159 +
2160 +#define CMDS_WPP_ENTRY_FILL_1 (CMDS_WPP_PAUSE + 2 + CMDS_NEW_ENTRY_POINT)
2161 +static int wpp_entry_fill(struct rpivid_dec_env *const de,
2162 + const struct rpivid_dec_state *const s,
2163 + const unsigned int last_y)
2164 +{
2165 + int rv;
2166 + const unsigned int last_x = s->ctb_width - 1;
2167 +
2168 + rv = cmds_check_space(de, CMDS_WPP_ENTRY_FILL_1 *
2169 + (last_y - de->entry_ctb_y));
2170 + if (rv)
2171 + return rv;
2172 +
2173 + while (de->entry_ctb_y < last_y) {
2174 + /* wpp_entry_x/y set by wpp_entry_point */
2175 + if (s->ctb_width > 2)
2176 + wpp_pause(de, de->entry_ctb_y);
2177 + p1_apb_write(de, RPI_STATUS,
2178 + (de->entry_ctb_y << 18) | (last_x << 5) | 2);
2179 +
2180 + /* if width == 1 then the saved state is the init one */
2181 + if (s->ctb_width == 2)
2182 + p1_apb_write(de, RPI_TRANSFER, PROB_BACKUP);
2183 + else
2184 + p1_apb_write(de, RPI_TRANSFER, PROB_RELOAD);
2185 +
2186 + new_entry_point(de, s, false, true, PAUSE_MODE_WPP,
2187 + 0, 0, 0, de->entry_ctb_y + 1,
2188 + de->entry_qp, de->entry_slice);
2189 + }
2190 + return 0;
2191 +}
2192 +
2193 +static int wpp_end_previous_slice(struct rpivid_dec_env *const de,
2194 + const struct rpivid_dec_state *const s)
2195 +{
2196 + int rv;
2197 +
2198 + rv = wpp_entry_fill(de, s, s->prev_ctb_y);
2199 + if (rv)
2200 + return rv;
2201 +
2202 + rv = cmds_check_space(de, CMDS_WPP_PAUSE + 2);
2203 + if (rv)
2204 + return rv;
2205 +
2206 + if (de->entry_ctb_x < 2 &&
2207 + (de->entry_ctb_y < s->start_ctb_y || s->start_ctb_x > 2) &&
2208 + s->ctb_width > 2)
2209 + wpp_pause(de, s->prev_ctb_y);
2210 + p1_apb_write(de, RPI_STATUS,
2211 + 1 | (s->prev_ctb_x << 5) | (s->prev_ctb_y << 18));
2212 + if (s->start_ctb_x == 2 ||
2213 + (s->ctb_width == 2 && de->entry_ctb_y < s->start_ctb_y))
2214 + p1_apb_write(de, RPI_TRANSFER, PROB_BACKUP);
2215 + return 0;
2216 +}
2217 +
2218 +/* Only main profile supported so WPP => !Tiles which makes some of the
2219 + * next chunk code simpler
2220 + */
2221 +static int wpp_decode_slice(struct rpivid_dec_env *const de,
2222 + const struct rpivid_dec_state *const s,
2223 + bool last_slice)
2224 +{
2225 + bool reset_qp_y = true;
2226 + const bool indep = !s->dependent_slice_segment_flag;
2227 + int rv;
2228 +
2229 + if (s->start_ts) {
2230 + rv = wpp_end_previous_slice(de, s);
2231 + if (rv)
2232 + return rv;
2233 + }
2234 + pre_slice_decode(de, s);
2235 +
2236 + rv = cmds_check_space(de,
2237 + CMDS_WRITE_BITSTREAM +
2238 + CMDS_WRITE_PROB +
2239 + CMDS_PROGRAM_SLICECMDS +
2240 + CMDS_NEW_SLICE_SEGMENT +
2241 + CMDS_NEW_ENTRY_POINT);
2242 + if (rv)
2243 + return rv;
2244 +
2245 + rv = write_bitstream(de, s);
2246 + if (rv)
2247 + return rv;
2248 +
2249 + if (!s->start_ts || indep || s->ctb_width == 1)
2250 + write_prob(de, s);
2251 + else if (!s->start_ctb_x)
2252 + p1_apb_write(de, RPI_TRANSFER, PROB_RELOAD);
2253 + else
2254 + reset_qp_y = false;
2255 +
2256 + program_slicecmds(de, s->slice_idx);
2257 + new_slice_segment(de, s);
2258 + new_entry_point(de, s, indep, reset_qp_y, PAUSE_MODE_WPP,
2259 + 0, 0, s->start_ctb_x, s->start_ctb_y,
2260 + s->slice_qp, slice_reg_const(s));
2261 +
2262 + if (last_slice) {
2263 + rv = wpp_entry_fill(de, s, s->ctb_height - 1);
2264 + if (rv)
2265 + return rv;
2266 +
2267 + rv = cmds_check_space(de, CMDS_WPP_PAUSE + 1);
2268 + if (rv)
2269 + return rv;
2270 +
2271 + if (de->entry_ctb_x < 2 && s->ctb_width > 2)
2272 + wpp_pause(de, s->ctb_height - 1);
2273 +
2274 + p1_apb_write(de, RPI_STATUS,
2275 + 1 | ((s->ctb_width - 1) << 5) |
2276 + ((s->ctb_height - 1) << 18));
2277 + }
2278 + return 0;
2279 +}
2280 +
2281 +//////////////////////////////////////////////////////////////////////////////
2282 +// Tiles mode
2283 +
2284 +// Guarantees 1 cmd entry free on exit
2285 +static int tile_entry_fill(struct rpivid_dec_env *const de,
2286 + const struct rpivid_dec_state *const s,
2287 + const unsigned int last_tile_x,
2288 + const unsigned int last_tile_y)
2289 +{
2290 + while (de->entry_tile_y < last_tile_y ||
2291 + (de->entry_tile_y == last_tile_y &&
2292 + de->entry_tile_x < last_tile_x)) {
2293 + int rv;
2294 + unsigned int t_x = de->entry_tile_x;
2295 + unsigned int t_y = de->entry_tile_y;
2296 + const unsigned int last_x = s->col_bd[t_x + 1] - 1;
2297 + const unsigned int last_y = s->row_bd[t_y + 1] - 1;
2298 +
2299 + // One more than needed here
2300 + rv = cmds_check_space(de, CMDS_NEW_ENTRY_POINT + 3);
2301 + if (rv)
2302 + return rv;
2303 +
2304 + p1_apb_write(de, RPI_STATUS,
2305 + 2 | (last_x << 5) | (last_y << 18));
2306 + p1_apb_write(de, RPI_TRANSFER, PROB_RELOAD);
2307 +
2308 + // Inc tile
2309 + if (++t_x >= s->tile_width) {
2310 + t_x = 0;
2311 + ++t_y;
2312 + }
2313 +
2314 + new_entry_point(de, s, false, true, PAUSE_MODE_TILE,
2315 + t_x, t_y, s->col_bd[t_x], s->row_bd[t_y],
2316 + de->entry_qp, de->entry_slice);
2317 + }
2318 + return 0;
2319 +}
2320 +
2321 +/*
2322 + * Write STATUS register with expected end CTU address of previous slice
2323 + */
2324 +static int end_previous_slice(struct rpivid_dec_env *const de,
2325 + const struct rpivid_dec_state *const s)
2326 +{
2327 + int rv;
2328 +
2329 + rv = tile_entry_fill(de, s,
2330 + ctb_to_tile_x(s, s->prev_ctb_x),
2331 + ctb_to_tile_y(s, s->prev_ctb_y));
2332 + if (rv)
2333 + return rv;
2334 +
2335 + p1_apb_write(de, RPI_STATUS,
2336 + 1 | (s->prev_ctb_x << 5) | (s->prev_ctb_y << 18));
2337 + return 0;
2338 +}
2339 +
2340 +static int decode_slice(struct rpivid_dec_env *const de,
2341 + const struct rpivid_dec_state *const s,
2342 + bool last_slice)
2343 +{
2344 + bool reset_qp_y;
2345 + unsigned int tile_x = ctb_to_tile_x(s, s->start_ctb_x);
2346 + unsigned int tile_y = ctb_to_tile_y(s, s->start_ctb_y);
2347 + int rv;
2348 +
2349 + if (s->start_ts) {
2350 + rv = end_previous_slice(de, s);
2351 + if (rv)
2352 + return rv;
2353 + }
2354 +
2355 + rv = cmds_check_space(de,
2356 + CMDS_WRITE_BITSTREAM +
2357 + CMDS_WRITE_PROB +
2358 + CMDS_PROGRAM_SLICECMDS +
2359 + CMDS_NEW_SLICE_SEGMENT +
2360 + CMDS_NEW_ENTRY_POINT);
2361 + if (rv)
2362 + return rv;
2363 +
2364 + pre_slice_decode(de, s);
2365 + rv = write_bitstream(de, s);
2366 + if (rv)
2367 + return rv;
2368 +
2369 + reset_qp_y = !s->start_ts ||
2370 + !s->dependent_slice_segment_flag ||
2371 + tile_x != ctb_to_tile_x(s, s->prev_ctb_x) ||
2372 + tile_y != ctb_to_tile_y(s, s->prev_ctb_y);
2373 + if (reset_qp_y)
2374 + write_prob(de, s);
2375 +
2376 + program_slicecmds(de, s->slice_idx);
2377 + new_slice_segment(de, s);
2378 + new_entry_point(de, s, !s->dependent_slice_segment_flag, reset_qp_y,
2379 + PAUSE_MODE_TILE,
2380 + tile_x, tile_y, s->start_ctb_x, s->start_ctb_y,
2381 + s->slice_qp, slice_reg_const(s));
2382 +
2383 + /*
2384 + * If this is the last slice then fill in the other tile entries
2385 + * now, otherwise this will be done at the start of the next slice
2386 + * when it will be known where this slice finishes
2387 + */
2388 + if (last_slice) {
2389 + rv = tile_entry_fill(de, s,
2390 + s->tile_width - 1,
2391 + s->tile_height - 1);
2392 + if (rv)
2393 + return rv;
2394 + p1_apb_write(de, RPI_STATUS,
2395 + 1 | ((s->ctb_width - 1) << 5) |
2396 + ((s->ctb_height - 1) << 18));
2397 + }
2398 + return 0;
2399 +}
2400 +
2401 +//////////////////////////////////////////////////////////////////////////////
2402 +// Scaling factors
2403 +
2404 +static void expand_scaling_list(const unsigned int size_id,
2405 + u8 *const dst0,
2406 + const u8 *const src0, uint8_t dc)
2407 +{
2408 + u8 *d;
2409 + unsigned int x, y;
2410 +
2411 + switch (size_id) {
2412 + case 0:
2413 + memcpy(dst0, src0, 16);
2414 + break;
2415 + case 1:
2416 + memcpy(dst0, src0, 64);
2417 + break;
2418 + case 2:
2419 + d = dst0;
2420 +
2421 + for (y = 0; y != 16; y++) {
2422 + const u8 *s = src0 + (y >> 1) * 8;
2423 +
2424 + for (x = 0; x != 8; ++x) {
2425 + *d++ = *s;
2426 + *d++ = *s++;
2427 + }
2428 + }
2429 + dst0[0] = dc;
2430 + break;
2431 + default:
2432 + d = dst0;
2433 +
2434 + for (y = 0; y != 32; y++) {
2435 + const u8 *s = src0 + (y >> 2) * 8;
2436 +
2437 + for (x = 0; x != 8; ++x) {
2438 + *d++ = *s;
2439 + *d++ = *s;
2440 + *d++ = *s;
2441 + *d++ = *s++;
2442 + }
2443 + }
2444 + dst0[0] = dc;
2445 + break;
2446 + }
2447 +}
2448 +
2449 +static void populate_scaling_factors(const struct rpivid_run *const run,
2450 + struct rpivid_dec_env *const de,
2451 + const struct rpivid_dec_state *const s)
2452 +{
2453 + const struct v4l2_ctrl_hevc_scaling_matrix *const sl =
2454 + run->h265.scaling_matrix;
2455 + // Array of constants for scaling factors
2456 + static const u32 scaling_factor_offsets[4][6] = {
2457 + // MID0 MID1 MID2 MID3 MID4 MID5
2458 + // SID0 (4x4)
2459 + { 0x0000, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050 },
2460 + // SID1 (8x8)
2461 + { 0x0060, 0x00A0, 0x00E0, 0x0120, 0x0160, 0x01A0 },
2462 + // SID2 (16x16)
2463 + { 0x01E0, 0x02E0, 0x03E0, 0x04E0, 0x05E0, 0x06E0 },
2464 + // SID3 (32x32)
2465 + { 0x07E0, 0x0BE0, 0x0000, 0x0000, 0x0000, 0x0000 }
2466 + };
2467 +
2468 + unsigned int mid;
2469 +
2470 + for (mid = 0; mid < 6; mid++)
2471 + expand_scaling_list(0, de->scaling_factors +
2472 + scaling_factor_offsets[0][mid],
2473 + sl->scaling_list_4x4[mid], 0);
2474 + for (mid = 0; mid < 6; mid++)
2475 + expand_scaling_list(1, de->scaling_factors +
2476 + scaling_factor_offsets[1][mid],
2477 + sl->scaling_list_8x8[mid], 0);
2478 + for (mid = 0; mid < 6; mid++)
2479 + expand_scaling_list(2, de->scaling_factors +
2480 + scaling_factor_offsets[2][mid],
2481 + sl->scaling_list_16x16[mid],
2482 + sl->scaling_list_dc_coef_16x16[mid]);
2483 + for (mid = 0; mid < 2; mid++)
2484 + expand_scaling_list(3, de->scaling_factors +
2485 + scaling_factor_offsets[3][mid],
2486 + sl->scaling_list_32x32[mid],
2487 + sl->scaling_list_dc_coef_32x32[mid]);
2488 +}
2489 +
2490 +static void free_ps_info(struct rpivid_dec_state *const s)
2491 +{
2492 + kfree(s->ctb_addr_rs_to_ts);
2493 + s->ctb_addr_rs_to_ts = NULL;
2494 + kfree(s->ctb_addr_ts_to_rs);
2495 + s->ctb_addr_ts_to_rs = NULL;
2496 +
2497 + kfree(s->col_bd);
2498 + s->col_bd = NULL;
2499 + kfree(s->row_bd);
2500 + s->row_bd = NULL;
2501 +}
2502 +
2503 +static unsigned int tile_width(const struct rpivid_dec_state *const s,
2504 + const unsigned int t_x)
2505 +{
2506 + return s->col_bd[t_x + 1] - s->col_bd[t_x];
2507 +}
2508 +
2509 +static unsigned int tile_height(const struct rpivid_dec_state *const s,
2510 + const unsigned int t_y)
2511 +{
2512 + return s->row_bd[t_y + 1] - s->row_bd[t_y];
2513 +}
2514 +
2515 +static void fill_rs_to_ts(struct rpivid_dec_state *const s)
2516 +{
2517 + unsigned int ts = 0;
2518 + unsigned int t_y;
2519 + unsigned int tr_rs = 0;
2520 +
2521 + for (t_y = 0; t_y != s->tile_height; ++t_y) {
2522 + const unsigned int t_h = tile_height(s, t_y);
2523 + unsigned int t_x;
2524 + unsigned int tc_rs = tr_rs;
2525 +
2526 + for (t_x = 0; t_x != s->tile_width; ++t_x) {
2527 + const unsigned int t_w = tile_width(s, t_x);
2528 + unsigned int y;
2529 + unsigned int rs = tc_rs;
2530 +
2531 + for (y = 0; y != t_h; ++y) {
2532 + unsigned int x;
2533 +
2534 + for (x = 0; x != t_w; ++x) {
2535 + s->ctb_addr_rs_to_ts[rs + x] = ts;
2536 + s->ctb_addr_ts_to_rs[ts] = rs + x;
2537 + ++ts;
2538 + }
2539 + rs += s->ctb_width;
2540 + }
2541 + tc_rs += t_w;
2542 + }
2543 + tr_rs += t_h * s->ctb_width;
2544 + }
2545 +}
2546 +
2547 +static int updated_ps(struct rpivid_dec_state *const s)
2548 +{
2549 + unsigned int i;
2550 +
2551 + free_ps_info(s);
2552 +
2553 + // Inferred parameters
2554 + s->log2_ctb_size = s->sps.log2_min_luma_coding_block_size_minus3 + 3 +
2555 + s->sps.log2_diff_max_min_luma_coding_block_size;
2556 +
2557 + s->ctb_width = (s->sps.pic_width_in_luma_samples +
2558 + (1 << s->log2_ctb_size) - 1) >>
2559 + s->log2_ctb_size;
2560 + s->ctb_height = (s->sps.pic_height_in_luma_samples +
2561 + (1 << s->log2_ctb_size) - 1) >>
2562 + s->log2_ctb_size;
2563 + s->ctb_size = s->ctb_width * s->ctb_height;
2564 +
2565 + // Inferred parameters
2566 +
2567 + s->ctb_addr_rs_to_ts = kmalloc_array(s->ctb_size,
2568 + sizeof(*s->ctb_addr_rs_to_ts),
2569 + GFP_KERNEL);
2570 + if (!s->ctb_addr_rs_to_ts)
2571 + goto fail;
2572 + s->ctb_addr_ts_to_rs = kmalloc_array(s->ctb_size,
2573 + sizeof(*s->ctb_addr_ts_to_rs),
2574 + GFP_KERNEL);
2575 + if (!s->ctb_addr_ts_to_rs)
2576 + goto fail;
2577 +
2578 + if (!(s->pps.flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED)) {
2579 + s->tile_width = 1;
2580 + s->tile_height = 1;
2581 + } else {
2582 + s->tile_width = s->pps.num_tile_columns_minus1 + 1;
2583 + s->tile_height = s->pps.num_tile_rows_minus1 + 1;
2584 + }
2585 +
2586 + s->col_bd = kmalloc((s->tile_width + 1) * sizeof(*s->col_bd),
2587 + GFP_KERNEL);
2588 + if (!s->col_bd)
2589 + goto fail;
2590 + s->row_bd = kmalloc((s->tile_height + 1) * sizeof(*s->row_bd),
2591 + GFP_KERNEL);
2592 + if (!s->row_bd)
2593 + goto fail;
2594 +
2595 + s->col_bd[0] = 0;
2596 + for (i = 1; i < s->tile_width; i++)
2597 + s->col_bd[i] = s->col_bd[i - 1] +
2598 + s->pps.column_width_minus1[i - 1] + 1;
2599 + s->col_bd[s->tile_width] = s->ctb_width;
2600 +
2601 + s->row_bd[0] = 0;
2602 + for (i = 1; i < s->tile_height; i++)
2603 + s->row_bd[i] = s->row_bd[i - 1] +
2604 + s->pps.row_height_minus1[i - 1] + 1;
2605 + s->row_bd[s->tile_height] = s->ctb_height;
2606 +
2607 + fill_rs_to_ts(s);
2608 + return 0;
2609 +
2610 +fail:
2611 + free_ps_info(s);
2612 + /* Set invalid to force reload */
2613 + s->sps.pic_width_in_luma_samples = 0;
2614 + return -ENOMEM;
2615 +}
2616 +
2617 +static int write_cmd_buffer(struct rpivid_dev *const dev,
2618 + struct rpivid_dec_env *const de,
2619 + const struct rpivid_dec_state *const s)
2620 +{
2621 + const size_t cmd_size = ALIGN(de->cmd_len * sizeof(de->cmd_fifo[0]),
2622 + dev->cache_align);
2623 +
2624 + de->cmd_addr = dma_map_single(dev->dev, de->cmd_fifo,
2625 + cmd_size, DMA_TO_DEVICE);
2626 + if (dma_mapping_error(dev->dev, de->cmd_addr)) {
2627 + v4l2_err(&dev->v4l2_dev,
2628 + "Map cmd buffer (%zu): FAILED\n", cmd_size);
2629 + return -ENOMEM;
2630 + }
2631 + de->cmd_size = cmd_size;
2632 + return 0;
2633 +}
2634 +
2635 +static void setup_colmv(struct rpivid_ctx *const ctx, struct rpivid_run *run,
2636 + struct rpivid_dec_state *const s)
2637 +{
2638 + ctx->colmv_stride = ALIGN(s->sps.pic_width_in_luma_samples, 64);
2639 + ctx->colmv_picsize = ctx->colmv_stride *
2640 + (ALIGN(s->sps.pic_height_in_luma_samples, 64) >> 4);
2641 +}
2642 +
2643 +// Can be called from irq context
2644 +static struct rpivid_dec_env *dec_env_new(struct rpivid_ctx *const ctx)
2645 +{
2646 + struct rpivid_dec_env *de;
2647 + unsigned long lock_flags;
2648 +
2649 + spin_lock_irqsave(&ctx->dec_lock, lock_flags);
2650 +
2651 + de = ctx->dec_free;
2652 + if (de) {
2653 + ctx->dec_free = de->next;
2654 + de->next = NULL;
2655 + de->state = RPIVID_DECODE_SLICE_START;
2656 + }
2657 +
2658 + spin_unlock_irqrestore(&ctx->dec_lock, lock_flags);
2659 + return de;
2660 +}
2661 +
2662 +// Can be called from irq context
2663 +static void dec_env_delete(struct rpivid_dec_env *const de)
2664 +{
2665 + struct rpivid_ctx * const ctx = de->ctx;
2666 + unsigned long lock_flags;
2667 +
2668 + if (de->cmd_size) {
2669 + dma_unmap_single(ctx->dev->dev, de->cmd_addr, de->cmd_size,
2670 + DMA_TO_DEVICE);
2671 + de->cmd_size = 0;
2672 + }
2673 +
2674 + aux_q_release(ctx, &de->frame_aux);
2675 + aux_q_release(ctx, &de->col_aux);
2676 +
2677 + spin_lock_irqsave(&ctx->dec_lock, lock_flags);
2678 +
2679 + de->state = RPIVID_DECODE_END;
2680 + de->next = ctx->dec_free;
2681 + ctx->dec_free = de;
2682 +
2683 + spin_unlock_irqrestore(&ctx->dec_lock, lock_flags);
2684 +}
2685 +
2686 +static void dec_env_uninit(struct rpivid_ctx *const ctx)
2687 +{
2688 + unsigned int i;
2689 +
2690 + if (ctx->dec_pool) {
2691 + for (i = 0; i != RPIVID_DEC_ENV_COUNT; ++i) {
2692 + struct rpivid_dec_env *const de = ctx->dec_pool + i;
2693 +
2694 + kfree(de->cmd_fifo);
2695 + }
2696 +
2697 + kfree(ctx->dec_pool);
2698 + }
2699 +
2700 + ctx->dec_pool = NULL;
2701 + ctx->dec_free = NULL;
2702 +}
2703 +
2704 +static int dec_env_init(struct rpivid_ctx *const ctx)
2705 +{
2706 + unsigned int i;
2707 +
2708 + ctx->dec_pool = kzalloc(sizeof(*ctx->dec_pool) * RPIVID_DEC_ENV_COUNT,
2709 + GFP_KERNEL);
2710 + if (!ctx->dec_pool)
2711 + return -1;
2712 +
2713 + spin_lock_init(&ctx->dec_lock);
2714 +
2715 + // Build free chain
2716 + ctx->dec_free = ctx->dec_pool;
2717 + for (i = 0; i != RPIVID_DEC_ENV_COUNT - 1; ++i)
2718 + ctx->dec_pool[i].next = ctx->dec_pool + i + 1;
2719 +
2720 + // Fill in other bits
2721 + for (i = 0; i != RPIVID_DEC_ENV_COUNT; ++i) {
2722 + struct rpivid_dec_env *const de = ctx->dec_pool + i;
2723 +
2724 + de->ctx = ctx;
2725 + de->decode_order = i;
2726 +// de->cmd_max = 1024;
2727 + de->cmd_max = 8096;
2728 + de->cmd_fifo = kmalloc_array(de->cmd_max,
2729 + sizeof(struct rpi_cmd),
2730 + GFP_KERNEL);
2731 + if (!de->cmd_fifo)
2732 + goto fail;
2733 + }
2734 +
2735 + return 0;
2736 +
2737 +fail:
2738 + dec_env_uninit(ctx);
2739 + return -1;
2740 +}
2741 +
2742 +// Assume that we get exactly the same DPB for every slice
2743 +// it makes no real sense otherwise
2744 +#if V4L2_HEVC_DPB_ENTRIES_NUM_MAX > 16
2745 +#error HEVC_DPB_ENTRIES > h/w slots
2746 +#endif
2747 +
2748 +static u32 mk_config2(const struct rpivid_dec_state *const s)
2749 +{
2750 + const struct v4l2_ctrl_hevc_sps *const sps = &s->sps;
2751 + const struct v4l2_ctrl_hevc_pps *const pps = &s->pps;
2752 + u32 c;
2753 + // BitDepthY
2754 + c = (sps->bit_depth_luma_minus8 + 8) << 0;
2755 + // BitDepthC
2756 + c |= (sps->bit_depth_chroma_minus8 + 8) << 4;
2757 + // BitDepthY
2758 + if (sps->bit_depth_luma_minus8)
2759 + c |= BIT(8);
2760 + // BitDepthC
2761 + if (sps->bit_depth_chroma_minus8)
2762 + c |= BIT(9);
2763 + c |= s->log2_ctb_size << 10;
2764 + if (pps->flags & V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED)
2765 + c |= BIT(13);
2766 + if (sps->flags & V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED)
2767 + c |= BIT(14);
2768 + if (s->mk_aux)
2769 + c |= BIT(15); /* Write motion vectors to external memory */
2770 + c |= (pps->log2_parallel_merge_level_minus2 + 2) << 16;
2771 + if (s->slice_temporal_mvp)
2772 + c |= BIT(19);
2773 + if (sps->flags & V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED)
2774 + c |= BIT(20);
2775 + c |= (pps->pps_cb_qp_offset & 31) << 21;
2776 + c |= (pps->pps_cr_qp_offset & 31) << 26;
2777 + return c;
2778 +}
2779 +
2780 +static inline bool is_ref_unit_type(const unsigned int nal_unit_type)
2781 +{
2782 + /* From Table 7-1
2783 + * True for 1, 3, 5, 7, 9, 11, 13, 15
2784 + */
2785 + return (nal_unit_type & ~0xe) != 0;
2786 +}
2787 +
2788 +static void rpivid_h265_setup(struct rpivid_ctx *ctx, struct rpivid_run *run)
2789 +{
2790 + struct rpivid_dev *const dev = ctx->dev;
2791 + const struct v4l2_ctrl_hevc_decode_params *const dec =
2792 + run->h265.dec;
2793 + /* sh0 used where slice header contents should be constant over all
2794 + * slices, or first slice of frame
2795 + */
2796 + const struct v4l2_ctrl_hevc_slice_params *const sh0 =
2797 + run->h265.slice_params;
2798 + struct rpivid_q_aux *dpb_q_aux[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
2799 + struct rpivid_dec_state *const s = ctx->state;
2800 + struct vb2_queue *vq;
2801 + struct rpivid_dec_env *de = ctx->dec0;
2802 + unsigned int prev_rs;
2803 + unsigned int i;
2804 + int rv;
2805 + bool slice_temporal_mvp;
2806 + bool frame_end;
2807 +
2808 + xtrace_in(dev, de);
2809 + s->sh = NULL; // Avoid use until in the slice loop
2810 +
2811 + frame_end =
2812 + ((run->src->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF) == 0);
2813 +
2814 + slice_temporal_mvp = (sh0->flags &
2815 + V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED);
2816 +
2817 + if (de && de->state != RPIVID_DECODE_END) {
2818 + switch (de->state) {
2819 + case RPIVID_DECODE_SLICE_CONTINUE:
2820 + // Expected state
2821 + break;
2822 + default:
2823 + v4l2_err(&dev->v4l2_dev, "%s: Unexpected state: %d\n",
2824 + __func__, de->state);
2825 + fallthrough;
2826 + case RPIVID_DECODE_ERROR_CONTINUE:
2827 + // Uncleared error - fail now
2828 + goto fail;
2829 + }
2830 +
2831 + if (s->slice_temporal_mvp != slice_temporal_mvp) {
2832 + v4l2_warn(&dev->v4l2_dev,
2833 + "Slice Temporal MVP non-constant\n");
2834 + goto fail;
2835 + }
2836 + } else {
2837 + /* Frame start */
2838 + unsigned int ctb_size_y;
2839 + bool sps_changed = false;
2840 +
2841 + if (memcmp(&s->sps, run->h265.sps, sizeof(s->sps)) != 0) {
2842 + /* SPS changed */
2843 + v4l2_info(&dev->v4l2_dev, "SPS changed\n");
2844 + memcpy(&s->sps, run->h265.sps, sizeof(s->sps));
2845 + sps_changed = true;
2846 + }
2847 + if (sps_changed ||
2848 + memcmp(&s->pps, run->h265.pps, sizeof(s->pps)) != 0) {
2849 + /* SPS changed */
2850 + v4l2_info(&dev->v4l2_dev, "PPS changed\n");
2851 + memcpy(&s->pps, run->h265.pps, sizeof(s->pps));
2852 +
2853 + /* Recalc stuff as required */
2854 + rv = updated_ps(s);
2855 + if (rv)
2856 + goto fail;
2857 + }
2858 +
2859 + de = dec_env_new(ctx);
2860 + if (!de) {
2861 + v4l2_err(&dev->v4l2_dev,
2862 + "Failed to find free decode env\n");
2863 + goto fail;
2864 + }
2865 + ctx->dec0 = de;
2866 +
2867 + ctb_size_y =
2868 + 1U << (s->sps.log2_min_luma_coding_block_size_minus3 +
2869 + 3 +
2870 + s->sps.log2_diff_max_min_luma_coding_block_size);
2871 +
2872 + de->pic_width_in_ctbs_y =
2873 + (s->sps.pic_width_in_luma_samples + ctb_size_y - 1) /
2874 + ctb_size_y; // 7-15
2875 + de->pic_height_in_ctbs_y =
2876 + (s->sps.pic_height_in_luma_samples + ctb_size_y - 1) /
2877 + ctb_size_y; // 7-17
2878 + de->cmd_len = 0;
2879 + de->dpbno_col = ~0U;
2880 +
2881 + de->bit_copy_gptr = ctx->bitbufs + ctx->p1idx;
2882 + de->bit_copy_len = 0;
2883 +
2884 + de->frame_c_offset = ctx->dst_fmt.height * 128;
2885 + de->frame_stride = ctx->dst_fmt.plane_fmt[0].bytesperline * 128;
2886 + de->frame_addr =
2887 + vb2_dma_contig_plane_dma_addr(&run->dst->vb2_buf, 0);
2888 + de->frame_aux = NULL;
2889 +
2890 + if (s->sps.bit_depth_luma_minus8 !=
2891 + s->sps.bit_depth_chroma_minus8) {
2892 + v4l2_warn(&dev->v4l2_dev,
2893 + "Chroma depth (%d) != Luma depth (%d)\n",
2894 + s->sps.bit_depth_chroma_minus8 + 8,
2895 + s->sps.bit_depth_luma_minus8 + 8);
2896 + goto fail;
2897 + }
2898 + if (s->sps.bit_depth_luma_minus8 == 0) {
2899 + if (ctx->dst_fmt.pixelformat !=
2900 + V4L2_PIX_FMT_NV12_COL128) {
2901 + v4l2_err(&dev->v4l2_dev,
2902 + "Pixel format %#x != NV12_COL128 for 8-bit output",
2903 + ctx->dst_fmt.pixelformat);
2904 + goto fail;
2905 + }
2906 + } else if (s->sps.bit_depth_luma_minus8 == 2) {
2907 + if (ctx->dst_fmt.pixelformat !=
2908 + V4L2_PIX_FMT_NV12_10_COL128) {
2909 + v4l2_err(&dev->v4l2_dev,
2910 + "Pixel format %#x != NV12_10_COL128 for 10-bit output",
2911 + ctx->dst_fmt.pixelformat);
2912 + goto fail;
2913 + }
2914 + } else {
2915 + v4l2_warn(&dev->v4l2_dev,
2916 + "Luma depth (%d) unsupported\n",
2917 + s->sps.bit_depth_luma_minus8 + 8);
2918 + goto fail;
2919 + }
2920 + if (run->dst->vb2_buf.num_planes != 1) {
2921 + v4l2_warn(&dev->v4l2_dev, "Capture planes (%d) != 1\n",
2922 + run->dst->vb2_buf.num_planes);
2923 + goto fail;
2924 + }
2925 + if (run->dst->planes[0].length <
2926 + ctx->dst_fmt.plane_fmt[0].sizeimage) {
2927 + v4l2_warn(&dev->v4l2_dev,
2928 + "Capture plane[0] length (%d) < sizeimage (%d)\n",
2929 + run->dst->planes[0].length,
2930 + ctx->dst_fmt.plane_fmt[0].sizeimage);
2931 + goto fail;
2932 + }
2933 +
2934 + // Fill in ref planes with our address s.t. if we mess
2935 + // up refs somehow then we still have a valid address
2936 + // entry
2937 + for (i = 0; i != 16; ++i)
2938 + de->ref_addrs[i] = de->frame_addr;
2939 +
2940 + /*
2941 + * Stash initial temporal_mvp flag
2942 + * This must be the same for all pic slices (7.4.7.1)
2943 + */
2944 + s->slice_temporal_mvp = slice_temporal_mvp;
2945 +
2946 + /*
2947 + * Need Aux ents for all (ref) DPB ents if temporal MV could
2948 + * be enabled for any pic
2949 + */
2950 + s->use_aux = ((s->sps.flags &
2951 + V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED) != 0);
2952 + s->mk_aux = s->use_aux &&
2953 + (s->sps.sps_max_sub_layers_minus1 >= sh0->nuh_temporal_id_plus1 ||
2954 + is_ref_unit_type(sh0->nal_unit_type));
2955 +
2956 + // Phase 2 reg pre-calc
2957 + de->rpi_config2 = mk_config2(s);
2958 + de->rpi_framesize = (s->sps.pic_height_in_luma_samples << 16) |
2959 + s->sps.pic_width_in_luma_samples;
2960 + de->rpi_currpoc = sh0->slice_pic_order_cnt;
2961 +
2962 + if (s->sps.flags &
2963 + V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED) {
2964 + setup_colmv(ctx, run, s);
2965 + }
2966 +
2967 + s->slice_idx = 0;
2968 +
2969 + if (sh0->slice_segment_addr != 0) {
2970 + v4l2_warn(&dev->v4l2_dev,
2971 + "New frame but segment_addr=%d\n",
2972 + sh0->slice_segment_addr);
2973 + goto fail;
2974 + }
2975 +
2976 + /* Allocate a bitbuf if we need one - don't need one if single
2977 + * slice as we can use the src buf directly
2978 + */
2979 + if (!frame_end && !de->bit_copy_gptr->ptr) {
2980 + size_t bits_alloc;
2981 + bits_alloc = rpivid_bit_buf_size(s->sps.pic_width_in_luma_samples,
2982 + s->sps.pic_height_in_luma_samples,
2983 + s->sps.bit_depth_luma_minus8);
2984 +
2985 + if (gptr_alloc(dev, de->bit_copy_gptr,
2986 + bits_alloc,
2987 + DMA_ATTR_FORCE_CONTIGUOUS) != 0) {
2988 + v4l2_err(&dev->v4l2_dev,
2989 + "Unable to alloc buf (%zu) for bit copy\n",
2990 + bits_alloc);
2991 + goto fail;
2992 + }
2993 + v4l2_info(&dev->v4l2_dev,
2994 + "Alloc buf (%zu) for bit copy OK\n",
2995 + bits_alloc);
2996 + }
2997 + }
2998 +
2999 + // Either map src buffer or use directly
3000 + s->src_addr = 0;
3001 + s->src_buf = NULL;
3002 +
3003 + if (frame_end)
3004 + s->src_addr = vb2_dma_contig_plane_dma_addr(&run->src->vb2_buf,
3005 + 0);
3006 + if (!s->src_addr)
3007 + s->src_buf = vb2_plane_vaddr(&run->src->vb2_buf, 0);
3008 + if (!s->src_addr && !s->src_buf) {
3009 + v4l2_err(&dev->v4l2_dev, "Failed to map src buffer\n");
3010 + goto fail;
3011 + }
3012 +
3013 + // Pre calc a few things
3014 + s->dec = dec;
3015 + for (i = 0; i != run->h265.slice_ents; ++i) {
3016 + const struct v4l2_ctrl_hevc_slice_params *const sh = sh0 + i;
3017 + const bool last_slice = frame_end && i + 1 == run->h265.slice_ents;
3018 +
3019 + s->sh = sh;
3020 +
3021 + if (run->src->planes[0].bytesused < (sh->bit_size + 7) / 8) {
3022 + v4l2_warn(&dev->v4l2_dev,
3023 + "Bit size %d > bytesused %d\n",
3024 + sh->bit_size, run->src->planes[0].bytesused);
3025 + goto fail;
3026 + }
3027 + if (sh->data_byte_offset >= sh->bit_size / 8) {
3028 + v4l2_warn(&dev->v4l2_dev,
3029 + "Bit size %u < Byte offset %u * 8\n",
3030 + sh->bit_size, sh->data_byte_offset);
3031 + goto fail;
3032 + }
3033 +
3034 + s->slice_qp = 26 + s->pps.init_qp_minus26 + sh->slice_qp_delta;
3035 + s->max_num_merge_cand = sh->slice_type == HEVC_SLICE_I ?
3036 + 0 :
3037 + (5 - sh->five_minus_max_num_merge_cand);
3038 + s->dependent_slice_segment_flag =
3039 + ((sh->flags &
3040 + V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT) != 0);
3041 +
3042 + s->nb_refs[0] = (sh->slice_type == HEVC_SLICE_I) ?
3043 + 0 :
3044 + sh->num_ref_idx_l0_active_minus1 + 1;
3045 + s->nb_refs[1] = (sh->slice_type != HEVC_SLICE_B) ?
3046 + 0 :
3047 + sh->num_ref_idx_l1_active_minus1 + 1;
3048 +
3049 + if (s->sps.flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED)
3050 + populate_scaling_factors(run, de, s);
3051 +
3052 + /* Calc all the random coord info to avoid repeated conversion in/out */
3053 + s->start_ts = s->ctb_addr_rs_to_ts[sh->slice_segment_addr];
3054 + s->start_ctb_x = sh->slice_segment_addr % de->pic_width_in_ctbs_y;
3055 + s->start_ctb_y = sh->slice_segment_addr / de->pic_width_in_ctbs_y;
3056 + /* Last CTB of previous slice */
3057 + prev_rs = !s->start_ts ? 0 : s->ctb_addr_ts_to_rs[s->start_ts - 1];
3058 + s->prev_ctb_x = prev_rs % de->pic_width_in_ctbs_y;
3059 + s->prev_ctb_y = prev_rs / de->pic_width_in_ctbs_y;
3060 +
3061 + if ((s->pps.flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED))
3062 + rv = wpp_decode_slice(de, s, last_slice);
3063 + else
3064 + rv = decode_slice(de, s, last_slice);
3065 + if (rv)
3066 + goto fail;
3067 +
3068 + ++s->slice_idx;
3069 + }
3070 +
3071 + if (!frame_end) {
3072 + xtrace_ok(dev, de);
3073 + return;
3074 + }
3075 +
3076 + // Frame end
3077 + memset(dpb_q_aux, 0,
3078 + sizeof(*dpb_q_aux) * V4L2_HEVC_DPB_ENTRIES_NUM_MAX);
3079 +
3080 + // Locate ref frames
3081 + // At least in the current implementation this is constant across all
3082 + // slices. If this changes we will need idx mapping code.
3083 + // Uses sh so here rather than trigger
3084 +
3085 + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
3086 + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
3087 +
3088 + if (!vq) {
3089 + v4l2_err(&dev->v4l2_dev, "VQ gone!\n");
3090 + goto fail;
3091 + }
3092 +
3093 + // v4l2_info(&dev->v4l2_dev, "rpivid_h265_end of frame\n");
3094 + if (write_cmd_buffer(dev, de, s))
3095 + goto fail;
3096 +
3097 + for (i = 0; i < dec->num_active_dpb_entries; ++i) {
3098 + struct vb2_buffer *buf = vb2_find_buffer(vq, dec->dpb[i].timestamp);
3099 + if (!buf) {
3100 + v4l2_warn(&dev->v4l2_dev,
3101 + "Missing DPB ent %d, timestamp=%lld\n",
3102 + i, (long long)dec->dpb[i].timestamp);
3103 + continue;
3104 + }
3105 +
3106 + if (s->use_aux) {
3107 + int buffer_index = buf->index;
3108 + dpb_q_aux[i] = aux_q_ref_idx(ctx, buffer_index);
3109 + if (!dpb_q_aux[i])
3110 + v4l2_warn(&dev->v4l2_dev,
3111 + "Missing DPB AUX ent %d, timestamp=%lld, index=%d\n",
3112 + i, (long long)dec->dpb[i].timestamp,
3113 + buffer_index);
3114 + }
3115 +
3116 + de->ref_addrs[i] =
3117 + vb2_dma_contig_plane_dma_addr(buf, 0);
3118 + }
3119 +
3120 + // Move DPB from temp
3121 + for (i = 0; i != V4L2_HEVC_DPB_ENTRIES_NUM_MAX; ++i) {
3122 + aux_q_release(ctx, &s->ref_aux[i]);
3123 + s->ref_aux[i] = dpb_q_aux[i];
3124 + }
3125 + // Unref the old frame aux too - it is either in the DPB or not
3126 + // now
3127 + aux_q_release(ctx, &s->frame_aux);
3128 +
3129 + if (s->mk_aux) {
3130 + s->frame_aux = aux_q_new(ctx, run->dst->vb2_buf.index);
3131 +
3132 + if (!s->frame_aux) {
3133 + v4l2_err(&dev->v4l2_dev,
3134 + "Failed to obtain aux storage for frame\n");
3135 + goto fail;
3136 + }
3137 +
3138 + de->frame_aux = aux_q_ref(ctx, s->frame_aux);
3139 + }
3140 +
3141 + if (de->dpbno_col != ~0U) {
3142 + if (de->dpbno_col >= dec->num_active_dpb_entries) {
3143 + v4l2_err(&dev->v4l2_dev,
3144 + "Col ref index %d >= %d\n",
3145 + de->dpbno_col,
3146 + dec->num_active_dpb_entries);
3147 + } else {
3148 + // Standard requires that the col pic is
3149 + // constant for the duration of the pic
3150 + // (text of collocated_ref_idx in H265-2 2018
3151 + // 7.4.7.1)
3152 +
3153 + // Spot the collocated ref in passing
3154 + de->col_aux = aux_q_ref(ctx,
3155 + dpb_q_aux[de->dpbno_col]);
3156 +
3157 + if (!de->col_aux) {
3158 + v4l2_warn(&dev->v4l2_dev,
3159 + "Missing DPB ent for col\n");
3160 + // Probably need to abort if this fails
3161 + // as P2 may explode on bad data
3162 + goto fail;
3163 + }
3164 + }
3165 + }
3166 +
3167 + de->state = RPIVID_DECODE_PHASE1;
3168 + xtrace_ok(dev, de);
3169 + return;
3170 +
3171 +fail:
3172 + if (de)
3173 + // Actual error reporting happens in Trigger
3174 + de->state = frame_end ? RPIVID_DECODE_ERROR_DONE :
3175 + RPIVID_DECODE_ERROR_CONTINUE;
3176 + xtrace_fail(dev, de);
3177 +}
3178 +
3179 +//////////////////////////////////////////////////////////////////////////////
3180 +// Handle PU and COEFF stream overflow
3181 +
3182 +// Returns:
3183 +// -1 Phase 1 decode error
3184 +// 0 OK
3185 +// >0 Out of space (bitmask)
3186 +
3187 +#define STATUS_COEFF_EXHAUSTED 8
3188 +#define STATUS_PU_EXHAUSTED 16
3189 +
3190 +static int check_status(const struct rpivid_dev *const dev)
3191 +{
3192 + const u32 cfstatus = apb_read(dev, RPI_CFSTATUS);
3193 + const u32 cfnum = apb_read(dev, RPI_CFNUM);
3194 + u32 status = apb_read(dev, RPI_STATUS);
3195 +
3196 + // Handle PU and COEFF stream overflow
3197 +
3198 + // this is the definition of successful completion of phase 1
3199 + // it assures that status register is zero and all blocks in each tile
3200 + // have completed
3201 + if (cfstatus == cfnum)
3202 + return 0; //No error
3203 +
3204 + status &= (STATUS_PU_EXHAUSTED | STATUS_COEFF_EXHAUSTED);
3205 + if (status)
3206 + return status;
3207 +
3208 + return -1;
3209 +}
3210 +
3211 +static void phase2_cb(struct rpivid_dev *const dev, void *v)
3212 +{
3213 + struct rpivid_dec_env *const de = v;
3214 +
3215 + xtrace_in(dev, de);
3216 +
3217 + /* Done with buffers - allow new P1 */
3218 + rpivid_hw_irq_active1_enable_claim(dev, 1);
3219 +
3220 + v4l2_m2m_buf_done(de->frame_buf, VB2_BUF_STATE_DONE);
3221 + de->frame_buf = NULL;
3222 +
3223 +#if USE_REQUEST_PIN
3224 + media_request_unpin(de->req_pin);
3225 + de->req_pin = NULL;
3226 +#else
3227 + media_request_object_complete(de->req_obj);
3228 + de->req_obj = NULL;
3229 +#endif
3230 +
3231 + xtrace_ok(dev, de);
3232 + dec_env_delete(de);
3233 +}
3234 +
3235 +static void phase2_claimed(struct rpivid_dev *const dev, void *v)
3236 +{
3237 + struct rpivid_dec_env *const de = v;
3238 + unsigned int i;
3239 +
3240 + xtrace_in(dev, de);
3241 +
3242 + apb_write_vc_addr(dev, RPI_PURBASE, de->pu_base_vc);
3243 + apb_write_vc_len(dev, RPI_PURSTRIDE, de->pu_stride);
3244 + apb_write_vc_addr(dev, RPI_COEFFRBASE, de->coeff_base_vc);
3245 + apb_write_vc_len(dev, RPI_COEFFRSTRIDE, de->coeff_stride);
3246 +
3247 + apb_write_vc_addr(dev, RPI_OUTYBASE, de->frame_addr);
3248 + apb_write_vc_addr(dev, RPI_OUTCBASE,
3249 + de->frame_addr + de->frame_c_offset);
3250 + apb_write_vc_len(dev, RPI_OUTYSTRIDE, de->frame_stride);
3251 + apb_write_vc_len(dev, RPI_OUTCSTRIDE, de->frame_stride);
3252 +
3253 + // v4l2_info(&dev->v4l2_dev, "Frame: Y=%llx, C=%llx, Stride=%x\n",
3254 + // de->frame_addr, de->frame_addr + de->frame_c_offset,
3255 + // de->frame_stride);
3256 +
3257 + for (i = 0; i < 16; i++) {
3258 + // Strides are in fact unused but fill in anyway
3259 + apb_write_vc_addr(dev, 0x9000 + 16 * i, de->ref_addrs[i]);
3260 + apb_write_vc_len(dev, 0x9004 + 16 * i, de->frame_stride);
3261 + apb_write_vc_addr(dev, 0x9008 + 16 * i,
3262 + de->ref_addrs[i] + de->frame_c_offset);
3263 + apb_write_vc_len(dev, 0x900C + 16 * i, de->frame_stride);
3264 + }
3265 +
3266 + apb_write(dev, RPI_CONFIG2, de->rpi_config2);
3267 + apb_write(dev, RPI_FRAMESIZE, de->rpi_framesize);
3268 + apb_write(dev, RPI_CURRPOC, de->rpi_currpoc);
3269 + // v4l2_info(&dev->v4l2_dev, "Config2=%#x, FrameSize=%#x, POC=%#x\n",
3270 + // de->rpi_config2, de->rpi_framesize, de->rpi_currpoc);
3271 +
3272 + // collocated reads/writes
3273 + apb_write_vc_len(dev, RPI_COLSTRIDE,
3274 + de->ctx->colmv_stride); // Read vals
3275 + apb_write_vc_len(dev, RPI_MVSTRIDE,
3276 + de->ctx->colmv_stride); // Write vals
3277 + apb_write_vc_addr(dev, RPI_MVBASE,
3278 + !de->frame_aux ? 0 : de->frame_aux->col.addr);
3279 + apb_write_vc_addr(dev, RPI_COLBASE,
3280 + !de->col_aux ? 0 : de->col_aux->col.addr);
3281 +
3282 + //v4l2_info(&dev->v4l2_dev,
3283 + // "Mv=%llx, Col=%llx, Stride=%x, Buf=%llx->%llx\n",
3284 + // de->rpi_mvbase, de->rpi_colbase, de->ctx->colmv_stride,
3285 + // de->ctx->colmvbuf.addr, de->ctx->colmvbuf.addr +
3286 + // de->ctx->colmvbuf.size);
3287 +
3288 + rpivid_hw_irq_active2_irq(dev, &de->irq_ent, phase2_cb, de);
3289 +
3290 + apb_write_final(dev, RPI_NUMROWS, de->pic_height_in_ctbs_y);
3291 +
3292 + xtrace_ok(dev, de);
3293 +}
3294 +
3295 +static void phase1_claimed(struct rpivid_dev *const dev, void *v);
3296 +
3297 +// release any and all objects associated with de
3298 +// and reenable phase 1 if required
3299 +static void phase1_err_fin(struct rpivid_dev *const dev,
3300 + struct rpivid_ctx *const ctx,
3301 + struct rpivid_dec_env *const de)
3302 +{
3303 + /* Return all detached buffers */
3304 + if (de->src_buf)
3305 + v4l2_m2m_buf_done(de->src_buf, VB2_BUF_STATE_ERROR);
3306 + de->src_buf = NULL;
3307 + if (de->frame_buf)
3308 + v4l2_m2m_buf_done(de->frame_buf, VB2_BUF_STATE_ERROR);
3309 + de->frame_buf = NULL;
3310 +#if USE_REQUEST_PIN
3311 + if (de->req_pin)
3312 + media_request_unpin(de->req_pin);
3313 + de->req_pin = NULL;
3314 +#else
3315 + if (de->req_obj)
3316 + media_request_object_complete(de->req_obj);
3317 + de->req_obj = NULL;
3318 +#endif
3319 +
3320 + dec_env_delete(de);
3321 +
3322 + /* Reenable phase 0 if we were blocking */
3323 + if (atomic_add_return(-1, &ctx->p1out) >= RPIVID_P1BUF_COUNT - 1)
3324 + v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx);
3325 +
3326 + /* Done with P1-P2 buffers - allow new P1 */
3327 + rpivid_hw_irq_active1_enable_claim(dev, 1);
3328 +}
3329 +
3330 +static void phase1_thread(struct rpivid_dev *const dev, void *v)
3331 +{
3332 + struct rpivid_dec_env *const de = v;
3333 + struct rpivid_ctx *const ctx = de->ctx;
3334 +
3335 + struct rpivid_gptr *const pu_gptr = ctx->pu_bufs + ctx->p2idx;
3336 + struct rpivid_gptr *const coeff_gptr = ctx->coeff_bufs + ctx->p2idx;
3337 +
3338 + xtrace_in(dev, de);
3339 +
3340 + if (de->p1_status & STATUS_PU_EXHAUSTED) {
3341 + if (gptr_realloc_new(dev, pu_gptr, next_size(pu_gptr->size))) {
3342 + v4l2_err(&dev->v4l2_dev,
3343 + "%s: PU realloc (%zx) failed\n",
3344 + __func__, pu_gptr->size);
3345 + goto fail;
3346 + }
3347 + v4l2_info(&dev->v4l2_dev, "%s: PU realloc (%zx) OK\n",
3348 + __func__, pu_gptr->size);
3349 + }
3350 +
3351 + if (de->p1_status & STATUS_COEFF_EXHAUSTED) {
3352 + if (gptr_realloc_new(dev, coeff_gptr,
3353 + next_size(coeff_gptr->size))) {
3354 + v4l2_err(&dev->v4l2_dev,
3355 + "%s: Coeff realloc (%zx) failed\n",
3356 + __func__, coeff_gptr->size);
3357 + goto fail;
3358 + }
3359 + v4l2_info(&dev->v4l2_dev, "%s: Coeff realloc (%zx) OK\n",
3360 + __func__, coeff_gptr->size);
3361 + }
3362 +
3363 + phase1_claimed(dev, de);
3364 + xtrace_ok(dev, de);
3365 + return;
3366 +
3367 +fail:
3368 + if (!pu_gptr->addr || !coeff_gptr->addr) {
3369 + v4l2_err(&dev->v4l2_dev,
3370 + "%s: Fatal: failed to reclaim old alloc\n",
3371 + __func__);
3372 + ctx->fatal_err = 1;
3373 + }
3374 + xtrace_fail(dev, de);
3375 + phase1_err_fin(dev, ctx, de);
3376 +}
3377 +
3378 +/* Always called in irq context (this is good) */
3379 +static void phase1_cb(struct rpivid_dev *const dev, void *v)
3380 +{
3381 + struct rpivid_dec_env *const de = v;
3382 + struct rpivid_ctx *const ctx = de->ctx;
3383 +
3384 + xtrace_in(dev, de);
3385 +
3386 + de->p1_status = check_status(dev);
3387 +
3388 + if (de->p1_status != 0) {
3389 + v4l2_info(&dev->v4l2_dev, "%s: Post wait: %#x\n",
3390 + __func__, de->p1_status);
3391 +
3392 + if (de->p1_status < 0)
3393 + goto fail;
3394 +
3395 + /* Need to realloc - push onto a thread rather than IRQ */
3396 + rpivid_hw_irq_active1_thread(dev, &de->irq_ent,
3397 + phase1_thread, de);
3398 + return;
3399 + }
3400 +
3401 + v4l2_m2m_buf_done(de->src_buf, VB2_BUF_STATE_DONE);
3402 + de->src_buf = NULL;
3403 +
3404 + /* All phase1 error paths done - it is safe to inc p2idx */
3405 + ctx->p2idx =
3406 + (ctx->p2idx + 1 >= RPIVID_P2BUF_COUNT) ? 0 : ctx->p2idx + 1;
3407 +
3408 + /* Renable the next setup if we were blocking */
3409 + if (atomic_add_return(-1, &ctx->p1out) >= RPIVID_P1BUF_COUNT - 1) {
3410 + xtrace_fin(dev, de);
3411 + v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx);
3412 + }
3413 +
3414 + rpivid_hw_irq_active2_claim(dev, &de->irq_ent, phase2_claimed, de);
3415 +
3416 + xtrace_ok(dev, de);
3417 + return;
3418 +
3419 +fail:
3420 + xtrace_fail(dev, de);
3421 + phase1_err_fin(dev, ctx, de);
3422 +}
3423 +
3424 +static void phase1_claimed(struct rpivid_dev *const dev, void *v)
3425 +{
3426 + struct rpivid_dec_env *const de = v;
3427 + struct rpivid_ctx *const ctx = de->ctx;
3428 +
3429 + const struct rpivid_gptr * const pu_gptr = ctx->pu_bufs + ctx->p2idx;
3430 + const struct rpivid_gptr * const coeff_gptr = ctx->coeff_bufs +
3431 + ctx->p2idx;
3432 +
3433 + xtrace_in(dev, de);
3434 +
3435 + if (ctx->fatal_err)
3436 + goto fail;
3437 +
3438 + de->pu_base_vc = pu_gptr->addr;
3439 + de->pu_stride =
3440 + ALIGN_DOWN(pu_gptr->size / de->pic_height_in_ctbs_y, 64);
3441 +
3442 + de->coeff_base_vc = coeff_gptr->addr;
3443 + de->coeff_stride =
3444 + ALIGN_DOWN(coeff_gptr->size / de->pic_height_in_ctbs_y, 64);
3445 +
3446 + /* phase1_claimed blocked until cb_phase1 completed so p2idx inc
3447 + * in cb_phase1 after error detection
3448 + */
3449 +
3450 + apb_write_vc_addr(dev, RPI_PUWBASE, de->pu_base_vc);
3451 + apb_write_vc_len(dev, RPI_PUWSTRIDE, de->pu_stride);
3452 + apb_write_vc_addr(dev, RPI_COEFFWBASE, de->coeff_base_vc);
3453 + apb_write_vc_len(dev, RPI_COEFFWSTRIDE, de->coeff_stride);
3454 +
3455 + // Trigger command FIFO
3456 + apb_write(dev, RPI_CFNUM, de->cmd_len);
3457 +
3458 + // Claim irq
3459 + rpivid_hw_irq_active1_irq(dev, &de->irq_ent, phase1_cb, de);
3460 +
3461 + // And start the h/w
3462 + apb_write_vc_addr_final(dev, RPI_CFBASE, de->cmd_addr);
3463 +
3464 + xtrace_ok(dev, de);
3465 + return;
3466 +
3467 +fail:
3468 + xtrace_fail(dev, de);
3469 + phase1_err_fin(dev, ctx, de);
3470 +}
3471 +
3472 +static void dec_state_delete(struct rpivid_ctx *const ctx)
3473 +{
3474 + unsigned int i;
3475 + struct rpivid_dec_state *const s = ctx->state;
3476 +
3477 + if (!s)
3478 + return;
3479 + ctx->state = NULL;
3480 +
3481 + free_ps_info(s);
3482 +
3483 + for (i = 0; i != HEVC_MAX_REFS; ++i)
3484 + aux_q_release(ctx, &s->ref_aux[i]);
3485 + aux_q_release(ctx, &s->frame_aux);
3486 +
3487 + kfree(s);
3488 +}
3489 +
3490 +struct irq_sync {
3491 + atomic_t done;
3492 + wait_queue_head_t wq;
3493 + struct rpivid_hw_irq_ent irq_ent;
3494 +};
3495 +
3496 +static void phase2_sync_claimed(struct rpivid_dev *const dev, void *v)
3497 +{
3498 + struct irq_sync *const sync = v;
3499 +
3500 + atomic_set(&sync->done, 1);
3501 + wake_up(&sync->wq);
3502 +}
3503 +
3504 +static void phase1_sync_claimed(struct rpivid_dev *const dev, void *v)
3505 +{
3506 + struct irq_sync *const sync = v;
3507 +
3508 + rpivid_hw_irq_active1_enable_claim(dev, 1);
3509 + rpivid_hw_irq_active2_claim(dev, &sync->irq_ent, phase2_sync_claimed, sync);
3510 +}
3511 +
3512 +/* Sync with IRQ operations
3513 + *
3514 + * Claims phase1 and phase2 in turn and waits for the phase2 claim so any
3515 + * pending IRQ ops will have completed by the time this returns
3516 + *
3517 + * phase1 has counted enables so must reenable once claimed
3518 + * phase2 has unlimited enables
3519 + */
3520 +static void irq_sync(struct rpivid_dev *const dev)
3521 +{
3522 + struct irq_sync sync;
3523 +
3524 + atomic_set(&sync.done, 0);
3525 + init_waitqueue_head(&sync.wq);
3526 +
3527 + rpivid_hw_irq_active1_claim(dev, &sync.irq_ent, phase1_sync_claimed, &sync);
3528 + wait_event(sync.wq, atomic_read(&sync.done));
3529 +}
3530 +
3531 +static void h265_ctx_uninit(struct rpivid_dev *const dev, struct rpivid_ctx *ctx)
3532 +{
3533 + unsigned int i;
3534 +
3535 + dec_env_uninit(ctx);
3536 + dec_state_delete(ctx);
3537 +
3538 + // dec_env & state must be killed before this to release the buffer to
3539 + // the free pool
3540 + aux_q_uninit(ctx);
3541 +
3542 + for (i = 0; i != ARRAY_SIZE(ctx->bitbufs); ++i)
3543 + gptr_free(dev, ctx->bitbufs + i);
3544 + for (i = 0; i != ARRAY_SIZE(ctx->pu_bufs); ++i)
3545 + gptr_free(dev, ctx->pu_bufs + i);
3546 + for (i = 0; i != ARRAY_SIZE(ctx->coeff_bufs); ++i)
3547 + gptr_free(dev, ctx->coeff_bufs + i);
3548 +}
3549 +
3550 +static void rpivid_h265_stop(struct rpivid_ctx *ctx)
3551 +{
3552 + struct rpivid_dev *const dev = ctx->dev;
3553 +
3554 + v4l2_info(&dev->v4l2_dev, "%s\n", __func__);
3555 +
3556 + irq_sync(dev);
3557 + h265_ctx_uninit(dev, ctx);
3558 +}
3559 +
3560 +static int rpivid_h265_start(struct rpivid_ctx *ctx)
3561 +{
3562 + struct rpivid_dev *const dev = ctx->dev;
3563 + unsigned int i;
3564 +
3565 + unsigned int w = ctx->dst_fmt.width;
3566 + unsigned int h = ctx->dst_fmt.height;
3567 + unsigned int wxh;
3568 + size_t pu_alloc;
3569 + size_t coeff_alloc;
3570 +
3571 +#if DEBUG_TRACE_P1_CMD
3572 + p1_z = 0;
3573 +#endif
3574 +
3575 + // Generate a sanitised WxH for memory alloc
3576 + // Assume HD if unset
3577 + if (w == 0)
3578 + w = 1920;
3579 + if (w > 4096)
3580 + w = 4096;
3581 + if (h == 0)
3582 + h = 1088;
3583 + if (h > 4096)
3584 + h = 4096;
3585 + wxh = w * h;
3586 +
3587 + v4l2_info(&dev->v4l2_dev, "%s: (%dx%d)\n", __func__,
3588 + ctx->dst_fmt.width, ctx->dst_fmt.height);
3589 +
3590 + ctx->fatal_err = 0;
3591 + ctx->dec0 = NULL;
3592 + ctx->state = kzalloc(sizeof(*ctx->state), GFP_KERNEL);
3593 + if (!ctx->state) {
3594 + v4l2_err(&dev->v4l2_dev, "Failed to allocate decode state\n");
3595 + goto fail;
3596 + }
3597 +
3598 + if (dec_env_init(ctx) != 0) {
3599 + v4l2_err(&dev->v4l2_dev, "Failed to allocate decode envs\n");
3600 + goto fail;
3601 + }
3602 +
3603 + // Finger in the air PU & Coeff alloc
3604 + // Will be realloced if too small
3605 + coeff_alloc = rpivid_round_up_size(wxh);
3606 + pu_alloc = rpivid_round_up_size(wxh / 4);
3607 + for (i = 0; i != ARRAY_SIZE(ctx->pu_bufs); ++i) {
3608 + // Don't actually need a kernel mapping here
3609 + if (gptr_alloc(dev, ctx->pu_bufs + i, pu_alloc,
3610 + DMA_ATTR_NO_KERNEL_MAPPING))
3611 + goto fail;
3612 + if (gptr_alloc(dev, ctx->coeff_bufs + i, coeff_alloc,
3613 + DMA_ATTR_NO_KERNEL_MAPPING))
3614 + goto fail;
3615 + }
3616 + aux_q_init(ctx);
3617 +
3618 + return 0;
3619 +
3620 +fail:
3621 + h265_ctx_uninit(dev, ctx);
3622 + return -ENOMEM;
3623 +}
3624 +
3625 +static void rpivid_h265_trigger(struct rpivid_ctx *ctx)
3626 +{
3627 + struct rpivid_dev *const dev = ctx->dev;
3628 + struct rpivid_dec_env *const de = ctx->dec0;
3629 +
3630 + xtrace_in(dev, de);
3631 +
3632 + switch (!de ? RPIVID_DECODE_ERROR_CONTINUE : de->state) {
3633 + case RPIVID_DECODE_SLICE_START:
3634 + de->state = RPIVID_DECODE_SLICE_CONTINUE;
3635 + fallthrough;
3636 + case RPIVID_DECODE_SLICE_CONTINUE:
3637 + v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx,
3638 + VB2_BUF_STATE_DONE);
3639 + xtrace_ok(dev, de);
3640 + break;
3641 +
3642 + default:
3643 + v4l2_err(&dev->v4l2_dev, "%s: Unexpected state: %d\n", __func__,
3644 + de->state);
3645 + fallthrough;
3646 + case RPIVID_DECODE_ERROR_DONE:
3647 + ctx->dec0 = NULL;
3648 + dec_env_delete(de);
3649 + fallthrough;
3650 + case RPIVID_DECODE_ERROR_CONTINUE:
3651 + xtrace_fin(dev, de);
3652 + v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx,
3653 + VB2_BUF_STATE_ERROR);
3654 + break;
3655 +
3656 + case RPIVID_DECODE_PHASE1:
3657 + ctx->dec0 = NULL;
3658 +
3659 +#if !USE_REQUEST_PIN
3660 + /* Alloc a new request object - needs to be alloced dynamically
3661 + * as the media request will release it some random time after
3662 + * it is completed
3663 + */
3664 + de->req_obj = kmalloc(sizeof(*de->req_obj), GFP_KERNEL);
3665 + if (!de->req_obj) {
3666 + xtrace_fail(dev, de);
3667 + dec_env_delete(de);
3668 + v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev,
3669 + ctx->fh.m2m_ctx,
3670 + VB2_BUF_STATE_ERROR);
3671 + break;
3672 + }
3673 + media_request_object_init(de->req_obj);
3674 +#warning probably needs to _get the req obj too
3675 +#endif
3676 + ctx->p1idx = (ctx->p1idx + 1 >= RPIVID_P1BUF_COUNT) ?
3677 + 0 : ctx->p1idx + 1;
3678 +
3679 + /* We know we have src & dst so no need to test */
3680 + de->src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
3681 + de->frame_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
3682 +
3683 +#if USE_REQUEST_PIN
3684 + de->req_pin = de->src_buf->vb2_buf.req_obj.req;
3685 + media_request_pin(de->req_pin);
3686 +#else
3687 + media_request_object_bind(de->src_buf->vb2_buf.req_obj.req,
3688 + &dst_req_obj_ops, de, false,
3689 + de->req_obj);
3690 +#endif
3691 +
3692 + /* We could get rid of the src buffer here if we've already
3693 + * copied it, but we don't copy the last buffer unless it
3694 + * didn't return a contig dma addr and that shouldn't happen
3695 + */
3696 +
3697 + /* Enable the next setup if our Q isn't too big */
3698 + if (atomic_add_return(1, &ctx->p1out) < RPIVID_P1BUF_COUNT) {
3699 + xtrace_fin(dev, de);
3700 + v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx);
3701 + }
3702 +
3703 + rpivid_hw_irq_active1_claim(dev, &de->irq_ent, phase1_claimed,
3704 + de);
3705 + xtrace_ok(dev, de);
3706 + break;
3707 + }
3708 +}
3709 +
3710 +const struct rpivid_dec_ops rpivid_dec_ops_h265 = {
3711 + .setup = rpivid_h265_setup,
3712 + .start = rpivid_h265_start,
3713 + .stop = rpivid_h265_stop,
3714 + .trigger = rpivid_h265_trigger,
3715 +};
3716 +
3717 +static int try_ctrl_sps(struct v4l2_ctrl *ctrl)
3718 +{
3719 + const struct v4l2_ctrl_hevc_sps *const sps = ctrl->p_new.p_hevc_sps;
3720 + struct rpivid_ctx *const ctx = ctrl->priv;
3721 + struct rpivid_dev *const dev = ctx->dev;
3722 +
3723 + if (sps->chroma_format_idc != 1) {
3724 + v4l2_warn(&dev->v4l2_dev,
3725 + "Chroma format (%d) unsupported\n",
3726 + sps->chroma_format_idc);
3727 + return -EINVAL;
3728 + }
3729 +
3730 + if (sps->bit_depth_luma_minus8 != 0 &&
3731 + sps->bit_depth_luma_minus8 != 2) {
3732 + v4l2_warn(&dev->v4l2_dev,
3733 + "Luma depth (%d) unsupported\n",
3734 + sps->bit_depth_luma_minus8 + 8);
3735 + return -EINVAL;
3736 + }
3737 +
3738 + if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) {
3739 + v4l2_warn(&dev->v4l2_dev,
3740 + "Chroma depth (%d) != Luma depth (%d)\n",
3741 + sps->bit_depth_chroma_minus8 + 8,
3742 + sps->bit_depth_luma_minus8 + 8);
3743 + return -EINVAL;
3744 + }
3745 +
3746 + if (!sps->pic_width_in_luma_samples ||
3747 + !sps->pic_height_in_luma_samples ||
3748 + sps->pic_width_in_luma_samples > 4096 ||
3749 + sps->pic_height_in_luma_samples > 4096) {
3750 + v4l2_warn(&dev->v4l2_dev,
3751 + "Bad sps width (%u) x height (%u)\n",
3752 + sps->pic_width_in_luma_samples,
3753 + sps->pic_height_in_luma_samples);
3754 + return -EINVAL;
3755 + }
3756 +
3757 + if (!ctx->dst_fmt_set)
3758 + return 0;
3759 +
3760 + if ((sps->bit_depth_luma_minus8 == 0 &&
3761 + ctx->dst_fmt.pixelformat != V4L2_PIX_FMT_NV12_COL128) ||
3762 + (sps->bit_depth_luma_minus8 == 2 &&
3763 + ctx->dst_fmt.pixelformat != V4L2_PIX_FMT_NV12_10_COL128)) {
3764 + v4l2_warn(&dev->v4l2_dev,
3765 + "SPS luma depth %d does not match capture format\n",
3766 + sps->bit_depth_luma_minus8 + 8);
3767 + return -EINVAL;
3768 + }
3769 +
3770 + if (sps->pic_width_in_luma_samples > ctx->dst_fmt.width ||
3771 + sps->pic_height_in_luma_samples > ctx->dst_fmt.height) {
3772 + v4l2_warn(&dev->v4l2_dev,
3773 + "SPS size (%dx%d) > capture size (%d,%d)\n",
3774 + sps->pic_width_in_luma_samples,
3775 + sps->pic_height_in_luma_samples,
3776 + ctx->dst_fmt.width,
3777 + ctx->dst_fmt.height);
3778 + return -EINVAL;
3779 + }
3780 +
3781 + return 0;
3782 +}
3783 +
3784 +const struct v4l2_ctrl_ops rpivid_hevc_sps_ctrl_ops = {
3785 + .try_ctrl = try_ctrl_sps,
3786 +};
3787 +
3788 +static int try_ctrl_pps(struct v4l2_ctrl *ctrl)
3789 +{
3790 + const struct v4l2_ctrl_hevc_pps *const pps = ctrl->p_new.p_hevc_pps;
3791 + struct rpivid_ctx *const ctx = ctrl->priv;
3792 + struct rpivid_dev *const dev = ctx->dev;
3793 +
3794 + if ((pps->flags &
3795 + V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED) &&
3796 + (pps->flags &
3797 + V4L2_HEVC_PPS_FLAG_TILES_ENABLED) &&
3798 + (pps->num_tile_columns_minus1 || pps->num_tile_rows_minus1)) {
3799 + v4l2_warn(&dev->v4l2_dev,
3800 + "WPP + Tiles not supported\n");
3801 + return -EINVAL;
3802 + }
3803 +
3804 + return 0;
3805 +}
3806 +
3807 +const struct v4l2_ctrl_ops rpivid_hevc_pps_ctrl_ops = {
3808 + .try_ctrl = try_ctrl_pps,
3809 +};
3810 +
3811 --- /dev/null
3812 +++ b/drivers/staging/media/rpivid/rpivid_hw.c
3813 @@ -0,0 +1,383 @@
3814 +// SPDX-License-Identifier: GPL-2.0
3815 +/*
3816 + * Raspberry Pi HEVC driver
3817 + *
3818 + * Copyright (C) 2020 Raspberry Pi (Trading) Ltd
3819 + *
3820 + * Based on the Cedrus VPU driver, that is:
3821 + *
3822 + * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
3823 + * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
3824 + * Copyright (C) 2018 Bootlin
3825 + */
3826 +#include <linux/clk.h>
3827 +#include <linux/component.h>
3828 +#include <linux/dma-mapping.h>
3829 +#include <linux/interrupt.h>
3830 +#include <linux/io.h>
3831 +#include <linux/of_reserved_mem.h>
3832 +#include <linux/of_device.h>
3833 +#include <linux/of_platform.h>
3834 +#include <linux/platform_device.h>
3835 +#include <linux/regmap.h>
3836 +#include <linux/reset.h>
3837 +
3838 +#include <media/videobuf2-core.h>
3839 +#include <media/v4l2-mem2mem.h>
3840 +
3841 +#include <soc/bcm2835/raspberrypi-firmware.h>
3842 +
3843 +#include "rpivid.h"
3844 +#include "rpivid_hw.h"
3845 +
3846 +static void pre_irq(struct rpivid_dev *dev, struct rpivid_hw_irq_ent *ient,
3847 + rpivid_irq_callback cb, void *v,
3848 + struct rpivid_hw_irq_ctrl *ictl)
3849 +{
3850 + unsigned long flags;
3851 +
3852 + if (ictl->irq) {
3853 + v4l2_err(&dev->v4l2_dev, "Attempt to claim IRQ when already claimed\n");
3854 + return;
3855 + }
3856 +
3857 + ient->cb = cb;
3858 + ient->v = v;
3859 +
3860 + spin_lock_irqsave(&ictl->lock, flags);
3861 + ictl->irq = ient;
3862 + ictl->no_sched++;
3863 + spin_unlock_irqrestore(&ictl->lock, flags);
3864 +}
3865 +
3866 +/* Should be called from inside ictl->lock */
3867 +static inline bool sched_enabled(const struct rpivid_hw_irq_ctrl * const ictl)
3868 +{
3869 + return ictl->no_sched <= 0 && ictl->enable;
3870 +}
3871 +
3872 +/* Should be called from inside ictl->lock & after checking sched_enabled() */
3873 +static inline void set_claimed(struct rpivid_hw_irq_ctrl * const ictl)
3874 +{
3875 + if (ictl->enable > 0)
3876 + --ictl->enable;
3877 + ictl->no_sched = 1;
3878 +}
3879 +
3880 +/* Should be called from inside ictl->lock */
3881 +static struct rpivid_hw_irq_ent *get_sched(struct rpivid_hw_irq_ctrl * const ictl)
3882 +{
3883 + struct rpivid_hw_irq_ent *ient;
3884 +
3885 + if (!sched_enabled(ictl))
3886 + return NULL;
3887 +
3888 + ient = ictl->claim;
3889 + if (!ient)
3890 + return NULL;
3891 + ictl->claim = ient->next;
3892 +
3893 + set_claimed(ictl);
3894 + return ient;
3895 +}
3896 +
3897 +/* Run a callback & check to see if there is anything else to run */
3898 +static void sched_cb(struct rpivid_dev * const dev,
3899 + struct rpivid_hw_irq_ctrl * const ictl,
3900 + struct rpivid_hw_irq_ent *ient)
3901 +{
3902 + while (ient) {
3903 + unsigned long flags;
3904 +
3905 + ient->cb(dev, ient->v);
3906 +
3907 + spin_lock_irqsave(&ictl->lock, flags);
3908 +
3909 + /* Always dec no_sched after cb exec - must have been set
3910 + * on entry to cb
3911 + */
3912 + --ictl->no_sched;
3913 + ient = get_sched(ictl);
3914 +
3915 + spin_unlock_irqrestore(&ictl->lock, flags);
3916 + }
3917 +}
3918 +
3919 +/* Should only ever be called from its own IRQ cb so no lock required */
3920 +static void pre_thread(struct rpivid_dev *dev,
3921 + struct rpivid_hw_irq_ent *ient,
3922 + rpivid_irq_callback cb, void *v,
3923 + struct rpivid_hw_irq_ctrl *ictl)
3924 +{
3925 + ient->cb = cb;
3926 + ient->v = v;
3927 + ictl->irq = ient;
3928 + ictl->thread_reqed = true;
3929 + ictl->no_sched++; /* This is unwound in do_thread */
3930 +}
3931 +
3932 +// Called in irq context
3933 +static void do_irq(struct rpivid_dev * const dev,
3934 + struct rpivid_hw_irq_ctrl * const ictl)
3935 +{
3936 + struct rpivid_hw_irq_ent *ient;
3937 + unsigned long flags;
3938 +
3939 + spin_lock_irqsave(&ictl->lock, flags);
3940 + ient = ictl->irq;
3941 + ictl->irq = NULL;
3942 + spin_unlock_irqrestore(&ictl->lock, flags);
3943 +
3944 + sched_cb(dev, ictl, ient);
3945 +}
3946 +
3947 +static void do_claim(struct rpivid_dev * const dev,
3948 + struct rpivid_hw_irq_ent *ient,
3949 + const rpivid_irq_callback cb, void * const v,
3950 + struct rpivid_hw_irq_ctrl * const ictl)
3951 +{
3952 + unsigned long flags;
3953 +
3954 + ient->next = NULL;
3955 + ient->cb = cb;
3956 + ient->v = v;
3957 +
3958 + spin_lock_irqsave(&ictl->lock, flags);
3959 +
3960 + if (ictl->claim) {
3961 + // If we have a Q then add to end
3962 + ictl->tail->next = ient;
3963 + ictl->tail = ient;
3964 + ient = NULL;
3965 + } else if (!sched_enabled(ictl)) {
3966 + // Empty Q but other activity in progress so Q
3967 + ictl->claim = ient;
3968 + ictl->tail = ient;
3969 + ient = NULL;
3970 + } else {
3971 + // Nothing else going on - schedule immediately and
3972 + // prevent anything else scheduling claims
3973 + set_claimed(ictl);
3974 + }
3975 +
3976 + spin_unlock_irqrestore(&ictl->lock, flags);
3977 +
3978 + sched_cb(dev, ictl, ient);
3979 +}
3980 +
3981 +/* Enable n claims.
3982 + * n < 0 set to unlimited (default on init)
3983 + * n = 0 if previously unlimited then disable otherwise nop
3984 + * n > 0 if previously unlimited then set to n enables
3985 + * otherwise add n enables
3986 + * The enable count is automatically decremented every time a claim is run
3987 + */
3988 +static void do_enable_claim(struct rpivid_dev * const dev,
3989 + int n,
3990 + struct rpivid_hw_irq_ctrl * const ictl)
3991 +{
3992 + unsigned long flags;
3993 + struct rpivid_hw_irq_ent *ient;
3994 +
3995 + spin_lock_irqsave(&ictl->lock, flags);
3996 + ictl->enable = n < 0 ? -1 : ictl->enable <= 0 ? n : ictl->enable + n;
3997 + ient = get_sched(ictl);
3998 + spin_unlock_irqrestore(&ictl->lock, flags);
3999 +
4000 + sched_cb(dev, ictl, ient);
4001 +}
4002 +
4003 +static void ictl_init(struct rpivid_hw_irq_ctrl * const ictl, int enables)
4004 +{
4005 + spin_lock_init(&ictl->lock);
4006 + ictl->claim = NULL;
4007 + ictl->tail = NULL;
4008 + ictl->irq = NULL;
4009 + ictl->no_sched = 0;
4010 + ictl->enable = enables;
4011 + ictl->thread_reqed = false;
4012 +}
4013 +
4014 +static void ictl_uninit(struct rpivid_hw_irq_ctrl * const ictl)
4015 +{
4016 + // Nothing to do
4017 +}
4018 +
4019 +#if !OPT_DEBUG_POLL_IRQ
4020 +static irqreturn_t rpivid_irq_irq(int irq, void *data)
4021 +{
4022 + struct rpivid_dev * const dev = data;
4023 + __u32 ictrl;
4024 +
4025 + ictrl = irq_read(dev, ARG_IC_ICTRL);
4026 + if (!(ictrl & ARG_IC_ICTRL_ALL_IRQ_MASK)) {
4027 + v4l2_warn(&dev->v4l2_dev, "IRQ but no IRQ bits set\n");
4028 + return IRQ_NONE;
4029 + }
4030 +
4031 + // Cancel any/all irqs
4032 + irq_write(dev, ARG_IC_ICTRL, ictrl & ~ARG_IC_ICTRL_SET_ZERO_MASK);
4033 +
4034 + // Service Active2 before Active1 so Phase 1 can transition to Phase 2
4035 + // without delay
4036 + if (ictrl & ARG_IC_ICTRL_ACTIVE2_INT_SET)
4037 + do_irq(dev, &dev->ic_active2);
4038 + if (ictrl & ARG_IC_ICTRL_ACTIVE1_INT_SET)
4039 + do_irq(dev, &dev->ic_active1);
4040 +
4041 + return dev->ic_active1.thread_reqed || dev->ic_active2.thread_reqed ?
4042 + IRQ_WAKE_THREAD : IRQ_HANDLED;
4043 +}
4044 +
4045 +static void do_thread(struct rpivid_dev * const dev,
4046 + struct rpivid_hw_irq_ctrl *const ictl)
4047 +{
4048 + unsigned long flags;
4049 + struct rpivid_hw_irq_ent *ient = NULL;
4050 +
4051 + spin_lock_irqsave(&ictl->lock, flags);
4052 +
4053 + if (ictl->thread_reqed) {
4054 + ient = ictl->irq;
4055 + ictl->thread_reqed = false;
4056 + ictl->irq = NULL;
4057 + }
4058 +
4059 + spin_unlock_irqrestore(&ictl->lock, flags);
4060 +
4061 + sched_cb(dev, ictl, ient);
4062 +}
4063 +
4064 +static irqreturn_t rpivid_irq_thread(int irq, void *data)
4065 +{
4066 + struct rpivid_dev * const dev = data;
4067 +
4068 + do_thread(dev, &dev->ic_active1);
4069 + do_thread(dev, &dev->ic_active2);
4070 +
4071 + return IRQ_HANDLED;
4072 +}
4073 +#endif
4074 +
4075 +/* May only be called from Active1 CB
4076 + * IRQs should not be expected until execution continues in the cb
4077 + */
4078 +void rpivid_hw_irq_active1_thread(struct rpivid_dev *dev,
4079 + struct rpivid_hw_irq_ent *ient,
4080 + rpivid_irq_callback thread_cb, void *ctx)
4081 +{
4082 + pre_thread(dev, ient, thread_cb, ctx, &dev->ic_active1);
4083 +}
4084 +
4085 +void rpivid_hw_irq_active1_enable_claim(struct rpivid_dev *dev,
4086 + int n)
4087 +{
4088 + do_enable_claim(dev, n, &dev->ic_active1);
4089 +}
4090 +
4091 +void rpivid_hw_irq_active1_claim(struct rpivid_dev *dev,
4092 + struct rpivid_hw_irq_ent *ient,
4093 + rpivid_irq_callback ready_cb, void *ctx)
4094 +{
4095 + do_claim(dev, ient, ready_cb, ctx, &dev->ic_active1);
4096 +}
4097 +
4098 +void rpivid_hw_irq_active1_irq(struct rpivid_dev *dev,
4099 + struct rpivid_hw_irq_ent *ient,
4100 + rpivid_irq_callback irq_cb, void *ctx)
4101 +{
4102 + pre_irq(dev, ient, irq_cb, ctx, &dev->ic_active1);
4103 +}
4104 +
4105 +void rpivid_hw_irq_active2_claim(struct rpivid_dev *dev,
4106 + struct rpivid_hw_irq_ent *ient,
4107 + rpivid_irq_callback ready_cb, void *ctx)
4108 +{
4109 + do_claim(dev, ient, ready_cb, ctx, &dev->ic_active2);
4110 +}
4111 +
4112 +void rpivid_hw_irq_active2_irq(struct rpivid_dev *dev,
4113 + struct rpivid_hw_irq_ent *ient,
4114 + rpivid_irq_callback irq_cb, void *ctx)
4115 +{
4116 + pre_irq(dev, ient, irq_cb, ctx, &dev->ic_active2);
4117 +}
4118 +
4119 +int rpivid_hw_probe(struct rpivid_dev *dev)
4120 +{
4121 + struct rpi_firmware *firmware;
4122 + struct device_node *node;
4123 + struct resource *res;
4124 + __u32 irq_stat;
4125 + int irq_dec;
4126 + int ret = 0;
4127 +
4128 + ictl_init(&dev->ic_active1, RPIVID_P2BUF_COUNT);
4129 + ictl_init(&dev->ic_active2, RPIVID_ICTL_ENABLE_UNLIMITED);
4130 +
4131 + res = platform_get_resource_byname(dev->pdev, IORESOURCE_MEM, "intc");
4132 + if (!res)
4133 + return -ENODEV;
4134 +
4135 + dev->base_irq = devm_ioremap(dev->dev, res->start, resource_size(res));
4136 + if (IS_ERR(dev->base_irq))
4137 + return PTR_ERR(dev->base_irq);
4138 +
4139 + res = platform_get_resource_byname(dev->pdev, IORESOURCE_MEM, "hevc");
4140 + if (!res)
4141 + return -ENODEV;
4142 +
4143 + dev->base_h265 = devm_ioremap(dev->dev, res->start, resource_size(res));
4144 + if (IS_ERR(dev->base_h265))
4145 + return PTR_ERR(dev->base_h265);
4146 +
4147 + dev->clock = devm_clk_get(&dev->pdev->dev, "hevc");
4148 + if (IS_ERR(dev->clock))
4149 + return PTR_ERR(dev->clock);
4150 +
4151 + node = rpi_firmware_find_node();
4152 + if (!node)
4153 + return -EINVAL;
4154 +
4155 + firmware = rpi_firmware_get(node);
4156 + of_node_put(node);
4157 + if (!firmware)
4158 + return -EPROBE_DEFER;
4159 +
4160 + dev->max_clock_rate = rpi_firmware_clk_get_max_rate(firmware,
4161 + RPI_FIRMWARE_HEVC_CLK_ID);
4162 + rpi_firmware_put(firmware);
4163 +
4164 + dev->cache_align = dma_get_cache_alignment();
4165 +
4166 + // Disable IRQs & reset anything pending
4167 + irq_write(dev, 0,
4168 + ARG_IC_ICTRL_ACTIVE1_EN_SET | ARG_IC_ICTRL_ACTIVE2_EN_SET);
4169 + irq_stat = irq_read(dev, 0);
4170 + irq_write(dev, 0, irq_stat);
4171 +
4172 +#if !OPT_DEBUG_POLL_IRQ
4173 + irq_dec = platform_get_irq(dev->pdev, 0);
4174 + if (irq_dec <= 0)
4175 + return irq_dec;
4176 + ret = devm_request_threaded_irq(dev->dev, irq_dec,
4177 + rpivid_irq_irq,
4178 + rpivid_irq_thread,
4179 + 0, dev_name(dev->dev), dev);
4180 + if (ret) {
4181 + dev_err(dev->dev, "Failed to request IRQ - %d\n", ret);
4182 +
4183 + return ret;
4184 + }
4185 +#endif
4186 + return ret;
4187 +}
4188 +
4189 +void rpivid_hw_remove(struct rpivid_dev *dev)
4190 +{
4191 + // IRQ auto freed on unload so no need to do it here
4192 + // ioremap auto freed on unload
4193 + ictl_uninit(&dev->ic_active1);
4194 + ictl_uninit(&dev->ic_active2);
4195 +}
4196 +
4197 --- /dev/null
4198 +++ b/drivers/staging/media/rpivid/rpivid_hw.h
4199 @@ -0,0 +1,303 @@
4200 +/* SPDX-License-Identifier: GPL-2.0 */
4201 +/*
4202 + * Raspberry Pi HEVC driver
4203 + *
4204 + * Copyright (C) 2020 Raspberry Pi (Trading) Ltd
4205 + *
4206 + * Based on the Cedrus VPU driver, that is:
4207 + *
4208 + * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
4209 + * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
4210 + * Copyright (C) 2018 Bootlin
4211 + */
4212 +
4213 +#ifndef _RPIVID_HW_H_
4214 +#define _RPIVID_HW_H_
4215 +
4216 +struct rpivid_hw_irq_ent {
4217 + struct rpivid_hw_irq_ent *next;
4218 + rpivid_irq_callback cb;
4219 + void *v;
4220 +};
4221 +
4222 +/* Phase 1 Register offsets */
4223 +
4224 +#define RPI_SPS0 0
4225 +#define RPI_SPS1 4
4226 +#define RPI_PPS 8
4227 +#define RPI_SLICE 12
4228 +#define RPI_TILESTART 16
4229 +#define RPI_TILEEND 20
4230 +#define RPI_SLICESTART 24
4231 +#define RPI_MODE 28
4232 +#define RPI_LEFT0 32
4233 +#define RPI_LEFT1 36
4234 +#define RPI_LEFT2 40
4235 +#define RPI_LEFT3 44
4236 +#define RPI_QP 48
4237 +#define RPI_CONTROL 52
4238 +#define RPI_STATUS 56
4239 +#define RPI_VERSION 60
4240 +#define RPI_BFBASE 64
4241 +#define RPI_BFNUM 68
4242 +#define RPI_BFCONTROL 72
4243 +#define RPI_BFSTATUS 76
4244 +#define RPI_PUWBASE 80
4245 +#define RPI_PUWSTRIDE 84
4246 +#define RPI_COEFFWBASE 88
4247 +#define RPI_COEFFWSTRIDE 92
4248 +#define RPI_SLICECMDS 96
4249 +#define RPI_BEGINTILEEND 100
4250 +#define RPI_TRANSFER 104
4251 +#define RPI_CFBASE 108
4252 +#define RPI_CFNUM 112
4253 +#define RPI_CFSTATUS 116
4254 +
4255 +/* Phase 2 Register offsets */
4256 +
4257 +#define RPI_PURBASE 0x8000
4258 +#define RPI_PURSTRIDE 0x8004
4259 +#define RPI_COEFFRBASE 0x8008
4260 +#define RPI_COEFFRSTRIDE 0x800C
4261 +#define RPI_NUMROWS 0x8010
4262 +#define RPI_CONFIG2 0x8014
4263 +#define RPI_OUTYBASE 0x8018
4264 +#define RPI_OUTYSTRIDE 0x801C
4265 +#define RPI_OUTCBASE 0x8020
4266 +#define RPI_OUTCSTRIDE 0x8024
4267 +#define RPI_STATUS2 0x8028
4268 +#define RPI_FRAMESIZE 0x802C
4269 +#define RPI_MVBASE 0x8030
4270 +#define RPI_MVSTRIDE 0x8034
4271 +#define RPI_COLBASE 0x8038
4272 +#define RPI_COLSTRIDE 0x803C
4273 +#define RPI_CURRPOC 0x8040
4274 +
4275 +/*
4276 + * Write a general register value
4277 + * Order is unimportant
4278 + */
4279 +static inline void apb_write(const struct rpivid_dev * const dev,
4280 + const unsigned int offset, const u32 val)
4281 +{
4282 + writel_relaxed(val, dev->base_h265 + offset);
4283 +}
4284 +
4285 +/* Write the final register value that actually starts the phase */
4286 +static inline void apb_write_final(const struct rpivid_dev * const dev,
4287 + const unsigned int offset, const u32 val)
4288 +{
4289 + writel(val, dev->base_h265 + offset);
4290 +}
4291 +
4292 +static inline u32 apb_read(const struct rpivid_dev * const dev,
4293 + const unsigned int offset)
4294 +{
4295 + return readl(dev->base_h265 + offset);
4296 +}
4297 +
4298 +static inline void irq_write(const struct rpivid_dev * const dev,
4299 + const unsigned int offset, const u32 val)
4300 +{
4301 + writel(val, dev->base_irq + offset);
4302 +}
4303 +
4304 +static inline u32 irq_read(const struct rpivid_dev * const dev,
4305 + const unsigned int offset)
4306 +{
4307 + return readl(dev->base_irq + offset);
4308 +}
4309 +
4310 +static inline void apb_write_vc_addr(const struct rpivid_dev * const dev,
4311 + const unsigned int offset,
4312 + const dma_addr_t a)
4313 +{
4314 + apb_write(dev, offset, (u32)(a >> 6));
4315 +}
4316 +
4317 +static inline void apb_write_vc_addr_final(const struct rpivid_dev * const dev,
4318 + const unsigned int offset,
4319 + const dma_addr_t a)
4320 +{
4321 + apb_write_final(dev, offset, (u32)(a >> 6));
4322 +}
4323 +
4324 +static inline void apb_write_vc_len(const struct rpivid_dev * const dev,
4325 + const unsigned int offset,
4326 + const unsigned int x)
4327 +{
4328 + apb_write(dev, offset, (x + 63) >> 6);
4329 +}
4330 +
4331 +/* *ARG_IC_ICTRL - Interrupt control for ARGON Core*
4332 + * Offset (byte space) = 40'h2b10000
4333 + * Physical Address (byte space) = 40'h7eb10000
4334 + * Verilog Macro Address = `ARG_IC_REG_START + `ARGON_INTCTRL_ICTRL
4335 + * Reset Value = 32'b100x100x_100xxxxx_xxxxxxx0_x100x100
4336 + * Access = RW (32-bit only)
4337 + * Interrupt control logic for ARGON Core.
4338 + */
4339 +#define ARG_IC_ICTRL 0
4340 +
4341 +/* acc=LWC ACTIVE1_INT FIELD ACCESS: LWC
4342 + *
4343 + * Interrupt 1
4344 + * This is set and held when an hevc_active1 interrupt edge is detected
4345 + * The polarity of the edge is set by the ACTIVE1_EDGE field
4346 + * Write a 1 to this bit to clear down the latched interrupt
4347 + * The latched interrupt is only enabled out onto the interrupt line if
4348 + * ACTIVE1_EN is set
4349 + * Reset value is *0* decimal.
4350 + */
4351 +#define ARG_IC_ICTRL_ACTIVE1_INT_SET BIT(0)
4352 +
4353 +/* ACTIVE1_EDGE Sets the polarity of the interrupt edge detection logic
4354 + * This logic detects edges of the hevc_active1 line from the argon core
4355 + * 0 = negedge, 1 = posedge
4356 + * Reset value is *0* decimal.
4357 + */
4358 +#define ARG_IC_ICTRL_ACTIVE1_EDGE_SET BIT(1)
4359 +
4360 +/* ACTIVE1_EN Enables ACTIVE1_INT out onto the argon interrupt line.
4361 + * If this isn't set, the interrupt logic will work but no interrupt will be
4362 + * set to the interrupt controller
4363 + * Reset value is *1* decimal.
4364 + *
4365 + * [JC] The above appears to be a lie - if unset then b0 is never set
4366 + */
4367 +#define ARG_IC_ICTRL_ACTIVE1_EN_SET BIT(2)
4368 +
4369 +/* acc=RO ACTIVE1_STATUS FIELD ACCESS: RO
4370 + *
4371 + * The current status of the hevc_active1 signal
4372 + */
4373 +#define ARG_IC_ICTRL_ACTIVE1_STATUS_SET BIT(3)
4374 +
4375 +/* acc=LWC ACTIVE2_INT FIELD ACCESS: LWC
4376 + *
4377 + * Interrupt 2
4378 + * This is set and held when an hevc_active2 interrupt edge is detected
4379 + * The polarity of the edge is set by the ACTIVE2_EDGE field
4380 + * Write a 1 to this bit to clear down the latched interrupt
4381 + * The latched interrupt is only enabled out onto the interrupt line if
4382 + * ACTIVE2_EN is set
4383 + * Reset value is *0* decimal.
4384 + */
4385 +#define ARG_IC_ICTRL_ACTIVE2_INT_SET BIT(4)
4386 +
4387 +/* ACTIVE2_EDGE Sets the polarity of the interrupt edge detection logic
4388 + * This logic detects edges of the hevc_active2 line from the argon core
4389 + * 0 = negedge, 1 = posedge
4390 + * Reset value is *0* decimal.
4391 + */
4392 +#define ARG_IC_ICTRL_ACTIVE2_EDGE_SET BIT(5)
4393 +
4394 +/* ACTIVE2_EN Enables ACTIVE2_INT out onto the argon interrupt line.
4395 + * If this isn't set, the interrupt logic will work but no interrupt will be
4396 + * set to the interrupt controller
4397 + * Reset value is *1* decimal.
4398 + */
4399 +#define ARG_IC_ICTRL_ACTIVE2_EN_SET BIT(6)
4400 +
4401 +/* acc=RO ACTIVE2_STATUS FIELD ACCESS: RO
4402 + *
4403 + * The current status of the hevc_active2 signal
4404 + */
4405 +#define ARG_IC_ICTRL_ACTIVE2_STATUS_SET BIT(7)
4406 +
4407 +/* TEST_INT Forces the argon int high for test purposes.
4408 + * Reset value is *0* decimal.
4409 + */
4410 +#define ARG_IC_ICTRL_TEST_INT BIT(8)
4411 +#define ARG_IC_ICTRL_SPARE BIT(9)
4412 +
4413 +/* acc=RO VP9_INTERRUPT_STATUS FIELD ACCESS: RO
4414 + *
4415 + * The current status of the vp9_interrupt signal
4416 + */
4417 +#define ARG_IC_ICTRL_VP9_INTERRUPT_STATUS BIT(10)
4418 +
4419 +/* AIO_INT_ENABLE 1 = Or the AIO int in with the Argon int so the VPU can see
4420 + * it
4421 + * 0 = the AIO int is masked. (It should still be connected to the GIC though).
4422 + */
4423 +#define ARG_IC_ICTRL_AIO_INT_ENABLE BIT(20)
4424 +#define ARG_IC_ICTRL_H264_ACTIVE_INT BIT(21)
4425 +#define ARG_IC_ICTRL_H264_ACTIVE_EDGE BIT(22)
4426 +#define ARG_IC_ICTRL_H264_ACTIVE_EN BIT(23)
4427 +#define ARG_IC_ICTRL_H264_ACTIVE_STATUS BIT(24)
4428 +#define ARG_IC_ICTRL_H264_INTERRUPT_INT BIT(25)
4429 +#define ARG_IC_ICTRL_H264_INTERRUPT_EDGE BIT(26)
4430 +#define ARG_IC_ICTRL_H264_INTERRUPT_EN BIT(27)
4431 +
4432 +/* acc=RO H264_INTERRUPT_STATUS FIELD ACCESS: RO
4433 + *
4434 + * The current status of the h264_interrupt signal
4435 + */
4436 +#define ARG_IC_ICTRL_H264_INTERRUPT_STATUS BIT(28)
4437 +
4438 +/* acc=LWC VP9_INTERRUPT_INT FIELD ACCESS: LWC
4439 + *
4440 + * Interrupt 1
4441 + * This is set and held when an vp9_interrupt interrupt edge is detected
4442 + * The polarity of the edge is set by the VP9_INTERRUPT_EDGE field
4443 + * Write a 1 to this bit to clear down the latched interrupt
4444 + * The latched interrupt is only enabled out onto the interrupt line if
4445 + * VP9_INTERRUPT_EN is set
4446 + * Reset value is *0* decimal.
4447 + */
4448 +#define ARG_IC_ICTRL_VP9_INTERRUPT_INT BIT(29)
4449 +
4450 +/* VP9_INTERRUPT_EDGE Sets the polarity of the interrupt edge detection logic
4451 + * This logic detects edges of the vp9_interrupt line from the argon h264 core
4452 + * 0 = negedge, 1 = posedge
4453 + * Reset value is *0* decimal.
4454 + */
4455 +#define ARG_IC_ICTRL_VP9_INTERRUPT_EDGE BIT(30)
4456 +
4457 +/* VP9_INTERRUPT_EN Enables VP9_INTERRUPT_INT out onto the argon interrupt line.
4458 + * If this isn't set, the interrupt logic will work but no interrupt will be
4459 + * set to the interrupt controller
4460 + * Reset value is *1* decimal.
4461 + */
4462 +#define ARG_IC_ICTRL_VP9_INTERRUPT_EN BIT(31)
4463 +
4464 +/* Bits 19:12, 11 reserved - read ?, write 0 */
4465 +#define ARG_IC_ICTRL_SET_ZERO_MASK ((0xff << 12) | BIT(11))
4466 +
4467 +/* All IRQ bits */
4468 +#define ARG_IC_ICTRL_ALL_IRQ_MASK (\
4469 + ARG_IC_ICTRL_VP9_INTERRUPT_INT |\
4470 + ARG_IC_ICTRL_H264_INTERRUPT_INT |\
4471 + ARG_IC_ICTRL_ACTIVE1_INT_SET |\
4472 + ARG_IC_ICTRL_ACTIVE2_INT_SET)
4473 +
4474 +/* Regulate claim Q */
4475 +void rpivid_hw_irq_active1_enable_claim(struct rpivid_dev *dev,
4476 + int n);
4477 +/* Auto release once all CBs called */
4478 +void rpivid_hw_irq_active1_claim(struct rpivid_dev *dev,
4479 + struct rpivid_hw_irq_ent *ient,
4480 + rpivid_irq_callback ready_cb, void *ctx);
4481 +/* May only be called in claim cb */
4482 +void rpivid_hw_irq_active1_irq(struct rpivid_dev *dev,
4483 + struct rpivid_hw_irq_ent *ient,
4484 + rpivid_irq_callback irq_cb, void *ctx);
4485 +/* May only be called in irq cb */
4486 +void rpivid_hw_irq_active1_thread(struct rpivid_dev *dev,
4487 + struct rpivid_hw_irq_ent *ient,
4488 + rpivid_irq_callback thread_cb, void *ctx);
4489 +
4490 +/* Auto release once all CBs called */
4491 +void rpivid_hw_irq_active2_claim(struct rpivid_dev *dev,
4492 + struct rpivid_hw_irq_ent *ient,
4493 + rpivid_irq_callback ready_cb, void *ctx);
4494 +/* May only be called in claim cb */
4495 +void rpivid_hw_irq_active2_irq(struct rpivid_dev *dev,
4496 + struct rpivid_hw_irq_ent *ient,
4497 + rpivid_irq_callback irq_cb, void *ctx);
4498 +
4499 +int rpivid_hw_probe(struct rpivid_dev *dev);
4500 +void rpivid_hw_remove(struct rpivid_dev *dev);
4501 +
4502 +#endif
4503 --- /dev/null
4504 +++ b/drivers/staging/media/rpivid/rpivid_video.c
4505 @@ -0,0 +1,696 @@
4506 +// SPDX-License-Identifier: GPL-2.0
4507 +/*
4508 + * Raspberry Pi HEVC driver
4509 + *
4510 + * Copyright (C) 2020 Raspberry Pi (Trading) Ltd
4511 + *
4512 + * Based on the Cedrus VPU driver, that is:
4513 + *
4514 + * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
4515 + * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
4516 + * Copyright (C) 2018 Bootlin
4517 + */
4518 +
4519 +#include <media/videobuf2-dma-contig.h>
4520 +#include <media/v4l2-device.h>
4521 +#include <media/v4l2-ioctl.h>
4522 +#include <media/v4l2-event.h>
4523 +#include <media/v4l2-mem2mem.h>
4524 +
4525 +#include "rpivid.h"
4526 +#include "rpivid_hw.h"
4527 +#include "rpivid_video.h"
4528 +#include "rpivid_dec.h"
4529 +
4530 +#define RPIVID_DECODE_SRC BIT(0)
4531 +#define RPIVID_DECODE_DST BIT(1)
4532 +
4533 +#define RPIVID_MIN_WIDTH 16U
4534 +#define RPIVID_MIN_HEIGHT 16U
4535 +#define RPIVID_DEFAULT_WIDTH 1920U
4536 +#define RPIVID_DEFAULT_HEIGHT 1088U
4537 +#define RPIVID_MAX_WIDTH 4096U
4538 +#define RPIVID_MAX_HEIGHT 4096U
4539 +
4540 +static inline struct rpivid_ctx *rpivid_file2ctx(struct file *file)
4541 +{
4542 + return container_of(file->private_data, struct rpivid_ctx, fh);
4543 +}
4544 +
4545 +/* constrain x to y,y*2 */
4546 +static inline unsigned int constrain2x(unsigned int x, unsigned int y)
4547 +{
4548 + return (x < y) ?
4549 + y :
4550 + (x > y * 2) ? y : x;
4551 +}
4552 +
4553 +size_t rpivid_round_up_size(const size_t x)
4554 +{
4555 + /* Admit no size < 256 */
4556 + const unsigned int n = x < 256 ? 8 : ilog2(x);
4557 +
4558 + return x >= (3 << n) ? 4 << n : (3 << n);
4559 +}
4560 +
4561 +size_t rpivid_bit_buf_size(unsigned int w, unsigned int h, unsigned int bits_minus8)
4562 +{
4563 + const size_t wxh = w * h;
4564 + size_t bits_alloc;
4565 +
4566 + /* Annex A gives a min compression of 2 @ lvl 3.1
4567 + * (wxh <= 983040) and min 4 thereafter but avoid
4568 + * the odity of 983041 having a lower limit than
4569 + * 983040.
4570 + * Multiply by 3/2 for 4:2:0
4571 + */
4572 + bits_alloc = wxh < 983040 ? wxh * 3 / 4 :
4573 + wxh < 983040 * 2 ? 983040 * 3 / 4 :
4574 + wxh * 3 / 8;
4575 + /* Allow for bit depth */
4576 + bits_alloc += (bits_alloc * bits_minus8) / 8;
4577 + return rpivid_round_up_size(bits_alloc);
4578 +}
4579 +
4580 +void rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt)
4581 +{
4582 + size_t size;
4583 + u32 w;
4584 + u32 h;
4585 +
4586 + w = pix_fmt->width;
4587 + h = pix_fmt->height;
4588 + if (!w || !h) {
4589 + w = RPIVID_DEFAULT_WIDTH;
4590 + h = RPIVID_DEFAULT_HEIGHT;
4591 + }
4592 + if (w > RPIVID_MAX_WIDTH)
4593 + w = RPIVID_MAX_WIDTH;
4594 + if (h > RPIVID_MAX_HEIGHT)
4595 + h = RPIVID_MAX_HEIGHT;
4596 +
4597 + if (!pix_fmt->plane_fmt[0].sizeimage ||
4598 + pix_fmt->plane_fmt[0].sizeimage > SZ_32M) {
4599 + /* Unspecified or way too big - pick max for size */
4600 + size = rpivid_bit_buf_size(w, h, 2);
4601 + }
4602 + /* Set a minimum */
4603 + size = max_t(u32, SZ_4K, pix_fmt->plane_fmt[0].sizeimage);
4604 +
4605 + pix_fmt->pixelformat = V4L2_PIX_FMT_HEVC_SLICE;
4606 + pix_fmt->width = w;
4607 + pix_fmt->height = h;
4608 + pix_fmt->num_planes = 1;
4609 + pix_fmt->field = V4L2_FIELD_NONE;
4610 + /* Zero bytes per line for encoded source. */
4611 + pix_fmt->plane_fmt[0].bytesperline = 0;
4612 + pix_fmt->plane_fmt[0].sizeimage = size;
4613 +}
4614 +
4615 +/* Take any pix_format and make it valid */
4616 +static void rpivid_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt)
4617 +{
4618 + unsigned int width = pix_fmt->width;
4619 + unsigned int height = pix_fmt->height;
4620 + unsigned int sizeimage = pix_fmt->plane_fmt[0].sizeimage;
4621 + unsigned int bytesperline = pix_fmt->plane_fmt[0].bytesperline;
4622 +
4623 + if (!width)
4624 + width = RPIVID_DEFAULT_WIDTH;
4625 + if (width > RPIVID_MAX_WIDTH)
4626 + width = RPIVID_MAX_WIDTH;
4627 + if (!height)
4628 + height = RPIVID_DEFAULT_HEIGHT;
4629 + if (height > RPIVID_MAX_HEIGHT)
4630 + height = RPIVID_MAX_HEIGHT;
4631 +
4632 + /* For column formats set bytesperline to column height (stride2) */
4633 + switch (pix_fmt->pixelformat) {
4634 + default:
4635 + pix_fmt->pixelformat = V4L2_PIX_FMT_NV12_COL128;
4636 + fallthrough;
4637 + case V4L2_PIX_FMT_NV12_COL128:
4638 + /* Width rounds up to columns */
4639 + width = ALIGN(width, 128);
4640 +
4641 + /* 16 aligned height - not sure we even need that */
4642 + height = ALIGN(height, 16);
4643 + /* column height
4644 + * Accept suggested shape if at least min & < 2 * min
4645 + */
4646 + bytesperline = constrain2x(bytesperline, height * 3 / 2);
4647 +
4648 + /* image size
4649 + * Again allow plausible variation in case added padding is
4650 + * required
4651 + */
4652 + sizeimage = constrain2x(sizeimage, bytesperline * width);
4653 + break;
4654 +
4655 + case V4L2_PIX_FMT_NV12_10_COL128:
4656 + /* width in pixels (3 pels = 4 bytes) rounded to 128 byte
4657 + * columns
4658 + */
4659 + width = ALIGN(((width + 2) / 3), 32) * 3;
4660 +
4661 + /* 16-aligned height. */
4662 + height = ALIGN(height, 16);
4663 +
4664 + /* column height
4665 + * Accept suggested shape if at least min & < 2 * min
4666 + */
4667 + bytesperline = constrain2x(bytesperline, height * 3 / 2);
4668 +
4669 + /* image size
4670 + * Again allow plausible variation in case added padding is
4671 + * required
4672 + */
4673 + sizeimage = constrain2x(sizeimage,
4674 + bytesperline * width * 4 / 3);
4675 + break;
4676 + }
4677 +
4678 + pix_fmt->width = width;
4679 + pix_fmt->height = height;
4680 +
4681 + pix_fmt->field = V4L2_FIELD_NONE;
4682 + pix_fmt->plane_fmt[0].bytesperline = bytesperline;
4683 + pix_fmt->plane_fmt[0].sizeimage = sizeimage;
4684 + pix_fmt->num_planes = 1;
4685 +}
4686 +
4687 +static int rpivid_querycap(struct file *file, void *priv,
4688 + struct v4l2_capability *cap)
4689 +{
4690 + strscpy(cap->driver, RPIVID_NAME, sizeof(cap->driver));
4691 + strscpy(cap->card, RPIVID_NAME, sizeof(cap->card));
4692 + snprintf(cap->bus_info, sizeof(cap->bus_info),
4693 + "platform:%s", RPIVID_NAME);
4694 +
4695 + return 0;
4696 +}
4697 +
4698 +static int rpivid_enum_fmt_vid_out(struct file *file, void *priv,
4699 + struct v4l2_fmtdesc *f)
4700 +{
4701 + // Input formats
4702 +
4703 + // H.265 Slice only currently
4704 + if (f->index == 0) {
4705 + f->pixelformat = V4L2_PIX_FMT_HEVC_SLICE;
4706 + return 0;
4707 + }
4708 +
4709 + return -EINVAL;
4710 +}
4711 +
4712 +static int rpivid_hevc_validate_sps(const struct v4l2_ctrl_hevc_sps * const sps)
4713 +{
4714 + const unsigned int ctb_log2_size_y =
4715 + sps->log2_min_luma_coding_block_size_minus3 + 3 +
4716 + sps->log2_diff_max_min_luma_coding_block_size;
4717 + const unsigned int min_tb_log2_size_y =
4718 + sps->log2_min_luma_transform_block_size_minus2 + 2;
4719 + const unsigned int max_tb_log2_size_y = min_tb_log2_size_y +
4720 + sps->log2_diff_max_min_luma_transform_block_size;
4721 +
4722 + /* Local limitations */
4723 + if (sps->pic_width_in_luma_samples < 32 ||
4724 + sps->pic_width_in_luma_samples > 4096)
4725 + return 0;
4726 + if (sps->pic_height_in_luma_samples < 32 ||
4727 + sps->pic_height_in_luma_samples > 4096)
4728 + return 0;
4729 + if (!(sps->bit_depth_luma_minus8 == 0 ||
4730 + sps->bit_depth_luma_minus8 == 2))
4731 + return 0;
4732 + if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8)
4733 + return 0;
4734 + if (sps->chroma_format_idc != 1)
4735 + return 0;
4736 +
4737 + /* Limits from H.265 7.4.3.2.1 */
4738 + if (sps->log2_max_pic_order_cnt_lsb_minus4 > 12)
4739 + return 0;
4740 + if (sps->sps_max_dec_pic_buffering_minus1 > 15)
4741 + return 0;
4742 + if (sps->sps_max_num_reorder_pics >
4743 + sps->sps_max_dec_pic_buffering_minus1)
4744 + return 0;
4745 + if (ctb_log2_size_y > 6)
4746 + return 0;
4747 + if (max_tb_log2_size_y > 5)
4748 + return 0;
4749 + if (max_tb_log2_size_y > ctb_log2_size_y)
4750 + return 0;
4751 + if (sps->max_transform_hierarchy_depth_inter >
4752 + (ctb_log2_size_y - min_tb_log2_size_y))
4753 + return 0;
4754 + if (sps->max_transform_hierarchy_depth_intra >
4755 + (ctb_log2_size_y - min_tb_log2_size_y))
4756 + return 0;
4757 + /* Check pcm stuff */
4758 + if (sps->num_short_term_ref_pic_sets > 64)
4759 + return 0;
4760 + if (sps->num_long_term_ref_pics_sps > 32)
4761 + return 0;
4762 + return 1;
4763 +}
4764 +
4765 +static inline int is_sps_set(const struct v4l2_ctrl_hevc_sps * const sps)
4766 +{
4767 + return sps && sps->pic_width_in_luma_samples != 0;
4768 +}
4769 +
4770 +static u32 pixelformat_from_sps(const struct v4l2_ctrl_hevc_sps * const sps,
4771 + const int index)
4772 +{
4773 + u32 pf = 0;
4774 +
4775 + if (!is_sps_set(sps) || !rpivid_hevc_validate_sps(sps)) {
4776 + /* Treat this as an error? For now return both */
4777 + if (index == 0)
4778 + pf = V4L2_PIX_FMT_NV12_COL128;
4779 + else if (index == 1)
4780 + pf = V4L2_PIX_FMT_NV12_10_COL128;
4781 + } else if (index == 0) {
4782 + if (sps->bit_depth_luma_minus8 == 0)
4783 + pf = V4L2_PIX_FMT_NV12_COL128;
4784 + else if (sps->bit_depth_luma_minus8 == 2)
4785 + pf = V4L2_PIX_FMT_NV12_10_COL128;
4786 + }
4787 +
4788 + return pf;
4789 +}
4790 +
4791 +static struct v4l2_pix_format_mplane
4792 +rpivid_hevc_default_dst_fmt(struct rpivid_ctx * const ctx)
4793 +{
4794 + const struct v4l2_ctrl_hevc_sps * const sps =
4795 + rpivid_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_SPS);
4796 + struct v4l2_pix_format_mplane pix_fmt;
4797 +
4798 + memset(&pix_fmt, 0, sizeof(pix_fmt));
4799 + if (is_sps_set(sps)) {
4800 + pix_fmt.width = sps->pic_width_in_luma_samples;
4801 + pix_fmt.height = sps->pic_height_in_luma_samples;
4802 + pix_fmt.pixelformat = pixelformat_from_sps(sps, 0);
4803 + }
4804 +
4805 + rpivid_prepare_dst_format(&pix_fmt);
4806 + return pix_fmt;
4807 +}
4808 +
4809 +static u32 rpivid_hevc_get_dst_pixelformat(struct rpivid_ctx * const ctx,
4810 + const int index)
4811 +{
4812 + const struct v4l2_ctrl_hevc_sps * const sps =
4813 + rpivid_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_SPS);
4814 +
4815 + return pixelformat_from_sps(sps, index);
4816 +}
4817 +
4818 +static int rpivid_enum_fmt_vid_cap(struct file *file, void *priv,
4819 + struct v4l2_fmtdesc *f)
4820 +{
4821 + struct rpivid_ctx * const ctx = rpivid_file2ctx(file);
4822 +
4823 + const u32 pf = rpivid_hevc_get_dst_pixelformat(ctx, f->index);
4824 +
4825 + if (pf == 0)
4826 + return -EINVAL;
4827 +
4828 + f->pixelformat = pf;
4829 + return 0;
4830 +}
4831 +
4832 +/*
4833 + * get dst format - sets it to default if otherwise unset
4834 + * returns a pointer to the struct as a convienience
4835 + */
4836 +static struct v4l2_pix_format_mplane *get_dst_fmt(struct rpivid_ctx *const ctx)
4837 +{
4838 + if (!ctx->dst_fmt_set)
4839 + ctx->dst_fmt = rpivid_hevc_default_dst_fmt(ctx);
4840 + return &ctx->dst_fmt;
4841 +}
4842 +
4843 +static int rpivid_g_fmt_vid_cap(struct file *file, void *priv,
4844 + struct v4l2_format *f)
4845 +{
4846 + struct rpivid_ctx *ctx = rpivid_file2ctx(file);
4847 +
4848 + f->fmt.pix_mp = *get_dst_fmt(ctx);
4849 + return 0;
4850 +}
4851 +
4852 +static int rpivid_g_fmt_vid_out(struct file *file, void *priv,
4853 + struct v4l2_format *f)
4854 +{
4855 + struct rpivid_ctx *ctx = rpivid_file2ctx(file);
4856 +
4857 + f->fmt.pix_mp = ctx->src_fmt;
4858 + return 0;
4859 +}
4860 +
4861 +static inline void copy_color(struct v4l2_pix_format_mplane *d,
4862 + const struct v4l2_pix_format_mplane *s)
4863 +{
4864 + d->colorspace = s->colorspace;
4865 + d->xfer_func = s->xfer_func;
4866 + d->ycbcr_enc = s->ycbcr_enc;
4867 + d->quantization = s->quantization;
4868 +}
4869 +
4870 +static int rpivid_try_fmt_vid_cap(struct file *file, void *priv,
4871 + struct v4l2_format *f)
4872 +{
4873 + struct rpivid_ctx *ctx = rpivid_file2ctx(file);
4874 + const struct v4l2_ctrl_hevc_sps * const sps =
4875 + rpivid_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_SPS);
4876 + u32 pixelformat;
4877 + int i;
4878 +
4879 + for (i = 0; (pixelformat = pixelformat_from_sps(sps, i)) != 0; i++) {
4880 + if (f->fmt.pix_mp.pixelformat == pixelformat)
4881 + break;
4882 + }
4883 +
4884 + // We don't have any way of finding out colourspace so believe
4885 + // anything we are told - take anything set in src as a default
4886 + if (f->fmt.pix_mp.colorspace == V4L2_COLORSPACE_DEFAULT)
4887 + copy_color(&f->fmt.pix_mp, &ctx->src_fmt);
4888 +
4889 + f->fmt.pix_mp.pixelformat = pixelformat;
4890 + rpivid_prepare_dst_format(&f->fmt.pix_mp);
4891 + return 0;
4892 +}
4893 +
4894 +static int rpivid_try_fmt_vid_out(struct file *file, void *priv,
4895 + struct v4l2_format *f)
4896 +{
4897 + rpivid_prepare_src_format(&f->fmt.pix_mp);
4898 + return 0;
4899 +}
4900 +
4901 +static int rpivid_s_fmt_vid_cap(struct file *file, void *priv,
4902 + struct v4l2_format *f)
4903 +{
4904 + struct rpivid_ctx *ctx = rpivid_file2ctx(file);
4905 + struct vb2_queue *vq;
4906 + int ret;
4907 +
4908 + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
4909 + if (vb2_is_busy(vq))
4910 + return -EBUSY;
4911 +
4912 + ret = rpivid_try_fmt_vid_cap(file, priv, f);
4913 + if (ret)
4914 + return ret;
4915 +
4916 + ctx->dst_fmt = f->fmt.pix_mp;
4917 + ctx->dst_fmt_set = 1;
4918 +
4919 + return 0;
4920 +}
4921 +
4922 +static int rpivid_s_fmt_vid_out(struct file *file, void *priv,
4923 + struct v4l2_format *f)
4924 +{
4925 + struct rpivid_ctx *ctx = rpivid_file2ctx(file);
4926 + struct vb2_queue *vq;
4927 + int ret;
4928 +
4929 + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
4930 + if (vb2_is_busy(vq))
4931 + return -EBUSY;
4932 +
4933 + ret = rpivid_try_fmt_vid_out(file, priv, f);
4934 + if (ret)
4935 + return ret;
4936 +
4937 + ctx->src_fmt = f->fmt.pix_mp;
4938 + ctx->dst_fmt_set = 0; // Setting src invalidates dst
4939 +
4940 + vq->subsystem_flags |=
4941 + VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF;
4942 +
4943 + /* Propagate colorspace information to capture. */
4944 + copy_color(&ctx->dst_fmt, &f->fmt.pix_mp);
4945 + return 0;
4946 +}
4947 +
4948 +const struct v4l2_ioctl_ops rpivid_ioctl_ops = {
4949 + .vidioc_querycap = rpivid_querycap,
4950 +
4951 + .vidioc_enum_fmt_vid_cap = rpivid_enum_fmt_vid_cap,
4952 + .vidioc_g_fmt_vid_cap_mplane = rpivid_g_fmt_vid_cap,
4953 + .vidioc_try_fmt_vid_cap_mplane = rpivid_try_fmt_vid_cap,
4954 + .vidioc_s_fmt_vid_cap_mplane = rpivid_s_fmt_vid_cap,
4955 +
4956 + .vidioc_enum_fmt_vid_out = rpivid_enum_fmt_vid_out,
4957 + .vidioc_g_fmt_vid_out_mplane = rpivid_g_fmt_vid_out,
4958 + .vidioc_try_fmt_vid_out_mplane = rpivid_try_fmt_vid_out,
4959 + .vidioc_s_fmt_vid_out_mplane = rpivid_s_fmt_vid_out,
4960 +
4961 + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
4962 + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
4963 + .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
4964 + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
4965 + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
4966 + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
4967 + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
4968 +
4969 + .vidioc_streamon = v4l2_m2m_ioctl_streamon,
4970 + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
4971 +
4972 + .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd,
4973 + .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd,
4974 +
4975 + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
4976 + .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
4977 +};
4978 +
4979 +static int rpivid_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
4980 + unsigned int *nplanes, unsigned int sizes[],
4981 + struct device *alloc_devs[])
4982 +{
4983 + struct rpivid_ctx *ctx = vb2_get_drv_priv(vq);
4984 + struct v4l2_pix_format_mplane *pix_fmt;
4985 +
4986 + if (V4L2_TYPE_IS_OUTPUT(vq->type))
4987 + pix_fmt = &ctx->src_fmt;
4988 + else
4989 + pix_fmt = get_dst_fmt(ctx);
4990 +
4991 + if (*nplanes) {
4992 + if (sizes[0] < pix_fmt->plane_fmt[0].sizeimage)
4993 + return -EINVAL;
4994 + } else {
4995 + sizes[0] = pix_fmt->plane_fmt[0].sizeimage;
4996 + *nplanes = 1;
4997 + }
4998 +
4999 + return 0;
5000 +}
5001 +
5002 +static void rpivid_queue_cleanup(struct vb2_queue *vq, u32 state)
5003 +{
5004 + struct rpivid_ctx *ctx = vb2_get_drv_priv(vq);
5005 + struct vb2_v4l2_buffer *vbuf;
5006 +
5007 + for (;;) {
5008 + if (V4L2_TYPE_IS_OUTPUT(vq->type))
5009 + vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
5010 + else
5011 + vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
5012 +
5013 + if (!vbuf)
5014 + return;
5015 +
5016 + v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
5017 + &ctx->hdl);
5018 + v4l2_m2m_buf_done(vbuf, state);
5019 + }
5020 +}
5021 +
5022 +static int rpivid_buf_out_validate(struct vb2_buffer *vb)
5023 +{
5024 + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
5025 +
5026 + vbuf->field = V4L2_FIELD_NONE;
5027 + return 0;
5028 +}
5029 +
5030 +static int rpivid_buf_prepare(struct vb2_buffer *vb)
5031 +{
5032 + struct vb2_queue *vq = vb->vb2_queue;
5033 + struct rpivid_ctx *ctx = vb2_get_drv_priv(vq);
5034 + struct v4l2_pix_format_mplane *pix_fmt;
5035 +
5036 + if (V4L2_TYPE_IS_OUTPUT(vq->type))
5037 + pix_fmt = &ctx->src_fmt;
5038 + else
5039 + pix_fmt = &ctx->dst_fmt;
5040 +
5041 + if (vb2_plane_size(vb, 0) < pix_fmt->plane_fmt[0].sizeimage)
5042 + return -EINVAL;
5043 +
5044 + vb2_set_plane_payload(vb, 0, pix_fmt->plane_fmt[0].sizeimage);
5045 +
5046 + return 0;
5047 +}
5048 +
5049 +/* Only stops the clock if streaom off on both output & capture */
5050 +static void stop_clock(struct rpivid_dev *dev, struct rpivid_ctx *ctx)
5051 +{
5052 + if (ctx->src_stream_on ||
5053 + ctx->dst_stream_on)
5054 + return;
5055 +
5056 + clk_set_min_rate(dev->clock, 0);
5057 + clk_disable_unprepare(dev->clock);
5058 +}
5059 +
5060 +/* Always starts the clock if it isn't already on this ctx */
5061 +static int start_clock(struct rpivid_dev *dev, struct rpivid_ctx *ctx)
5062 +{
5063 + int rv;
5064 +
5065 + rv = clk_set_min_rate(dev->clock, dev->max_clock_rate);
5066 + if (rv) {
5067 + dev_err(dev->dev, "Failed to set clock rate\n");
5068 + return rv;
5069 + }
5070 +
5071 + rv = clk_prepare_enable(dev->clock);
5072 + if (rv) {
5073 + dev_err(dev->dev, "Failed to enable clock\n");
5074 + return rv;
5075 + }
5076 +
5077 + return 0;
5078 +}
5079 +
5080 +static int rpivid_start_streaming(struct vb2_queue *vq, unsigned int count)
5081 +{
5082 + struct rpivid_ctx *ctx = vb2_get_drv_priv(vq);
5083 + struct rpivid_dev *dev = ctx->dev;
5084 + int ret = 0;
5085 +
5086 + if (!V4L2_TYPE_IS_OUTPUT(vq->type)) {
5087 + ctx->dst_stream_on = 1;
5088 + goto ok;
5089 + }
5090 +
5091 + if (ctx->src_fmt.pixelformat != V4L2_PIX_FMT_HEVC_SLICE) {
5092 + ret = -EINVAL;
5093 + goto fail_cleanup;
5094 + }
5095 +
5096 + if (ctx->src_stream_on)
5097 + goto ok;
5098 +
5099 + ret = start_clock(dev, ctx);
5100 + if (ret)
5101 + goto fail_cleanup;
5102 +
5103 + if (dev->dec_ops->start)
5104 + ret = dev->dec_ops->start(ctx);
5105 + if (ret)
5106 + goto fail_stop_clock;
5107 +
5108 + ctx->src_stream_on = 1;
5109 +ok:
5110 + return 0;
5111 +
5112 +fail_stop_clock:
5113 + stop_clock(dev, ctx);
5114 +fail_cleanup:
5115 + v4l2_err(&dev->v4l2_dev, "%s: qtype=%d: FAIL\n", __func__, vq->type);
5116 + rpivid_queue_cleanup(vq, VB2_BUF_STATE_QUEUED);
5117 + return ret;
5118 +}
5119 +
5120 +static void rpivid_stop_streaming(struct vb2_queue *vq)
5121 +{
5122 + struct rpivid_ctx *ctx = vb2_get_drv_priv(vq);
5123 + struct rpivid_dev *dev = ctx->dev;
5124 +
5125 + if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
5126 + ctx->src_stream_on = 0;
5127 + if (dev->dec_ops->stop)
5128 + dev->dec_ops->stop(ctx);
5129 + } else {
5130 + ctx->dst_stream_on = 0;
5131 + }
5132 +
5133 + rpivid_queue_cleanup(vq, VB2_BUF_STATE_ERROR);
5134 +
5135 + vb2_wait_for_all_buffers(vq);
5136 +
5137 + stop_clock(dev, ctx);
5138 +}
5139 +
5140 +static void rpivid_buf_queue(struct vb2_buffer *vb)
5141 +{
5142 + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
5143 + struct rpivid_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
5144 +
5145 + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
5146 +}
5147 +
5148 +static void rpivid_buf_request_complete(struct vb2_buffer *vb)
5149 +{
5150 + struct rpivid_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
5151 +
5152 + v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl);
5153 +}
5154 +
5155 +static struct vb2_ops rpivid_qops = {
5156 + .queue_setup = rpivid_queue_setup,
5157 + .buf_prepare = rpivid_buf_prepare,
5158 + .buf_queue = rpivid_buf_queue,
5159 + .buf_out_validate = rpivid_buf_out_validate,
5160 + .buf_request_complete = rpivid_buf_request_complete,
5161 + .start_streaming = rpivid_start_streaming,
5162 + .stop_streaming = rpivid_stop_streaming,
5163 + .wait_prepare = vb2_ops_wait_prepare,
5164 + .wait_finish = vb2_ops_wait_finish,
5165 +};
5166 +
5167 +int rpivid_queue_init(void *priv, struct vb2_queue *src_vq,
5168 + struct vb2_queue *dst_vq)
5169 +{
5170 + struct rpivid_ctx *ctx = priv;
5171 + int ret;
5172 +
5173 + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
5174 + src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
5175 + src_vq->drv_priv = ctx;
5176 + src_vq->buf_struct_size = sizeof(struct rpivid_buffer);
5177 + src_vq->ops = &rpivid_qops;
5178 + src_vq->mem_ops = &vb2_dma_contig_memops;
5179 + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
5180 + src_vq->lock = &ctx->ctx_mutex;
5181 + src_vq->dev = ctx->dev->dev;
5182 + src_vq->supports_requests = true;
5183 + src_vq->requires_requests = true;
5184 +
5185 + ret = vb2_queue_init(src_vq);
5186 + if (ret)
5187 + return ret;
5188 +
5189 + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
5190 + dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
5191 + dst_vq->drv_priv = ctx;
5192 + dst_vq->buf_struct_size = sizeof(struct rpivid_buffer);
5193 + dst_vq->min_buffers_needed = 1;
5194 + dst_vq->ops = &rpivid_qops;
5195 + dst_vq->mem_ops = &vb2_dma_contig_memops;
5196 + dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
5197 + dst_vq->lock = &ctx->ctx_mutex;
5198 + dst_vq->dev = ctx->dev->dev;
5199 +
5200 + return vb2_queue_init(dst_vq);
5201 +}
5202 --- /dev/null
5203 +++ b/drivers/staging/media/rpivid/rpivid_video.h
5204 @@ -0,0 +1,33 @@
5205 +/* SPDX-License-Identifier: GPL-2.0 */
5206 +/*
5207 + * Raspberry Pi HEVC driver
5208 + *
5209 + * Copyright (C) 2020 Raspberry Pi (Trading) Ltd
5210 + *
5211 + * Based on the Cedrus VPU driver, that is:
5212 + *
5213 + * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
5214 + * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
5215 + * Copyright (C) 2018 Bootlin
5216 + */
5217 +
5218 +#ifndef _RPIVID_VIDEO_H_
5219 +#define _RPIVID_VIDEO_H_
5220 +
5221 +struct rpivid_format {
5222 + u32 pixelformat;
5223 + u32 directions;
5224 + unsigned int capabilities;
5225 +};
5226 +
5227 +extern const struct v4l2_ioctl_ops rpivid_ioctl_ops;
5228 +
5229 +int rpivid_queue_init(void *priv, struct vb2_queue *src_vq,
5230 + struct vb2_queue *dst_vq);
5231 +
5232 +size_t rpivid_bit_buf_size(unsigned int w, unsigned int h, unsigned int bits_minus8);
5233 +size_t rpivid_round_up_size(const size_t x);
5234 +
5235 +void rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt);
5236 +
5237 +#endif