1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
4 * Author: Jacob Chen <jacob-chen@iotwrt.com>
5 */
6
7 #include <linux/clk.h>
8 #include <linux/debugfs.h>
9 #include <linux/delay.h>
10 #include <linux/fs.h>
11 #include <linux/interrupt.h>
12 #include <linux/module.h>
13 #include <linux/of.h>
14 #include <linux/pm_runtime.h>
15 #include <linux/reset.h>
16 #include <linux/sched.h>
17 #include <linux/slab.h>
18 #include <linux/timer.h>
19
20 #include <linux/platform_device.h>
21 #include <media/v4l2-device.h>
22 #include <media/v4l2-event.h>
23 #include <media/v4l2-ioctl.h>
24 #include <media/v4l2-mem2mem.h>
25 #include <media/videobuf2-dma-sg.h>
26 #include <media/videobuf2-v4l2.h>
27
28 #include "rga-hw.h"
29 #include "rga.h"
30
31 static int debug;
32 module_param(debug, int, 0644);
33
device_run(void * prv)34 static void device_run(void *prv)
35 {
36 struct rga_ctx *ctx = prv;
37 struct rockchip_rga *rga = ctx->rga;
38 struct vb2_v4l2_buffer *src, *dst;
39 unsigned long flags;
40
41 spin_lock_irqsave(&rga->ctrl_lock, flags);
42
43 rga->curr = ctx;
44
45 src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
46 dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
47
48 rga_hw_start(rga, vb_to_rga(src), vb_to_rga(dst));
49
50 spin_unlock_irqrestore(&rga->ctrl_lock, flags);
51 }
52
rga_isr(int irq,void * prv)53 static irqreturn_t rga_isr(int irq, void *prv)
54 {
55 struct rockchip_rga *rga = prv;
56 int intr;
57
58 intr = rga_read(rga, RGA_INT) & 0xf;
59
60 rga_mod(rga, RGA_INT, intr << 4, 0xf << 4);
61
62 if (intr & 0x04) {
63 struct vb2_v4l2_buffer *src, *dst;
64 struct rga_ctx *ctx = rga->curr;
65
66 WARN_ON(!ctx);
67
68 rga->curr = NULL;
69
70 src = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
71 dst = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
72
73 WARN_ON(!src);
74 WARN_ON(!dst);
75
76 v4l2_m2m_buf_copy_metadata(src, dst, true);
77
78 v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE);
79 v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
80 v4l2_m2m_job_finish(rga->m2m_dev, ctx->fh.m2m_ctx);
81 }
82
83 return IRQ_HANDLED;
84 }
85
86 static const struct v4l2_m2m_ops rga_m2m_ops = {
87 .device_run = device_run,
88 };
89
90 static int
queue_init(void * priv,struct vb2_queue * src_vq,struct vb2_queue * dst_vq)91 queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
92 {
93 struct rga_ctx *ctx = priv;
94 int ret;
95
96 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
97 src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
98 src_vq->drv_priv = ctx;
99 src_vq->ops = &rga_qops;
100 src_vq->mem_ops = &vb2_dma_sg_memops;
101 dst_vq->gfp_flags = __GFP_DMA32;
102 src_vq->buf_struct_size = sizeof(struct rga_vb_buffer);
103 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
104 src_vq->lock = &ctx->rga->mutex;
105 src_vq->dev = ctx->rga->v4l2_dev.dev;
106
107 ret = vb2_queue_init(src_vq);
108 if (ret)
109 return ret;
110
111 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
112 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
113 dst_vq->drv_priv = ctx;
114 dst_vq->ops = &rga_qops;
115 dst_vq->mem_ops = &vb2_dma_sg_memops;
116 dst_vq->gfp_flags = __GFP_DMA32;
117 dst_vq->buf_struct_size = sizeof(struct rga_vb_buffer);
118 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
119 dst_vq->lock = &ctx->rga->mutex;
120 dst_vq->dev = ctx->rga->v4l2_dev.dev;
121
122 return vb2_queue_init(dst_vq);
123 }
124
rga_s_ctrl(struct v4l2_ctrl * ctrl)125 static int rga_s_ctrl(struct v4l2_ctrl *ctrl)
126 {
127 struct rga_ctx *ctx = container_of(ctrl->handler, struct rga_ctx,
128 ctrl_handler);
129 unsigned long flags;
130
131 spin_lock_irqsave(&ctx->rga->ctrl_lock, flags);
132 switch (ctrl->id) {
133 case V4L2_CID_HFLIP:
134 ctx->hflip = ctrl->val;
135 break;
136 case V4L2_CID_VFLIP:
137 ctx->vflip = ctrl->val;
138 break;
139 case V4L2_CID_ROTATE:
140 ctx->rotate = ctrl->val;
141 break;
142 case V4L2_CID_BG_COLOR:
143 ctx->fill_color = ctrl->val;
144 break;
145 }
146 spin_unlock_irqrestore(&ctx->rga->ctrl_lock, flags);
147 return 0;
148 }
149
150 static const struct v4l2_ctrl_ops rga_ctrl_ops = {
151 .s_ctrl = rga_s_ctrl,
152 };
153
rga_setup_ctrls(struct rga_ctx * ctx)154 static int rga_setup_ctrls(struct rga_ctx *ctx)
155 {
156 struct rockchip_rga *rga = ctx->rga;
157
158 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4);
159
160 v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops,
161 V4L2_CID_HFLIP, 0, 1, 1, 0);
162
163 v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops,
164 V4L2_CID_VFLIP, 0, 1, 1, 0);
165
166 v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops,
167 V4L2_CID_ROTATE, 0, 270, 90, 0);
168
169 v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops,
170 V4L2_CID_BG_COLOR, 0, 0xffffffff, 1, 0);
171
172 if (ctx->ctrl_handler.error) {
173 int err = ctx->ctrl_handler.error;
174
175 v4l2_err(&rga->v4l2_dev, "%s failed\n", __func__);
176 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
177 return err;
178 }
179
180 return 0;
181 }
182
183 static struct rga_fmt formats[] = {
184 {
185 .fourcc = V4L2_PIX_FMT_ARGB32,
186 .color_swap = RGA_COLOR_ALPHA_SWAP,
187 .hw_format = RGA_COLOR_FMT_ABGR8888,
188 .depth = 32,
189 .uv_factor = 1,
190 .y_div = 1,
191 .x_div = 1,
192 },
193 {
194 .fourcc = V4L2_PIX_FMT_ABGR32,
195 .color_swap = RGA_COLOR_RB_SWAP,
196 .hw_format = RGA_COLOR_FMT_ABGR8888,
197 .depth = 32,
198 .uv_factor = 1,
199 .y_div = 1,
200 .x_div = 1,
201 },
202 {
203 .fourcc = V4L2_PIX_FMT_XBGR32,
204 .color_swap = RGA_COLOR_RB_SWAP,
205 .hw_format = RGA_COLOR_FMT_XBGR8888,
206 .depth = 32,
207 .uv_factor = 1,
208 .y_div = 1,
209 .x_div = 1,
210 },
211 {
212 .fourcc = V4L2_PIX_FMT_RGB24,
213 .color_swap = RGA_COLOR_NONE_SWAP,
214 .hw_format = RGA_COLOR_FMT_RGB888,
215 .depth = 24,
216 .uv_factor = 1,
217 .y_div = 1,
218 .x_div = 1,
219 },
220 {
221 .fourcc = V4L2_PIX_FMT_BGR24,
222 .color_swap = RGA_COLOR_RB_SWAP,
223 .hw_format = RGA_COLOR_FMT_RGB888,
224 .depth = 24,
225 .uv_factor = 1,
226 .y_div = 1,
227 .x_div = 1,
228 },
229 {
230 .fourcc = V4L2_PIX_FMT_ARGB444,
231 .color_swap = RGA_COLOR_RB_SWAP,
232 .hw_format = RGA_COLOR_FMT_ABGR4444,
233 .depth = 16,
234 .uv_factor = 1,
235 .y_div = 1,
236 .x_div = 1,
237 },
238 {
239 .fourcc = V4L2_PIX_FMT_ARGB555,
240 .color_swap = RGA_COLOR_RB_SWAP,
241 .hw_format = RGA_COLOR_FMT_ABGR1555,
242 .depth = 16,
243 .uv_factor = 1,
244 .y_div = 1,
245 .x_div = 1,
246 },
247 {
248 .fourcc = V4L2_PIX_FMT_RGB565,
249 .color_swap = RGA_COLOR_RB_SWAP,
250 .hw_format = RGA_COLOR_FMT_BGR565,
251 .depth = 16,
252 .uv_factor = 1,
253 .y_div = 1,
254 .x_div = 1,
255 },
256 {
257 .fourcc = V4L2_PIX_FMT_NV21,
258 .color_swap = RGA_COLOR_UV_SWAP,
259 .hw_format = RGA_COLOR_FMT_YUV420SP,
260 .depth = 12,
261 .uv_factor = 4,
262 .y_div = 2,
263 .x_div = 1,
264 },
265 {
266 .fourcc = V4L2_PIX_FMT_NV61,
267 .color_swap = RGA_COLOR_UV_SWAP,
268 .hw_format = RGA_COLOR_FMT_YUV422SP,
269 .depth = 16,
270 .uv_factor = 2,
271 .y_div = 1,
272 .x_div = 1,
273 },
274 {
275 .fourcc = V4L2_PIX_FMT_NV12,
276 .color_swap = RGA_COLOR_NONE_SWAP,
277 .hw_format = RGA_COLOR_FMT_YUV420SP,
278 .depth = 12,
279 .uv_factor = 4,
280 .y_div = 2,
281 .x_div = 1,
282 },
283 {
284 .fourcc = V4L2_PIX_FMT_NV12M,
285 .color_swap = RGA_COLOR_NONE_SWAP,
286 .hw_format = RGA_COLOR_FMT_YUV420SP,
287 .depth = 12,
288 .uv_factor = 4,
289 .y_div = 2,
290 .x_div = 1,
291 },
292 {
293 .fourcc = V4L2_PIX_FMT_NV16,
294 .color_swap = RGA_COLOR_NONE_SWAP,
295 .hw_format = RGA_COLOR_FMT_YUV422SP,
296 .depth = 16,
297 .uv_factor = 2,
298 .y_div = 1,
299 .x_div = 1,
300 },
301 {
302 .fourcc = V4L2_PIX_FMT_YUV420,
303 .color_swap = RGA_COLOR_NONE_SWAP,
304 .hw_format = RGA_COLOR_FMT_YUV420P,
305 .depth = 12,
306 .uv_factor = 4,
307 .y_div = 2,
308 .x_div = 2,
309 },
310 {
311 .fourcc = V4L2_PIX_FMT_YUV422P,
312 .color_swap = RGA_COLOR_NONE_SWAP,
313 .hw_format = RGA_COLOR_FMT_YUV422P,
314 .depth = 16,
315 .uv_factor = 2,
316 .y_div = 1,
317 .x_div = 2,
318 },
319 {
320 .fourcc = V4L2_PIX_FMT_YVU420,
321 .color_swap = RGA_COLOR_UV_SWAP,
322 .hw_format = RGA_COLOR_FMT_YUV420P,
323 .depth = 12,
324 .uv_factor = 4,
325 .y_div = 2,
326 .x_div = 2,
327 },
328 };
329
330 #define NUM_FORMATS ARRAY_SIZE(formats)
331
rga_fmt_find(u32 pixelformat)332 static struct rga_fmt *rga_fmt_find(u32 pixelformat)
333 {
334 unsigned int i;
335
336 for (i = 0; i < NUM_FORMATS; i++) {
337 if (formats[i].fourcc == pixelformat)
338 return &formats[i];
339 }
340 return NULL;
341 }
342
343 static struct rga_frame def_frame = {
344 .width = DEFAULT_WIDTH,
345 .height = DEFAULT_HEIGHT,
346 .colorspace = V4L2_COLORSPACE_DEFAULT,
347 .crop.left = 0,
348 .crop.top = 0,
349 .crop.width = DEFAULT_WIDTH,
350 .crop.height = DEFAULT_HEIGHT,
351 .fmt = &formats[0],
352 };
353
rga_get_frame(struct rga_ctx * ctx,enum v4l2_buf_type type)354 struct rga_frame *rga_get_frame(struct rga_ctx *ctx, enum v4l2_buf_type type)
355 {
356 if (V4L2_TYPE_IS_OUTPUT(type))
357 return &ctx->in;
358 if (V4L2_TYPE_IS_CAPTURE(type))
359 return &ctx->out;
360 return ERR_PTR(-EINVAL);
361 }
362
rga_open(struct file * file)363 static int rga_open(struct file *file)
364 {
365 struct rockchip_rga *rga = video_drvdata(file);
366 struct rga_ctx *ctx = NULL;
367 int ret = 0;
368
369 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
370 if (!ctx)
371 return -ENOMEM;
372 ctx->rga = rga;
373 /* Set default formats */
374 ctx->in = def_frame;
375 ctx->out = def_frame;
376
377 v4l2_fill_pixfmt_mp(&ctx->in.pix,
378 ctx->in.fmt->fourcc, ctx->out.width, ctx->out.height);
379 v4l2_fill_pixfmt_mp(&ctx->out.pix,
380 ctx->out.fmt->fourcc, ctx->out.width, ctx->out.height);
381
382 if (mutex_lock_interruptible(&rga->mutex)) {
383 kfree(ctx);
384 return -ERESTARTSYS;
385 }
386 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(rga->m2m_dev, ctx, &queue_init);
387 if (IS_ERR(ctx->fh.m2m_ctx)) {
388 ret = PTR_ERR(ctx->fh.m2m_ctx);
389 mutex_unlock(&rga->mutex);
390 kfree(ctx);
391 return ret;
392 }
393 v4l2_fh_init(&ctx->fh, video_devdata(file));
394 file->private_data = &ctx->fh;
395 v4l2_fh_add(&ctx->fh);
396
397 rga_setup_ctrls(ctx);
398
399 /* Write the default values to the ctx struct */
400 v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
401
402 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
403 mutex_unlock(&rga->mutex);
404
405 return 0;
406 }
407
rga_release(struct file * file)408 static int rga_release(struct file *file)
409 {
410 struct rga_ctx *ctx =
411 container_of(file->private_data, struct rga_ctx, fh);
412 struct rockchip_rga *rga = ctx->rga;
413
414 mutex_lock(&rga->mutex);
415
416 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
417
418 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
419 v4l2_fh_del(&ctx->fh);
420 v4l2_fh_exit(&ctx->fh);
421 kfree(ctx);
422
423 mutex_unlock(&rga->mutex);
424
425 return 0;
426 }
427
428 static const struct v4l2_file_operations rga_fops = {
429 .owner = THIS_MODULE,
430 .open = rga_open,
431 .release = rga_release,
432 .poll = v4l2_m2m_fop_poll,
433 .unlocked_ioctl = video_ioctl2,
434 .mmap = v4l2_m2m_fop_mmap,
435 };
436
437 static int
vidioc_querycap(struct file * file,void * priv,struct v4l2_capability * cap)438 vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
439 {
440 strscpy(cap->driver, RGA_NAME, sizeof(cap->driver));
441 strscpy(cap->card, "rockchip-rga", sizeof(cap->card));
442 strscpy(cap->bus_info, "platform:rga", sizeof(cap->bus_info));
443
444 return 0;
445 }
446
vidioc_enum_fmt(struct file * file,void * prv,struct v4l2_fmtdesc * f)447 static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
448 {
449 struct rga_fmt *fmt;
450
451 if (f->index >= NUM_FORMATS)
452 return -EINVAL;
453
454 fmt = &formats[f->index];
455 f->pixelformat = fmt->fourcc;
456
457 return 0;
458 }
459
vidioc_g_fmt(struct file * file,void * prv,struct v4l2_format * f)460 static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
461 {
462 struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp;
463 struct rga_ctx *ctx = prv;
464 struct vb2_queue *vq;
465 struct rga_frame *frm;
466
467 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
468 if (!vq)
469 return -EINVAL;
470 frm = rga_get_frame(ctx, f->type);
471 if (IS_ERR(frm))
472 return PTR_ERR(frm);
473
474 v4l2_fill_pixfmt_mp(pix_fmt, frm->fmt->fourcc, frm->width, frm->height);
475
476 pix_fmt->field = V4L2_FIELD_NONE;
477 pix_fmt->colorspace = frm->colorspace;
478
479 return 0;
480 }
481
vidioc_try_fmt(struct file * file,void * prv,struct v4l2_format * f)482 static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f)
483 {
484 struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp;
485 struct rga_fmt *fmt;
486
487 fmt = rga_fmt_find(pix_fmt->pixelformat);
488 if (!fmt)
489 fmt = &formats[0];
490
491 pix_fmt->width = clamp(pix_fmt->width,
492 (u32)MIN_WIDTH, (u32)MAX_WIDTH);
493 pix_fmt->height = clamp(pix_fmt->height,
494 (u32)MIN_HEIGHT, (u32)MAX_HEIGHT);
495
496 v4l2_fill_pixfmt_mp(pix_fmt, fmt->fourcc, pix_fmt->width, pix_fmt->height);
497 pix_fmt->field = V4L2_FIELD_NONE;
498
499 return 0;
500 }
501
vidioc_s_fmt(struct file * file,void * prv,struct v4l2_format * f)502 static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
503 {
504 struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp;
505 struct rga_ctx *ctx = prv;
506 struct rockchip_rga *rga = ctx->rga;
507 struct vb2_queue *vq;
508 struct rga_frame *frm;
509 int ret = 0;
510 int i;
511
512 /* Adjust all values accordingly to the hardware capabilities
513 * and chosen format.
514 */
515 ret = vidioc_try_fmt(file, prv, f);
516 if (ret)
517 return ret;
518 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
519 if (vb2_is_busy(vq)) {
520 v4l2_err(&rga->v4l2_dev, "queue (%d) bust\n", f->type);
521 return -EBUSY;
522 }
523 frm = rga_get_frame(ctx, f->type);
524 if (IS_ERR(frm))
525 return PTR_ERR(frm);
526 frm->width = pix_fmt->width;
527 frm->height = pix_fmt->height;
528 frm->size = 0;
529 for (i = 0; i < pix_fmt->num_planes; i++)
530 frm->size += pix_fmt->plane_fmt[i].sizeimage;
531 frm->fmt = rga_fmt_find(pix_fmt->pixelformat);
532 frm->stride = pix_fmt->plane_fmt[0].bytesperline;
533 frm->colorspace = pix_fmt->colorspace;
534
535 /* Reset crop settings */
536 frm->crop.left = 0;
537 frm->crop.top = 0;
538 frm->crop.width = frm->width;
539 frm->crop.height = frm->height;
540
541 frm->pix = *pix_fmt;
542
543 v4l2_dbg(debug, 1, &rga->v4l2_dev,
544 "[%s] fmt - %p4cc %dx%d (stride %d, sizeimage %d)\n",
545 V4L2_TYPE_IS_OUTPUT(f->type) ? "OUTPUT" : "CAPTURE",
546 &frm->fmt->fourcc, frm->width, frm->height,
547 frm->stride, frm->size);
548
549 for (i = 0; i < pix_fmt->num_planes; i++) {
550 v4l2_dbg(debug, 1, &rga->v4l2_dev,
551 "plane[%d]: size %d, bytesperline %d\n",
552 i, pix_fmt->plane_fmt[i].sizeimage,
553 pix_fmt->plane_fmt[i].bytesperline);
554 }
555
556 return 0;
557 }
558
vidioc_g_selection(struct file * file,void * prv,struct v4l2_selection * s)559 static int vidioc_g_selection(struct file *file, void *prv,
560 struct v4l2_selection *s)
561 {
562 struct rga_ctx *ctx = prv;
563 struct rga_frame *f;
564 bool use_frame = false;
565
566 f = rga_get_frame(ctx, s->type);
567 if (IS_ERR(f))
568 return PTR_ERR(f);
569
570 switch (s->target) {
571 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
572 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
573 if (!V4L2_TYPE_IS_CAPTURE(s->type))
574 return -EINVAL;
575 break;
576 case V4L2_SEL_TGT_CROP_DEFAULT:
577 case V4L2_SEL_TGT_CROP_BOUNDS:
578 if (!V4L2_TYPE_IS_OUTPUT(s->type))
579 return -EINVAL;
580 break;
581 case V4L2_SEL_TGT_COMPOSE:
582 if (!V4L2_TYPE_IS_CAPTURE(s->type))
583 return -EINVAL;
584 use_frame = true;
585 break;
586 case V4L2_SEL_TGT_CROP:
587 if (!V4L2_TYPE_IS_OUTPUT(s->type))
588 return -EINVAL;
589 use_frame = true;
590 break;
591 default:
592 return -EINVAL;
593 }
594
595 if (use_frame) {
596 s->r = f->crop;
597 } else {
598 s->r.left = 0;
599 s->r.top = 0;
600 s->r.width = f->width;
601 s->r.height = f->height;
602 }
603
604 return 0;
605 }
606
vidioc_s_selection(struct file * file,void * prv,struct v4l2_selection * s)607 static int vidioc_s_selection(struct file *file, void *prv,
608 struct v4l2_selection *s)
609 {
610 struct rga_ctx *ctx = prv;
611 struct rockchip_rga *rga = ctx->rga;
612 struct rga_frame *f;
613 int ret = 0;
614
615 f = rga_get_frame(ctx, s->type);
616 if (IS_ERR(f))
617 return PTR_ERR(f);
618
619 switch (s->target) {
620 case V4L2_SEL_TGT_COMPOSE:
621 /*
622 * COMPOSE target is only valid for capture buffer type, return
623 * error for output buffer type
624 */
625 if (!V4L2_TYPE_IS_CAPTURE(s->type))
626 return -EINVAL;
627 break;
628 case V4L2_SEL_TGT_CROP:
629 /*
630 * CROP target is only valid for output buffer type, return
631 * error for capture buffer type
632 */
633 if (!V4L2_TYPE_IS_OUTPUT(s->type))
634 return -EINVAL;
635 break;
636 /*
637 * bound and default crop/compose targets are invalid targets to
638 * try/set
639 */
640 default:
641 return -EINVAL;
642 }
643
644 if (s->r.top < 0 || s->r.left < 0) {
645 v4l2_dbg(debug, 1, &rga->v4l2_dev,
646 "doesn't support negative values for top & left.\n");
647 return -EINVAL;
648 }
649
650 if (s->r.left + s->r.width > f->width ||
651 s->r.top + s->r.height > f->height ||
652 s->r.width < MIN_WIDTH || s->r.height < MIN_HEIGHT) {
653 v4l2_dbg(debug, 1, &rga->v4l2_dev, "unsupported crop value.\n");
654 return -EINVAL;
655 }
656
657 f->crop = s->r;
658
659 return ret;
660 }
661
662 static const struct v4l2_ioctl_ops rga_ioctl_ops = {
663 .vidioc_querycap = vidioc_querycap,
664
665 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt,
666 .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt,
667 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt,
668 .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt,
669
670 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt,
671 .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt,
672 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt,
673 .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt,
674
675 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
676 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
677 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
678 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
679 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
680 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
681 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
682
683 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
684 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
685
686 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
687 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
688
689 .vidioc_g_selection = vidioc_g_selection,
690 .vidioc_s_selection = vidioc_s_selection,
691 };
692
693 static const struct video_device rga_videodev = {
694 .name = "rockchip-rga",
695 .fops = &rga_fops,
696 .ioctl_ops = &rga_ioctl_ops,
697 .minor = -1,
698 .release = video_device_release,
699 .vfl_dir = VFL_DIR_M2M,
700 .device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING,
701 };
702
rga_enable_clocks(struct rockchip_rga * rga)703 static int rga_enable_clocks(struct rockchip_rga *rga)
704 {
705 int ret;
706
707 ret = clk_prepare_enable(rga->sclk);
708 if (ret) {
709 dev_err(rga->dev, "Cannot enable rga sclk: %d\n", ret);
710 return ret;
711 }
712
713 ret = clk_prepare_enable(rga->aclk);
714 if (ret) {
715 dev_err(rga->dev, "Cannot enable rga aclk: %d\n", ret);
716 goto err_disable_sclk;
717 }
718
719 ret = clk_prepare_enable(rga->hclk);
720 if (ret) {
721 dev_err(rga->dev, "Cannot enable rga hclk: %d\n", ret);
722 goto err_disable_aclk;
723 }
724
725 return 0;
726
727 err_disable_aclk:
728 clk_disable_unprepare(rga->aclk);
729 err_disable_sclk:
730 clk_disable_unprepare(rga->sclk);
731
732 return ret;
733 }
734
rga_disable_clocks(struct rockchip_rga * rga)735 static void rga_disable_clocks(struct rockchip_rga *rga)
736 {
737 clk_disable_unprepare(rga->sclk);
738 clk_disable_unprepare(rga->hclk);
739 clk_disable_unprepare(rga->aclk);
740 }
741
rga_parse_dt(struct rockchip_rga * rga)742 static int rga_parse_dt(struct rockchip_rga *rga)
743 {
744 struct reset_control *core_rst, *axi_rst, *ahb_rst;
745
746 core_rst = devm_reset_control_get(rga->dev, "core");
747 if (IS_ERR(core_rst)) {
748 dev_err(rga->dev, "failed to get core reset controller\n");
749 return PTR_ERR(core_rst);
750 }
751
752 axi_rst = devm_reset_control_get(rga->dev, "axi");
753 if (IS_ERR(axi_rst)) {
754 dev_err(rga->dev, "failed to get axi reset controller\n");
755 return PTR_ERR(axi_rst);
756 }
757
758 ahb_rst = devm_reset_control_get(rga->dev, "ahb");
759 if (IS_ERR(ahb_rst)) {
760 dev_err(rga->dev, "failed to get ahb reset controller\n");
761 return PTR_ERR(ahb_rst);
762 }
763
764 reset_control_assert(core_rst);
765 udelay(1);
766 reset_control_deassert(core_rst);
767
768 reset_control_assert(axi_rst);
769 udelay(1);
770 reset_control_deassert(axi_rst);
771
772 reset_control_assert(ahb_rst);
773 udelay(1);
774 reset_control_deassert(ahb_rst);
775
776 rga->sclk = devm_clk_get(rga->dev, "sclk");
777 if (IS_ERR(rga->sclk)) {
778 dev_err(rga->dev, "failed to get sclk clock\n");
779 return PTR_ERR(rga->sclk);
780 }
781
782 rga->aclk = devm_clk_get(rga->dev, "aclk");
783 if (IS_ERR(rga->aclk)) {
784 dev_err(rga->dev, "failed to get aclk clock\n");
785 return PTR_ERR(rga->aclk);
786 }
787
788 rga->hclk = devm_clk_get(rga->dev, "hclk");
789 if (IS_ERR(rga->hclk)) {
790 dev_err(rga->dev, "failed to get hclk clock\n");
791 return PTR_ERR(rga->hclk);
792 }
793
794 return 0;
795 }
796
rga_probe(struct platform_device * pdev)797 static int rga_probe(struct platform_device *pdev)
798 {
799 struct rockchip_rga *rga;
800 struct video_device *vfd;
801 int ret = 0;
802 int irq;
803
804 if (!pdev->dev.of_node)
805 return -ENODEV;
806
807 rga = devm_kzalloc(&pdev->dev, sizeof(*rga), GFP_KERNEL);
808 if (!rga)
809 return -ENOMEM;
810
811 rga->dev = &pdev->dev;
812 spin_lock_init(&rga->ctrl_lock);
813 mutex_init(&rga->mutex);
814
815 ret = rga_parse_dt(rga);
816 if (ret)
817 return dev_err_probe(&pdev->dev, ret, "Unable to parse OF data\n");
818
819 pm_runtime_enable(rga->dev);
820
821 rga->regs = devm_platform_ioremap_resource(pdev, 0);
822 if (IS_ERR(rga->regs)) {
823 ret = PTR_ERR(rga->regs);
824 goto err_put_clk;
825 }
826
827 irq = platform_get_irq(pdev, 0);
828 if (irq < 0) {
829 ret = irq;
830 goto err_put_clk;
831 }
832
833 ret = devm_request_irq(rga->dev, irq, rga_isr, 0,
834 dev_name(rga->dev), rga);
835 if (ret < 0) {
836 dev_err(rga->dev, "failed to request irq\n");
837 goto err_put_clk;
838 }
839
840 ret = dma_set_mask_and_coherent(rga->dev, DMA_BIT_MASK(32));
841 if (ret) {
842 dev_err(rga->dev, "32-bit DMA not supported");
843 goto err_put_clk;
844 }
845
846 ret = v4l2_device_register(&pdev->dev, &rga->v4l2_dev);
847 if (ret)
848 goto err_put_clk;
849 vfd = video_device_alloc();
850 if (!vfd) {
851 v4l2_err(&rga->v4l2_dev, "Failed to allocate video device\n");
852 ret = -ENOMEM;
853 goto unreg_v4l2_dev;
854 }
855 *vfd = rga_videodev;
856 vfd->lock = &rga->mutex;
857 vfd->v4l2_dev = &rga->v4l2_dev;
858
859 video_set_drvdata(vfd, rga);
860 rga->vfd = vfd;
861
862 platform_set_drvdata(pdev, rga);
863 rga->m2m_dev = v4l2_m2m_init(&rga_m2m_ops);
864 if (IS_ERR(rga->m2m_dev)) {
865 v4l2_err(&rga->v4l2_dev, "Failed to init mem2mem device\n");
866 ret = PTR_ERR(rga->m2m_dev);
867 goto rel_vdev;
868 }
869
870 ret = pm_runtime_resume_and_get(rga->dev);
871 if (ret < 0)
872 goto rel_m2m;
873
874 rga->version.major = (rga_read(rga, RGA_VERSION_INFO) >> 24) & 0xFF;
875 rga->version.minor = (rga_read(rga, RGA_VERSION_INFO) >> 20) & 0x0F;
876
877 v4l2_info(&rga->v4l2_dev, "HW Version: 0x%02x.%02x\n",
878 rga->version.major, rga->version.minor);
879
880 pm_runtime_put(rga->dev);
881
882 /* Create CMD buffer */
883 rga->cmdbuf_virt = dma_alloc_attrs(rga->dev, RGA_CMDBUF_SIZE,
884 &rga->cmdbuf_phy, GFP_KERNEL,
885 DMA_ATTR_WRITE_COMBINE);
886 if (!rga->cmdbuf_virt) {
887 ret = -ENOMEM;
888 goto rel_m2m;
889 }
890
891 def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3;
892 def_frame.size = def_frame.stride * def_frame.height;
893
894 ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
895 if (ret) {
896 v4l2_err(&rga->v4l2_dev, "Failed to register video device\n");
897 goto free_dma;
898 }
899
900 v4l2_info(&rga->v4l2_dev, "Registered %s as /dev/%s\n",
901 vfd->name, video_device_node_name(vfd));
902
903 return 0;
904
905 free_dma:
906 dma_free_attrs(rga->dev, RGA_CMDBUF_SIZE, rga->cmdbuf_virt,
907 rga->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE);
908 rel_m2m:
909 v4l2_m2m_release(rga->m2m_dev);
910 rel_vdev:
911 video_device_release(vfd);
912 unreg_v4l2_dev:
913 v4l2_device_unregister(&rga->v4l2_dev);
914 err_put_clk:
915 pm_runtime_disable(rga->dev);
916
917 return ret;
918 }
919
rga_remove(struct platform_device * pdev)920 static void rga_remove(struct platform_device *pdev)
921 {
922 struct rockchip_rga *rga = platform_get_drvdata(pdev);
923
924 dma_free_attrs(rga->dev, RGA_CMDBUF_SIZE, rga->cmdbuf_virt,
925 rga->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE);
926
927 v4l2_info(&rga->v4l2_dev, "Removing\n");
928
929 v4l2_m2m_release(rga->m2m_dev);
930 video_unregister_device(rga->vfd);
931 v4l2_device_unregister(&rga->v4l2_dev);
932
933 pm_runtime_disable(rga->dev);
934 }
935
rga_runtime_suspend(struct device * dev)936 static int __maybe_unused rga_runtime_suspend(struct device *dev)
937 {
938 struct rockchip_rga *rga = dev_get_drvdata(dev);
939
940 rga_disable_clocks(rga);
941
942 return 0;
943 }
944
rga_runtime_resume(struct device * dev)945 static int __maybe_unused rga_runtime_resume(struct device *dev)
946 {
947 struct rockchip_rga *rga = dev_get_drvdata(dev);
948
949 return rga_enable_clocks(rga);
950 }
951
952 static const struct dev_pm_ops rga_pm = {
953 SET_RUNTIME_PM_OPS(rga_runtime_suspend,
954 rga_runtime_resume, NULL)
955 };
956
957 static const struct of_device_id rockchip_rga_match[] = {
958 {
959 .compatible = "rockchip,rk3288-rga",
960 },
961 {
962 .compatible = "rockchip,rk3399-rga",
963 },
964 {},
965 };
966
967 MODULE_DEVICE_TABLE(of, rockchip_rga_match);
968
969 static struct platform_driver rga_pdrv = {
970 .probe = rga_probe,
971 .remove_new = rga_remove,
972 .driver = {
973 .name = RGA_NAME,
974 .pm = &rga_pm,
975 .of_match_table = rockchip_rga_match,
976 },
977 };
978
979 module_platform_driver(rga_pdrv);
980
981 MODULE_AUTHOR("Jacob Chen <jacob-chen@iotwrt.com>");
982 MODULE_DESCRIPTION("Rockchip Raster 2d Graphic Acceleration Unit");
983 MODULE_LICENSE("GPL");
984