1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Rockchip Video Decoder driver
4 *
5 * Copyright (C) 2019 Collabora, Ltd.
6 *
7 * Based on rkvdec driver by Google LLC. (Tomasz Figa <tfiga@chromium.org>)
8 * Based on s5p-mfc driver by Samsung Electronics Co., Ltd.
9 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
10 */
11
12 #include <linux/hw_bitfield.h>
13 #include <linux/clk.h>
14 #include <linux/genalloc.h>
15 #include <linux/interrupt.h>
16 #include <linux/iommu.h>
17 #include <linux/module.h>
18 #include <linux/of.h>
19 #include <linux/of_device.h>
20 #include <linux/platform_device.h>
21 #include <linux/pm.h>
22 #include <linux/pm_runtime.h>
23 #include <linux/slab.h>
24 #include <linux/videodev2.h>
25 #include <linux/workqueue.h>
26 #include <media/v4l2-event.h>
27 #include <media/v4l2-mem2mem.h>
28 #include <media/videobuf2-core.h>
29 #include <media/videobuf2-vmalloc.h>
30
31 #include "rkvdec.h"
32 #include "rkvdec-regs.h"
33 #include "rkvdec-vdpu381-regs.h"
34 #include "rkvdec-vdpu383-regs.h"
35 #include "rkvdec-rcb.h"
36
rkvdec_image_fmt_match(enum rkvdec_image_fmt fmt1,enum rkvdec_image_fmt fmt2)37 static bool rkvdec_image_fmt_match(enum rkvdec_image_fmt fmt1,
38 enum rkvdec_image_fmt fmt2)
39 {
40 return fmt1 == fmt2 || fmt2 == RKVDEC_IMG_FMT_ANY ||
41 fmt1 == RKVDEC_IMG_FMT_ANY;
42 }
43
rkvdec_image_fmt_changed(struct rkvdec_ctx * ctx,enum rkvdec_image_fmt image_fmt)44 static bool rkvdec_image_fmt_changed(struct rkvdec_ctx *ctx,
45 enum rkvdec_image_fmt image_fmt)
46 {
47 if (image_fmt == RKVDEC_IMG_FMT_ANY)
48 return false;
49
50 return ctx->image_fmt != image_fmt;
51 }
52
rkvdec_enum_decoded_fmt(struct rkvdec_ctx * ctx,int index,enum rkvdec_image_fmt image_fmt)53 static u32 rkvdec_enum_decoded_fmt(struct rkvdec_ctx *ctx, int index,
54 enum rkvdec_image_fmt image_fmt)
55 {
56 const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc;
57 int fmt_idx = -1;
58 unsigned int i;
59
60 if (WARN_ON(!desc))
61 return 0;
62
63 for (i = 0; i < desc->num_decoded_fmts; i++) {
64 if (!rkvdec_image_fmt_match(desc->decoded_fmts[i].image_fmt,
65 image_fmt))
66 continue;
67 fmt_idx++;
68 if (index == fmt_idx)
69 return desc->decoded_fmts[i].fourcc;
70 }
71
72 return 0;
73 }
74
rkvdec_is_valid_fmt(struct rkvdec_ctx * ctx,u32 fourcc,enum rkvdec_image_fmt image_fmt)75 static bool rkvdec_is_valid_fmt(struct rkvdec_ctx *ctx, u32 fourcc,
76 enum rkvdec_image_fmt image_fmt)
77 {
78 const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc;
79 unsigned int i;
80
81 for (i = 0; i < desc->num_decoded_fmts; i++) {
82 if (rkvdec_image_fmt_match(desc->decoded_fmts[i].image_fmt,
83 image_fmt) &&
84 desc->decoded_fmts[i].fourcc == fourcc)
85 return true;
86 }
87
88 return false;
89 }
90
rkvdec_colmv_size(u16 width,u16 height)91 static u32 rkvdec_colmv_size(u16 width, u16 height)
92 {
93 return 128 * DIV_ROUND_UP(width, 16) * DIV_ROUND_UP(height, 16);
94 }
95
vdpu383_colmv_size(u16 width,u16 height)96 static u32 vdpu383_colmv_size(u16 width, u16 height)
97 {
98 return ALIGN(width, 64) * ALIGN(height, 16);
99 }
100
rkvdec_fill_decoded_pixfmt(struct rkvdec_ctx * ctx,struct v4l2_pix_format_mplane * pix_mp)101 static void rkvdec_fill_decoded_pixfmt(struct rkvdec_ctx *ctx,
102 struct v4l2_pix_format_mplane *pix_mp)
103 {
104 const struct rkvdec_variant *variant = ctx->dev->variant;
105
106 v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat, pix_mp->width, pix_mp->height);
107
108 ctx->colmv_offset = pix_mp->plane_fmt[0].sizeimage;
109
110 pix_mp->plane_fmt[0].sizeimage += variant->ops->colmv_size(pix_mp->width, pix_mp->height);
111 }
112
rkvdec_reset_fmt(struct rkvdec_ctx * ctx,struct v4l2_format * f,u32 fourcc)113 static void rkvdec_reset_fmt(struct rkvdec_ctx *ctx, struct v4l2_format *f,
114 u32 fourcc)
115 {
116 memset(f, 0, sizeof(*f));
117 f->fmt.pix_mp.pixelformat = fourcc;
118 f->fmt.pix_mp.field = V4L2_FIELD_NONE;
119 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
120 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
121 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
122 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
123 }
124
rkvdec_reset_decoded_fmt(struct rkvdec_ctx * ctx)125 static void rkvdec_reset_decoded_fmt(struct rkvdec_ctx *ctx)
126 {
127 struct v4l2_format *f = &ctx->decoded_fmt;
128 u32 fourcc;
129
130 fourcc = rkvdec_enum_decoded_fmt(ctx, 0, ctx->image_fmt);
131 rkvdec_reset_fmt(ctx, f, fourcc);
132 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
133 f->fmt.pix_mp.width = ctx->coded_fmt.fmt.pix_mp.width;
134 f->fmt.pix_mp.height = ctx->coded_fmt.fmt.pix_mp.height;
135 rkvdec_fill_decoded_pixfmt(ctx, &f->fmt.pix_mp);
136 }
137
rkvdec_try_ctrl(struct v4l2_ctrl * ctrl)138 static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl)
139 {
140 struct rkvdec_ctx *ctx = container_of(ctrl->handler, struct rkvdec_ctx, ctrl_hdl);
141 const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc;
142
143 if (desc->ops->try_ctrl)
144 return desc->ops->try_ctrl(ctx, ctrl);
145
146 return 0;
147 }
148
rkvdec_s_ctrl(struct v4l2_ctrl * ctrl)149 static int rkvdec_s_ctrl(struct v4l2_ctrl *ctrl)
150 {
151 struct rkvdec_ctx *ctx = container_of(ctrl->handler, struct rkvdec_ctx, ctrl_hdl);
152 const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc;
153 enum rkvdec_image_fmt image_fmt;
154 struct vb2_queue *vq;
155
156 if (ctrl->id == V4L2_CID_STATELESS_HEVC_EXT_SPS_ST_RPS) {
157 ctx->has_sps_st_rps |= !!(ctrl->has_changed);
158 return 0;
159 }
160
161 if (ctrl->id == V4L2_CID_STATELESS_HEVC_EXT_SPS_LT_RPS) {
162 ctx->has_sps_lt_rps |= !!(ctrl->has_changed);
163 return 0;
164 }
165
166 /* Check if this change requires a capture format reset */
167 if (!desc->ops->get_image_fmt)
168 return 0;
169
170 image_fmt = desc->ops->get_image_fmt(ctx, ctrl);
171 if (rkvdec_image_fmt_changed(ctx, image_fmt)) {
172 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
173 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
174 if (vb2_is_busy(vq))
175 return -EBUSY;
176
177 ctx->image_fmt = image_fmt;
178 rkvdec_reset_decoded_fmt(ctx);
179 }
180
181 return 0;
182 }
183
184 static const struct v4l2_ctrl_ops rkvdec_ctrl_ops = {
185 .try_ctrl = rkvdec_try_ctrl,
186 .s_ctrl = rkvdec_s_ctrl,
187 };
188
189 static const struct rkvdec_ctrl_desc rkvdec_hevc_ctrl_descs[] = {
190 {
191 .cfg.id = V4L2_CID_STATELESS_HEVC_SLICE_PARAMS,
192 .cfg.flags = V4L2_CTRL_FLAG_DYNAMIC_ARRAY,
193 .cfg.type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS,
194 .cfg.dims = { 600 },
195 },
196 {
197 .cfg.id = V4L2_CID_STATELESS_HEVC_SPS,
198 .cfg.ops = &rkvdec_ctrl_ops,
199 },
200 {
201 .cfg.id = V4L2_CID_STATELESS_HEVC_PPS,
202 },
203 {
204 .cfg.id = V4L2_CID_STATELESS_HEVC_SCALING_MATRIX,
205 },
206 {
207 .cfg.id = V4L2_CID_STATELESS_HEVC_DECODE_PARAMS,
208 },
209 {
210 .cfg.id = V4L2_CID_STATELESS_HEVC_DECODE_MODE,
211 .cfg.min = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED,
212 .cfg.max = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED,
213 .cfg.def = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED,
214 },
215 {
216 .cfg.id = V4L2_CID_STATELESS_HEVC_START_CODE,
217 .cfg.min = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
218 .cfg.def = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
219 .cfg.max = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
220 },
221 {
222 .cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
223 .cfg.min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
224 .cfg.max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
225 .cfg.def = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
226 },
227 {
228 .cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
229 .cfg.min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
230 .cfg.max = V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1,
231 },
232 };
233
234 static const struct rkvdec_ctrls rkvdec_hevc_ctrls = {
235 .ctrls = rkvdec_hevc_ctrl_descs,
236 .num_ctrls = ARRAY_SIZE(rkvdec_hevc_ctrl_descs),
237 };
238
239 static const struct rkvdec_ctrl_desc vdpu38x_hevc_ctrl_descs[] = {
240 {
241 .cfg.id = V4L2_CID_STATELESS_HEVC_DECODE_PARAMS,
242 },
243 {
244 .cfg.id = V4L2_CID_STATELESS_HEVC_SPS,
245 .cfg.ops = &rkvdec_ctrl_ops,
246 },
247 {
248 .cfg.id = V4L2_CID_STATELESS_HEVC_PPS,
249 },
250 {
251 .cfg.id = V4L2_CID_STATELESS_HEVC_SCALING_MATRIX,
252 },
253 {
254 .cfg.id = V4L2_CID_STATELESS_HEVC_DECODE_MODE,
255 .cfg.min = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED,
256 .cfg.max = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED,
257 .cfg.def = V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED,
258 },
259 {
260 .cfg.id = V4L2_CID_STATELESS_HEVC_START_CODE,
261 .cfg.min = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
262 .cfg.def = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
263 .cfg.max = V4L2_STATELESS_HEVC_START_CODE_ANNEX_B,
264 },
265 {
266 .cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
267 .cfg.min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
268 .cfg.max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
269 .cfg.menu_skip_mask =
270 BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE),
271 .cfg.def = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
272 },
273 {
274 .cfg.id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
275 .cfg.min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
276 .cfg.max = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1,
277 },
278 {
279 .cfg.id = V4L2_CID_STATELESS_HEVC_EXT_SPS_ST_RPS,
280 .cfg.ops = &rkvdec_ctrl_ops,
281 .cfg.dims = { 65 },
282 },
283 {
284 .cfg.id = V4L2_CID_STATELESS_HEVC_EXT_SPS_LT_RPS,
285 .cfg.ops = &rkvdec_ctrl_ops,
286 .cfg.dims = { 65 },
287 },
288 };
289
290 static const struct rkvdec_ctrls vdpu38x_hevc_ctrls = {
291 .ctrls = vdpu38x_hevc_ctrl_descs,
292 .num_ctrls = ARRAY_SIZE(vdpu38x_hevc_ctrl_descs),
293 };
294
295 static const struct rkvdec_decoded_fmt_desc rkvdec_hevc_decoded_fmts[] = {
296 {
297 .fourcc = V4L2_PIX_FMT_NV12,
298 .image_fmt = RKVDEC_IMG_FMT_420_8BIT,
299 },
300 {
301 .fourcc = V4L2_PIX_FMT_NV15,
302 .image_fmt = RKVDEC_IMG_FMT_420_10BIT,
303 },
304 };
305
306 static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = {
307 {
308 .cfg.id = V4L2_CID_STATELESS_H264_DECODE_PARAMS,
309 },
310 {
311 .cfg.id = V4L2_CID_STATELESS_H264_SPS,
312 .cfg.ops = &rkvdec_ctrl_ops,
313 },
314 {
315 .cfg.id = V4L2_CID_STATELESS_H264_PPS,
316 },
317 {
318 .cfg.id = V4L2_CID_STATELESS_H264_SCALING_MATRIX,
319 },
320 {
321 .cfg.id = V4L2_CID_STATELESS_H264_DECODE_MODE,
322 .cfg.min = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
323 .cfg.max = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
324 .cfg.def = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
325 },
326 {
327 .cfg.id = V4L2_CID_STATELESS_H264_START_CODE,
328 .cfg.min = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
329 .cfg.def = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
330 .cfg.max = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
331 },
332 {
333 .cfg.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
334 .cfg.min = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE,
335 .cfg.max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA,
336 .cfg.menu_skip_mask =
337 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED) |
338 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE),
339 .cfg.def = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN,
340 },
341 {
342 .cfg.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
343 .cfg.min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
344 .cfg.max = V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
345 },
346 };
347
348 static const struct rkvdec_ctrls rkvdec_h264_ctrls = {
349 .ctrls = rkvdec_h264_ctrl_descs,
350 .num_ctrls = ARRAY_SIZE(rkvdec_h264_ctrl_descs),
351 };
352
353 static const struct rkvdec_ctrl_desc vdpu38x_h264_ctrl_descs[] = {
354 {
355 .cfg.id = V4L2_CID_STATELESS_H264_DECODE_PARAMS,
356 },
357 {
358 .cfg.id = V4L2_CID_STATELESS_H264_SPS,
359 .cfg.ops = &rkvdec_ctrl_ops,
360 },
361 {
362 .cfg.id = V4L2_CID_STATELESS_H264_PPS,
363 },
364 {
365 .cfg.id = V4L2_CID_STATELESS_H264_SCALING_MATRIX,
366 },
367 {
368 .cfg.id = V4L2_CID_STATELESS_H264_DECODE_MODE,
369 .cfg.min = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
370 .cfg.max = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
371 .cfg.def = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
372 },
373 {
374 .cfg.id = V4L2_CID_STATELESS_H264_START_CODE,
375 .cfg.min = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
376 .cfg.def = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
377 .cfg.max = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
378 },
379 {
380 .cfg.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
381 .cfg.min = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE,
382 .cfg.max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA,
383 .cfg.menu_skip_mask =
384 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED) |
385 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE),
386 .cfg.def = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN,
387 },
388 {
389 .cfg.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
390 .cfg.min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
391 .cfg.max = V4L2_MPEG_VIDEO_H264_LEVEL_6_0,
392 },
393 };
394
395 static const struct rkvdec_ctrls vdpu38x_h264_ctrls = {
396 .ctrls = vdpu38x_h264_ctrl_descs,
397 .num_ctrls = ARRAY_SIZE(vdpu38x_h264_ctrl_descs),
398 };
399
400 static const struct rkvdec_decoded_fmt_desc rkvdec_h264_decoded_fmts[] = {
401 {
402 .fourcc = V4L2_PIX_FMT_NV12,
403 .image_fmt = RKVDEC_IMG_FMT_420_8BIT,
404 },
405 {
406 .fourcc = V4L2_PIX_FMT_NV15,
407 .image_fmt = RKVDEC_IMG_FMT_420_10BIT,
408 },
409 {
410 .fourcc = V4L2_PIX_FMT_NV16,
411 .image_fmt = RKVDEC_IMG_FMT_422_8BIT,
412 },
413 {
414 .fourcc = V4L2_PIX_FMT_NV20,
415 .image_fmt = RKVDEC_IMG_FMT_422_10BIT,
416 },
417 };
418
419 static const struct rkvdec_ctrl_desc rkvdec_vp9_ctrl_descs[] = {
420 {
421 .cfg.id = V4L2_CID_STATELESS_VP9_FRAME,
422 },
423 {
424 .cfg.id = V4L2_CID_STATELESS_VP9_COMPRESSED_HDR,
425 },
426 {
427 .cfg.id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
428 .cfg.min = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
429 .cfg.max = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
430 .cfg.def = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
431 },
432 };
433
434 static const struct rkvdec_ctrls rkvdec_vp9_ctrls = {
435 .ctrls = rkvdec_vp9_ctrl_descs,
436 .num_ctrls = ARRAY_SIZE(rkvdec_vp9_ctrl_descs),
437 };
438
439 static const struct rkvdec_decoded_fmt_desc rkvdec_vp9_decoded_fmts[] = {
440 {
441 .fourcc = V4L2_PIX_FMT_NV12,
442 .image_fmt = RKVDEC_IMG_FMT_420_8BIT,
443 },
444 };
445
446 static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = {
447 {
448 .fourcc = V4L2_PIX_FMT_HEVC_SLICE,
449 .frmsize = {
450 .min_width = 64,
451 .max_width = 4096,
452 .step_width = 64,
453 .min_height = 64,
454 .max_height = 2304,
455 .step_height = 16,
456 },
457 .ctrls = &rkvdec_hevc_ctrls,
458 .ops = &rkvdec_hevc_fmt_ops,
459 .num_decoded_fmts = ARRAY_SIZE(rkvdec_hevc_decoded_fmts),
460 .decoded_fmts = rkvdec_hevc_decoded_fmts,
461 },
462 {
463 .fourcc = V4L2_PIX_FMT_H264_SLICE,
464 .frmsize = {
465 .min_width = 64,
466 .max_width = 4096,
467 .step_width = 64,
468 .min_height = 48,
469 .max_height = 2560,
470 .step_height = 16,
471 },
472 .ctrls = &rkvdec_h264_ctrls,
473 .ops = &rkvdec_h264_fmt_ops,
474 .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts),
475 .decoded_fmts = rkvdec_h264_decoded_fmts,
476 .subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
477 },
478 {
479 .fourcc = V4L2_PIX_FMT_VP9_FRAME,
480 .frmsize = {
481 .min_width = 64,
482 .max_width = 4096,
483 .step_width = 64,
484 .min_height = 64,
485 .max_height = 2304,
486 .step_height = 64,
487 },
488 .ctrls = &rkvdec_vp9_ctrls,
489 .ops = &rkvdec_vp9_fmt_ops,
490 .num_decoded_fmts = ARRAY_SIZE(rkvdec_vp9_decoded_fmts),
491 .decoded_fmts = rkvdec_vp9_decoded_fmts,
492 }
493 };
494
495 static const struct rkvdec_coded_fmt_desc rk3288_coded_fmts[] = {
496 {
497 .fourcc = V4L2_PIX_FMT_HEVC_SLICE,
498 .frmsize = {
499 .min_width = 64,
500 .max_width = 4096,
501 .step_width = 64,
502 .min_height = 64,
503 .max_height = 2304,
504 .step_height = 16,
505 },
506 .ctrls = &rkvdec_hevc_ctrls,
507 .ops = &rkvdec_hevc_fmt_ops,
508 .num_decoded_fmts = ARRAY_SIZE(rkvdec_hevc_decoded_fmts),
509 .decoded_fmts = rkvdec_hevc_decoded_fmts,
510 }
511 };
512
513 static const struct rkvdec_coded_fmt_desc vdpu381_coded_fmts[] = {
514 {
515 .fourcc = V4L2_PIX_FMT_HEVC_SLICE,
516 .frmsize = {
517 .min_width = 64,
518 .max_width = 65472,
519 .step_width = 64,
520 .min_height = 64,
521 .max_height = 65472,
522 .step_height = 16,
523 },
524 .ctrls = &vdpu38x_hevc_ctrls,
525 .ops = &rkvdec_vdpu381_hevc_fmt_ops,
526 .num_decoded_fmts = ARRAY_SIZE(rkvdec_hevc_decoded_fmts),
527 .decoded_fmts = rkvdec_hevc_decoded_fmts,
528 .subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
529 },
530 {
531 .fourcc = V4L2_PIX_FMT_H264_SLICE,
532 .frmsize = {
533 .min_width = 64,
534 .max_width = 65520,
535 .step_width = 64,
536 .min_height = 64,
537 .max_height = 65520,
538 .step_height = 16,
539 },
540 .ctrls = &vdpu38x_h264_ctrls,
541 .ops = &rkvdec_vdpu381_h264_fmt_ops,
542 .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts),
543 .decoded_fmts = rkvdec_h264_decoded_fmts,
544 .subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
545 },
546 };
547
548 static const struct rkvdec_coded_fmt_desc vdpu383_coded_fmts[] = {
549 {
550 .fourcc = V4L2_PIX_FMT_HEVC_SLICE,
551 .frmsize = {
552 .min_width = 64,
553 .max_width = 65472,
554 .step_width = 64,
555 .min_height = 64,
556 .max_height = 65472,
557 .step_height = 16,
558 },
559 .ctrls = &vdpu38x_hevc_ctrls,
560 .ops = &rkvdec_vdpu383_hevc_fmt_ops,
561 .num_decoded_fmts = ARRAY_SIZE(rkvdec_hevc_decoded_fmts),
562 .decoded_fmts = rkvdec_hevc_decoded_fmts,
563 .subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
564 },
565 {
566 .fourcc = V4L2_PIX_FMT_H264_SLICE,
567 .frmsize = {
568 .min_width = 64,
569 .max_width = 65520,
570 .step_width = 64,
571 .min_height = 64,
572 .max_height = 65520,
573 .step_height = 16,
574 },
575 .ctrls = &vdpu38x_h264_ctrls,
576 .ops = &rkvdec_vdpu383_h264_fmt_ops,
577 .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts),
578 .decoded_fmts = rkvdec_h264_decoded_fmts,
579 .subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF,
580 },
581 };
582
583 static const struct rkvdec_coded_fmt_desc *
rkvdec_enum_coded_fmt_desc(struct rkvdec_ctx * ctx,int index)584 rkvdec_enum_coded_fmt_desc(struct rkvdec_ctx *ctx, int index)
585 {
586 const struct rkvdec_variant *variant = ctx->dev->variant;
587 int fmt_idx = -1;
588 unsigned int i;
589
590 for (i = 0; i < variant->num_coded_fmts; i++) {
591 fmt_idx++;
592 if (index == fmt_idx)
593 return &variant->coded_fmts[i];
594 }
595
596 return NULL;
597 }
598
599 static const struct rkvdec_coded_fmt_desc *
rkvdec_find_coded_fmt_desc(struct rkvdec_ctx * ctx,u32 fourcc)600 rkvdec_find_coded_fmt_desc(struct rkvdec_ctx *ctx, u32 fourcc)
601 {
602 const struct rkvdec_variant *variant = ctx->dev->variant;
603 unsigned int i;
604
605 for (i = 0; i < variant->num_coded_fmts; i++) {
606 if (variant->coded_fmts[i].fourcc == fourcc)
607 return &variant->coded_fmts[i];
608 }
609
610 return NULL;
611 }
612
rkvdec_reset_coded_fmt(struct rkvdec_ctx * ctx)613 static void rkvdec_reset_coded_fmt(struct rkvdec_ctx *ctx)
614 {
615 struct v4l2_format *f = &ctx->coded_fmt;
616
617 ctx->coded_fmt_desc = rkvdec_enum_coded_fmt_desc(ctx, 0);
618 rkvdec_reset_fmt(ctx, f, ctx->coded_fmt_desc->fourcc);
619
620 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
621 f->fmt.pix_mp.width = ctx->coded_fmt_desc->frmsize.min_width;
622 f->fmt.pix_mp.height = ctx->coded_fmt_desc->frmsize.min_height;
623
624 if (ctx->coded_fmt_desc->ops->adjust_fmt)
625 ctx->coded_fmt_desc->ops->adjust_fmt(ctx, f);
626 }
627
rkvdec_enum_framesizes(struct file * file,void * priv,struct v4l2_frmsizeenum * fsize)628 static int rkvdec_enum_framesizes(struct file *file, void *priv,
629 struct v4l2_frmsizeenum *fsize)
630 {
631 struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
632 const struct rkvdec_coded_fmt_desc *desc;
633
634 if (fsize->index != 0)
635 return -EINVAL;
636
637 desc = rkvdec_find_coded_fmt_desc(ctx, fsize->pixel_format);
638 if (!desc)
639 return -EINVAL;
640
641 fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
642 fsize->stepwise.min_width = 1;
643 fsize->stepwise.max_width = desc->frmsize.max_width;
644 fsize->stepwise.step_width = 1;
645 fsize->stepwise.min_height = 1;
646 fsize->stepwise.max_height = desc->frmsize.max_height;
647 fsize->stepwise.step_height = 1;
648
649 return 0;
650 }
651
rkvdec_querycap(struct file * file,void * priv,struct v4l2_capability * cap)652 static int rkvdec_querycap(struct file *file, void *priv,
653 struct v4l2_capability *cap)
654 {
655 struct rkvdec_dev *rkvdec = video_drvdata(file);
656 struct video_device *vdev = video_devdata(file);
657
658 strscpy(cap->driver, rkvdec->dev->driver->name,
659 sizeof(cap->driver));
660 strscpy(cap->card, vdev->name, sizeof(cap->card));
661 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
662 rkvdec->dev->driver->name);
663 return 0;
664 }
665
rkvdec_try_capture_fmt(struct file * file,void * priv,struct v4l2_format * f)666 static int rkvdec_try_capture_fmt(struct file *file, void *priv,
667 struct v4l2_format *f)
668 {
669 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
670 struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
671 const struct rkvdec_coded_fmt_desc *coded_desc;
672
673 /*
674 * The codec context should point to a coded format desc, if the format
675 * on the coded end has not been set yet, it should point to the
676 * default value.
677 */
678 coded_desc = ctx->coded_fmt_desc;
679 if (WARN_ON(!coded_desc))
680 return -EINVAL;
681
682 if (!rkvdec_is_valid_fmt(ctx, pix_mp->pixelformat, ctx->image_fmt))
683 pix_mp->pixelformat = rkvdec_enum_decoded_fmt(ctx, 0,
684 ctx->image_fmt);
685
686 /* Always apply the frmsize constraint of the coded end. */
687 pix_mp->width = max(pix_mp->width, ctx->coded_fmt.fmt.pix_mp.width);
688 pix_mp->height = max(pix_mp->height, ctx->coded_fmt.fmt.pix_mp.height);
689 v4l2_apply_frmsize_constraints(&pix_mp->width,
690 &pix_mp->height,
691 &coded_desc->frmsize);
692
693 rkvdec_fill_decoded_pixfmt(ctx, pix_mp);
694 pix_mp->field = V4L2_FIELD_NONE;
695
696 return 0;
697 }
698
rkvdec_try_output_fmt(struct file * file,void * priv,struct v4l2_format * f)699 static int rkvdec_try_output_fmt(struct file *file, void *priv,
700 struct v4l2_format *f)
701 {
702 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
703 struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
704 const struct rkvdec_coded_fmt_desc *desc;
705
706 desc = rkvdec_find_coded_fmt_desc(ctx, pix_mp->pixelformat);
707 if (!desc) {
708 desc = rkvdec_enum_coded_fmt_desc(ctx, 0);
709 pix_mp->pixelformat = desc->fourcc;
710 }
711
712 v4l2_apply_frmsize_constraints(&pix_mp->width,
713 &pix_mp->height,
714 &desc->frmsize);
715
716 pix_mp->field = V4L2_FIELD_NONE;
717 /* All coded formats are considered single planar for now. */
718 pix_mp->num_planes = 1;
719
720 if (desc->ops->adjust_fmt) {
721 int ret;
722
723 ret = desc->ops->adjust_fmt(ctx, f);
724 if (ret)
725 return ret;
726 }
727
728 return 0;
729 }
730
rkvdec_s_capture_fmt(struct file * file,void * priv,struct v4l2_format * f)731 static int rkvdec_s_capture_fmt(struct file *file, void *priv,
732 struct v4l2_format *f)
733 {
734 struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
735 struct vb2_queue *vq;
736 int ret;
737
738 /* Change not allowed if queue is busy */
739 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
740 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
741 if (vb2_is_busy(vq))
742 return -EBUSY;
743
744 ret = rkvdec_try_capture_fmt(file, priv, f);
745 if (ret)
746 return ret;
747
748 ctx->decoded_fmt = *f;
749 return 0;
750 }
751
rkvdec_s_output_fmt(struct file * file,void * priv,struct v4l2_format * f)752 static int rkvdec_s_output_fmt(struct file *file, void *priv,
753 struct v4l2_format *f)
754 {
755 struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
756 struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
757 const struct rkvdec_coded_fmt_desc *desc;
758 struct v4l2_format *cap_fmt;
759 struct vb2_queue *peer_vq, *vq;
760 int ret;
761
762 /*
763 * In order to support dynamic resolution change, the decoder admits
764 * a resolution change, as long as the pixelformat remains. Can't be
765 * done if streaming.
766 */
767 vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
768 if (vb2_is_streaming(vq) ||
769 (vb2_is_busy(vq) &&
770 f->fmt.pix_mp.pixelformat != ctx->coded_fmt.fmt.pix_mp.pixelformat))
771 return -EBUSY;
772
773 /*
774 * Since format change on the OUTPUT queue will reset the CAPTURE
775 * queue, we can't allow doing so when the CAPTURE queue has buffers
776 * allocated.
777 */
778 peer_vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
779 if (vb2_is_busy(peer_vq))
780 return -EBUSY;
781
782 ret = rkvdec_try_output_fmt(file, priv, f);
783 if (ret)
784 return ret;
785
786 desc = rkvdec_find_coded_fmt_desc(ctx, f->fmt.pix_mp.pixelformat);
787 if (!desc)
788 return -EINVAL;
789 ctx->coded_fmt_desc = desc;
790 ctx->coded_fmt = *f;
791
792 /*
793 * Current decoded format might have become invalid with newly
794 * selected codec, so reset it to default just to be safe and
795 * keep internal driver state sane. User is mandated to set
796 * the decoded format again after we return, so we don't need
797 * anything smarter.
798 *
799 * Note that this will propagates any size changes to the decoded format.
800 */
801 ctx->image_fmt = RKVDEC_IMG_FMT_ANY;
802 rkvdec_reset_decoded_fmt(ctx);
803
804 /* Propagate colorspace information to capture. */
805 cap_fmt = &ctx->decoded_fmt;
806 cap_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
807 cap_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
808 cap_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
809 cap_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
810
811 /* Enable format specific queue features */
812 vq->subsystem_flags |= desc->subsystem_flags;
813
814 return 0;
815 }
816
rkvdec_g_output_fmt(struct file * file,void * priv,struct v4l2_format * f)817 static int rkvdec_g_output_fmt(struct file *file, void *priv,
818 struct v4l2_format *f)
819 {
820 struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
821
822 *f = ctx->coded_fmt;
823 return 0;
824 }
825
rkvdec_g_capture_fmt(struct file * file,void * priv,struct v4l2_format * f)826 static int rkvdec_g_capture_fmt(struct file *file, void *priv,
827 struct v4l2_format *f)
828 {
829 struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
830
831 *f = ctx->decoded_fmt;
832 return 0;
833 }
834
rkvdec_enum_output_fmt(struct file * file,void * priv,struct v4l2_fmtdesc * f)835 static int rkvdec_enum_output_fmt(struct file *file, void *priv,
836 struct v4l2_fmtdesc *f)
837 {
838 struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
839 const struct rkvdec_coded_fmt_desc *desc;
840
841 desc = rkvdec_enum_coded_fmt_desc(ctx, f->index);
842 if (!desc)
843 return -EINVAL;
844
845 f->pixelformat = desc->fourcc;
846 return 0;
847 }
848
rkvdec_enum_capture_fmt(struct file * file,void * priv,struct v4l2_fmtdesc * f)849 static int rkvdec_enum_capture_fmt(struct file *file, void *priv,
850 struct v4l2_fmtdesc *f)
851 {
852 struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
853 u32 fourcc;
854
855 fourcc = rkvdec_enum_decoded_fmt(ctx, f->index, ctx->image_fmt);
856 if (!fourcc)
857 return -EINVAL;
858
859 f->pixelformat = fourcc;
860 return 0;
861 }
862
863 static const struct v4l2_ioctl_ops rkvdec_ioctl_ops = {
864 .vidioc_querycap = rkvdec_querycap,
865 .vidioc_enum_framesizes = rkvdec_enum_framesizes,
866
867 .vidioc_try_fmt_vid_cap_mplane = rkvdec_try_capture_fmt,
868 .vidioc_try_fmt_vid_out_mplane = rkvdec_try_output_fmt,
869 .vidioc_s_fmt_vid_out_mplane = rkvdec_s_output_fmt,
870 .vidioc_s_fmt_vid_cap_mplane = rkvdec_s_capture_fmt,
871 .vidioc_g_fmt_vid_out_mplane = rkvdec_g_output_fmt,
872 .vidioc_g_fmt_vid_cap_mplane = rkvdec_g_capture_fmt,
873 .vidioc_enum_fmt_vid_out = rkvdec_enum_output_fmt,
874 .vidioc_enum_fmt_vid_cap = rkvdec_enum_capture_fmt,
875
876 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
877 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
878 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
879 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
880 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
881 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
882 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
883
884 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
885 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
886
887 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
888 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
889
890 .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd,
891 .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd,
892 };
893
rkvdec_queue_setup(struct vb2_queue * vq,unsigned int * num_buffers,unsigned int * num_planes,unsigned int sizes[],struct device * alloc_devs[])894 static int rkvdec_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
895 unsigned int *num_planes, unsigned int sizes[],
896 struct device *alloc_devs[])
897 {
898 struct rkvdec_ctx *ctx = vb2_get_drv_priv(vq);
899 struct v4l2_format *f;
900 unsigned int i;
901
902 if (V4L2_TYPE_IS_OUTPUT(vq->type))
903 f = &ctx->coded_fmt;
904 else
905 f = &ctx->decoded_fmt;
906
907 if (*num_planes) {
908 if (*num_planes != f->fmt.pix_mp.num_planes)
909 return -EINVAL;
910
911 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) {
912 if (sizes[i] < f->fmt.pix_mp.plane_fmt[i].sizeimage)
913 return -EINVAL;
914 }
915 } else {
916 *num_planes = f->fmt.pix_mp.num_planes;
917 for (i = 0; i < f->fmt.pix_mp.num_planes; i++)
918 sizes[i] = f->fmt.pix_mp.plane_fmt[i].sizeimage;
919 }
920
921 return 0;
922 }
923
rkvdec_buf_prepare(struct vb2_buffer * vb)924 static int rkvdec_buf_prepare(struct vb2_buffer *vb)
925 {
926 struct vb2_queue *vq = vb->vb2_queue;
927 struct rkvdec_ctx *ctx = vb2_get_drv_priv(vq);
928 struct v4l2_format *f;
929 unsigned int i;
930
931 if (V4L2_TYPE_IS_OUTPUT(vq->type))
932 f = &ctx->coded_fmt;
933 else
934 f = &ctx->decoded_fmt;
935
936 for (i = 0; i < f->fmt.pix_mp.num_planes; ++i) {
937 u32 sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage;
938
939 if (vb2_plane_size(vb, i) < sizeimage)
940 return -EINVAL;
941 }
942
943 /*
944 * Buffer's bytesused must be written by driver for CAPTURE buffers.
945 * (for OUTPUT buffers, if userspace passes 0 bytesused, v4l2-core sets
946 * it to buffer length).
947 */
948 if (V4L2_TYPE_IS_CAPTURE(vq->type))
949 vb2_set_plane_payload(vb, 0, f->fmt.pix_mp.plane_fmt[0].sizeimage);
950
951 return 0;
952 }
953
rkvdec_buf_queue(struct vb2_buffer * vb)954 static void rkvdec_buf_queue(struct vb2_buffer *vb)
955 {
956 struct rkvdec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
957 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
958
959 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
960 }
961
rkvdec_buf_out_validate(struct vb2_buffer * vb)962 static int rkvdec_buf_out_validate(struct vb2_buffer *vb)
963 {
964 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
965
966 vbuf->field = V4L2_FIELD_NONE;
967 return 0;
968 }
969
rkvdec_buf_request_complete(struct vb2_buffer * vb)970 static void rkvdec_buf_request_complete(struct vb2_buffer *vb)
971 {
972 struct rkvdec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
973
974 v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->ctrl_hdl);
975 }
976
rkvdec_start_streaming(struct vb2_queue * q,unsigned int count)977 static int rkvdec_start_streaming(struct vb2_queue *q, unsigned int count)
978 {
979 struct rkvdec_ctx *ctx = vb2_get_drv_priv(q);
980 const struct rkvdec_coded_fmt_desc *desc;
981 const struct rkvdec_variant *variant = ctx->dev->variant;
982 int ret;
983
984 if (V4L2_TYPE_IS_CAPTURE(q->type))
985 return 0;
986
987 desc = ctx->coded_fmt_desc;
988 if (WARN_ON(!desc))
989 return -EINVAL;
990
991 ret = rkvdec_allocate_rcb(ctx, variant->rcb_sizes, variant->num_rcb_sizes);
992 if (ret)
993 return ret;
994
995 if (desc->ops->start) {
996 ret = desc->ops->start(ctx);
997 if (ret)
998 goto err_ops_start;
999 }
1000
1001 return 0;
1002
1003 err_ops_start:
1004 rkvdec_free_rcb(ctx);
1005
1006 return ret;
1007 }
1008
rkvdec_queue_cleanup(struct vb2_queue * vq,u32 state)1009 static void rkvdec_queue_cleanup(struct vb2_queue *vq, u32 state)
1010 {
1011 struct rkvdec_ctx *ctx = vb2_get_drv_priv(vq);
1012
1013 while (true) {
1014 struct vb2_v4l2_buffer *vbuf;
1015
1016 if (V4L2_TYPE_IS_OUTPUT(vq->type))
1017 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1018 else
1019 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1020
1021 if (!vbuf)
1022 break;
1023
1024 v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
1025 &ctx->ctrl_hdl);
1026 v4l2_m2m_buf_done(vbuf, state);
1027 }
1028 }
1029
rkvdec_stop_streaming(struct vb2_queue * q)1030 static void rkvdec_stop_streaming(struct vb2_queue *q)
1031 {
1032 struct rkvdec_ctx *ctx = vb2_get_drv_priv(q);
1033
1034 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1035 const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc;
1036
1037 if (WARN_ON(!desc))
1038 return;
1039
1040 if (desc->ops->stop)
1041 desc->ops->stop(ctx);
1042
1043 rkvdec_free_rcb(ctx);
1044 }
1045
1046 rkvdec_queue_cleanup(q, VB2_BUF_STATE_ERROR);
1047 }
1048
1049 static const struct vb2_ops rkvdec_queue_ops = {
1050 .queue_setup = rkvdec_queue_setup,
1051 .buf_prepare = rkvdec_buf_prepare,
1052 .buf_queue = rkvdec_buf_queue,
1053 .buf_out_validate = rkvdec_buf_out_validate,
1054 .buf_request_complete = rkvdec_buf_request_complete,
1055 .start_streaming = rkvdec_start_streaming,
1056 .stop_streaming = rkvdec_stop_streaming,
1057 };
1058
rkvdec_request_validate(struct media_request * req)1059 static int rkvdec_request_validate(struct media_request *req)
1060 {
1061 unsigned int count;
1062
1063 count = vb2_request_buffer_cnt(req);
1064 if (!count)
1065 return -ENOENT;
1066 else if (count > 1)
1067 return -EINVAL;
1068
1069 return vb2_request_validate(req);
1070 }
1071
1072 static const struct media_device_ops rkvdec_media_ops = {
1073 .req_validate = rkvdec_request_validate,
1074 .req_queue = v4l2_m2m_request_queue,
1075 };
1076
rkvdec_job_finish_no_pm(struct rkvdec_ctx * ctx,enum vb2_buffer_state result)1077 static void rkvdec_job_finish_no_pm(struct rkvdec_ctx *ctx,
1078 enum vb2_buffer_state result)
1079 {
1080 if (ctx->coded_fmt_desc->ops->done) {
1081 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1082
1083 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1084 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1085 ctx->coded_fmt_desc->ops->done(ctx, src_buf, dst_buf, result);
1086 }
1087
1088 v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx,
1089 result);
1090 }
1091
rkvdec_job_finish(struct rkvdec_ctx * ctx,enum vb2_buffer_state result)1092 static void rkvdec_job_finish(struct rkvdec_ctx *ctx,
1093 enum vb2_buffer_state result)
1094 {
1095 struct rkvdec_dev *rkvdec = ctx->dev;
1096
1097 pm_runtime_put_autosuspend(rkvdec->dev);
1098 rkvdec_job_finish_no_pm(ctx, result);
1099 }
1100
rkvdec_run_preamble(struct rkvdec_ctx * ctx,struct rkvdec_run * run)1101 void rkvdec_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run)
1102 {
1103 struct media_request *src_req;
1104
1105 memset(run, 0, sizeof(*run));
1106
1107 run->bufs.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1108 run->bufs.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1109
1110 /* Apply request(s) controls if needed. */
1111 src_req = run->bufs.src->vb2_buf.req_obj.req;
1112 if (src_req)
1113 v4l2_ctrl_request_setup(src_req, &ctx->ctrl_hdl);
1114
1115 v4l2_m2m_buf_copy_metadata(run->bufs.src, run->bufs.dst);
1116 }
1117
rkvdec_run_postamble(struct rkvdec_ctx * ctx,struct rkvdec_run * run)1118 void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run)
1119 {
1120 struct media_request *src_req = run->bufs.src->vb2_buf.req_obj.req;
1121
1122 if (src_req)
1123 v4l2_ctrl_request_complete(src_req, &ctx->ctrl_hdl);
1124 }
1125
rkvdec_quirks_disable_qos(struct rkvdec_ctx * ctx)1126 void rkvdec_quirks_disable_qos(struct rkvdec_ctx *ctx)
1127 {
1128 struct rkvdec_dev *rkvdec = ctx->dev;
1129 u32 reg;
1130
1131 /* Set undocumented swreg_block_gating_e field */
1132 reg = readl(rkvdec->regs + RKVDEC_REG_QOS_CTRL);
1133 reg &= GENMASK(31, 16);
1134 reg |= 0xEFFF;
1135 writel(reg, rkvdec->regs + RKVDEC_REG_QOS_CTRL);
1136 }
1137
rkvdec_memcpy_toio(void __iomem * dst,void * src,size_t len)1138 void rkvdec_memcpy_toio(void __iomem *dst, void *src, size_t len)
1139 {
1140 #ifdef CONFIG_ARM64
1141 __iowrite32_copy(dst, src, len / 4);
1142 #else
1143 memcpy_toio(dst, src, len);
1144 #endif
1145 }
1146
rkvdec_schedule_watchdog(struct rkvdec_dev * rkvdec,u32 timeout_threshold)1147 void rkvdec_schedule_watchdog(struct rkvdec_dev *rkvdec, u32 timeout_threshold)
1148 {
1149 /* Set watchdog at 2 times the hardware timeout threshold */
1150 u32 watchdog_time;
1151 unsigned long axi_rate = clk_get_rate(rkvdec->axi_clk);
1152
1153 if (axi_rate)
1154 watchdog_time = 2 * div_u64(1000 * (u64)timeout_threshold, axi_rate);
1155 else
1156 watchdog_time = 2000;
1157
1158 schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(watchdog_time));
1159 }
1160
rkvdec_device_run(void * priv)1161 static void rkvdec_device_run(void *priv)
1162 {
1163 struct rkvdec_ctx *ctx = priv;
1164 struct rkvdec_dev *rkvdec = ctx->dev;
1165 const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc;
1166 int ret;
1167
1168 if (WARN_ON(!desc))
1169 return;
1170
1171 ret = pm_runtime_resume_and_get(rkvdec->dev);
1172 if (ret < 0) {
1173 rkvdec_job_finish_no_pm(ctx, VB2_BUF_STATE_ERROR);
1174 return;
1175 }
1176
1177 ret = desc->ops->run(ctx);
1178 if (ret)
1179 rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR);
1180 }
1181
1182 static const struct v4l2_m2m_ops rkvdec_m2m_ops = {
1183 .device_run = rkvdec_device_run,
1184 };
1185
rkvdec_queue_init(void * priv,struct vb2_queue * src_vq,struct vb2_queue * dst_vq)1186 static int rkvdec_queue_init(void *priv,
1187 struct vb2_queue *src_vq,
1188 struct vb2_queue *dst_vq)
1189 {
1190 struct rkvdec_ctx *ctx = priv;
1191 struct rkvdec_dev *rkvdec = ctx->dev;
1192 int ret;
1193
1194 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1195 src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
1196 src_vq->drv_priv = ctx;
1197 src_vq->ops = &rkvdec_queue_ops;
1198 src_vq->mem_ops = &vb2_dma_contig_memops;
1199
1200 /*
1201 * Driver does mostly sequential access, so sacrifice TLB efficiency
1202 * for faster allocation. Also, no CPU access on the source queue,
1203 * so no kernel mapping needed.
1204 */
1205 src_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES |
1206 DMA_ATTR_NO_KERNEL_MAPPING;
1207 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1208 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1209 src_vq->lock = &rkvdec->vdev_lock;
1210 src_vq->dev = rkvdec->v4l2_dev.dev;
1211 src_vq->supports_requests = true;
1212 src_vq->requires_requests = true;
1213
1214 ret = vb2_queue_init(src_vq);
1215 if (ret)
1216 return ret;
1217
1218 dst_vq->bidirectional = true;
1219 dst_vq->mem_ops = &vb2_dma_contig_memops;
1220 dst_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES |
1221 DMA_ATTR_NO_KERNEL_MAPPING;
1222 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1223 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
1224 dst_vq->drv_priv = ctx;
1225 dst_vq->ops = &rkvdec_queue_ops;
1226 dst_vq->buf_struct_size = sizeof(struct rkvdec_decoded_buffer);
1227 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1228 dst_vq->lock = &rkvdec->vdev_lock;
1229 dst_vq->dev = rkvdec->v4l2_dev.dev;
1230
1231 return vb2_queue_init(dst_vq);
1232 }
1233
rkvdec_add_ctrls(struct rkvdec_ctx * ctx,const struct rkvdec_ctrls * ctrls)1234 static int rkvdec_add_ctrls(struct rkvdec_ctx *ctx,
1235 const struct rkvdec_ctrls *ctrls)
1236 {
1237 unsigned int i;
1238
1239 for (i = 0; i < ctrls->num_ctrls; i++) {
1240 const struct v4l2_ctrl_config *cfg = &ctrls->ctrls[i].cfg;
1241
1242 v4l2_ctrl_new_custom(&ctx->ctrl_hdl, cfg, ctx);
1243 if (ctx->ctrl_hdl.error)
1244 return ctx->ctrl_hdl.error;
1245 }
1246
1247 return 0;
1248 }
1249
rkvdec_init_ctrls(struct rkvdec_ctx * ctx)1250 static int rkvdec_init_ctrls(struct rkvdec_ctx *ctx)
1251 {
1252 const struct rkvdec_variant *variant = ctx->dev->variant;
1253 unsigned int i, nctrls = 0;
1254 int ret;
1255
1256 for (i = 0; i < variant->num_coded_fmts; i++)
1257 nctrls += variant->coded_fmts[i].ctrls->num_ctrls;
1258
1259 v4l2_ctrl_handler_init(&ctx->ctrl_hdl, nctrls);
1260
1261 for (i = 0; i < variant->num_coded_fmts; i++) {
1262 ret = rkvdec_add_ctrls(ctx, variant->coded_fmts[i].ctrls);
1263 if (ret)
1264 goto err_free_handler;
1265 }
1266
1267 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
1268 if (ret)
1269 goto err_free_handler;
1270
1271 ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
1272 return 0;
1273
1274 err_free_handler:
1275 v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
1276 return ret;
1277 }
1278
rkvdec_open(struct file * filp)1279 static int rkvdec_open(struct file *filp)
1280 {
1281 struct rkvdec_dev *rkvdec = video_drvdata(filp);
1282 struct rkvdec_ctx *ctx;
1283 int ret;
1284
1285 ctx = kzalloc_obj(*ctx);
1286 if (!ctx)
1287 return -ENOMEM;
1288
1289 ctx->dev = rkvdec;
1290 rkvdec_reset_coded_fmt(ctx);
1291 rkvdec_reset_decoded_fmt(ctx);
1292 v4l2_fh_init(&ctx->fh, video_devdata(filp));
1293
1294 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(rkvdec->m2m_dev, ctx,
1295 rkvdec_queue_init);
1296 if (IS_ERR(ctx->fh.m2m_ctx)) {
1297 ret = PTR_ERR(ctx->fh.m2m_ctx);
1298 goto err_free_ctx;
1299 }
1300
1301 ret = rkvdec_init_ctrls(ctx);
1302 if (ret)
1303 goto err_cleanup_m2m_ctx;
1304
1305 v4l2_fh_add(&ctx->fh, filp);
1306
1307 return 0;
1308
1309 err_cleanup_m2m_ctx:
1310 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1311
1312 err_free_ctx:
1313 kfree(ctx);
1314 return ret;
1315 }
1316
rkvdec_release(struct file * filp)1317 static int rkvdec_release(struct file *filp)
1318 {
1319 struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(filp);
1320
1321 v4l2_fh_del(&ctx->fh, filp);
1322 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1323 v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
1324 v4l2_fh_exit(&ctx->fh);
1325 kfree(ctx);
1326
1327 return 0;
1328 }
1329
1330 static const struct v4l2_file_operations rkvdec_fops = {
1331 .owner = THIS_MODULE,
1332 .open = rkvdec_open,
1333 .release = rkvdec_release,
1334 .poll = v4l2_m2m_fop_poll,
1335 .unlocked_ioctl = video_ioctl2,
1336 .mmap = v4l2_m2m_fop_mmap,
1337 };
1338
rkvdec_v4l2_init(struct rkvdec_dev * rkvdec)1339 static int rkvdec_v4l2_init(struct rkvdec_dev *rkvdec)
1340 {
1341 int ret;
1342
1343 ret = v4l2_device_register(rkvdec->dev, &rkvdec->v4l2_dev);
1344 if (ret) {
1345 dev_err(rkvdec->dev, "Failed to register V4L2 device\n");
1346 return ret;
1347 }
1348
1349 rkvdec->m2m_dev = v4l2_m2m_init(&rkvdec_m2m_ops);
1350 if (IS_ERR(rkvdec->m2m_dev)) {
1351 v4l2_err(&rkvdec->v4l2_dev, "Failed to init mem2mem device\n");
1352 ret = PTR_ERR(rkvdec->m2m_dev);
1353 goto err_unregister_v4l2;
1354 }
1355
1356 rkvdec->mdev.dev = rkvdec->dev;
1357 strscpy(rkvdec->mdev.model, "rkvdec", sizeof(rkvdec->mdev.model));
1358 strscpy(rkvdec->mdev.bus_info, "platform:rkvdec",
1359 sizeof(rkvdec->mdev.bus_info));
1360 media_device_init(&rkvdec->mdev);
1361 rkvdec->mdev.ops = &rkvdec_media_ops;
1362 rkvdec->v4l2_dev.mdev = &rkvdec->mdev;
1363
1364 rkvdec->vdev.lock = &rkvdec->vdev_lock;
1365 rkvdec->vdev.v4l2_dev = &rkvdec->v4l2_dev;
1366 rkvdec->vdev.fops = &rkvdec_fops;
1367 rkvdec->vdev.release = video_device_release_empty;
1368 rkvdec->vdev.vfl_dir = VFL_DIR_M2M;
1369 rkvdec->vdev.device_caps = V4L2_CAP_STREAMING |
1370 V4L2_CAP_VIDEO_M2M_MPLANE;
1371 rkvdec->vdev.ioctl_ops = &rkvdec_ioctl_ops;
1372 video_set_drvdata(&rkvdec->vdev, rkvdec);
1373 strscpy(rkvdec->vdev.name, "rkvdec", sizeof(rkvdec->vdev.name));
1374
1375 ret = video_register_device(&rkvdec->vdev, VFL_TYPE_VIDEO, -1);
1376 if (ret) {
1377 v4l2_err(&rkvdec->v4l2_dev, "Failed to register video device\n");
1378 goto err_cleanup_mc;
1379 }
1380
1381 ret = v4l2_m2m_register_media_controller(rkvdec->m2m_dev, &rkvdec->vdev,
1382 MEDIA_ENT_F_PROC_VIDEO_DECODER);
1383 if (ret) {
1384 v4l2_err(&rkvdec->v4l2_dev,
1385 "Failed to initialize V4L2 M2M media controller\n");
1386 goto err_unregister_vdev;
1387 }
1388
1389 ret = media_device_register(&rkvdec->mdev);
1390 if (ret) {
1391 v4l2_err(&rkvdec->v4l2_dev, "Failed to register media device\n");
1392 goto err_unregister_mc;
1393 }
1394
1395 return 0;
1396
1397 err_unregister_mc:
1398 v4l2_m2m_unregister_media_controller(rkvdec->m2m_dev);
1399
1400 err_unregister_vdev:
1401 video_unregister_device(&rkvdec->vdev);
1402
1403 err_cleanup_mc:
1404 media_device_cleanup(&rkvdec->mdev);
1405 v4l2_m2m_release(rkvdec->m2m_dev);
1406
1407 err_unregister_v4l2:
1408 v4l2_device_unregister(&rkvdec->v4l2_dev);
1409 return ret;
1410 }
1411
rkvdec_v4l2_cleanup(struct rkvdec_dev * rkvdec)1412 static void rkvdec_v4l2_cleanup(struct rkvdec_dev *rkvdec)
1413 {
1414 media_device_unregister(&rkvdec->mdev);
1415 v4l2_m2m_unregister_media_controller(rkvdec->m2m_dev);
1416 video_unregister_device(&rkvdec->vdev);
1417 media_device_cleanup(&rkvdec->mdev);
1418 v4l2_m2m_release(rkvdec->m2m_dev);
1419 v4l2_device_unregister(&rkvdec->v4l2_dev);
1420 }
1421
rkvdec_iommu_restore(struct rkvdec_dev * rkvdec)1422 static void rkvdec_iommu_restore(struct rkvdec_dev *rkvdec)
1423 {
1424 if (rkvdec->empty_domain) {
1425 /*
1426 * To rewrite mapping into the attached IOMMU core, attach a new empty domain that
1427 * will program an empty table, then detach it to restore the default domain and
1428 * all cached mappings.
1429 * This is safely done in this interrupt handler to make sure no memory get mapped
1430 * through the IOMMU while the empty domain is attached.
1431 */
1432 iommu_attach_device(rkvdec->empty_domain, rkvdec->dev);
1433 iommu_detach_device(rkvdec->empty_domain, rkvdec->dev);
1434 }
1435 }
1436
rk3399_irq_handler(struct rkvdec_ctx * ctx)1437 static irqreturn_t rk3399_irq_handler(struct rkvdec_ctx *ctx)
1438 {
1439 struct rkvdec_dev *rkvdec = ctx->dev;
1440 enum vb2_buffer_state state;
1441 u32 status;
1442
1443 status = readl(rkvdec->regs + RKVDEC_REG_INTERRUPT);
1444 writel(0, rkvdec->regs + RKVDEC_REG_INTERRUPT);
1445
1446 if (status & RKVDEC_RDY_STA) {
1447 state = VB2_BUF_STATE_DONE;
1448 } else {
1449 state = VB2_BUF_STATE_ERROR;
1450 if (status & RKVDEC_SOFTRESET_RDY)
1451 rkvdec_iommu_restore(rkvdec);
1452 }
1453
1454 if (cancel_delayed_work(&rkvdec->watchdog_work))
1455 rkvdec_job_finish(ctx, state);
1456
1457 return IRQ_HANDLED;
1458 }
1459
vdpu381_irq_handler(struct rkvdec_ctx * ctx)1460 static irqreturn_t vdpu381_irq_handler(struct rkvdec_ctx *ctx)
1461 {
1462 struct rkvdec_dev *rkvdec = ctx->dev;
1463 enum vb2_buffer_state state;
1464 bool need_reset = 0;
1465 u32 status;
1466
1467 status = readl(rkvdec->regs + VDPU381_REG_STA_INT);
1468 writel(0, rkvdec->regs + VDPU381_REG_STA_INT);
1469
1470 if (status & VDPU381_STA_INT_DEC_RDY_STA) {
1471 state = VB2_BUF_STATE_DONE;
1472 } else {
1473 state = VB2_BUF_STATE_ERROR;
1474 if (status & (VDPU381_STA_INT_SOFTRESET_RDY |
1475 VDPU381_STA_INT_TIMEOUT |
1476 VDPU381_STA_INT_ERROR))
1477 rkvdec_iommu_restore(rkvdec);
1478 }
1479
1480 if (need_reset)
1481 rkvdec_iommu_restore(rkvdec);
1482
1483 if (cancel_delayed_work(&rkvdec->watchdog_work))
1484 rkvdec_job_finish(ctx, state);
1485
1486 return IRQ_HANDLED;
1487 }
1488
vdpu383_irq_handler(struct rkvdec_ctx * ctx)1489 static irqreturn_t vdpu383_irq_handler(struct rkvdec_ctx *ctx)
1490 {
1491 struct rkvdec_dev *rkvdec = ctx->dev;
1492 enum vb2_buffer_state state;
1493 bool need_reset = 0;
1494 u32 status;
1495
1496 status = readl(rkvdec->link + VDPU383_LINK_STA_INT);
1497 writel(FIELD_PREP_WM16(VDPU383_STA_INT_ALL, 0), rkvdec->link + VDPU383_LINK_STA_INT);
1498 /* On vdpu383, the interrupts must be disabled */
1499 writel(FIELD_PREP_WM16(VDPU383_INT_EN_IRQ | VDPU383_INT_EN_LINE_IRQ, 0),
1500 rkvdec->link + VDPU383_LINK_INT_EN);
1501
1502 if (status & VDPU383_STA_INT_DEC_RDY_STA) {
1503 state = VB2_BUF_STATE_DONE;
1504 } else {
1505 state = VB2_BUF_STATE_ERROR;
1506 rkvdec_iommu_restore(rkvdec);
1507 }
1508
1509 if (need_reset)
1510 rkvdec_iommu_restore(rkvdec);
1511
1512 if (cancel_delayed_work(&rkvdec->watchdog_work))
1513 rkvdec_job_finish(ctx, state);
1514
1515 return IRQ_HANDLED;
1516 }
1517
rkvdec_irq_handler(int irq,void * priv)1518 static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
1519 {
1520 struct rkvdec_dev *rkvdec = priv;
1521 struct rkvdec_ctx *ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);
1522 const struct rkvdec_variant *variant = rkvdec->variant;
1523
1524 return variant->ops->irq_handler(ctx);
1525 }
1526
1527 /*
1528 * Flip one or more matrices along their main diagonal and flatten them
1529 * before writing it to the memory.
1530 * Convert:
1531 * ABCD AEIM
1532 * EFGH => BFJN => AEIMBFJNCGKODHLP
1533 * IJKL CGKO
1534 * MNOP DHLP
1535 */
transpose_and_flatten_matrices(u8 * output,const u8 * input,int matrices,int row_length)1536 static void transpose_and_flatten_matrices(u8 *output, const u8 *input,
1537 int matrices, int row_length)
1538 {
1539 int i, j, row, x_offset, matrix_offset, rot_index, y_offset, matrix_size, new_value;
1540
1541 matrix_size = row_length * row_length;
1542 for (i = 0; i < matrices; i++) {
1543 row = 0;
1544 x_offset = 0;
1545 matrix_offset = i * matrix_size;
1546 for (j = 0; j < matrix_size; j++) {
1547 y_offset = j - (row * row_length);
1548 rot_index = y_offset * row_length + x_offset;
1549 new_value = *(input + i * matrix_size + j);
1550 output[matrix_offset + rot_index] = new_value;
1551 if ((j + 1) % row_length == 0) {
1552 row += 1;
1553 x_offset += 1;
1554 }
1555 }
1556 }
1557 }
1558
1559 /*
1560 * VDPU383 needs a specific order:
1561 * The 8x8 flatten matrix is based on 4x4 blocks.
1562 * Each 4x4 block is written separately in order.
1563 *
1564 * Base data => Transposed VDPU383 transposed
1565 *
1566 * ABCDEFGH AIQYaiqy AIQYBJRZ
1567 * IJKLMNOP BJRZbjrz CKS0DLT1
1568 * QRSTUVWX CKS0cks6 aiqybjrz
1569 * YZ012345 => DLT1dlt7 cks6dlt7
1570 * abcdefgh EMU2emu8 EMU2FNV3
1571 * ijklmnop FNV3fnv9 GOW4HPX5
1572 * qrstuvwx GOW4gow# emu8fnv9
1573 * yz6789#$ HPX5hpx$ gow#hpx$
1574 *
1575 * As the function reads block of 4x4 it can be used for both 4x4 and 8x8 matrices.
1576 *
1577 */
vdpu383_flatten_matrices(u8 * output,const u8 * input,int matrices,int row_length)1578 static void vdpu383_flatten_matrices(u8 *output, const u8 *input, int matrices, int row_length)
1579 {
1580 u8 block;
1581 int i, j, matrix_offset, matrix_size, new_value, input_idx, line_offset, block_offset;
1582
1583 matrix_size = row_length * row_length;
1584 for (i = 0; i < matrices; i++) {
1585 matrix_offset = i * matrix_size;
1586 for (j = 0; j < matrix_size; j++) {
1587 block = j / 16;
1588 line_offset = (j % 16) / 4;
1589 block_offset = (block & 1) * 32 + (block & 2) * 2;
1590 input_idx = ((j % 4) * row_length) + line_offset + block_offset;
1591
1592 new_value = *(input + i * matrix_size + input_idx);
1593
1594 output[matrix_offset + j] = new_value;
1595 }
1596 }
1597 }
1598
rkvdec_watchdog_func(struct work_struct * work)1599 static void rkvdec_watchdog_func(struct work_struct *work)
1600 {
1601 struct rkvdec_dev *rkvdec;
1602 struct rkvdec_ctx *ctx;
1603
1604 rkvdec = container_of(to_delayed_work(work), struct rkvdec_dev,
1605 watchdog_work);
1606 ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);
1607 if (ctx) {
1608 dev_err(rkvdec->dev, "Frame processing timed out!\n");
1609 writel(RKVDEC_IRQ_DIS, rkvdec->regs + RKVDEC_REG_INTERRUPT);
1610 rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR);
1611 }
1612 }
1613
1614 /*
1615 * Some SoCs, like RK3588 have multiple identical VDPU cores, but the
1616 * kernel is currently missing support for multi-core handling. Exposing
1617 * separate devices for each core to userspace is bad, since that does
1618 * not allow scheduling tasks properly (and creates ABI). With this workaround
1619 * the driver will only probe for the first core and early exit for the other
1620 * cores. Once the driver gains multi-core support, the same technique
1621 * for detecting the first core can be used to cluster all cores together.
1622 */
rkvdec_disable_multicore(struct rkvdec_dev * rkvdec)1623 static int rkvdec_disable_multicore(struct rkvdec_dev *rkvdec)
1624 {
1625 struct device_node *node = NULL;
1626 const char *compatible;
1627 bool is_first_core;
1628 int ret;
1629
1630 /* Intentionally ignores the fallback strings */
1631 ret = of_property_read_string(rkvdec->dev->of_node, "compatible", &compatible);
1632 if (ret)
1633 return ret;
1634
1635 /* The first compatible and available node found is considered the main core */
1636 do {
1637 node = of_find_compatible_node(node, NULL, compatible);
1638 if (of_device_is_available(node))
1639 break;
1640 } while (node);
1641
1642 if (!node)
1643 return -EINVAL;
1644
1645 is_first_core = (rkvdec->dev->of_node == node);
1646
1647 of_node_put(node);
1648
1649 if (!is_first_core) {
1650 dev_info(rkvdec->dev, "missing multi-core support, ignoring this instance\n");
1651 return -ENODEV;
1652 }
1653
1654 return 0;
1655 }
1656
1657 static const struct rkvdec_variant_ops rk3399_variant_ops = {
1658 .irq_handler = rk3399_irq_handler,
1659 .colmv_size = rkvdec_colmv_size,
1660 .flatten_matrices = transpose_and_flatten_matrices,
1661 };
1662
1663 static const struct rkvdec_variant rk3288_rkvdec_variant = {
1664 .num_regs = 68,
1665 .coded_fmts = rk3288_coded_fmts,
1666 .num_coded_fmts = ARRAY_SIZE(rk3288_coded_fmts),
1667 .ops = &rk3399_variant_ops,
1668 .has_single_reg_region = true,
1669 };
1670
1671 static const struct rkvdec_variant rk3328_rkvdec_variant = {
1672 .num_regs = 109,
1673 .coded_fmts = rkvdec_coded_fmts,
1674 .num_coded_fmts = ARRAY_SIZE(rkvdec_coded_fmts),
1675 .ops = &rk3399_variant_ops,
1676 .has_single_reg_region = true,
1677 .quirks = RKVDEC_QUIRK_DISABLE_QOS,
1678 };
1679
1680 static const struct rkvdec_variant rk3399_rkvdec_variant = {
1681 .num_regs = 78,
1682 .coded_fmts = rkvdec_coded_fmts,
1683 .num_coded_fmts = ARRAY_SIZE(rkvdec_coded_fmts),
1684 .ops = &rk3399_variant_ops,
1685 .has_single_reg_region = true,
1686 };
1687
1688 static const struct rcb_size_info vdpu381_rcb_sizes[] = {
1689 {6, PIC_WIDTH}, // intrar
1690 {1, PIC_WIDTH}, // transdr (Is actually 0.4*pic_width)
1691 {1, PIC_HEIGHT}, // transdc (Is actually 0.1*pic_height)
1692 {3, PIC_WIDTH}, // streamdr
1693 {6, PIC_WIDTH}, // interr
1694 {3, PIC_HEIGHT}, // interc
1695 {22, PIC_WIDTH}, // dblkr
1696 {6, PIC_WIDTH}, // saor
1697 {11, PIC_WIDTH}, // fbcr
1698 {67, PIC_HEIGHT}, // filtc col
1699 };
1700
1701 static const struct rkvdec_variant_ops vdpu381_variant_ops = {
1702 .irq_handler = vdpu381_irq_handler,
1703 .colmv_size = rkvdec_colmv_size,
1704 .flatten_matrices = transpose_and_flatten_matrices,
1705 };
1706
1707 static const struct rkvdec_variant vdpu381_variant = {
1708 .coded_fmts = vdpu381_coded_fmts,
1709 .num_coded_fmts = ARRAY_SIZE(vdpu381_coded_fmts),
1710 .rcb_sizes = vdpu381_rcb_sizes,
1711 .num_rcb_sizes = ARRAY_SIZE(vdpu381_rcb_sizes),
1712 .ops = &vdpu381_variant_ops,
1713 };
1714
1715 static const struct rcb_size_info vdpu383_rcb_sizes[] = {
1716 {6, PIC_WIDTH}, // streamd
1717 {6, PIC_WIDTH}, // streamd_tile
1718 {12, PIC_WIDTH}, // inter
1719 {12, PIC_WIDTH}, // inter_tile
1720 {16, PIC_WIDTH}, // intra
1721 {10, PIC_WIDTH}, // intra_tile
1722 {120, PIC_WIDTH}, // filterd
1723 {120, PIC_WIDTH}, // filterd_protect
1724 {120, PIC_WIDTH}, // filterd_tile_row
1725 {180, PIC_HEIGHT}, // filterd_tile_col
1726 };
1727
1728 static const struct rkvdec_variant_ops vdpu383_variant_ops = {
1729 .irq_handler = vdpu383_irq_handler,
1730 .colmv_size = vdpu383_colmv_size,
1731 .flatten_matrices = vdpu383_flatten_matrices,
1732 };
1733
1734 static const struct rkvdec_variant vdpu383_variant = {
1735 .coded_fmts = vdpu383_coded_fmts,
1736 .num_coded_fmts = ARRAY_SIZE(vdpu383_coded_fmts),
1737 .rcb_sizes = vdpu383_rcb_sizes,
1738 .num_rcb_sizes = ARRAY_SIZE(vdpu383_rcb_sizes),
1739 .ops = &vdpu383_variant_ops,
1740 };
1741
1742 static const struct of_device_id of_rkvdec_match[] = {
1743 {
1744 .compatible = "rockchip,rk3288-vdec",
1745 .data = &rk3288_rkvdec_variant,
1746 },
1747 {
1748 .compatible = "rockchip,rk3328-vdec",
1749 .data = &rk3328_rkvdec_variant,
1750 },
1751 {
1752 .compatible = "rockchip,rk3399-vdec",
1753 .data = &rk3399_rkvdec_variant,
1754 },
1755 {
1756 .compatible = "rockchip,rk3588-vdec",
1757 .data = &vdpu381_variant,
1758 },
1759 {
1760 .compatible = "rockchip,rk3576-vdec",
1761 .data = &vdpu383_variant,
1762 },
1763 { /* sentinel */ }
1764 };
1765 MODULE_DEVICE_TABLE(of, of_rkvdec_match);
1766
rkvdec_probe(struct platform_device * pdev)1767 static int rkvdec_probe(struct platform_device *pdev)
1768 {
1769 const struct rkvdec_variant *variant;
1770 struct rkvdec_dev *rkvdec;
1771 int ret, irq;
1772
1773 variant = of_device_get_match_data(&pdev->dev);
1774 if (!variant)
1775 return -EINVAL;
1776
1777 rkvdec = devm_kzalloc(&pdev->dev, sizeof(*rkvdec), GFP_KERNEL);
1778 if (!rkvdec)
1779 return -ENOMEM;
1780
1781 platform_set_drvdata(pdev, rkvdec);
1782 rkvdec->dev = &pdev->dev;
1783 rkvdec->variant = variant;
1784 mutex_init(&rkvdec->vdev_lock);
1785 INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec_watchdog_func);
1786
1787 ret = rkvdec_disable_multicore(rkvdec);
1788 if (ret)
1789 return ret;
1790
1791 ret = devm_clk_bulk_get_all_enabled(&pdev->dev, &rkvdec->clocks);
1792 if (ret < 0)
1793 return ret;
1794
1795 rkvdec->num_clocks = ret;
1796 rkvdec->axi_clk = devm_clk_get(&pdev->dev, "axi");
1797
1798 if (rkvdec->variant->has_single_reg_region) {
1799 rkvdec->regs = devm_platform_ioremap_resource(pdev, 0);
1800 if (IS_ERR(rkvdec->regs))
1801 return PTR_ERR(rkvdec->regs);
1802 } else {
1803 rkvdec->regs = devm_platform_ioremap_resource_byname(pdev, "function");
1804 if (IS_ERR(rkvdec->regs))
1805 return PTR_ERR(rkvdec->regs);
1806
1807 rkvdec->link = devm_platform_ioremap_resource_byname(pdev, "link");
1808 if (IS_ERR(rkvdec->link))
1809 return PTR_ERR(rkvdec->link);
1810 }
1811
1812 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
1813 if (ret) {
1814 dev_err(&pdev->dev, "Could not set DMA coherent mask.\n");
1815 return ret;
1816 }
1817
1818 vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
1819
1820 irq = platform_get_irq(pdev, 0);
1821 if (irq <= 0)
1822 return -ENXIO;
1823
1824 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
1825 rkvdec_irq_handler, IRQF_ONESHOT,
1826 dev_name(&pdev->dev), rkvdec);
1827 if (ret) {
1828 dev_err(&pdev->dev, "Could not request vdec IRQ\n");
1829 return ret;
1830 }
1831
1832 rkvdec->sram_pool = of_gen_pool_get(pdev->dev.of_node, "sram", 0);
1833 if (!rkvdec->sram_pool && rkvdec->variant->num_rcb_sizes > 0)
1834 dev_info(&pdev->dev, "No sram node, RCB will be stored in RAM\n");
1835
1836 pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
1837 pm_runtime_use_autosuspend(&pdev->dev);
1838 pm_runtime_enable(&pdev->dev);
1839
1840 ret = rkvdec_v4l2_init(rkvdec);
1841 if (ret)
1842 goto err_disable_runtime_pm;
1843
1844 rkvdec->iommu_domain = iommu_get_domain_for_dev(&pdev->dev);
1845 if (rkvdec->iommu_domain) {
1846 rkvdec->empty_domain = iommu_paging_domain_alloc(rkvdec->dev);
1847
1848 if (IS_ERR(rkvdec->empty_domain)) {
1849 rkvdec->empty_domain = NULL;
1850 dev_warn(rkvdec->dev, "cannot alloc new empty domain\n");
1851 }
1852 }
1853
1854 return 0;
1855
1856 err_disable_runtime_pm:
1857 pm_runtime_dont_use_autosuspend(&pdev->dev);
1858 pm_runtime_disable(&pdev->dev);
1859
1860 if (rkvdec->sram_pool)
1861 gen_pool_destroy(rkvdec->sram_pool);
1862
1863 return ret;
1864 }
1865
rkvdec_remove(struct platform_device * pdev)1866 static void rkvdec_remove(struct platform_device *pdev)
1867 {
1868 struct rkvdec_dev *rkvdec = platform_get_drvdata(pdev);
1869
1870 cancel_delayed_work_sync(&rkvdec->watchdog_work);
1871
1872 rkvdec_v4l2_cleanup(rkvdec);
1873 pm_runtime_disable(&pdev->dev);
1874 pm_runtime_dont_use_autosuspend(&pdev->dev);
1875
1876 if (rkvdec->empty_domain)
1877 iommu_domain_free(rkvdec->empty_domain);
1878 }
1879
1880 #ifdef CONFIG_PM
rkvdec_runtime_resume(struct device * dev)1881 static int rkvdec_runtime_resume(struct device *dev)
1882 {
1883 struct rkvdec_dev *rkvdec = dev_get_drvdata(dev);
1884
1885 return clk_bulk_prepare_enable(rkvdec->num_clocks, rkvdec->clocks);
1886 }
1887
rkvdec_runtime_suspend(struct device * dev)1888 static int rkvdec_runtime_suspend(struct device *dev)
1889 {
1890 struct rkvdec_dev *rkvdec = dev_get_drvdata(dev);
1891
1892 clk_bulk_disable_unprepare(rkvdec->num_clocks, rkvdec->clocks);
1893 return 0;
1894 }
1895 #endif
1896
1897 static const struct dev_pm_ops rkvdec_pm_ops = {
1898 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1899 pm_runtime_force_resume)
1900 SET_RUNTIME_PM_OPS(rkvdec_runtime_suspend, rkvdec_runtime_resume, NULL)
1901 };
1902
1903 static struct platform_driver rkvdec_driver = {
1904 .probe = rkvdec_probe,
1905 .remove = rkvdec_remove,
1906 .driver = {
1907 .name = "rkvdec",
1908 .of_match_table = of_rkvdec_match,
1909 .pm = &rkvdec_pm_ops,
1910 },
1911 };
1912 module_platform_driver(rkvdec_driver);
1913
1914 MODULE_AUTHOR("Boris Brezillon <boris.brezillon@collabora.com>");
1915 MODULE_DESCRIPTION("Rockchip Video Decoder driver");
1916 MODULE_LICENSE("GPL v2");
1917