1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 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-dma-contig.h> 27 #include <media/videobuf2-v4l2.h> 28 29 #include "rga.h" 30 31 static int debug; 32 module_param(debug, int, 0644); 33 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 if (ctx->cmdbuf_dirty) { 43 ctx->cmdbuf_dirty = false; 44 rga->hw->setup_cmdbuf(ctx); 45 } 46 spin_unlock_irqrestore(&rga->ctrl_lock, flags); 47 48 rga->curr = ctx; 49 50 src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); 51 src->sequence = ctx->osequence++; 52 53 dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); 54 55 rga->hw->start(rga, vb_to_rga(src), vb_to_rga(dst)); 56 } 57 58 static irqreturn_t rga_isr(int irq, void *prv) 59 { 60 struct rockchip_rga *rga = prv; 61 62 if (rga->hw->handle_irq(rga)) { 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); 77 78 dst->sequence = ctx->csequence++; 79 80 v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE); 81 v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE); 82 v4l2_m2m_job_finish(rga->m2m_dev, ctx->fh.m2m_ctx); 83 } 84 85 return IRQ_HANDLED; 86 } 87 88 static const struct v4l2_m2m_ops rga_m2m_ops = { 89 .device_run = device_run, 90 }; 91 92 static int 93 queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) 94 { 95 struct rga_ctx *ctx = priv; 96 int ret; 97 98 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 99 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; 100 src_vq->drv_priv = ctx; 101 src_vq->ops = &rga_qops; 102 if (rga_has_internal_iommu(ctx->rga)) 103 src_vq->mem_ops = &vb2_dma_sg_memops; 104 else 105 src_vq->mem_ops = &vb2_dma_contig_memops; 106 src_vq->gfp_flags = __GFP_DMA32; 107 src_vq->buf_struct_size = sizeof(struct rga_vb_buffer); 108 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 109 src_vq->lock = &ctx->rga->mutex; 110 src_vq->dev = ctx->rga->v4l2_dev.dev; 111 112 ret = vb2_queue_init(src_vq); 113 if (ret) 114 return ret; 115 116 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 117 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; 118 dst_vq->drv_priv = ctx; 119 dst_vq->ops = &rga_qops; 120 if (rga_has_internal_iommu(ctx->rga)) 121 dst_vq->mem_ops = &vb2_dma_sg_memops; 122 else 123 dst_vq->mem_ops = &vb2_dma_contig_memops; 124 dst_vq->gfp_flags = __GFP_DMA32; 125 dst_vq->buf_struct_size = sizeof(struct rga_vb_buffer); 126 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 127 dst_vq->lock = &ctx->rga->mutex; 128 dst_vq->dev = ctx->rga->v4l2_dev.dev; 129 130 return vb2_queue_init(dst_vq); 131 } 132 133 static int rga_s_ctrl(struct v4l2_ctrl *ctrl) 134 { 135 struct rga_ctx *ctx = container_of(ctrl->handler, struct rga_ctx, 136 ctrl_handler); 137 const struct rga_hw *hw = ctx->rga->hw; 138 unsigned long flags; 139 int ret = 0; 140 141 spin_lock_irqsave(&ctx->rga->ctrl_lock, flags); 142 switch (ctrl->id) { 143 case V4L2_CID_HFLIP: 144 ctx->hflip = ctrl->val; 145 break; 146 case V4L2_CID_VFLIP: 147 ctx->vflip = ctrl->val; 148 break; 149 case V4L2_CID_ROTATE: 150 if (vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx)) && 151 vb2_is_streaming(v4l2_m2m_get_src_vq(ctx->fh.m2m_ctx))) { 152 ret = rga_check_scaling(hw, &ctx->in.crop, 153 &ctx->out.crop, ctrl->val); 154 if (ret < 0) 155 goto s_ctrl_done; 156 } 157 ctx->rotate = ctrl->val; 158 break; 159 case V4L2_CID_BG_COLOR: 160 ctx->fill_color = ctrl->val; 161 break; 162 } 163 ctx->cmdbuf_dirty = true; 164 165 s_ctrl_done: 166 spin_unlock_irqrestore(&ctx->rga->ctrl_lock, flags); 167 return ret; 168 } 169 170 static const struct v4l2_ctrl_ops rga_ctrl_ops = { 171 .s_ctrl = rga_s_ctrl, 172 }; 173 174 static int rga_setup_ctrls(struct rga_ctx *ctx) 175 { 176 struct rockchip_rga *rga = ctx->rga; 177 178 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4); 179 180 if (rga->hw->features & RGA_FEATURE_FLIP) { 181 v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops, 182 V4L2_CID_HFLIP, 0, 1, 1, 0); 183 184 v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops, 185 V4L2_CID_VFLIP, 0, 1, 1, 0); 186 } 187 188 if (rga->hw->features & RGA_FEATURE_ROTATE) 189 v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops, 190 V4L2_CID_ROTATE, 0, 270, 90, 0); 191 192 if (rga->hw->features & RGA_FEATURE_BG_COLOR) 193 v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops, 194 V4L2_CID_BG_COLOR, 0, 0xffffffff, 1, 0); 195 196 if (ctx->ctrl_handler.error) { 197 int err = ctx->ctrl_handler.error; 198 199 v4l2_err(&rga->v4l2_dev, "%s failed\n", __func__); 200 v4l2_ctrl_handler_free(&ctx->ctrl_handler); 201 return err; 202 } 203 204 return 0; 205 } 206 207 static bool check_scaling_factor(const struct rga_hw *hw, u32 src_size, 208 u32 dst_size) 209 { 210 if (src_size < dst_size) 211 return src_size * hw->max_scaling_factor >= dst_size; 212 else 213 return dst_size * hw->max_scaling_factor >= src_size; 214 } 215 216 int rga_check_scaling(const struct rga_hw *hw, const struct v4l2_rect *crop_in, 217 const struct v4l2_rect *crop_out, u32 rotate) 218 { 219 u32 scaled_width; 220 u32 scaled_height; 221 222 if (rotate == 90 || rotate == 270) { 223 scaled_width = crop_out->height; 224 scaled_height = crop_out->width; 225 } else { 226 scaled_width = crop_out->width; 227 scaled_height = crop_out->height; 228 } 229 230 if (!check_scaling_factor(hw, crop_in->width, scaled_width)) 231 return -EINVAL; 232 233 if (!check_scaling_factor(hw, crop_in->height, scaled_height)) 234 return -EINVAL; 235 236 return 0; 237 } 238 239 struct rga_frame *rga_get_frame(struct rga_ctx *ctx, enum v4l2_buf_type type) 240 { 241 if (V4L2_TYPE_IS_OUTPUT(type)) 242 return &ctx->in; 243 if (V4L2_TYPE_IS_CAPTURE(type)) 244 return &ctx->out; 245 return ERR_PTR(-EINVAL); 246 } 247 248 static int rga_open(struct file *file) 249 { 250 struct rockchip_rga *rga = video_drvdata(file); 251 struct rga_ctx *ctx = NULL; 252 int ret = 0; 253 u32 def_width = clamp(DEFAULT_WIDTH, rga->hw->min_width, rga->hw->max_width); 254 u32 def_height = clamp(DEFAULT_HEIGHT, rga->hw->min_height, rga->hw->max_height); 255 struct rga_frame def_frame = { 256 .crop.left = 0, 257 .crop.top = 0, 258 .crop.width = def_width, 259 .crop.height = def_height, 260 }; 261 262 ctx = kzalloc_obj(*ctx); 263 if (!ctx) 264 return -ENOMEM; 265 266 /* Create CMD buffer */ 267 ctx->cmdbuf_virt = dma_alloc_attrs(rga->dev, rga->hw->cmdbuf_size, 268 &ctx->cmdbuf_phy, GFP_KERNEL, 269 DMA_ATTR_WRITE_COMBINE); 270 if (!ctx->cmdbuf_virt) { 271 ret = -ENOMEM; 272 goto rel_ctx; 273 } 274 ctx->cmdbuf_dirty = true; 275 276 ctx->rga = rga; 277 /* Set default formats */ 278 ctx->in = def_frame; 279 ctx->out = def_frame; 280 281 ctx->in.fmt = rga->hw->adjust_and_map_format(ctx, &ctx->in.pix, true); 282 v4l2_fill_pixfmt_mp_aligned(&ctx->in.pix, ctx->in.pix.pixelformat, 283 def_width, def_height, rga->hw->stride_alignment); 284 ctx->out.fmt = 285 rga->hw->adjust_and_map_format(ctx, &ctx->out.pix, false); 286 v4l2_fill_pixfmt_mp_aligned(&ctx->out.pix, ctx->out.pix.pixelformat, 287 def_width, def_height, rga->hw->stride_alignment); 288 289 if (mutex_lock_interruptible(&rga->mutex)) { 290 ret = -ERESTARTSYS; 291 goto rel_cmdbuf; 292 } 293 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(rga->m2m_dev, ctx, &queue_init); 294 if (IS_ERR(ctx->fh.m2m_ctx)) { 295 ret = PTR_ERR(ctx->fh.m2m_ctx); 296 goto unlock_mutex; 297 } 298 v4l2_fh_init(&ctx->fh, video_devdata(file)); 299 v4l2_fh_add(&ctx->fh, file); 300 301 rga_setup_ctrls(ctx); 302 303 /* Write the default values to the ctx struct */ 304 v4l2_ctrl_handler_setup(&ctx->ctrl_handler); 305 306 ctx->fh.ctrl_handler = &ctx->ctrl_handler; 307 mutex_unlock(&rga->mutex); 308 309 return 0; 310 311 unlock_mutex: 312 mutex_unlock(&rga->mutex); 313 rel_cmdbuf: 314 dma_free_attrs(rga->dev, rga->hw->cmdbuf_size, ctx->cmdbuf_virt, 315 ctx->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE); 316 rel_ctx: 317 kfree(ctx); 318 return ret; 319 } 320 321 static int rga_release(struct file *file) 322 { 323 struct rga_ctx *ctx = file_to_rga_ctx(file); 324 struct rockchip_rga *rga = ctx->rga; 325 326 mutex_lock(&rga->mutex); 327 328 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); 329 330 v4l2_ctrl_handler_free(&ctx->ctrl_handler); 331 v4l2_fh_del(&ctx->fh, file); 332 v4l2_fh_exit(&ctx->fh); 333 334 dma_free_attrs(rga->dev, rga->hw->cmdbuf_size, ctx->cmdbuf_virt, 335 ctx->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE); 336 337 kfree(ctx); 338 339 mutex_unlock(&rga->mutex); 340 341 return 0; 342 } 343 344 static const struct v4l2_file_operations rga_fops = { 345 .owner = THIS_MODULE, 346 .open = rga_open, 347 .release = rga_release, 348 .poll = v4l2_m2m_fop_poll, 349 .unlocked_ioctl = video_ioctl2, 350 .mmap = v4l2_m2m_fop_mmap, 351 }; 352 353 static int 354 vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) 355 { 356 struct rockchip_rga *rga = video_drvdata(file); 357 358 strscpy(cap->driver, RGA_NAME, sizeof(cap->driver)); 359 strscpy(cap->card, rga->hw->card_type, sizeof(cap->card)); 360 strscpy(cap->bus_info, "platform:rga", sizeof(cap->bus_info)); 361 362 return 0; 363 } 364 365 static int vidioc_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f) 366 { 367 struct rockchip_rga *rga = video_drvdata(file); 368 int ret; 369 370 ret = rga->hw->enum_format(f); 371 if (ret != 0) 372 return ret; 373 374 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 375 f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 376 return 0; 377 378 /* allow changing the quantization and xfer func for YUV formats */ 379 if (v4l2_is_format_yuv(v4l2_format_info(f->pixelformat))) 380 f->flags |= V4L2_FMT_FLAG_CSC_QUANTIZATION | 381 V4L2_FMT_FLAG_CSC_YCBCR_ENC; 382 383 return 0; 384 } 385 386 static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) 387 { 388 struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp; 389 struct rga_ctx *ctx = file_to_rga_ctx(file); 390 struct rga_frame *frm; 391 392 frm = rga_get_frame(ctx, f->type); 393 if (IS_ERR(frm)) 394 return PTR_ERR(frm); 395 396 *pix_fmt = frm->pix; 397 pix_fmt->field = V4L2_FIELD_NONE; 398 399 return 0; 400 } 401 402 static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) 403 { 404 struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp; 405 struct rga_ctx *ctx = file_to_rga_ctx(file); 406 const struct rga_hw *hw = ctx->rga->hw; 407 struct v4l2_frmsize_stepwise frmsize = { 408 .min_width = hw->min_width, 409 .max_width = hw->max_width, 410 .min_height = hw->min_height, 411 .max_height = hw->max_height, 412 .step_width = 1, 413 .step_height = 1, 414 }; 415 416 if (v4l2_is_format_yuv(v4l2_format_info(pix_fmt->pixelformat))) { 417 frmsize.step_width = 2; 418 frmsize.step_height = 2; 419 } 420 421 if (V4L2_TYPE_IS_CAPTURE(f->type)) { 422 const struct rga_frame *frm; 423 424 frm = rga_get_frame(ctx, f->type); 425 if (IS_ERR(frm)) 426 return PTR_ERR(frm); 427 428 if (!(pix_fmt->flags & V4L2_PIX_FMT_FLAG_SET_CSC)) { 429 pix_fmt->quantization = frm->pix.quantization; 430 pix_fmt->ycbcr_enc = frm->pix.ycbcr_enc; 431 } 432 /* disallow values not announced in vidioc_enum_fmt */ 433 pix_fmt->colorspace = frm->pix.colorspace; 434 pix_fmt->xfer_func = frm->pix.xfer_func; 435 } 436 437 hw->adjust_and_map_format(ctx, pix_fmt, V4L2_TYPE_IS_OUTPUT(f->type)); 438 439 v4l2_apply_frmsize_constraints(&pix_fmt->width, &pix_fmt->height, &frmsize); 440 v4l2_fill_pixfmt_mp_aligned(pix_fmt, pix_fmt->pixelformat, 441 pix_fmt->width, pix_fmt->height, hw->stride_alignment); 442 pix_fmt->field = V4L2_FIELD_NONE; 443 444 return 0; 445 } 446 447 static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) 448 { 449 struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp; 450 struct rga_ctx *ctx = file_to_rga_ctx(file); 451 struct rockchip_rga *rga = ctx->rga; 452 struct vb2_queue *vq; 453 struct rga_frame *frm; 454 int ret = 0; 455 int i; 456 457 /* Adjust all values accordingly to the hardware capabilities 458 * and chosen format. 459 */ 460 ret = vidioc_try_fmt(file, priv, f); 461 if (ret) 462 return ret; 463 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); 464 if (vb2_is_busy(vq)) { 465 v4l2_err(&rga->v4l2_dev, "queue (%d) bust\n", f->type); 466 return -EBUSY; 467 } 468 frm = rga_get_frame(ctx, f->type); 469 if (IS_ERR(frm)) 470 return PTR_ERR(frm); 471 frm->fmt = rga->hw->adjust_and_map_format(ctx, pix_fmt, 472 V4L2_TYPE_IS_OUTPUT(f->type)); 473 474 /* 475 * Copy colorimetry from output to capture as required by the 476 * v4l2-compliance tests 477 */ 478 if (V4L2_TYPE_IS_OUTPUT(f->type)) { 479 ctx->out.pix.colorspace = pix_fmt->colorspace; 480 ctx->out.pix.ycbcr_enc = pix_fmt->ycbcr_enc; 481 ctx->out.pix.quantization = pix_fmt->quantization; 482 ctx->out.pix.xfer_func = pix_fmt->xfer_func; 483 } 484 485 /* Reset crop settings */ 486 frm->crop.left = 0; 487 frm->crop.top = 0; 488 frm->crop.width = pix_fmt->width; 489 frm->crop.height = pix_fmt->height; 490 491 frm->pix = *pix_fmt; 492 ctx->cmdbuf_dirty = true; 493 494 v4l2_dbg(debug, 1, &rga->v4l2_dev, 495 "[%s] fmt - %p4cc %dx%d (stride %d)\n", 496 V4L2_TYPE_IS_OUTPUT(f->type) ? "OUTPUT" : "CAPTURE", 497 &pix_fmt->pixelformat, pix_fmt->width, pix_fmt->height, 498 pix_fmt->plane_fmt[0].bytesperline); 499 500 for (i = 0; i < pix_fmt->num_planes; i++) { 501 v4l2_dbg(debug, 1, &rga->v4l2_dev, 502 "plane[%d]: size %d, bytesperline %d\n", 503 i, pix_fmt->plane_fmt[i].sizeimage, 504 pix_fmt->plane_fmt[i].bytesperline); 505 } 506 507 return 0; 508 } 509 510 static int vidioc_g_selection(struct file *file, void *priv, 511 struct v4l2_selection *s) 512 { 513 struct rga_ctx *ctx = file_to_rga_ctx(file); 514 struct rga_frame *f; 515 bool use_frame = false; 516 517 f = rga_get_frame(ctx, s->type); 518 if (IS_ERR(f)) 519 return PTR_ERR(f); 520 521 switch (s->target) { 522 case V4L2_SEL_TGT_COMPOSE_DEFAULT: 523 case V4L2_SEL_TGT_COMPOSE_BOUNDS: 524 if (!V4L2_TYPE_IS_CAPTURE(s->type)) 525 return -EINVAL; 526 break; 527 case V4L2_SEL_TGT_CROP_DEFAULT: 528 case V4L2_SEL_TGT_CROP_BOUNDS: 529 if (!V4L2_TYPE_IS_OUTPUT(s->type)) 530 return -EINVAL; 531 break; 532 case V4L2_SEL_TGT_COMPOSE: 533 if (!V4L2_TYPE_IS_CAPTURE(s->type)) 534 return -EINVAL; 535 use_frame = true; 536 break; 537 case V4L2_SEL_TGT_CROP: 538 if (!V4L2_TYPE_IS_OUTPUT(s->type)) 539 return -EINVAL; 540 use_frame = true; 541 break; 542 default: 543 return -EINVAL; 544 } 545 546 if (use_frame) { 547 s->r = f->crop; 548 } else { 549 s->r.left = 0; 550 s->r.top = 0; 551 s->r.width = f->pix.width; 552 s->r.height = f->pix.height; 553 } 554 555 return 0; 556 } 557 558 static int vidioc_s_selection(struct file *file, void *priv, 559 struct v4l2_selection *s) 560 { 561 struct rga_ctx *ctx = file_to_rga_ctx(file); 562 struct rockchip_rga *rga = ctx->rga; 563 struct rga_frame *f; 564 565 f = rga_get_frame(ctx, s->type); 566 if (IS_ERR(f)) 567 return PTR_ERR(f); 568 569 switch (s->target) { 570 case V4L2_SEL_TGT_COMPOSE: 571 /* 572 * COMPOSE target is only valid for capture buffer type, return 573 * error for output buffer type 574 */ 575 if (!V4L2_TYPE_IS_CAPTURE(s->type)) 576 return -EINVAL; 577 break; 578 case V4L2_SEL_TGT_CROP: 579 /* 580 * CROP target is only valid for output buffer type, return 581 * error for capture buffer type 582 */ 583 if (!V4L2_TYPE_IS_OUTPUT(s->type)) 584 return -EINVAL; 585 break; 586 /* 587 * bound and default crop/compose targets are invalid targets to 588 * try/set 589 */ 590 default: 591 return -EINVAL; 592 } 593 594 if (s->r.top < 0 || s->r.left < 0) { 595 v4l2_dbg(debug, 1, &rga->v4l2_dev, 596 "doesn't support negative values for top & left.\n"); 597 return -EINVAL; 598 } 599 600 if (s->r.left + s->r.width > f->pix.width || 601 s->r.top + s->r.height > f->pix.height || 602 s->r.width < rga->hw->min_width || s->r.height < rga->hw->min_height) { 603 v4l2_dbg(debug, 1, &rga->v4l2_dev, "unsupported crop value.\n"); 604 return -EINVAL; 605 } 606 607 if (vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx)) && 608 vb2_is_streaming(v4l2_m2m_get_src_vq(ctx->fh.m2m_ctx))) { 609 int ret = 0; 610 611 if (V4L2_TYPE_IS_OUTPUT(s->type)) 612 ret = rga_check_scaling(rga->hw, &s->r, &ctx->out.crop, 613 ctx->rotate); 614 else 615 ret = rga_check_scaling(rga->hw, &ctx->in.crop, &s->r, 616 ctx->rotate); 617 618 if (ret < 0) 619 return ret; 620 } 621 622 f->crop = s->r; 623 ctx->cmdbuf_dirty = true; 624 625 return 0; 626 } 627 628 static const struct v4l2_ioctl_ops rga_ioctl_ops = { 629 .vidioc_querycap = vidioc_querycap, 630 631 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt, 632 .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt, 633 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt, 634 .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt, 635 636 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt, 637 .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt, 638 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt, 639 .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt, 640 641 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 642 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 643 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 644 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 645 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 646 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 647 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 648 649 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 650 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 651 652 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 653 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 654 655 .vidioc_g_selection = vidioc_g_selection, 656 .vidioc_s_selection = vidioc_s_selection, 657 }; 658 659 static const struct video_device rga_videodev = { 660 .name = "rockchip-rga", 661 .fops = &rga_fops, 662 .ioctl_ops = &rga_ioctl_ops, 663 .minor = -1, 664 .release = video_device_release, 665 .vfl_dir = VFL_DIR_M2M, 666 .device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING, 667 }; 668 669 static int rga_parse_dt(struct rockchip_rga *rga) 670 { 671 struct reset_control *core_rst, *axi_rst, *ahb_rst; 672 int ret; 673 674 core_rst = devm_reset_control_get(rga->dev, "core"); 675 if (IS_ERR(core_rst)) { 676 dev_err(rga->dev, "failed to get core reset controller\n"); 677 return PTR_ERR(core_rst); 678 } 679 680 axi_rst = devm_reset_control_get(rga->dev, "axi"); 681 if (IS_ERR(axi_rst)) { 682 dev_err(rga->dev, "failed to get axi reset controller\n"); 683 return PTR_ERR(axi_rst); 684 } 685 686 ahb_rst = devm_reset_control_get(rga->dev, "ahb"); 687 if (IS_ERR(ahb_rst)) { 688 dev_err(rga->dev, "failed to get ahb reset controller\n"); 689 return PTR_ERR(ahb_rst); 690 } 691 692 reset_control_assert(core_rst); 693 udelay(1); 694 reset_control_deassert(core_rst); 695 696 reset_control_assert(axi_rst); 697 udelay(1); 698 reset_control_deassert(axi_rst); 699 700 reset_control_assert(ahb_rst); 701 udelay(1); 702 reset_control_deassert(ahb_rst); 703 704 ret = devm_clk_bulk_get_all(rga->dev, &rga->clks); 705 if (ret < 0) { 706 dev_err(rga->dev, "failed to get clocks\n"); 707 return ret; 708 } 709 rga->num_clks = ret; 710 711 return 0; 712 } 713 714 /* 715 * Some SoCs, like RK3588 have multiple identical RGA3 cores, but the 716 * kernel is currently missing support for multi-core handling. Exposing 717 * separate devices for each core to userspace is bad, since that does 718 * not allow scheduling tasks properly (and creates ABI). With this workaround 719 * the driver will only probe for the first core and early exit for the other 720 * cores. Once the driver gains multi-core support, the same technique 721 * for detecting the main core can be used to cluster all cores together. 722 */ 723 static int rga_disable_multicore(struct device *dev) 724 { 725 struct device_node *node = NULL; 726 const char *compatible; 727 bool is_main_core; 728 int ret; 729 730 /* Intentionally ignores the fallback strings */ 731 ret = of_property_read_string(dev->of_node, "compatible", &compatible); 732 if (ret) 733 return ret; 734 735 /* The first compatible and available node found is considered the main core */ 736 do { 737 node = of_find_compatible_node(node, NULL, compatible); 738 if (of_device_is_available(node)) 739 break; 740 } while (node); 741 742 if (!node) 743 return -EINVAL; 744 745 is_main_core = (dev->of_node == node); 746 747 of_node_put(node); 748 749 if (!is_main_core) { 750 dev_info(dev, "missing multi-core support, ignoring this instance\n"); 751 return -ENODEV; 752 } 753 754 return 0; 755 } 756 757 static int rga_probe(struct platform_device *pdev) 758 { 759 struct rockchip_rga *rga; 760 struct video_device *vfd; 761 int ret = 0; 762 int irq; 763 764 if (!pdev->dev.of_node) 765 return -ENODEV; 766 767 ret = rga_disable_multicore(&pdev->dev); 768 if (ret) 769 return ret; 770 771 rga = devm_kzalloc(&pdev->dev, sizeof(*rga), GFP_KERNEL); 772 if (!rga) 773 return -ENOMEM; 774 775 rga->hw = of_device_get_match_data(&pdev->dev); 776 if (!rga->hw) 777 return dev_err_probe(&pdev->dev, -ENODEV, "failed to get match data\n"); 778 779 rga->dev = &pdev->dev; 780 spin_lock_init(&rga->ctrl_lock); 781 mutex_init(&rga->mutex); 782 783 ret = rga_parse_dt(rga); 784 if (ret) 785 return dev_err_probe(&pdev->dev, ret, "Unable to parse OF data\n"); 786 787 pm_runtime_enable(rga->dev); 788 789 rga->regs = devm_platform_ioremap_resource(pdev, 0); 790 if (IS_ERR(rga->regs)) { 791 ret = PTR_ERR(rga->regs); 792 goto err_put_clk; 793 } 794 795 irq = platform_get_irq(pdev, 0); 796 if (irq < 0) { 797 ret = irq; 798 goto err_put_clk; 799 } 800 801 ret = devm_request_irq(rga->dev, irq, rga_isr, 802 rga_has_internal_iommu(rga) ? 0 : IRQF_SHARED, 803 dev_name(rga->dev), rga); 804 if (ret < 0) { 805 dev_err(rga->dev, "failed to request irq\n"); 806 goto err_put_clk; 807 } 808 809 ret = dma_set_mask_and_coherent(rga->dev, DMA_BIT_MASK(32)); 810 if (ret) { 811 dev_err(rga->dev, "32-bit DMA not supported"); 812 goto err_put_clk; 813 } 814 815 ret = v4l2_device_register(&pdev->dev, &rga->v4l2_dev); 816 if (ret) 817 goto err_put_clk; 818 vfd = video_device_alloc(); 819 if (!vfd) { 820 v4l2_err(&rga->v4l2_dev, "Failed to allocate video device\n"); 821 ret = -ENOMEM; 822 goto unreg_v4l2_dev; 823 } 824 *vfd = rga_videodev; 825 vfd->lock = &rga->mutex; 826 vfd->v4l2_dev = &rga->v4l2_dev; 827 828 video_set_drvdata(vfd, rga); 829 rga->vfd = vfd; 830 831 platform_set_drvdata(pdev, rga); 832 rga->m2m_dev = v4l2_m2m_init(&rga_m2m_ops); 833 if (IS_ERR(rga->m2m_dev)) { 834 v4l2_err(&rga->v4l2_dev, "Failed to init mem2mem device\n"); 835 ret = PTR_ERR(rga->m2m_dev); 836 goto rel_vdev; 837 } 838 839 ret = pm_runtime_resume_and_get(rga->dev); 840 if (ret < 0) 841 goto rel_m2m; 842 843 rga->hw->get_version(rga); 844 845 v4l2_info(&rga->v4l2_dev, "HW Version: 0x%02x.%02x\n", 846 rga->version.major, rga->version.minor); 847 848 pm_runtime_put(rga->dev); 849 850 ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1); 851 if (ret) { 852 v4l2_err(&rga->v4l2_dev, "Failed to register video device\n"); 853 goto rel_m2m; 854 } 855 856 v4l2_info(&rga->v4l2_dev, "Registered %s as /dev/%s\n", 857 vfd->name, video_device_node_name(vfd)); 858 859 return 0; 860 861 rel_m2m: 862 v4l2_m2m_release(rga->m2m_dev); 863 rel_vdev: 864 video_device_release(vfd); 865 unreg_v4l2_dev: 866 v4l2_device_unregister(&rga->v4l2_dev); 867 err_put_clk: 868 pm_runtime_disable(rga->dev); 869 870 return ret; 871 } 872 873 static void rga_remove(struct platform_device *pdev) 874 { 875 struct rockchip_rga *rga = platform_get_drvdata(pdev); 876 877 v4l2_info(&rga->v4l2_dev, "Removing\n"); 878 879 v4l2_m2m_release(rga->m2m_dev); 880 video_unregister_device(rga->vfd); 881 v4l2_device_unregister(&rga->v4l2_dev); 882 883 pm_runtime_disable(rga->dev); 884 } 885 886 static int __maybe_unused rga_runtime_suspend(struct device *dev) 887 { 888 struct rockchip_rga *rga = dev_get_drvdata(dev); 889 890 clk_bulk_disable_unprepare(rga->num_clks, rga->clks); 891 892 return 0; 893 } 894 895 static int __maybe_unused rga_runtime_resume(struct device *dev) 896 { 897 struct rockchip_rga *rga = dev_get_drvdata(dev); 898 899 return clk_bulk_prepare_enable(rga->num_clks, rga->clks); 900 } 901 902 static const struct dev_pm_ops rga_pm = { 903 SET_RUNTIME_PM_OPS(rga_runtime_suspend, 904 rga_runtime_resume, NULL) 905 }; 906 907 static const struct of_device_id rockchip_rga_match[] = { 908 { 909 .compatible = "rockchip,rk3288-rga", 910 .data = &rga2_hw, 911 }, 912 { 913 .compatible = "rockchip,rk3399-rga", 914 .data = &rga2_hw, 915 }, 916 { 917 .compatible = "rockchip,rk3588-rga3", 918 .data = &rga3_hw, 919 }, 920 {}, 921 }; 922 923 MODULE_DEVICE_TABLE(of, rockchip_rga_match); 924 925 static struct platform_driver rga_pdrv = { 926 .probe = rga_probe, 927 .remove = rga_remove, 928 .driver = { 929 .name = RGA_NAME, 930 .pm = &rga_pm, 931 .of_match_table = rockchip_rga_match, 932 }, 933 }; 934 935 module_platform_driver(rga_pdrv); 936 937 MODULE_AUTHOR("Jacob Chen <jacob-chen@iotwrt.com>"); 938 MODULE_DESCRIPTION("Rockchip Raster 2d Graphic Acceleration Unit"); 939 MODULE_LICENSE("GPL"); 940