2 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
3 * Author: Jacob Chen <jacob-chen@iotwrt.com>
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <linux/clk.h>
16 #include <linux/debugfs.h>
17 #include <linux/delay.h>
19 #include <linux/interrupt.h>
20 #include <linux/module.h>
22 #include <linux/pm_runtime.h>
23 #include <linux/reset.h>
24 #include <linux/sched.h>
25 #include <linux/slab.h>
26 #include <linux/timer.h>
28 #include <linux/platform_device.h>
29 #include <media/v4l2-device.h>
30 #include <media/v4l2-event.h>
31 #include <media/v4l2-ioctl.h>
32 #include <media/v4l2-mem2mem.h>
33 #include <media/videobuf2-dma-sg.h>
34 #include <media/videobuf2-v4l2.h>
40 module_param(debug
, int, 0644);
42 static void job_abort(void *prv
)
44 struct rga_ctx
*ctx
= prv
;
45 struct rockchip_rga
*rga
= ctx
->rga
;
47 if (!rga
->curr
) /* No job currently running */
50 wait_event_timeout(rga
->irq_queue
,
51 !rga
->curr
, msecs_to_jiffies(RGA_TIMEOUT
));
54 static void device_run(void *prv
)
56 struct rga_ctx
*ctx
= prv
;
57 struct rockchip_rga
*rga
= ctx
->rga
;
58 struct vb2_buffer
*src
, *dst
;
61 spin_lock_irqsave(&rga
->ctrl_lock
, flags
);
65 src
= v4l2_m2m_next_src_buf(ctx
->fh
.m2m_ctx
);
66 dst
= v4l2_m2m_next_dst_buf(ctx
->fh
.m2m_ctx
);
73 spin_unlock_irqrestore(&rga
->ctrl_lock
, flags
);
76 static irqreturn_t
rga_isr(int irq
, void *prv
)
78 struct rockchip_rga
*rga
= prv
;
81 intr
= rga_read(rga
, RGA_INT
) & 0xf;
83 rga_mod(rga
, RGA_INT
, intr
<< 4, 0xf << 4);
86 struct vb2_v4l2_buffer
*src
, *dst
;
87 struct rga_ctx
*ctx
= rga
->curr
;
93 src
= v4l2_m2m_src_buf_remove(ctx
->fh
.m2m_ctx
);
94 dst
= v4l2_m2m_dst_buf_remove(ctx
->fh
.m2m_ctx
);
99 dst
->timecode
= src
->timecode
;
100 dst
->vb2_buf
.timestamp
= src
->vb2_buf
.timestamp
;
101 dst
->flags
&= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK
;
102 dst
->flags
|= src
->flags
& V4L2_BUF_FLAG_TSTAMP_SRC_MASK
;
104 v4l2_m2m_buf_done(src
, VB2_BUF_STATE_DONE
);
105 v4l2_m2m_buf_done(dst
, VB2_BUF_STATE_DONE
);
106 v4l2_m2m_job_finish(rga
->m2m_dev
, ctx
->fh
.m2m_ctx
);
108 wake_up(&rga
->irq_queue
);
114 static struct v4l2_m2m_ops rga_m2m_ops
= {
115 .device_run
= device_run
,
116 .job_abort
= job_abort
,
120 queue_init(void *priv
, struct vb2_queue
*src_vq
, struct vb2_queue
*dst_vq
)
122 struct rga_ctx
*ctx
= priv
;
125 src_vq
->type
= V4L2_BUF_TYPE_VIDEO_OUTPUT
;
126 src_vq
->io_modes
= VB2_MMAP
| VB2_DMABUF
;
127 src_vq
->drv_priv
= ctx
;
128 src_vq
->ops
= &rga_qops
;
129 src_vq
->mem_ops
= &vb2_dma_sg_memops
;
130 src_vq
->buf_struct_size
= sizeof(struct v4l2_m2m_buffer
);
131 src_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
132 src_vq
->lock
= &ctx
->rga
->mutex
;
133 src_vq
->dev
= ctx
->rga
->v4l2_dev
.dev
;
135 ret
= vb2_queue_init(src_vq
);
139 dst_vq
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
140 dst_vq
->io_modes
= VB2_MMAP
| VB2_DMABUF
;
141 dst_vq
->drv_priv
= ctx
;
142 dst_vq
->ops
= &rga_qops
;
143 dst_vq
->mem_ops
= &vb2_dma_sg_memops
;
144 dst_vq
->buf_struct_size
= sizeof(struct v4l2_m2m_buffer
);
145 dst_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
146 dst_vq
->lock
= &ctx
->rga
->mutex
;
147 dst_vq
->dev
= ctx
->rga
->v4l2_dev
.dev
;
149 return vb2_queue_init(dst_vq
);
152 static int rga_s_ctrl(struct v4l2_ctrl
*ctrl
)
154 struct rga_ctx
*ctx
= container_of(ctrl
->handler
, struct rga_ctx
,
158 spin_lock_irqsave(&ctx
->rga
->ctrl_lock
, flags
);
161 ctx
->hflip
= ctrl
->val
;
164 ctx
->vflip
= ctrl
->val
;
166 case V4L2_CID_ROTATE
:
167 ctx
->rotate
= ctrl
->val
;
169 case V4L2_CID_BG_COLOR
:
170 ctx
->fill_color
= ctrl
->val
;
173 spin_unlock_irqrestore(&ctx
->rga
->ctrl_lock
, flags
);
177 static const struct v4l2_ctrl_ops rga_ctrl_ops
= {
178 .s_ctrl
= rga_s_ctrl
,
181 static int rga_setup_ctrls(struct rga_ctx
*ctx
)
183 struct rockchip_rga
*rga
= ctx
->rga
;
185 v4l2_ctrl_handler_init(&ctx
->ctrl_handler
, 4);
187 v4l2_ctrl_new_std(&ctx
->ctrl_handler
, &rga_ctrl_ops
,
188 V4L2_CID_HFLIP
, 0, 1, 1, 0);
190 v4l2_ctrl_new_std(&ctx
->ctrl_handler
, &rga_ctrl_ops
,
191 V4L2_CID_VFLIP
, 0, 1, 1, 0);
193 v4l2_ctrl_new_std(&ctx
->ctrl_handler
, &rga_ctrl_ops
,
194 V4L2_CID_ROTATE
, 0, 270, 90, 0);
196 v4l2_ctrl_new_std(&ctx
->ctrl_handler
, &rga_ctrl_ops
,
197 V4L2_CID_BG_COLOR
, 0, 0xffffffff, 1, 0);
199 if (ctx
->ctrl_handler
.error
) {
200 int err
= ctx
->ctrl_handler
.error
;
202 v4l2_err(&rga
->v4l2_dev
, "%s failed\n", __func__
);
203 v4l2_ctrl_handler_free(&ctx
->ctrl_handler
);
210 struct rga_fmt formats
[] = {
212 .fourcc
= V4L2_PIX_FMT_ARGB32
,
213 .color_swap
= RGA_COLOR_RB_SWAP
,
214 .hw_format
= RGA_COLOR_FMT_ABGR8888
,
221 .fourcc
= V4L2_PIX_FMT_XRGB32
,
222 .color_swap
= RGA_COLOR_RB_SWAP
,
223 .hw_format
= RGA_COLOR_FMT_XBGR8888
,
230 .fourcc
= V4L2_PIX_FMT_ABGR32
,
231 .color_swap
= RGA_COLOR_ALPHA_SWAP
,
232 .hw_format
= RGA_COLOR_FMT_ABGR8888
,
239 .fourcc
= V4L2_PIX_FMT_XBGR32
,
240 .color_swap
= RGA_COLOR_ALPHA_SWAP
,
241 .hw_format
= RGA_COLOR_FMT_XBGR8888
,
248 .fourcc
= V4L2_PIX_FMT_RGB24
,
249 .color_swap
= RGA_COLOR_NONE_SWAP
,
250 .hw_format
= RGA_COLOR_FMT_RGB888
,
257 .fourcc
= V4L2_PIX_FMT_BGR24
,
258 .color_swap
= RGA_COLOR_RB_SWAP
,
259 .hw_format
= RGA_COLOR_FMT_RGB888
,
266 .fourcc
= V4L2_PIX_FMT_ARGB444
,
267 .color_swap
= RGA_COLOR_RB_SWAP
,
268 .hw_format
= RGA_COLOR_FMT_ABGR4444
,
275 .fourcc
= V4L2_PIX_FMT_ARGB555
,
276 .color_swap
= RGA_COLOR_RB_SWAP
,
277 .hw_format
= RGA_COLOR_FMT_ABGR1555
,
284 .fourcc
= V4L2_PIX_FMT_RGB565
,
285 .color_swap
= RGA_COLOR_RB_SWAP
,
286 .hw_format
= RGA_COLOR_FMT_BGR565
,
293 .fourcc
= V4L2_PIX_FMT_NV21
,
294 .color_swap
= RGA_COLOR_UV_SWAP
,
295 .hw_format
= RGA_COLOR_FMT_YUV420SP
,
302 .fourcc
= V4L2_PIX_FMT_NV61
,
303 .color_swap
= RGA_COLOR_UV_SWAP
,
304 .hw_format
= RGA_COLOR_FMT_YUV422SP
,
311 .fourcc
= V4L2_PIX_FMT_NV12
,
312 .color_swap
= RGA_COLOR_NONE_SWAP
,
313 .hw_format
= RGA_COLOR_FMT_YUV420SP
,
320 .fourcc
= V4L2_PIX_FMT_NV16
,
321 .color_swap
= RGA_COLOR_NONE_SWAP
,
322 .hw_format
= RGA_COLOR_FMT_YUV422SP
,
329 .fourcc
= V4L2_PIX_FMT_YUV420
,
330 .color_swap
= RGA_COLOR_NONE_SWAP
,
331 .hw_format
= RGA_COLOR_FMT_YUV420P
,
338 .fourcc
= V4L2_PIX_FMT_YUV422P
,
339 .color_swap
= RGA_COLOR_NONE_SWAP
,
340 .hw_format
= RGA_COLOR_FMT_YUV422P
,
347 .fourcc
= V4L2_PIX_FMT_YVU420
,
348 .color_swap
= RGA_COLOR_UV_SWAP
,
349 .hw_format
= RGA_COLOR_FMT_YUV420P
,
357 #define NUM_FORMATS ARRAY_SIZE(formats)
359 static struct rga_fmt
*rga_fmt_find(struct v4l2_format
*f
)
363 for (i
= 0; i
< NUM_FORMATS
; i
++) {
364 if (formats
[i
].fourcc
== f
->fmt
.pix
.pixelformat
)
370 static struct rga_frame def_frame
= {
371 .width
= DEFAULT_WIDTH
,
372 .height
= DEFAULT_HEIGHT
,
373 .colorspace
= V4L2_COLORSPACE_DEFAULT
,
376 .crop
.width
= DEFAULT_WIDTH
,
377 .crop
.height
= DEFAULT_HEIGHT
,
381 struct rga_frame
*rga_get_frame(struct rga_ctx
*ctx
, enum v4l2_buf_type type
)
384 case V4L2_BUF_TYPE_VIDEO_OUTPUT
:
386 case V4L2_BUF_TYPE_VIDEO_CAPTURE
:
389 return ERR_PTR(-EINVAL
);
393 static int rga_open(struct file
*file
)
395 struct rockchip_rga
*rga
= video_drvdata(file
);
396 struct rga_ctx
*ctx
= NULL
;
399 ctx
= kzalloc(sizeof(*ctx
), GFP_KERNEL
);
403 /* Set default formats */
405 ctx
->out
= def_frame
;
407 if (mutex_lock_interruptible(&rga
->mutex
)) {
411 ctx
->fh
.m2m_ctx
= v4l2_m2m_ctx_init(rga
->m2m_dev
, ctx
, &queue_init
);
412 if (IS_ERR(ctx
->fh
.m2m_ctx
)) {
413 ret
= PTR_ERR(ctx
->fh
.m2m_ctx
);
414 mutex_unlock(&rga
->mutex
);
418 v4l2_fh_init(&ctx
->fh
, video_devdata(file
));
419 file
->private_data
= &ctx
->fh
;
420 v4l2_fh_add(&ctx
->fh
);
422 rga_setup_ctrls(ctx
);
424 /* Write the default values to the ctx struct */
425 v4l2_ctrl_handler_setup(&ctx
->ctrl_handler
);
427 ctx
->fh
.ctrl_handler
= &ctx
->ctrl_handler
;
428 mutex_unlock(&rga
->mutex
);
433 static int rga_release(struct file
*file
)
435 struct rga_ctx
*ctx
=
436 container_of(file
->private_data
, struct rga_ctx
, fh
);
437 struct rockchip_rga
*rga
= ctx
->rga
;
439 mutex_lock(&rga
->mutex
);
441 v4l2_m2m_ctx_release(ctx
->fh
.m2m_ctx
);
443 v4l2_ctrl_handler_free(&ctx
->ctrl_handler
);
444 v4l2_fh_del(&ctx
->fh
);
445 v4l2_fh_exit(&ctx
->fh
);
448 mutex_unlock(&rga
->mutex
);
453 static const struct v4l2_file_operations rga_fops
= {
454 .owner
= THIS_MODULE
,
456 .release
= rga_release
,
457 .poll
= v4l2_m2m_fop_poll
,
458 .unlocked_ioctl
= video_ioctl2
,
459 .mmap
= v4l2_m2m_fop_mmap
,
463 vidioc_querycap(struct file
*file
, void *priv
, struct v4l2_capability
*cap
)
465 strlcpy(cap
->driver
, RGA_NAME
, sizeof(cap
->driver
));
466 strlcpy(cap
->card
, "rockchip-rga", sizeof(cap
->card
));
467 strlcpy(cap
->bus_info
, "platform:rga", sizeof(cap
->bus_info
));
472 static int vidioc_enum_fmt(struct file
*file
, void *prv
, struct v4l2_fmtdesc
*f
)
476 if (f
->index
>= NUM_FORMATS
)
479 fmt
= &formats
[f
->index
];
480 f
->pixelformat
= fmt
->fourcc
;
485 static int vidioc_g_fmt(struct file
*file
, void *prv
, struct v4l2_format
*f
)
487 struct rga_ctx
*ctx
= prv
;
488 struct vb2_queue
*vq
;
489 struct rga_frame
*frm
;
491 vq
= v4l2_m2m_get_vq(ctx
->fh
.m2m_ctx
, f
->type
);
494 frm
= rga_get_frame(ctx
, f
->type
);
498 f
->fmt
.pix
.width
= frm
->width
;
499 f
->fmt
.pix
.height
= frm
->height
;
500 f
->fmt
.pix
.field
= V4L2_FIELD_NONE
;
501 f
->fmt
.pix
.pixelformat
= frm
->fmt
->fourcc
;
502 f
->fmt
.pix
.bytesperline
= frm
->stride
;
503 f
->fmt
.pix
.sizeimage
= frm
->size
;
504 f
->fmt
.pix
.colorspace
= frm
->colorspace
;
509 static int vidioc_try_fmt(struct file
*file
, void *prv
, struct v4l2_format
*f
)
513 fmt
= rga_fmt_find(f
);
516 f
->fmt
.pix
.pixelformat
= fmt
->fourcc
;
519 f
->fmt
.pix
.field
= V4L2_FIELD_NONE
;
521 if (f
->fmt
.pix
.width
> MAX_WIDTH
)
522 f
->fmt
.pix
.width
= MAX_WIDTH
;
523 if (f
->fmt
.pix
.height
> MAX_HEIGHT
)
524 f
->fmt
.pix
.height
= MAX_HEIGHT
;
526 if (f
->fmt
.pix
.width
< MIN_WIDTH
)
527 f
->fmt
.pix
.width
= MIN_WIDTH
;
528 if (f
->fmt
.pix
.height
< MIN_HEIGHT
)
529 f
->fmt
.pix
.height
= MIN_HEIGHT
;
531 if (fmt
->hw_format
>= RGA_COLOR_FMT_YUV422SP
)
532 f
->fmt
.pix
.bytesperline
= f
->fmt
.pix
.width
;
534 f
->fmt
.pix
.bytesperline
= (f
->fmt
.pix
.width
* fmt
->depth
) >> 3;
536 f
->fmt
.pix
.sizeimage
=
537 f
->fmt
.pix
.height
* (f
->fmt
.pix
.width
* fmt
->depth
) >> 3;
542 static int vidioc_s_fmt(struct file
*file
, void *prv
, struct v4l2_format
*f
)
544 struct rga_ctx
*ctx
= prv
;
545 struct rockchip_rga
*rga
= ctx
->rga
;
546 struct vb2_queue
*vq
;
547 struct rga_frame
*frm
;
551 /* Adjust all values accordingly to the hardware capabilities
554 ret
= vidioc_try_fmt(file
, prv
, f
);
557 vq
= v4l2_m2m_get_vq(ctx
->fh
.m2m_ctx
, f
->type
);
558 if (vb2_is_busy(vq
)) {
559 v4l2_err(&rga
->v4l2_dev
, "queue (%d) bust\n", f
->type
);
562 frm
= rga_get_frame(ctx
, f
->type
);
565 fmt
= rga_fmt_find(f
);
568 frm
->width
= f
->fmt
.pix
.width
;
569 frm
->height
= f
->fmt
.pix
.height
;
570 frm
->size
= f
->fmt
.pix
.sizeimage
;
572 frm
->stride
= f
->fmt
.pix
.bytesperline
;
573 frm
->colorspace
= f
->fmt
.pix
.colorspace
;
575 /* Reset crop settings */
578 frm
->crop
.width
= frm
->width
;
579 frm
->crop
.height
= frm
->height
;
584 static int vidioc_g_selection(struct file
*file
, void *prv
,
585 struct v4l2_selection
*s
)
587 struct rga_ctx
*ctx
= prv
;
589 bool use_frame
= false;
591 f
= rga_get_frame(ctx
, s
->type
);
596 case V4L2_SEL_TGT_COMPOSE_DEFAULT
:
597 case V4L2_SEL_TGT_COMPOSE_BOUNDS
:
598 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
601 case V4L2_SEL_TGT_CROP_DEFAULT
:
602 case V4L2_SEL_TGT_CROP_BOUNDS
:
603 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
606 case V4L2_SEL_TGT_COMPOSE
:
607 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
611 case V4L2_SEL_TGT_CROP
:
612 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
625 s
->r
.width
= f
->width
;
626 s
->r
.height
= f
->height
;
632 static int vidioc_s_selection(struct file
*file
, void *prv
,
633 struct v4l2_selection
*s
)
635 struct rga_ctx
*ctx
= prv
;
636 struct rockchip_rga
*rga
= ctx
->rga
;
640 f
= rga_get_frame(ctx
, s
->type
);
645 case V4L2_SEL_TGT_COMPOSE
:
647 * COMPOSE target is only valid for capture buffer type, return
648 * error for output buffer type
650 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
653 case V4L2_SEL_TGT_CROP
:
655 * CROP target is only valid for output buffer type, return
656 * error for capture buffer type
658 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
662 * bound and default crop/compose targets are invalid targets to
669 if (s
->r
.top
< 0 || s
->r
.left
< 0) {
670 v4l2_dbg(debug
, 1, &rga
->v4l2_dev
,
671 "doesn't support negative values for top & left.\n");
675 if (s
->r
.left
+ s
->r
.width
> f
->width
||
676 s
->r
.top
+ s
->r
.height
> f
->height
||
677 s
->r
.width
< MIN_WIDTH
|| s
->r
.height
< MIN_HEIGHT
) {
678 v4l2_dbg(debug
, 1, &rga
->v4l2_dev
, "unsupported crop value.\n");
687 static const struct v4l2_ioctl_ops rga_ioctl_ops
= {
688 .vidioc_querycap
= vidioc_querycap
,
690 .vidioc_enum_fmt_vid_cap
= vidioc_enum_fmt
,
691 .vidioc_g_fmt_vid_cap
= vidioc_g_fmt
,
692 .vidioc_try_fmt_vid_cap
= vidioc_try_fmt
,
693 .vidioc_s_fmt_vid_cap
= vidioc_s_fmt
,
695 .vidioc_enum_fmt_vid_out
= vidioc_enum_fmt
,
696 .vidioc_g_fmt_vid_out
= vidioc_g_fmt
,
697 .vidioc_try_fmt_vid_out
= vidioc_try_fmt
,
698 .vidioc_s_fmt_vid_out
= vidioc_s_fmt
,
700 .vidioc_reqbufs
= v4l2_m2m_ioctl_reqbufs
,
701 .vidioc_querybuf
= v4l2_m2m_ioctl_querybuf
,
702 .vidioc_qbuf
= v4l2_m2m_ioctl_qbuf
,
703 .vidioc_dqbuf
= v4l2_m2m_ioctl_dqbuf
,
704 .vidioc_prepare_buf
= v4l2_m2m_ioctl_prepare_buf
,
705 .vidioc_create_bufs
= v4l2_m2m_ioctl_create_bufs
,
706 .vidioc_expbuf
= v4l2_m2m_ioctl_expbuf
,
708 .vidioc_subscribe_event
= v4l2_ctrl_subscribe_event
,
709 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
711 .vidioc_streamon
= v4l2_m2m_ioctl_streamon
,
712 .vidioc_streamoff
= v4l2_m2m_ioctl_streamoff
,
714 .vidioc_g_selection
= vidioc_g_selection
,
715 .vidioc_s_selection
= vidioc_s_selection
,
718 static struct video_device rga_videodev
= {
719 .name
= "rockchip-rga",
721 .ioctl_ops
= &rga_ioctl_ops
,
723 .release
= video_device_release
,
724 .vfl_dir
= VFL_DIR_M2M
,
725 .device_caps
= V4L2_CAP_VIDEO_M2M
| V4L2_CAP_STREAMING
,
728 static int rga_enable_clocks(struct rockchip_rga
*rga
)
732 ret
= clk_prepare_enable(rga
->sclk
);
734 dev_err(rga
->dev
, "Cannot enable rga sclk: %d\n", ret
);
738 ret
= clk_prepare_enable(rga
->aclk
);
740 dev_err(rga
->dev
, "Cannot enable rga aclk: %d\n", ret
);
741 goto err_disable_sclk
;
744 ret
= clk_prepare_enable(rga
->hclk
);
746 dev_err(rga
->dev
, "Cannot enable rga hclk: %d\n", ret
);
747 goto err_disable_aclk
;
753 clk_disable_unprepare(rga
->sclk
);
755 clk_disable_unprepare(rga
->aclk
);
760 static void rga_disable_clocks(struct rockchip_rga
*rga
)
762 clk_disable_unprepare(rga
->sclk
);
763 clk_disable_unprepare(rga
->hclk
);
764 clk_disable_unprepare(rga
->aclk
);
767 static int rga_parse_dt(struct rockchip_rga
*rga
)
769 struct reset_control
*core_rst
, *axi_rst
, *ahb_rst
;
771 core_rst
= devm_reset_control_get(rga
->dev
, "core");
772 if (IS_ERR(core_rst
)) {
773 dev_err(rga
->dev
, "failed to get core reset controller\n");
774 return PTR_ERR(core_rst
);
777 axi_rst
= devm_reset_control_get(rga
->dev
, "axi");
778 if (IS_ERR(axi_rst
)) {
779 dev_err(rga
->dev
, "failed to get axi reset controller\n");
780 return PTR_ERR(axi_rst
);
783 ahb_rst
= devm_reset_control_get(rga
->dev
, "ahb");
784 if (IS_ERR(ahb_rst
)) {
785 dev_err(rga
->dev
, "failed to get ahb reset controller\n");
786 return PTR_ERR(ahb_rst
);
789 reset_control_assert(core_rst
);
791 reset_control_deassert(core_rst
);
793 reset_control_assert(axi_rst
);
795 reset_control_deassert(axi_rst
);
797 reset_control_assert(ahb_rst
);
799 reset_control_deassert(ahb_rst
);
801 rga
->sclk
= devm_clk_get(rga
->dev
, "sclk");
802 if (IS_ERR(rga
->sclk
)) {
803 dev_err(rga
->dev
, "failed to get sclk clock\n");
804 return PTR_ERR(rga
->sclk
);
807 rga
->aclk
= devm_clk_get(rga
->dev
, "aclk");
808 if (IS_ERR(rga
->aclk
)) {
809 dev_err(rga
->dev
, "failed to get aclk clock\n");
810 return PTR_ERR(rga
->aclk
);
813 rga
->hclk
= devm_clk_get(rga
->dev
, "hclk");
814 if (IS_ERR(rga
->hclk
)) {
815 dev_err(rga
->dev
, "failed to get hclk clock\n");
816 return PTR_ERR(rga
->hclk
);
822 static int rga_probe(struct platform_device
*pdev
)
824 struct rockchip_rga
*rga
;
825 struct video_device
*vfd
;
826 struct resource
*res
;
830 if (!pdev
->dev
.of_node
)
833 rga
= devm_kzalloc(&pdev
->dev
, sizeof(*rga
), GFP_KERNEL
);
837 rga
->dev
= &pdev
->dev
;
838 spin_lock_init(&rga
->ctrl_lock
);
839 mutex_init(&rga
->mutex
);
841 init_waitqueue_head(&rga
->irq_queue
);
843 ret
= rga_parse_dt(rga
);
845 dev_err(&pdev
->dev
, "Unable to parse OF data\n");
847 pm_runtime_enable(rga
->dev
);
849 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
851 rga
->regs
= devm_ioremap_resource(rga
->dev
, res
);
852 if (IS_ERR(rga
->regs
)) {
853 ret
= PTR_ERR(rga
->regs
);
857 irq
= platform_get_irq(pdev
, 0);
859 dev_err(rga
->dev
, "failed to get irq\n");
864 ret
= devm_request_irq(rga
->dev
, irq
, rga_isr
, 0,
865 dev_name(rga
->dev
), rga
);
867 dev_err(rga
->dev
, "failed to request irq\n");
871 ret
= v4l2_device_register(&pdev
->dev
, &rga
->v4l2_dev
);
874 vfd
= video_device_alloc();
876 v4l2_err(&rga
->v4l2_dev
, "Failed to allocate video device\n");
881 vfd
->lock
= &rga
->mutex
;
882 vfd
->v4l2_dev
= &rga
->v4l2_dev
;
884 video_set_drvdata(vfd
, rga
);
885 snprintf(vfd
->name
, sizeof(vfd
->name
), "%s", rga_videodev
.name
);
888 platform_set_drvdata(pdev
, rga
);
889 rga
->m2m_dev
= v4l2_m2m_init(&rga_m2m_ops
);
890 if (IS_ERR(rga
->m2m_dev
)) {
891 v4l2_err(&rga
->v4l2_dev
, "Failed to init mem2mem device\n");
892 ret
= PTR_ERR(rga
->m2m_dev
);
893 goto unreg_video_dev
;
896 pm_runtime_get_sync(rga
->dev
);
898 rga
->version
.major
= (rga_read(rga
, RGA_VERSION_INFO
) >> 24) & 0xFF;
899 rga
->version
.minor
= (rga_read(rga
, RGA_VERSION_INFO
) >> 20) & 0x0F;
901 v4l2_info(&rga
->v4l2_dev
, "HW Version: 0x%02x.%02x\n",
902 rga
->version
.major
, rga
->version
.minor
);
904 pm_runtime_put(rga
->dev
);
906 /* Create CMD buffer */
907 rga
->cmdbuf_virt
= dma_alloc_attrs(rga
->dev
, RGA_CMDBUF_SIZE
,
908 &rga
->cmdbuf_phy
, GFP_KERNEL
,
909 DMA_ATTR_WRITE_COMBINE
);
912 (unsigned int *)__get_free_pages(GFP_KERNEL
| __GFP_ZERO
, 3);
914 (unsigned int *)__get_free_pages(GFP_KERNEL
| __GFP_ZERO
, 3);
916 def_frame
.stride
= (def_frame
.width
* def_frame
.fmt
->depth
) >> 3;
917 def_frame
.size
= def_frame
.stride
* def_frame
.height
;
919 ret
= video_register_device(vfd
, VFL_TYPE_GRABBER
, -1);
921 v4l2_err(&rga
->v4l2_dev
, "Failed to register video device\n");
925 v4l2_info(&rga
->v4l2_dev
, "Registered %s as /dev/%s\n",
926 vfd
->name
, video_device_node_name(vfd
));
931 video_device_release(vfd
);
933 video_unregister_device(rga
->vfd
);
935 v4l2_device_unregister(&rga
->v4l2_dev
);
937 pm_runtime_disable(rga
->dev
);
942 static int rga_remove(struct platform_device
*pdev
)
944 struct rockchip_rga
*rga
= platform_get_drvdata(pdev
);
946 dma_free_attrs(rga
->dev
, RGA_CMDBUF_SIZE
, &rga
->cmdbuf_virt
,
947 rga
->cmdbuf_phy
, DMA_ATTR_WRITE_COMBINE
);
949 free_pages((unsigned long)rga
->src_mmu_pages
, 3);
950 free_pages((unsigned long)rga
->dst_mmu_pages
, 3);
952 v4l2_info(&rga
->v4l2_dev
, "Removing\n");
954 v4l2_m2m_release(rga
->m2m_dev
);
955 video_unregister_device(rga
->vfd
);
956 v4l2_device_unregister(&rga
->v4l2_dev
);
958 pm_runtime_disable(rga
->dev
);
963 static int __maybe_unused
rga_runtime_suspend(struct device
*dev
)
965 struct rockchip_rga
*rga
= dev_get_drvdata(dev
);
967 rga_disable_clocks(rga
);
972 static int __maybe_unused
rga_runtime_resume(struct device
*dev
)
974 struct rockchip_rga
*rga
= dev_get_drvdata(dev
);
976 return rga_enable_clocks(rga
);
979 static const struct dev_pm_ops rga_pm
= {
980 SET_RUNTIME_PM_OPS(rga_runtime_suspend
,
981 rga_runtime_resume
, NULL
)
984 static const struct of_device_id rockchip_rga_match
[] = {
986 .compatible
= "rockchip,rk3288-rga",
989 .compatible
= "rockchip,rk3399-rga",
994 MODULE_DEVICE_TABLE(of
, rockchip_rga_match
);
996 static struct platform_driver rga_pdrv
= {
998 .remove
= rga_remove
,
1002 .of_match_table
= rockchip_rga_match
,
1006 module_platform_driver(rga_pdrv
);
1008 MODULE_AUTHOR("Jacob Chen <jacob-chen@iotwrt.com>");
1009 MODULE_DESCRIPTION("Rockchip Raster 2d Graphic Acceleration Unit");
1010 MODULE_LICENSE("GPL");