1
2
3
4
5
6
7
8
9
10
11
12#include <linux/clk.h>
13#include <linux/interrupt.h>
14#include <linux/module.h>
15#include <linux/of.h>
16#include <linux/platform_device.h>
17#include <linux/pm.h>
18#include <linux/pm_runtime.h>
19#include <linux/slab.h>
20#include <linux/videodev2.h>
21#include <linux/workqueue.h>
22#include <media/v4l2-event.h>
23#include <media/v4l2-mem2mem.h>
24#include <media/videobuf2-core.h>
25#include <media/videobuf2-vmalloc.h>
26
27#include "rkvdec.h"
28#include "rkvdec-regs.h"
29
30static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl)
31{
32 if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) {
33 const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
34
35
36
37
38
39 if (sps->chroma_format_idc > 1)
40
41 return -EINVAL;
42 if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8)
43
44 return -EINVAL;
45 if (sps->bit_depth_luma_minus8 != 0)
46
47 return -EINVAL;
48 }
49 return 0;
50}
51
52static const struct v4l2_ctrl_ops rkvdec_ctrl_ops = {
53 .try_ctrl = rkvdec_try_ctrl,
54};
55
56static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = {
57 {
58 .cfg.id = V4L2_CID_STATELESS_H264_DECODE_PARAMS,
59 },
60 {
61 .cfg.id = V4L2_CID_STATELESS_H264_SPS,
62 .cfg.ops = &rkvdec_ctrl_ops,
63 },
64 {
65 .cfg.id = V4L2_CID_STATELESS_H264_PPS,
66 },
67 {
68 .cfg.id = V4L2_CID_STATELESS_H264_SCALING_MATRIX,
69 },
70 {
71 .cfg.id = V4L2_CID_STATELESS_H264_DECODE_MODE,
72 .cfg.min = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
73 .cfg.max = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
74 .cfg.def = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
75 },
76 {
77 .cfg.id = V4L2_CID_STATELESS_H264_START_CODE,
78 .cfg.min = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
79 .cfg.def = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
80 .cfg.max = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
81 },
82 {
83 .cfg.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
84 .cfg.min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
85 .cfg.max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
86 .cfg.menu_skip_mask =
87 BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED),
88 .cfg.def = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN,
89 },
90 {
91 .cfg.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
92 .cfg.min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
93 .cfg.max = V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
94 },
95};
96
97static const struct rkvdec_ctrls rkvdec_h264_ctrls = {
98 .ctrls = rkvdec_h264_ctrl_descs,
99 .num_ctrls = ARRAY_SIZE(rkvdec_h264_ctrl_descs),
100};
101
102static const u32 rkvdec_h264_vp9_decoded_fmts[] = {
103 V4L2_PIX_FMT_NV12,
104};
105
106static const struct rkvdec_ctrl_desc rkvdec_vp9_ctrl_descs[] = {
107 {
108 .cfg.id = V4L2_CID_STATELESS_VP9_FRAME,
109 },
110 {
111 .cfg.id = V4L2_CID_STATELESS_VP9_COMPRESSED_HDR,
112 },
113 {
114 .cfg.id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
115 .cfg.min = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
116 .cfg.max = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
117 .cfg.def = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
118 },
119};
120
121static const struct rkvdec_ctrls rkvdec_vp9_ctrls = {
122 .ctrls = rkvdec_vp9_ctrl_descs,
123 .num_ctrls = ARRAY_SIZE(rkvdec_vp9_ctrl_descs),
124};
125
126static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = {
127 {
128 .fourcc = V4L2_PIX_FMT_H264_SLICE,
129 .frmsize = {
130 .min_width = 48,
131 .max_width = 4096,
132 .step_width = 16,
133 .min_height = 48,
134 .max_height = 2304,
135 .step_height = 16,
136 },
137 .ctrls = &rkvdec_h264_ctrls,
138 .ops = &rkvdec_h264_fmt_ops,
139 .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_vp9_decoded_fmts),
140 .decoded_fmts = rkvdec_h264_vp9_decoded_fmts,
141 },
142 {
143 .fourcc = V4L2_PIX_FMT_VP9_FRAME,
144 .frmsize = {
145 .min_width = 64,
146 .max_width = 4096,
147 .step_width = 64,
148 .min_height = 64,
149 .max_height = 2304,
150 .step_height = 64,
151 },
152 .ctrls = &rkvdec_vp9_ctrls,
153 .ops = &rkvdec_vp9_fmt_ops,
154 .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_vp9_decoded_fmts),
155 .decoded_fmts = rkvdec_h264_vp9_decoded_fmts,
156 }
157};
158
159static const struct rkvdec_coded_fmt_desc *
160rkvdec_find_coded_fmt_desc(u32 fourcc)
161{
162 unsigned int i;
163
164 for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) {
165 if (rkvdec_coded_fmts[i].fourcc == fourcc)
166 return &rkvdec_coded_fmts[i];
167 }
168
169 return NULL;
170}
171
172static void rkvdec_reset_fmt(struct rkvdec_ctx *ctx, struct v4l2_format *f,
173 u32 fourcc)
174{
175 memset(f, 0, sizeof(*f));
176 f->fmt.pix_mp.pixelformat = fourcc;
177 f->fmt.pix_mp.field = V4L2_FIELD_NONE;
178 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
179 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
180 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
181 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
182}
183
184static void rkvdec_reset_coded_fmt(struct rkvdec_ctx *ctx)
185{
186 struct v4l2_format *f = &ctx->coded_fmt;
187
188 ctx->coded_fmt_desc = &rkvdec_coded_fmts[0];
189 rkvdec_reset_fmt(ctx, f, ctx->coded_fmt_desc->fourcc);
190
191 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
192 f->fmt.pix_mp.width = ctx->coded_fmt_desc->frmsize.min_width;
193 f->fmt.pix_mp.height = ctx->coded_fmt_desc->frmsize.min_height;
194
195 if (ctx->coded_fmt_desc->ops->adjust_fmt)
196 ctx->coded_fmt_desc->ops->adjust_fmt(ctx, f);
197}
198
199static void rkvdec_reset_decoded_fmt(struct rkvdec_ctx *ctx)
200{
201 struct v4l2_format *f = &ctx->decoded_fmt;
202
203 rkvdec_reset_fmt(ctx, f, ctx->coded_fmt_desc->decoded_fmts[0]);
204 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
205 v4l2_fill_pixfmt_mp(&f->fmt.pix_mp,
206 ctx->coded_fmt_desc->decoded_fmts[0],
207 ctx->coded_fmt.fmt.pix_mp.width,
208 ctx->coded_fmt.fmt.pix_mp.height);
209 f->fmt.pix_mp.plane_fmt[0].sizeimage += 128 *
210 DIV_ROUND_UP(f->fmt.pix_mp.width, 16) *
211 DIV_ROUND_UP(f->fmt.pix_mp.height, 16);
212}
213
214static int rkvdec_enum_framesizes(struct file *file, void *priv,
215 struct v4l2_frmsizeenum *fsize)
216{
217 const struct rkvdec_coded_fmt_desc *fmt;
218
219 if (fsize->index != 0)
220 return -EINVAL;
221
222 fmt = rkvdec_find_coded_fmt_desc(fsize->pixel_format);
223 if (!fmt)
224 return -EINVAL;
225
226 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
227 fsize->stepwise = fmt->frmsize;
228 return 0;
229}
230
231static int rkvdec_querycap(struct file *file, void *priv,
232 struct v4l2_capability *cap)
233{
234 struct rkvdec_dev *rkvdec = video_drvdata(file);
235 struct video_device *vdev = video_devdata(file);
236
237 strscpy(cap->driver, rkvdec->dev->driver->name,
238 sizeof(cap->driver));
239 strscpy(cap->card, vdev->name, sizeof(cap->card));
240 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
241 rkvdec->dev->driver->name);
242 return 0;
243}
244
245static int rkvdec_try_capture_fmt(struct file *file, void *priv,
246 struct v4l2_format *f)
247{
248 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
249 struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
250 const struct rkvdec_coded_fmt_desc *coded_desc;
251 unsigned int i;
252
253
254
255
256
257
258 coded_desc = ctx->coded_fmt_desc;
259 if (WARN_ON(!coded_desc))
260 return -EINVAL;
261
262 for (i = 0; i < coded_desc->num_decoded_fmts; i++) {
263 if (coded_desc->decoded_fmts[i] == pix_mp->pixelformat)
264 break;
265 }
266
267 if (i == coded_desc->num_decoded_fmts)
268 pix_mp->pixelformat = coded_desc->decoded_fmts[0];
269
270
271 v4l2_apply_frmsize_constraints(&pix_mp->width,
272 &pix_mp->height,
273 &coded_desc->frmsize);
274
275 v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat,
276 pix_mp->width, pix_mp->height);
277 pix_mp->plane_fmt[0].sizeimage +=
278 128 *
279 DIV_ROUND_UP(pix_mp->width, 16) *
280 DIV_ROUND_UP(pix_mp->height, 16);
281 pix_mp->field = V4L2_FIELD_NONE;
282
283 return 0;
284}
285
286static int rkvdec_try_output_fmt(struct file *file, void *priv,
287 struct v4l2_format *f)
288{
289 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
290 struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
291 const struct rkvdec_coded_fmt_desc *desc;
292
293 desc = rkvdec_find_coded_fmt_desc(pix_mp->pixelformat);
294 if (!desc) {
295 pix_mp->pixelformat = rkvdec_coded_fmts[0].fourcc;
296 desc = &rkvdec_coded_fmts[0];
297 }
298
299 v4l2_apply_frmsize_constraints(&pix_mp->width,
300 &pix_mp->height,
301 &desc->frmsize);
302
303 pix_mp->field = V4L2_FIELD_NONE;
304
305 pix_mp->num_planes = 1;
306
307 if (desc->ops->adjust_fmt) {
308 int ret;
309
310 ret = desc->ops->adjust_fmt(ctx, f);
311 if (ret)
312 return ret;
313 }
314
315 return 0;
316}
317
318static int rkvdec_s_capture_fmt(struct file *file, void *priv,
319 struct v4l2_format *f)
320{
321 struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
322 struct vb2_queue *vq;
323 int ret;
324
325
326 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
327 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
328 if (vb2_is_busy(vq))
329 return -EBUSY;
330
331 ret = rkvdec_try_capture_fmt(file, priv, f);
332 if (ret)
333 return ret;
334
335 ctx->decoded_fmt = *f;
336 return 0;
337}
338
339static int rkvdec_s_output_fmt(struct file *file, void *priv,
340 struct v4l2_format *f)
341{
342 struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
343 struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
344 const struct rkvdec_coded_fmt_desc *desc;
345 struct v4l2_format *cap_fmt;
346 struct vb2_queue *peer_vq, *vq;
347 int ret;
348
349
350
351
352
353
354 vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
355 if (vb2_is_streaming(vq) ||
356 (vb2_is_busy(vq) &&
357 f->fmt.pix_mp.pixelformat != ctx->coded_fmt.fmt.pix_mp.pixelformat))
358 return -EBUSY;
359
360
361
362
363
364
365 peer_vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
366 if (vb2_is_busy(peer_vq))
367 return -EBUSY;
368
369 ret = rkvdec_try_output_fmt(file, priv, f);
370 if (ret)
371 return ret;
372
373 desc = rkvdec_find_coded_fmt_desc(f->fmt.pix_mp.pixelformat);
374 if (!desc)
375 return -EINVAL;
376 ctx->coded_fmt_desc = desc;
377 ctx->coded_fmt = *f;
378
379
380
381
382
383
384
385
386
387
388 rkvdec_reset_decoded_fmt(ctx);
389
390
391 cap_fmt = &ctx->decoded_fmt;
392 cap_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
393 cap_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
394 cap_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
395 cap_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
396
397 return 0;
398}
399
400static int rkvdec_g_output_fmt(struct file *file, void *priv,
401 struct v4l2_format *f)
402{
403 struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
404
405 *f = ctx->coded_fmt;
406 return 0;
407}
408
409static int rkvdec_g_capture_fmt(struct file *file, void *priv,
410 struct v4l2_format *f)
411{
412 struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
413
414 *f = ctx->decoded_fmt;
415 return 0;
416}
417
418static int rkvdec_enum_output_fmt(struct file *file, void *priv,
419 struct v4l2_fmtdesc *f)
420{
421 if (f->index >= ARRAY_SIZE(rkvdec_coded_fmts))
422 return -EINVAL;
423
424 f->pixelformat = rkvdec_coded_fmts[f->index].fourcc;
425 return 0;
426}
427
428static int rkvdec_enum_capture_fmt(struct file *file, void *priv,
429 struct v4l2_fmtdesc *f)
430{
431 struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
432
433 if (WARN_ON(!ctx->coded_fmt_desc))
434 return -EINVAL;
435
436 if (f->index >= ctx->coded_fmt_desc->num_decoded_fmts)
437 return -EINVAL;
438
439 f->pixelformat = ctx->coded_fmt_desc->decoded_fmts[f->index];
440 return 0;
441}
442
443static const struct v4l2_ioctl_ops rkvdec_ioctl_ops = {
444 .vidioc_querycap = rkvdec_querycap,
445 .vidioc_enum_framesizes = rkvdec_enum_framesizes,
446
447 .vidioc_try_fmt_vid_cap_mplane = rkvdec_try_capture_fmt,
448 .vidioc_try_fmt_vid_out_mplane = rkvdec_try_output_fmt,
449 .vidioc_s_fmt_vid_out_mplane = rkvdec_s_output_fmt,
450 .vidioc_s_fmt_vid_cap_mplane = rkvdec_s_capture_fmt,
451 .vidioc_g_fmt_vid_out_mplane = rkvdec_g_output_fmt,
452 .vidioc_g_fmt_vid_cap_mplane = rkvdec_g_capture_fmt,
453 .vidioc_enum_fmt_vid_out = rkvdec_enum_output_fmt,
454 .vidioc_enum_fmt_vid_cap = rkvdec_enum_capture_fmt,
455
456 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
457 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
458 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
459 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
460 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
461 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
462 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
463
464 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
465 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
466
467 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
468 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
469};
470
471static int rkvdec_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
472 unsigned int *num_planes, unsigned int sizes[],
473 struct device *alloc_devs[])
474{
475 struct rkvdec_ctx *ctx = vb2_get_drv_priv(vq);
476 struct v4l2_format *f;
477 unsigned int i;
478
479 if (V4L2_TYPE_IS_OUTPUT(vq->type))
480 f = &ctx->coded_fmt;
481 else
482 f = &ctx->decoded_fmt;
483
484 if (*num_planes) {
485 if (*num_planes != f->fmt.pix_mp.num_planes)
486 return -EINVAL;
487
488 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) {
489 if (sizes[i] < f->fmt.pix_mp.plane_fmt[i].sizeimage)
490 return -EINVAL;
491 }
492 } else {
493 *num_planes = f->fmt.pix_mp.num_planes;
494 for (i = 0; i < f->fmt.pix_mp.num_planes; i++)
495 sizes[i] = f->fmt.pix_mp.plane_fmt[i].sizeimage;
496 }
497
498 return 0;
499}
500
501static int rkvdec_buf_prepare(struct vb2_buffer *vb)
502{
503 struct vb2_queue *vq = vb->vb2_queue;
504 struct rkvdec_ctx *ctx = vb2_get_drv_priv(vq);
505 struct v4l2_format *f;
506 unsigned int i;
507
508 if (V4L2_TYPE_IS_OUTPUT(vq->type))
509 f = &ctx->coded_fmt;
510 else
511 f = &ctx->decoded_fmt;
512
513 for (i = 0; i < f->fmt.pix_mp.num_planes; ++i) {
514 u32 sizeimage = f->fmt.pix_mp.plane_fmt[i].sizeimage;
515
516 if (vb2_plane_size(vb, i) < sizeimage)
517 return -EINVAL;
518 }
519
520
521
522
523
524
525 if (V4L2_TYPE_IS_CAPTURE(vq->type))
526 vb2_set_plane_payload(vb, 0, f->fmt.pix_mp.plane_fmt[0].sizeimage);
527
528 return 0;
529}
530
531static void rkvdec_buf_queue(struct vb2_buffer *vb)
532{
533 struct rkvdec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
534 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
535
536 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
537}
538
539static int rkvdec_buf_out_validate(struct vb2_buffer *vb)
540{
541 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
542
543 vbuf->field = V4L2_FIELD_NONE;
544 return 0;
545}
546
547static void rkvdec_buf_request_complete(struct vb2_buffer *vb)
548{
549 struct rkvdec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
550
551 v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->ctrl_hdl);
552}
553
554static int rkvdec_start_streaming(struct vb2_queue *q, unsigned int count)
555{
556 struct rkvdec_ctx *ctx = vb2_get_drv_priv(q);
557 const struct rkvdec_coded_fmt_desc *desc;
558 int ret;
559
560 if (V4L2_TYPE_IS_CAPTURE(q->type))
561 return 0;
562
563 desc = ctx->coded_fmt_desc;
564 if (WARN_ON(!desc))
565 return -EINVAL;
566
567 if (desc->ops->start) {
568 ret = desc->ops->start(ctx);
569 if (ret)
570 return ret;
571 }
572
573 return 0;
574}
575
576static void rkvdec_queue_cleanup(struct vb2_queue *vq, u32 state)
577{
578 struct rkvdec_ctx *ctx = vb2_get_drv_priv(vq);
579
580 while (true) {
581 struct vb2_v4l2_buffer *vbuf;
582
583 if (V4L2_TYPE_IS_OUTPUT(vq->type))
584 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
585 else
586 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
587
588 if (!vbuf)
589 break;
590
591 v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
592 &ctx->ctrl_hdl);
593 v4l2_m2m_buf_done(vbuf, state);
594 }
595}
596
597static void rkvdec_stop_streaming(struct vb2_queue *q)
598{
599 struct rkvdec_ctx *ctx = vb2_get_drv_priv(q);
600
601 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
602 const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc;
603
604 if (WARN_ON(!desc))
605 return;
606
607 if (desc->ops->stop)
608 desc->ops->stop(ctx);
609 }
610
611 rkvdec_queue_cleanup(q, VB2_BUF_STATE_ERROR);
612}
613
614static const struct vb2_ops rkvdec_queue_ops = {
615 .queue_setup = rkvdec_queue_setup,
616 .buf_prepare = rkvdec_buf_prepare,
617 .buf_queue = rkvdec_buf_queue,
618 .buf_out_validate = rkvdec_buf_out_validate,
619 .buf_request_complete = rkvdec_buf_request_complete,
620 .start_streaming = rkvdec_start_streaming,
621 .stop_streaming = rkvdec_stop_streaming,
622 .wait_prepare = vb2_ops_wait_prepare,
623 .wait_finish = vb2_ops_wait_finish,
624};
625
626static int rkvdec_request_validate(struct media_request *req)
627{
628 unsigned int count;
629
630 count = vb2_request_buffer_cnt(req);
631 if (!count)
632 return -ENOENT;
633 else if (count > 1)
634 return -EINVAL;
635
636 return vb2_request_validate(req);
637}
638
639static const struct media_device_ops rkvdec_media_ops = {
640 .req_validate = rkvdec_request_validate,
641 .req_queue = v4l2_m2m_request_queue,
642};
643
644static void rkvdec_job_finish_no_pm(struct rkvdec_ctx *ctx,
645 enum vb2_buffer_state result)
646{
647 if (ctx->coded_fmt_desc->ops->done) {
648 struct vb2_v4l2_buffer *src_buf, *dst_buf;
649
650 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
651 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
652 ctx->coded_fmt_desc->ops->done(ctx, src_buf, dst_buf, result);
653 }
654
655 v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx,
656 result);
657}
658
659static void rkvdec_job_finish(struct rkvdec_ctx *ctx,
660 enum vb2_buffer_state result)
661{
662 struct rkvdec_dev *rkvdec = ctx->dev;
663
664 pm_runtime_mark_last_busy(rkvdec->dev);
665 pm_runtime_put_autosuspend(rkvdec->dev);
666 rkvdec_job_finish_no_pm(ctx, result);
667}
668
669void rkvdec_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run)
670{
671 struct media_request *src_req;
672
673 memset(run, 0, sizeof(*run));
674
675 run->bufs.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
676 run->bufs.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
677
678
679 src_req = run->bufs.src->vb2_buf.req_obj.req;
680 if (src_req)
681 v4l2_ctrl_request_setup(src_req, &ctx->ctrl_hdl);
682
683 v4l2_m2m_buf_copy_metadata(run->bufs.src, run->bufs.dst, true);
684}
685
686void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run)
687{
688 struct media_request *src_req = run->bufs.src->vb2_buf.req_obj.req;
689
690 if (src_req)
691 v4l2_ctrl_request_complete(src_req, &ctx->ctrl_hdl);
692}
693
694static void rkvdec_device_run(void *priv)
695{
696 struct rkvdec_ctx *ctx = priv;
697 struct rkvdec_dev *rkvdec = ctx->dev;
698 const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc;
699 int ret;
700
701 if (WARN_ON(!desc))
702 return;
703
704 ret = pm_runtime_resume_and_get(rkvdec->dev);
705 if (ret < 0) {
706 rkvdec_job_finish_no_pm(ctx, VB2_BUF_STATE_ERROR);
707 return;
708 }
709
710 ret = desc->ops->run(ctx);
711 if (ret)
712 rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR);
713}
714
715static const struct v4l2_m2m_ops rkvdec_m2m_ops = {
716 .device_run = rkvdec_device_run,
717};
718
719static int rkvdec_queue_init(void *priv,
720 struct vb2_queue *src_vq,
721 struct vb2_queue *dst_vq)
722{
723 struct rkvdec_ctx *ctx = priv;
724 struct rkvdec_dev *rkvdec = ctx->dev;
725 int ret;
726
727 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
728 src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
729 src_vq->drv_priv = ctx;
730 src_vq->ops = &rkvdec_queue_ops;
731 src_vq->mem_ops = &vb2_dma_contig_memops;
732
733
734
735
736
737
738 src_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES |
739 DMA_ATTR_NO_KERNEL_MAPPING;
740 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
741 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
742 src_vq->lock = &rkvdec->vdev_lock;
743 src_vq->dev = rkvdec->v4l2_dev.dev;
744 src_vq->supports_requests = true;
745 src_vq->requires_requests = true;
746
747 ret = vb2_queue_init(src_vq);
748 if (ret)
749 return ret;
750
751 dst_vq->bidirectional = true;
752 dst_vq->mem_ops = &vb2_dma_contig_memops;
753 dst_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES |
754 DMA_ATTR_NO_KERNEL_MAPPING;
755 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
756 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
757 dst_vq->drv_priv = ctx;
758 dst_vq->ops = &rkvdec_queue_ops;
759 dst_vq->buf_struct_size = sizeof(struct rkvdec_decoded_buffer);
760 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
761 dst_vq->lock = &rkvdec->vdev_lock;
762 dst_vq->dev = rkvdec->v4l2_dev.dev;
763
764 return vb2_queue_init(dst_vq);
765}
766
767static int rkvdec_add_ctrls(struct rkvdec_ctx *ctx,
768 const struct rkvdec_ctrls *ctrls)
769{
770 unsigned int i;
771
772 for (i = 0; i < ctrls->num_ctrls; i++) {
773 const struct v4l2_ctrl_config *cfg = &ctrls->ctrls[i].cfg;
774
775 v4l2_ctrl_new_custom(&ctx->ctrl_hdl, cfg, ctx);
776 if (ctx->ctrl_hdl.error)
777 return ctx->ctrl_hdl.error;
778 }
779
780 return 0;
781}
782
783static int rkvdec_init_ctrls(struct rkvdec_ctx *ctx)
784{
785 unsigned int i, nctrls = 0;
786 int ret;
787
788 for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++)
789 nctrls += rkvdec_coded_fmts[i].ctrls->num_ctrls;
790
791 v4l2_ctrl_handler_init(&ctx->ctrl_hdl, nctrls);
792
793 for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) {
794 ret = rkvdec_add_ctrls(ctx, rkvdec_coded_fmts[i].ctrls);
795 if (ret)
796 goto err_free_handler;
797 }
798
799 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
800 if (ret)
801 goto err_free_handler;
802
803 ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
804 return 0;
805
806err_free_handler:
807 v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
808 return ret;
809}
810
811static int rkvdec_open(struct file *filp)
812{
813 struct rkvdec_dev *rkvdec = video_drvdata(filp);
814 struct rkvdec_ctx *ctx;
815 int ret;
816
817 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
818 if (!ctx)
819 return -ENOMEM;
820
821 ctx->dev = rkvdec;
822 rkvdec_reset_coded_fmt(ctx);
823 rkvdec_reset_decoded_fmt(ctx);
824 v4l2_fh_init(&ctx->fh, video_devdata(filp));
825
826 ret = rkvdec_init_ctrls(ctx);
827 if (ret)
828 goto err_free_ctx;
829
830 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(rkvdec->m2m_dev, ctx,
831 rkvdec_queue_init);
832 if (IS_ERR(ctx->fh.m2m_ctx)) {
833 ret = PTR_ERR(ctx->fh.m2m_ctx);
834 goto err_cleanup_ctrls;
835 }
836
837 filp->private_data = &ctx->fh;
838 v4l2_fh_add(&ctx->fh);
839
840 return 0;
841
842err_cleanup_ctrls:
843 v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
844
845err_free_ctx:
846 kfree(ctx);
847 return ret;
848}
849
850static int rkvdec_release(struct file *filp)
851{
852 struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(filp->private_data);
853
854 v4l2_fh_del(&ctx->fh);
855 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
856 v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
857 v4l2_fh_exit(&ctx->fh);
858 kfree(ctx);
859
860 return 0;
861}
862
863static const struct v4l2_file_operations rkvdec_fops = {
864 .owner = THIS_MODULE,
865 .open = rkvdec_open,
866 .release = rkvdec_release,
867 .poll = v4l2_m2m_fop_poll,
868 .unlocked_ioctl = video_ioctl2,
869 .mmap = v4l2_m2m_fop_mmap,
870};
871
872static int rkvdec_v4l2_init(struct rkvdec_dev *rkvdec)
873{
874 int ret;
875
876 ret = v4l2_device_register(rkvdec->dev, &rkvdec->v4l2_dev);
877 if (ret) {
878 dev_err(rkvdec->dev, "Failed to register V4L2 device\n");
879 return ret;
880 }
881
882 rkvdec->m2m_dev = v4l2_m2m_init(&rkvdec_m2m_ops);
883 if (IS_ERR(rkvdec->m2m_dev)) {
884 v4l2_err(&rkvdec->v4l2_dev, "Failed to init mem2mem device\n");
885 ret = PTR_ERR(rkvdec->m2m_dev);
886 goto err_unregister_v4l2;
887 }
888
889 rkvdec->mdev.dev = rkvdec->dev;
890 strscpy(rkvdec->mdev.model, "rkvdec", sizeof(rkvdec->mdev.model));
891 strscpy(rkvdec->mdev.bus_info, "platform:rkvdec",
892 sizeof(rkvdec->mdev.bus_info));
893 media_device_init(&rkvdec->mdev);
894 rkvdec->mdev.ops = &rkvdec_media_ops;
895 rkvdec->v4l2_dev.mdev = &rkvdec->mdev;
896
897 rkvdec->vdev.lock = &rkvdec->vdev_lock;
898 rkvdec->vdev.v4l2_dev = &rkvdec->v4l2_dev;
899 rkvdec->vdev.fops = &rkvdec_fops;
900 rkvdec->vdev.release = video_device_release_empty;
901 rkvdec->vdev.vfl_dir = VFL_DIR_M2M;
902 rkvdec->vdev.device_caps = V4L2_CAP_STREAMING |
903 V4L2_CAP_VIDEO_M2M_MPLANE;
904 rkvdec->vdev.ioctl_ops = &rkvdec_ioctl_ops;
905 video_set_drvdata(&rkvdec->vdev, rkvdec);
906 strscpy(rkvdec->vdev.name, "rkvdec", sizeof(rkvdec->vdev.name));
907
908 ret = video_register_device(&rkvdec->vdev, VFL_TYPE_VIDEO, -1);
909 if (ret) {
910 v4l2_err(&rkvdec->v4l2_dev, "Failed to register video device\n");
911 goto err_cleanup_mc;
912 }
913
914 ret = v4l2_m2m_register_media_controller(rkvdec->m2m_dev, &rkvdec->vdev,
915 MEDIA_ENT_F_PROC_VIDEO_DECODER);
916 if (ret) {
917 v4l2_err(&rkvdec->v4l2_dev,
918 "Failed to initialize V4L2 M2M media controller\n");
919 goto err_unregister_vdev;
920 }
921
922 ret = media_device_register(&rkvdec->mdev);
923 if (ret) {
924 v4l2_err(&rkvdec->v4l2_dev, "Failed to register media device\n");
925 goto err_unregister_mc;
926 }
927
928 return 0;
929
930err_unregister_mc:
931 v4l2_m2m_unregister_media_controller(rkvdec->m2m_dev);
932
933err_unregister_vdev:
934 video_unregister_device(&rkvdec->vdev);
935
936err_cleanup_mc:
937 media_device_cleanup(&rkvdec->mdev);
938 v4l2_m2m_release(rkvdec->m2m_dev);
939
940err_unregister_v4l2:
941 v4l2_device_unregister(&rkvdec->v4l2_dev);
942 return ret;
943}
944
945static void rkvdec_v4l2_cleanup(struct rkvdec_dev *rkvdec)
946{
947 media_device_unregister(&rkvdec->mdev);
948 v4l2_m2m_unregister_media_controller(rkvdec->m2m_dev);
949 video_unregister_device(&rkvdec->vdev);
950 media_device_cleanup(&rkvdec->mdev);
951 v4l2_m2m_release(rkvdec->m2m_dev);
952 v4l2_device_unregister(&rkvdec->v4l2_dev);
953}
954
955static irqreturn_t rkvdec_irq_handler(int irq, void *priv)
956{
957 struct rkvdec_dev *rkvdec = priv;
958 enum vb2_buffer_state state;
959 u32 status;
960
961 status = readl(rkvdec->regs + RKVDEC_REG_INTERRUPT);
962 state = (status & RKVDEC_RDY_STA) ?
963 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
964
965 writel(0, rkvdec->regs + RKVDEC_REG_INTERRUPT);
966 if (cancel_delayed_work(&rkvdec->watchdog_work)) {
967 struct rkvdec_ctx *ctx;
968
969 ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);
970 rkvdec_job_finish(ctx, state);
971 }
972
973 return IRQ_HANDLED;
974}
975
976static void rkvdec_watchdog_func(struct work_struct *work)
977{
978 struct rkvdec_dev *rkvdec;
979 struct rkvdec_ctx *ctx;
980
981 rkvdec = container_of(to_delayed_work(work), struct rkvdec_dev,
982 watchdog_work);
983 ctx = v4l2_m2m_get_curr_priv(rkvdec->m2m_dev);
984 if (ctx) {
985 dev_err(rkvdec->dev, "Frame processing timed out!\n");
986 writel(RKVDEC_IRQ_DIS, rkvdec->regs + RKVDEC_REG_INTERRUPT);
987 writel(0, rkvdec->regs + RKVDEC_REG_SYSCTRL);
988 rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR);
989 }
990}
991
992static const struct of_device_id of_rkvdec_match[] = {
993 { .compatible = "rockchip,rk3399-vdec" },
994 { }
995};
996MODULE_DEVICE_TABLE(of, of_rkvdec_match);
997
998static const char * const rkvdec_clk_names[] = {
999 "axi", "ahb", "cabac", "core"
1000};
1001
1002static int rkvdec_probe(struct platform_device *pdev)
1003{
1004 struct rkvdec_dev *rkvdec;
1005 unsigned int i;
1006 int ret, irq;
1007
1008 rkvdec = devm_kzalloc(&pdev->dev, sizeof(*rkvdec), GFP_KERNEL);
1009 if (!rkvdec)
1010 return -ENOMEM;
1011
1012 platform_set_drvdata(pdev, rkvdec);
1013 rkvdec->dev = &pdev->dev;
1014 mutex_init(&rkvdec->vdev_lock);
1015 INIT_DELAYED_WORK(&rkvdec->watchdog_work, rkvdec_watchdog_func);
1016
1017 rkvdec->clocks = devm_kcalloc(&pdev->dev, ARRAY_SIZE(rkvdec_clk_names),
1018 sizeof(*rkvdec->clocks), GFP_KERNEL);
1019 if (!rkvdec->clocks)
1020 return -ENOMEM;
1021
1022 for (i = 0; i < ARRAY_SIZE(rkvdec_clk_names); i++)
1023 rkvdec->clocks[i].id = rkvdec_clk_names[i];
1024
1025 ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(rkvdec_clk_names),
1026 rkvdec->clocks);
1027 if (ret)
1028 return ret;
1029
1030
1031
1032
1033
1034 clk_set_rate(rkvdec->clocks[0].clk, 500 * 1000 * 1000);
1035
1036 rkvdec->regs = devm_platform_ioremap_resource(pdev, 0);
1037 if (IS_ERR(rkvdec->regs))
1038 return PTR_ERR(rkvdec->regs);
1039
1040 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
1041 if (ret) {
1042 dev_err(&pdev->dev, "Could not set DMA coherent mask.\n");
1043 return ret;
1044 }
1045
1046 vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
1047
1048 irq = platform_get_irq(pdev, 0);
1049 if (irq <= 0)
1050 return -ENXIO;
1051
1052 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
1053 rkvdec_irq_handler, IRQF_ONESHOT,
1054 dev_name(&pdev->dev), rkvdec);
1055 if (ret) {
1056 dev_err(&pdev->dev, "Could not request vdec IRQ\n");
1057 return ret;
1058 }
1059
1060 pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
1061 pm_runtime_use_autosuspend(&pdev->dev);
1062 pm_runtime_enable(&pdev->dev);
1063
1064 ret = rkvdec_v4l2_init(rkvdec);
1065 if (ret)
1066 goto err_disable_runtime_pm;
1067
1068 return 0;
1069
1070err_disable_runtime_pm:
1071 pm_runtime_dont_use_autosuspend(&pdev->dev);
1072 pm_runtime_disable(&pdev->dev);
1073 return ret;
1074}
1075
1076static int rkvdec_remove(struct platform_device *pdev)
1077{
1078 struct rkvdec_dev *rkvdec = platform_get_drvdata(pdev);
1079
1080 rkvdec_v4l2_cleanup(rkvdec);
1081 pm_runtime_disable(&pdev->dev);
1082 pm_runtime_dont_use_autosuspend(&pdev->dev);
1083 return 0;
1084}
1085
1086#ifdef CONFIG_PM
1087static int rkvdec_runtime_resume(struct device *dev)
1088{
1089 struct rkvdec_dev *rkvdec = dev_get_drvdata(dev);
1090
1091 return clk_bulk_prepare_enable(ARRAY_SIZE(rkvdec_clk_names),
1092 rkvdec->clocks);
1093}
1094
1095static int rkvdec_runtime_suspend(struct device *dev)
1096{
1097 struct rkvdec_dev *rkvdec = dev_get_drvdata(dev);
1098
1099 clk_bulk_disable_unprepare(ARRAY_SIZE(rkvdec_clk_names),
1100 rkvdec->clocks);
1101 return 0;
1102}
1103#endif
1104
1105static const struct dev_pm_ops rkvdec_pm_ops = {
1106 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1107 pm_runtime_force_resume)
1108 SET_RUNTIME_PM_OPS(rkvdec_runtime_suspend, rkvdec_runtime_resume, NULL)
1109};
1110
1111static struct platform_driver rkvdec_driver = {
1112 .probe = rkvdec_probe,
1113 .remove = rkvdec_remove,
1114 .driver = {
1115 .name = "rkvdec",
1116 .of_match_table = of_rkvdec_match,
1117 .pm = &rkvdec_pm_ops,
1118 },
1119};
1120module_platform_driver(rkvdec_driver);
1121
1122MODULE_AUTHOR("Boris Brezillon <boris.brezillon@collabora.com>");
1123MODULE_DESCRIPTION("Rockchip Video Decoder driver");
1124MODULE_LICENSE("GPL v2");
1125