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