linux/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
   3 * Author:Mark Yao <mark.yao@rock-chips.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 <drm/drm.h>
  16#include <drm/drmP.h>
  17#include <drm/drm_crtc.h>
  18#include <drm/drm_crtc_helper.h>
  19#include <drm/drm_plane_helper.h>
  20
  21#include <linux/kernel.h>
  22#include <linux/platform_device.h>
  23#include <linux/clk.h>
  24#include <linux/of.h>
  25#include <linux/of_device.h>
  26#include <linux/pm_runtime.h>
  27#include <linux/component.h>
  28
  29#include <linux/reset.h>
  30#include <linux/delay.h>
  31
  32#include "rockchip_drm_drv.h"
  33#include "rockchip_drm_gem.h"
  34#include "rockchip_drm_fb.h"
  35#include "rockchip_drm_vop.h"
  36
  37#define VOP_REG(off, _mask, s) \
  38                {.offset = off, \
  39                 .mask = _mask, \
  40                 .shift = s,}
  41
  42#define __REG_SET_RELAXED(x, off, mask, shift, v) \
  43                vop_mask_write_relaxed(x, off, (mask) << shift, (v) << shift)
  44#define __REG_SET_NORMAL(x, off, mask, shift, v) \
  45                vop_mask_write(x, off, (mask) << shift, (v) << shift)
  46
  47#define REG_SET(x, base, reg, v, mode) \
  48                __REG_SET_##mode(x, base + reg.offset, reg.mask, reg.shift, v)
  49
  50#define VOP_WIN_SET(x, win, name, v) \
  51                REG_SET(x, win->base, win->phy->name, v, RELAXED)
  52#define VOP_CTRL_SET(x, name, v) \
  53                REG_SET(x, 0, (x)->data->ctrl->name, v, NORMAL)
  54
  55#define VOP_WIN_GET(x, win, name) \
  56                vop_read_reg(x, win->base, &win->phy->name)
  57
  58#define VOP_WIN_GET_YRGBADDR(vop, win) \
  59                vop_readl(vop, win->base + win->phy->yrgb_mst.offset)
  60
  61#define to_vop(x) container_of(x, struct vop, crtc)
  62#define to_vop_win(x) container_of(x, struct vop_win, base)
  63
  64struct vop_win_state {
  65        struct list_head head;
  66        struct drm_framebuffer *fb;
  67        dma_addr_t yrgb_mst;
  68        struct drm_pending_vblank_event *event;
  69};
  70
  71struct vop_win {
  72        struct drm_plane base;
  73        const struct vop_win_data *data;
  74        struct vop *vop;
  75
  76        struct list_head pending;
  77        struct vop_win_state *active;
  78};
  79
  80struct vop {
  81        struct drm_crtc crtc;
  82        struct device *dev;
  83        struct drm_device *drm_dev;
  84        bool is_enabled;
  85
  86        int connector_type;
  87        int connector_out_mode;
  88
  89        /* mutex vsync_ work */
  90        struct mutex vsync_mutex;
  91        bool vsync_work_pending;
  92        struct completion dsp_hold_completion;
  93
  94        const struct vop_data *data;
  95
  96        uint32_t *regsbak;
  97        void __iomem *regs;
  98
  99        /* physical map length of vop register */
 100        uint32_t len;
 101
 102        /* one time only one process allowed to config the register */
 103        spinlock_t reg_lock;
 104        /* lock vop irq reg */
 105        spinlock_t irq_lock;
 106
 107        unsigned int irq;
 108
 109        /* vop AHP clk */
 110        struct clk *hclk;
 111        /* vop dclk */
 112        struct clk *dclk;
 113        /* vop share memory frequency */
 114        struct clk *aclk;
 115
 116        /* vop dclk reset */
 117        struct reset_control *dclk_rst;
 118
 119        int pipe;
 120
 121        struct vop_win win[];
 122};
 123
 124enum vop_data_format {
 125        VOP_FMT_ARGB8888 = 0,
 126        VOP_FMT_RGB888,
 127        VOP_FMT_RGB565,
 128        VOP_FMT_YUV420SP = 4,
 129        VOP_FMT_YUV422SP,
 130        VOP_FMT_YUV444SP,
 131};
 132
 133struct vop_reg_data {
 134        uint32_t offset;
 135        uint32_t value;
 136};
 137
 138struct vop_reg {
 139        uint32_t offset;
 140        uint32_t shift;
 141        uint32_t mask;
 142};
 143
 144struct vop_ctrl {
 145        struct vop_reg standby;
 146        struct vop_reg data_blank;
 147        struct vop_reg gate_en;
 148        struct vop_reg mmu_en;
 149        struct vop_reg rgb_en;
 150        struct vop_reg edp_en;
 151        struct vop_reg hdmi_en;
 152        struct vop_reg mipi_en;
 153        struct vop_reg out_mode;
 154        struct vop_reg dither_down;
 155        struct vop_reg dither_up;
 156        struct vop_reg pin_pol;
 157
 158        struct vop_reg htotal_pw;
 159        struct vop_reg hact_st_end;
 160        struct vop_reg vtotal_pw;
 161        struct vop_reg vact_st_end;
 162        struct vop_reg hpost_st_end;
 163        struct vop_reg vpost_st_end;
 164};
 165
 166struct vop_win_phy {
 167        const uint32_t *data_formats;
 168        uint32_t nformats;
 169
 170        struct vop_reg enable;
 171        struct vop_reg format;
 172        struct vop_reg act_info;
 173        struct vop_reg dsp_info;
 174        struct vop_reg dsp_st;
 175        struct vop_reg yrgb_mst;
 176        struct vop_reg uv_mst;
 177        struct vop_reg yrgb_vir;
 178        struct vop_reg uv_vir;
 179
 180        struct vop_reg dst_alpha_ctl;
 181        struct vop_reg src_alpha_ctl;
 182};
 183
 184struct vop_win_data {
 185        uint32_t base;
 186        const struct vop_win_phy *phy;
 187        enum drm_plane_type type;
 188};
 189
 190struct vop_data {
 191        const struct vop_reg_data *init_table;
 192        unsigned int table_size;
 193        const struct vop_ctrl *ctrl;
 194        const struct vop_win_data *win;
 195        unsigned int win_size;
 196};
 197
 198static const uint32_t formats_01[] = {
 199        DRM_FORMAT_XRGB8888,
 200        DRM_FORMAT_ARGB8888,
 201        DRM_FORMAT_RGB888,
 202        DRM_FORMAT_RGB565,
 203        DRM_FORMAT_NV12,
 204        DRM_FORMAT_NV16,
 205        DRM_FORMAT_NV24,
 206};
 207
 208static const uint32_t formats_234[] = {
 209        DRM_FORMAT_XRGB8888,
 210        DRM_FORMAT_ARGB8888,
 211        DRM_FORMAT_RGB888,
 212        DRM_FORMAT_RGB565,
 213};
 214
 215static const struct vop_win_phy win01_data = {
 216        .data_formats = formats_01,
 217        .nformats = ARRAY_SIZE(formats_01),
 218        .enable = VOP_REG(WIN0_CTRL0, 0x1, 0),
 219        .format = VOP_REG(WIN0_CTRL0, 0x7, 1),
 220        .act_info = VOP_REG(WIN0_ACT_INFO, 0x1fff1fff, 0),
 221        .dsp_info = VOP_REG(WIN0_DSP_INFO, 0x0fff0fff, 0),
 222        .dsp_st = VOP_REG(WIN0_DSP_ST, 0x1fff1fff, 0),
 223        .yrgb_mst = VOP_REG(WIN0_YRGB_MST, 0xffffffff, 0),
 224        .uv_mst = VOP_REG(WIN0_CBR_MST, 0xffffffff, 0),
 225        .yrgb_vir = VOP_REG(WIN0_VIR, 0x3fff, 0),
 226        .uv_vir = VOP_REG(WIN0_VIR, 0x3fff, 16),
 227        .src_alpha_ctl = VOP_REG(WIN0_SRC_ALPHA_CTRL, 0xff, 0),
 228        .dst_alpha_ctl = VOP_REG(WIN0_DST_ALPHA_CTRL, 0xff, 0),
 229};
 230
 231static const struct vop_win_phy win23_data = {
 232        .data_formats = formats_234,
 233        .nformats = ARRAY_SIZE(formats_234),
 234        .enable = VOP_REG(WIN2_CTRL0, 0x1, 0),
 235        .format = VOP_REG(WIN2_CTRL0, 0x7, 1),
 236        .dsp_info = VOP_REG(WIN2_DSP_INFO0, 0x0fff0fff, 0),
 237        .dsp_st = VOP_REG(WIN2_DSP_ST0, 0x1fff1fff, 0),
 238        .yrgb_mst = VOP_REG(WIN2_MST0, 0xffffffff, 0),
 239        .yrgb_vir = VOP_REG(WIN2_VIR0_1, 0x1fff, 0),
 240        .src_alpha_ctl = VOP_REG(WIN2_SRC_ALPHA_CTRL, 0xff, 0),
 241        .dst_alpha_ctl = VOP_REG(WIN2_DST_ALPHA_CTRL, 0xff, 0),
 242};
 243
 244static const struct vop_win_phy cursor_data = {
 245        .data_formats = formats_234,
 246        .nformats = ARRAY_SIZE(formats_234),
 247        .enable = VOP_REG(HWC_CTRL0, 0x1, 0),
 248        .format = VOP_REG(HWC_CTRL0, 0x7, 1),
 249        .dsp_st = VOP_REG(HWC_DSP_ST, 0x1fff1fff, 0),
 250        .yrgb_mst = VOP_REG(HWC_MST, 0xffffffff, 0),
 251};
 252
 253static const struct vop_ctrl ctrl_data = {
 254        .standby = VOP_REG(SYS_CTRL, 0x1, 22),
 255        .gate_en = VOP_REG(SYS_CTRL, 0x1, 23),
 256        .mmu_en = VOP_REG(SYS_CTRL, 0x1, 20),
 257        .rgb_en = VOP_REG(SYS_CTRL, 0x1, 12),
 258        .hdmi_en = VOP_REG(SYS_CTRL, 0x1, 13),
 259        .edp_en = VOP_REG(SYS_CTRL, 0x1, 14),
 260        .mipi_en = VOP_REG(SYS_CTRL, 0x1, 15),
 261        .dither_down = VOP_REG(DSP_CTRL1, 0xf, 1),
 262        .dither_up = VOP_REG(DSP_CTRL1, 0x1, 6),
 263        .data_blank = VOP_REG(DSP_CTRL0, 0x1, 19),
 264        .out_mode = VOP_REG(DSP_CTRL0, 0xf, 0),
 265        .pin_pol = VOP_REG(DSP_CTRL0, 0xf, 4),
 266        .htotal_pw = VOP_REG(DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
 267        .hact_st_end = VOP_REG(DSP_HACT_ST_END, 0x1fff1fff, 0),
 268        .vtotal_pw = VOP_REG(DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
 269        .vact_st_end = VOP_REG(DSP_VACT_ST_END, 0x1fff1fff, 0),
 270        .hpost_st_end = VOP_REG(POST_DSP_HACT_INFO, 0x1fff1fff, 0),
 271        .vpost_st_end = VOP_REG(POST_DSP_VACT_INFO, 0x1fff1fff, 0),
 272};
 273
 274static const struct vop_reg_data vop_init_reg_table[] = {
 275        {SYS_CTRL, 0x00c00000},
 276        {DSP_CTRL0, 0x00000000},
 277        {WIN0_CTRL0, 0x00000080},
 278        {WIN1_CTRL0, 0x00000080},
 279};
 280
 281/*
 282 * Note: rk3288 has a dedicated 'cursor' window, however, that window requires
 283 * special support to get alpha blending working.  For now, just use overlay
 284 * window 1 for the drm cursor.
 285 */
 286static const struct vop_win_data rk3288_vop_win_data[] = {
 287        { .base = 0x00, .phy = &win01_data, .type = DRM_PLANE_TYPE_PRIMARY },
 288        { .base = 0x40, .phy = &win01_data, .type = DRM_PLANE_TYPE_CURSOR },
 289        { .base = 0x00, .phy = &win23_data, .type = DRM_PLANE_TYPE_OVERLAY },
 290        { .base = 0x50, .phy = &win23_data, .type = DRM_PLANE_TYPE_OVERLAY },
 291        { .base = 0x00, .phy = &cursor_data, .type = DRM_PLANE_TYPE_OVERLAY },
 292};
 293
 294static const struct vop_data rk3288_vop = {
 295        .init_table = vop_init_reg_table,
 296        .table_size = ARRAY_SIZE(vop_init_reg_table),
 297        .ctrl = &ctrl_data,
 298        .win = rk3288_vop_win_data,
 299        .win_size = ARRAY_SIZE(rk3288_vop_win_data),
 300};
 301
 302static const struct of_device_id vop_driver_dt_match[] = {
 303        { .compatible = "rockchip,rk3288-vop",
 304          .data = &rk3288_vop },
 305        {},
 306};
 307
 308static inline void vop_writel(struct vop *vop, uint32_t offset, uint32_t v)
 309{
 310        writel(v, vop->regs + offset);
 311        vop->regsbak[offset >> 2] = v;
 312}
 313
 314static inline uint32_t vop_readl(struct vop *vop, uint32_t offset)
 315{
 316        return readl(vop->regs + offset);
 317}
 318
 319static inline uint32_t vop_read_reg(struct vop *vop, uint32_t base,
 320                                    const struct vop_reg *reg)
 321{
 322        return (vop_readl(vop, base + reg->offset) >> reg->shift) & reg->mask;
 323}
 324
 325static inline void vop_cfg_done(struct vop *vop)
 326{
 327        writel(0x01, vop->regs + REG_CFG_DONE);
 328}
 329
 330static inline void vop_mask_write(struct vop *vop, uint32_t offset,
 331                                  uint32_t mask, uint32_t v)
 332{
 333        if (mask) {
 334                uint32_t cached_val = vop->regsbak[offset >> 2];
 335
 336                cached_val = (cached_val & ~mask) | v;
 337                writel(cached_val, vop->regs + offset);
 338                vop->regsbak[offset >> 2] = cached_val;
 339        }
 340}
 341
 342static inline void vop_mask_write_relaxed(struct vop *vop, uint32_t offset,
 343                                          uint32_t mask, uint32_t v)
 344{
 345        if (mask) {
 346                uint32_t cached_val = vop->regsbak[offset >> 2];
 347
 348                cached_val = (cached_val & ~mask) | v;
 349                writel_relaxed(cached_val, vop->regs + offset);
 350                vop->regsbak[offset >> 2] = cached_val;
 351        }
 352}
 353
 354static enum vop_data_format vop_convert_format(uint32_t format)
 355{
 356        switch (format) {
 357        case DRM_FORMAT_XRGB8888:
 358        case DRM_FORMAT_ARGB8888:
 359                return VOP_FMT_ARGB8888;
 360        case DRM_FORMAT_RGB888:
 361                return VOP_FMT_RGB888;
 362        case DRM_FORMAT_RGB565:
 363                return VOP_FMT_RGB565;
 364        case DRM_FORMAT_NV12:
 365                return VOP_FMT_YUV420SP;
 366        case DRM_FORMAT_NV16:
 367                return VOP_FMT_YUV422SP;
 368        case DRM_FORMAT_NV24:
 369                return VOP_FMT_YUV444SP;
 370        default:
 371                DRM_ERROR("unsupport format[%08x]\n", format);
 372                return -EINVAL;
 373        }
 374}
 375
 376static bool is_alpha_support(uint32_t format)
 377{
 378        switch (format) {
 379        case DRM_FORMAT_ARGB8888:
 380                return true;
 381        default:
 382                return false;
 383        }
 384}
 385
 386static void vop_dsp_hold_valid_irq_enable(struct vop *vop)
 387{
 388        unsigned long flags;
 389
 390        if (WARN_ON(!vop->is_enabled))
 391                return;
 392
 393        spin_lock_irqsave(&vop->irq_lock, flags);
 394
 395        vop_mask_write(vop, INTR_CTRL0, DSP_HOLD_VALID_INTR_MASK,
 396                       DSP_HOLD_VALID_INTR_EN(1));
 397
 398        spin_unlock_irqrestore(&vop->irq_lock, flags);
 399}
 400
 401static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
 402{
 403        unsigned long flags;
 404
 405        if (WARN_ON(!vop->is_enabled))
 406                return;
 407
 408        spin_lock_irqsave(&vop->irq_lock, flags);
 409
 410        vop_mask_write(vop, INTR_CTRL0, DSP_HOLD_VALID_INTR_MASK,
 411                       DSP_HOLD_VALID_INTR_EN(0));
 412
 413        spin_unlock_irqrestore(&vop->irq_lock, flags);
 414}
 415
 416static void vop_enable(struct drm_crtc *crtc)
 417{
 418        struct vop *vop = to_vop(crtc);
 419        int ret;
 420
 421        if (vop->is_enabled)
 422                return;
 423
 424        ret = pm_runtime_get_sync(vop->dev);
 425        if (ret < 0) {
 426                dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
 427                return;
 428        }
 429
 430        ret = clk_enable(vop->hclk);
 431        if (ret < 0) {
 432                dev_err(vop->dev, "failed to enable hclk - %d\n", ret);
 433                return;
 434        }
 435
 436        ret = clk_enable(vop->dclk);
 437        if (ret < 0) {
 438                dev_err(vop->dev, "failed to enable dclk - %d\n", ret);
 439                goto err_disable_hclk;
 440        }
 441
 442        ret = clk_enable(vop->aclk);
 443        if (ret < 0) {
 444                dev_err(vop->dev, "failed to enable aclk - %d\n", ret);
 445                goto err_disable_dclk;
 446        }
 447
 448        /*
 449         * Slave iommu shares power, irq and clock with vop.  It was associated
 450         * automatically with this master device via common driver code.
 451         * Now that we have enabled the clock we attach it to the shared drm
 452         * mapping.
 453         */
 454        ret = rockchip_drm_dma_attach_device(vop->drm_dev, vop->dev);
 455        if (ret) {
 456                dev_err(vop->dev, "failed to attach dma mapping, %d\n", ret);
 457                goto err_disable_aclk;
 458        }
 459
 460        /*
 461         * At here, vop clock & iommu is enable, R/W vop regs would be safe.
 462         */
 463        vop->is_enabled = true;
 464
 465        spin_lock(&vop->reg_lock);
 466
 467        VOP_CTRL_SET(vop, standby, 0);
 468
 469        spin_unlock(&vop->reg_lock);
 470
 471        enable_irq(vop->irq);
 472
 473        drm_vblank_on(vop->drm_dev, vop->pipe);
 474
 475        return;
 476
 477err_disable_aclk:
 478        clk_disable(vop->aclk);
 479err_disable_dclk:
 480        clk_disable(vop->dclk);
 481err_disable_hclk:
 482        clk_disable(vop->hclk);
 483}
 484
 485static void vop_disable(struct drm_crtc *crtc)
 486{
 487        struct vop *vop = to_vop(crtc);
 488
 489        if (!vop->is_enabled)
 490                return;
 491
 492        drm_vblank_off(crtc->dev, vop->pipe);
 493
 494        /*
 495         * Vop standby will take effect at end of current frame,
 496         * if dsp hold valid irq happen, it means standby complete.
 497         *
 498         * we must wait standby complete when we want to disable aclk,
 499         * if not, memory bus maybe dead.
 500         */
 501        reinit_completion(&vop->dsp_hold_completion);
 502        vop_dsp_hold_valid_irq_enable(vop);
 503
 504        spin_lock(&vop->reg_lock);
 505
 506        VOP_CTRL_SET(vop, standby, 1);
 507
 508        spin_unlock(&vop->reg_lock);
 509
 510        wait_for_completion(&vop->dsp_hold_completion);
 511
 512        vop_dsp_hold_valid_irq_disable(vop);
 513
 514        disable_irq(vop->irq);
 515
 516        vop->is_enabled = false;
 517
 518        /*
 519         * vop standby complete, so iommu detach is safe.
 520         */
 521        rockchip_drm_dma_detach_device(vop->drm_dev, vop->dev);
 522
 523        clk_disable(vop->dclk);
 524        clk_disable(vop->aclk);
 525        clk_disable(vop->hclk);
 526        pm_runtime_put(vop->dev);
 527}
 528
 529/*
 530 * Caller must hold vsync_mutex.
 531 */
 532static struct drm_framebuffer *vop_win_last_pending_fb(struct vop_win *vop_win)
 533{
 534        struct vop_win_state *last;
 535        struct vop_win_state *active = vop_win->active;
 536
 537        if (list_empty(&vop_win->pending))
 538                return active ? active->fb : NULL;
 539
 540        last = list_last_entry(&vop_win->pending, struct vop_win_state, head);
 541        return last ? last->fb : NULL;
 542}
 543
 544/*
 545 * Caller must hold vsync_mutex.
 546 */
 547static int vop_win_queue_fb(struct vop_win *vop_win,
 548                            struct drm_framebuffer *fb, dma_addr_t yrgb_mst,
 549                            struct drm_pending_vblank_event *event)
 550{
 551        struct vop_win_state *state;
 552
 553        state = kzalloc(sizeof(*state), GFP_KERNEL);
 554        if (!state)
 555                return -ENOMEM;
 556
 557        state->fb = fb;
 558        state->yrgb_mst = yrgb_mst;
 559        state->event = event;
 560
 561        list_add_tail(&state->head, &vop_win->pending);
 562
 563        return 0;
 564}
 565
 566static int vop_update_plane_event(struct drm_plane *plane,
 567                                  struct drm_crtc *crtc,
 568                                  struct drm_framebuffer *fb, int crtc_x,
 569                                  int crtc_y, unsigned int crtc_w,
 570                                  unsigned int crtc_h, uint32_t src_x,
 571                                  uint32_t src_y, uint32_t src_w,
 572                                  uint32_t src_h,
 573                                  struct drm_pending_vblank_event *event)
 574{
 575        struct vop_win *vop_win = to_vop_win(plane);
 576        const struct vop_win_data *win = vop_win->data;
 577        struct vop *vop = to_vop(crtc);
 578        struct drm_gem_object *obj;
 579        struct rockchip_gem_object *rk_obj;
 580        unsigned long offset;
 581        unsigned int actual_w;
 582        unsigned int actual_h;
 583        unsigned int dsp_stx;
 584        unsigned int dsp_sty;
 585        unsigned int y_vir_stride;
 586        dma_addr_t yrgb_mst;
 587        enum vop_data_format format;
 588        uint32_t val;
 589        bool is_alpha;
 590        bool visible;
 591        int ret;
 592        struct drm_rect dest = {
 593                .x1 = crtc_x,
 594                .y1 = crtc_y,
 595                .x2 = crtc_x + crtc_w,
 596                .y2 = crtc_y + crtc_h,
 597        };
 598        struct drm_rect src = {
 599                /* 16.16 fixed point */
 600                .x1 = src_x,
 601                .y1 = src_y,
 602                .x2 = src_x + src_w,
 603                .y2 = src_y + src_h,
 604        };
 605        const struct drm_rect clip = {
 606                .x2 = crtc->mode.hdisplay,
 607                .y2 = crtc->mode.vdisplay,
 608        };
 609        bool can_position = plane->type != DRM_PLANE_TYPE_PRIMARY;
 610
 611        ret = drm_plane_helper_check_update(plane, crtc, fb,
 612                                            &src, &dest, &clip,
 613                                            DRM_PLANE_HELPER_NO_SCALING,
 614                                            DRM_PLANE_HELPER_NO_SCALING,
 615                                            can_position, false, &visible);
 616        if (ret)
 617                return ret;
 618
 619        if (!visible)
 620                return 0;
 621
 622        is_alpha = is_alpha_support(fb->pixel_format);
 623        format = vop_convert_format(fb->pixel_format);
 624        if (format < 0)
 625                return format;
 626
 627        obj = rockchip_fb_get_gem_obj(fb, 0);
 628        if (!obj) {
 629                DRM_ERROR("fail to get rockchip gem object from framebuffer\n");
 630                return -EINVAL;
 631        }
 632
 633        rk_obj = to_rockchip_obj(obj);
 634
 635        actual_w = (src.x2 - src.x1) >> 16;
 636        actual_h = (src.y2 - src.y1) >> 16;
 637        crtc_x = max(0, crtc_x);
 638        crtc_y = max(0, crtc_y);
 639
 640        dsp_stx = crtc_x + crtc->mode.htotal - crtc->mode.hsync_start;
 641        dsp_sty = crtc_y + crtc->mode.vtotal - crtc->mode.vsync_start;
 642
 643        offset = (src.x1 >> 16) * (fb->bits_per_pixel >> 3);
 644        offset += (src.y1 >> 16) * fb->pitches[0];
 645        yrgb_mst = rk_obj->dma_addr + offset;
 646
 647        y_vir_stride = fb->pitches[0] / (fb->bits_per_pixel >> 3);
 648
 649        /*
 650         * If this plane update changes the plane's framebuffer, (or more
 651         * precisely, if this update has a different framebuffer than the last
 652         * update), enqueue it so we can track when it completes.
 653         *
 654         * Only when we discover that this update has completed, can we
 655         * unreference any previous framebuffers.
 656         */
 657        mutex_lock(&vop->vsync_mutex);
 658        if (fb != vop_win_last_pending_fb(vop_win)) {
 659                ret = drm_vblank_get(plane->dev, vop->pipe);
 660                if (ret) {
 661                        DRM_ERROR("failed to get vblank, %d\n", ret);
 662                        mutex_unlock(&vop->vsync_mutex);
 663                        return ret;
 664                }
 665
 666                drm_framebuffer_reference(fb);
 667
 668                ret = vop_win_queue_fb(vop_win, fb, yrgb_mst, event);
 669                if (ret) {
 670                        drm_vblank_put(plane->dev, vop->pipe);
 671                        mutex_unlock(&vop->vsync_mutex);
 672                        return ret;
 673                }
 674
 675                vop->vsync_work_pending = true;
 676        }
 677        mutex_unlock(&vop->vsync_mutex);
 678
 679        spin_lock(&vop->reg_lock);
 680
 681        VOP_WIN_SET(vop, win, format, format);
 682        VOP_WIN_SET(vop, win, yrgb_vir, y_vir_stride);
 683        VOP_WIN_SET(vop, win, yrgb_mst, yrgb_mst);
 684        val = (actual_h - 1) << 16;
 685        val |= (actual_w - 1) & 0xffff;
 686        VOP_WIN_SET(vop, win, act_info, val);
 687        VOP_WIN_SET(vop, win, dsp_info, val);
 688        val = (dsp_sty - 1) << 16;
 689        val |= (dsp_stx - 1) & 0xffff;
 690        VOP_WIN_SET(vop, win, dsp_st, val);
 691
 692        if (is_alpha) {
 693                VOP_WIN_SET(vop, win, dst_alpha_ctl,
 694                            DST_FACTOR_M0(ALPHA_SRC_INVERSE));
 695                val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) |
 696                        SRC_ALPHA_M0(ALPHA_STRAIGHT) |
 697                        SRC_BLEND_M0(ALPHA_PER_PIX) |
 698                        SRC_ALPHA_CAL_M0(ALPHA_NO_SATURATION) |
 699                        SRC_FACTOR_M0(ALPHA_ONE);
 700                VOP_WIN_SET(vop, win, src_alpha_ctl, val);
 701        } else {
 702                VOP_WIN_SET(vop, win, src_alpha_ctl, SRC_ALPHA_EN(0));
 703        }
 704
 705        VOP_WIN_SET(vop, win, enable, 1);
 706
 707        vop_cfg_done(vop);
 708        spin_unlock(&vop->reg_lock);
 709
 710        return 0;
 711}
 712
 713static int vop_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 714                            struct drm_framebuffer *fb, int crtc_x, int crtc_y,
 715                            unsigned int crtc_w, unsigned int crtc_h,
 716                            uint32_t src_x, uint32_t src_y, uint32_t src_w,
 717                            uint32_t src_h)
 718{
 719        return vop_update_plane_event(plane, crtc, fb, crtc_x, crtc_y, crtc_w,
 720                                      crtc_h, src_x, src_y, src_w, src_h,
 721                                      NULL);
 722}
 723
 724static int vop_update_primary_plane(struct drm_crtc *crtc,
 725                                    struct drm_pending_vblank_event *event)
 726{
 727        unsigned int crtc_w, crtc_h;
 728
 729        crtc_w = crtc->primary->fb->width - crtc->x;
 730        crtc_h = crtc->primary->fb->height - crtc->y;
 731
 732        return vop_update_plane_event(crtc->primary, crtc, crtc->primary->fb,
 733                                      0, 0, crtc_w, crtc_h, crtc->x << 16,
 734                                      crtc->y << 16, crtc_w << 16,
 735                                      crtc_h << 16, event);
 736}
 737
 738static int vop_disable_plane(struct drm_plane *plane)
 739{
 740        struct vop_win *vop_win = to_vop_win(plane);
 741        const struct vop_win_data *win = vop_win->data;
 742        struct vop *vop;
 743        int ret;
 744
 745        if (!plane->crtc)
 746                return 0;
 747
 748        vop = to_vop(plane->crtc);
 749
 750        ret = drm_vblank_get(plane->dev, vop->pipe);
 751        if (ret) {
 752                DRM_ERROR("failed to get vblank, %d\n", ret);
 753                return ret;
 754        }
 755
 756        mutex_lock(&vop->vsync_mutex);
 757
 758        ret = vop_win_queue_fb(vop_win, NULL, 0, NULL);
 759        if (ret) {
 760                drm_vblank_put(plane->dev, vop->pipe);
 761                mutex_unlock(&vop->vsync_mutex);
 762                return ret;
 763        }
 764
 765        vop->vsync_work_pending = true;
 766        mutex_unlock(&vop->vsync_mutex);
 767
 768        spin_lock(&vop->reg_lock);
 769        VOP_WIN_SET(vop, win, enable, 0);
 770        vop_cfg_done(vop);
 771        spin_unlock(&vop->reg_lock);
 772
 773        return 0;
 774}
 775
 776static void vop_plane_destroy(struct drm_plane *plane)
 777{
 778        vop_disable_plane(plane);
 779        drm_plane_cleanup(plane);
 780}
 781
 782static const struct drm_plane_funcs vop_plane_funcs = {
 783        .update_plane = vop_update_plane,
 784        .disable_plane = vop_disable_plane,
 785        .destroy = vop_plane_destroy,
 786};
 787
 788int rockchip_drm_crtc_mode_config(struct drm_crtc *crtc,
 789                                  int connector_type,
 790                                  int out_mode)
 791{
 792        struct vop *vop = to_vop(crtc);
 793
 794        vop->connector_type = connector_type;
 795        vop->connector_out_mode = out_mode;
 796
 797        return 0;
 798}
 799EXPORT_SYMBOL_GPL(rockchip_drm_crtc_mode_config);
 800
 801static int vop_crtc_enable_vblank(struct drm_crtc *crtc)
 802{
 803        struct vop *vop = to_vop(crtc);
 804        unsigned long flags;
 805
 806        if (!vop->is_enabled)
 807                return -EPERM;
 808
 809        spin_lock_irqsave(&vop->irq_lock, flags);
 810
 811        vop_mask_write(vop, INTR_CTRL0, FS_INTR_MASK, FS_INTR_EN(1));
 812
 813        spin_unlock_irqrestore(&vop->irq_lock, flags);
 814
 815        return 0;
 816}
 817
 818static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
 819{
 820        struct vop *vop = to_vop(crtc);
 821        unsigned long flags;
 822
 823        if (!vop->is_enabled)
 824                return;
 825
 826        spin_lock_irqsave(&vop->irq_lock, flags);
 827        vop_mask_write(vop, INTR_CTRL0, FS_INTR_MASK, FS_INTR_EN(0));
 828        spin_unlock_irqrestore(&vop->irq_lock, flags);
 829}
 830
 831static const struct rockchip_crtc_funcs private_crtc_funcs = {
 832        .enable_vblank = vop_crtc_enable_vblank,
 833        .disable_vblank = vop_crtc_disable_vblank,
 834};
 835
 836static void vop_crtc_dpms(struct drm_crtc *crtc, int mode)
 837{
 838        DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);
 839
 840        switch (mode) {
 841        case DRM_MODE_DPMS_ON:
 842                vop_enable(crtc);
 843                break;
 844        case DRM_MODE_DPMS_STANDBY:
 845        case DRM_MODE_DPMS_SUSPEND:
 846        case DRM_MODE_DPMS_OFF:
 847                vop_disable(crtc);
 848                break;
 849        default:
 850                DRM_DEBUG_KMS("unspecified mode %d\n", mode);
 851                break;
 852        }
 853}
 854
 855static void vop_crtc_prepare(struct drm_crtc *crtc)
 856{
 857        vop_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
 858}
 859
 860static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
 861                                const struct drm_display_mode *mode,
 862                                struct drm_display_mode *adjusted_mode)
 863{
 864        if (adjusted_mode->htotal == 0 || adjusted_mode->vtotal == 0)
 865                return false;
 866
 867        return true;
 868}
 869
 870static int vop_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 871                                  struct drm_framebuffer *old_fb)
 872{
 873        int ret;
 874
 875        crtc->x = x;
 876        crtc->y = y;
 877
 878        ret = vop_update_primary_plane(crtc, NULL);
 879        if (ret < 0) {
 880                DRM_ERROR("fail to update plane\n");
 881                return ret;
 882        }
 883
 884        return 0;
 885}
 886
 887static int vop_crtc_mode_set(struct drm_crtc *crtc,
 888                             struct drm_display_mode *mode,
 889                             struct drm_display_mode *adjusted_mode,
 890                             int x, int y, struct drm_framebuffer *fb)
 891{
 892        struct vop *vop = to_vop(crtc);
 893        u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
 894        u16 hdisplay = adjusted_mode->hdisplay;
 895        u16 htotal = adjusted_mode->htotal;
 896        u16 hact_st = adjusted_mode->htotal - adjusted_mode->hsync_start;
 897        u16 hact_end = hact_st + hdisplay;
 898        u16 vdisplay = adjusted_mode->vdisplay;
 899        u16 vtotal = adjusted_mode->vtotal;
 900        u16 vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
 901        u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start;
 902        u16 vact_end = vact_st + vdisplay;
 903        int ret, ret_clk;
 904        uint32_t val;
 905
 906        /*
 907         * disable dclk to stop frame scan, so that we can safe config mode and
 908         * enable iommu.
 909         */
 910        clk_disable(vop->dclk);
 911
 912        switch (vop->connector_type) {
 913        case DRM_MODE_CONNECTOR_LVDS:
 914                VOP_CTRL_SET(vop, rgb_en, 1);
 915                break;
 916        case DRM_MODE_CONNECTOR_eDP:
 917                VOP_CTRL_SET(vop, edp_en, 1);
 918                break;
 919        case DRM_MODE_CONNECTOR_HDMIA:
 920                VOP_CTRL_SET(vop, hdmi_en, 1);
 921                break;
 922        default:
 923                DRM_ERROR("unsupport connector_type[%d]\n",
 924                          vop->connector_type);
 925                ret = -EINVAL;
 926                goto out;
 927        };
 928        VOP_CTRL_SET(vop, out_mode, vop->connector_out_mode);
 929
 930        val = 0x8;
 931        val |= (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1;
 932        val |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : (1 << 1);
 933        VOP_CTRL_SET(vop, pin_pol, val);
 934
 935        VOP_CTRL_SET(vop, htotal_pw, (htotal << 16) | hsync_len);
 936        val = hact_st << 16;
 937        val |= hact_end;
 938        VOP_CTRL_SET(vop, hact_st_end, val);
 939        VOP_CTRL_SET(vop, hpost_st_end, val);
 940
 941        VOP_CTRL_SET(vop, vtotal_pw, (vtotal << 16) | vsync_len);
 942        val = vact_st << 16;
 943        val |= vact_end;
 944        VOP_CTRL_SET(vop, vact_st_end, val);
 945        VOP_CTRL_SET(vop, vpost_st_end, val);
 946
 947        ret = vop_crtc_mode_set_base(crtc, x, y, fb);
 948        if (ret)
 949                goto out;
 950
 951        /*
 952         * reset dclk, take all mode config affect, so the clk would run in
 953         * correct frame.
 954         */
 955        reset_control_assert(vop->dclk_rst);
 956        usleep_range(10, 20);
 957        reset_control_deassert(vop->dclk_rst);
 958
 959        clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
 960out:
 961        ret_clk = clk_enable(vop->dclk);
 962        if (ret_clk < 0) {
 963                dev_err(vop->dev, "failed to enable dclk - %d\n", ret_clk);
 964                return ret_clk;
 965        }
 966
 967        return ret;
 968}
 969
 970static void vop_crtc_commit(struct drm_crtc *crtc)
 971{
 972}
 973
 974static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
 975        .dpms = vop_crtc_dpms,
 976        .prepare = vop_crtc_prepare,
 977        .mode_fixup = vop_crtc_mode_fixup,
 978        .mode_set = vop_crtc_mode_set,
 979        .mode_set_base = vop_crtc_mode_set_base,
 980        .commit = vop_crtc_commit,
 981};
 982
 983static int vop_crtc_page_flip(struct drm_crtc *crtc,
 984                              struct drm_framebuffer *fb,
 985                              struct drm_pending_vblank_event *event,
 986                              uint32_t page_flip_flags)
 987{
 988        struct vop *vop = to_vop(crtc);
 989        struct drm_framebuffer *old_fb = crtc->primary->fb;
 990        int ret;
 991
 992        /* when the page flip is requested, crtc should be on */
 993        if (!vop->is_enabled) {
 994                DRM_DEBUG("page flip request rejected because crtc is off.\n");
 995                return 0;
 996        }
 997
 998        crtc->primary->fb = fb;
 999
1000        ret = vop_update_primary_plane(crtc, event);
1001        if (ret)
1002                crtc->primary->fb = old_fb;
1003
1004        return ret;
1005}
1006
1007static void vop_win_state_complete(struct vop_win *vop_win,
1008                                   struct vop_win_state *state)
1009{
1010        struct vop *vop = vop_win->vop;
1011        struct drm_crtc *crtc = &vop->crtc;
1012        struct drm_device *drm = crtc->dev;
1013        unsigned long flags;
1014
1015        if (state->event) {
1016                spin_lock_irqsave(&drm->event_lock, flags);
1017                drm_send_vblank_event(drm, -1, state->event);
1018                spin_unlock_irqrestore(&drm->event_lock, flags);
1019        }
1020
1021        list_del(&state->head);
1022        drm_vblank_put(crtc->dev, vop->pipe);
1023}
1024
1025static void vop_crtc_destroy(struct drm_crtc *crtc)
1026{
1027        drm_crtc_cleanup(crtc);
1028}
1029
1030static const struct drm_crtc_funcs vop_crtc_funcs = {
1031        .set_config = drm_crtc_helper_set_config,
1032        .page_flip = vop_crtc_page_flip,
1033        .destroy = vop_crtc_destroy,
1034};
1035
1036static bool vop_win_state_is_active(struct vop_win *vop_win,
1037                                    struct vop_win_state *state)
1038{
1039        bool active = false;
1040
1041        if (state->fb) {
1042                dma_addr_t yrgb_mst;
1043
1044                /* check yrgb_mst to tell if pending_fb is now front */
1045                yrgb_mst = VOP_WIN_GET_YRGBADDR(vop_win->vop, vop_win->data);
1046
1047                active = (yrgb_mst == state->yrgb_mst);
1048        } else {
1049                bool enabled;
1050
1051                /* if enable bit is clear, plane is now disabled */
1052                enabled = VOP_WIN_GET(vop_win->vop, vop_win->data, enable);
1053
1054                active = (enabled == 0);
1055        }
1056
1057        return active;
1058}
1059
1060static void vop_win_state_destroy(struct vop_win_state *state)
1061{
1062        struct drm_framebuffer *fb = state->fb;
1063
1064        if (fb)
1065                drm_framebuffer_unreference(fb);
1066
1067        kfree(state);
1068}
1069
1070static void vop_win_update_state(struct vop_win *vop_win)
1071{
1072        struct vop_win_state *state, *n, *new_active = NULL;
1073
1074        /* Check if any pending states are now active */
1075        list_for_each_entry(state, &vop_win->pending, head)
1076                if (vop_win_state_is_active(vop_win, state)) {
1077                        new_active = state;
1078                        break;
1079                }
1080
1081        if (!new_active)
1082                return;
1083
1084        /*
1085         * Destroy any 'skipped' pending states - states that were queued
1086         * before the newly active state.
1087         */
1088        list_for_each_entry_safe(state, n, &vop_win->pending, head) {
1089                if (state == new_active)
1090                        break;
1091                vop_win_state_complete(vop_win, state);
1092                vop_win_state_destroy(state);
1093        }
1094
1095        vop_win_state_complete(vop_win, new_active);
1096
1097        if (vop_win->active)
1098                vop_win_state_destroy(vop_win->active);
1099        vop_win->active = new_active;
1100}
1101
1102static bool vop_win_has_pending_state(struct vop_win *vop_win)
1103{
1104        return !list_empty(&vop_win->pending);
1105}
1106
1107static irqreturn_t vop_isr_thread(int irq, void *data)
1108{
1109        struct vop *vop = data;
1110        const struct vop_data *vop_data = vop->data;
1111        unsigned int i;
1112
1113        mutex_lock(&vop->vsync_mutex);
1114
1115        if (!vop->vsync_work_pending)
1116                goto done;
1117
1118        vop->vsync_work_pending = false;
1119
1120        for (i = 0; i < vop_data->win_size; i++) {
1121                struct vop_win *vop_win = &vop->win[i];
1122
1123                vop_win_update_state(vop_win);
1124                if (vop_win_has_pending_state(vop_win))
1125                        vop->vsync_work_pending = true;
1126        }
1127
1128done:
1129        mutex_unlock(&vop->vsync_mutex);
1130
1131        return IRQ_HANDLED;
1132}
1133
1134static irqreturn_t vop_isr(int irq, void *data)
1135{
1136        struct vop *vop = data;
1137        uint32_t intr0_reg, active_irqs;
1138        unsigned long flags;
1139        int ret = IRQ_NONE;
1140
1141        /*
1142         * INTR_CTRL0 register has interrupt status, enable and clear bits, we
1143         * must hold irq_lock to avoid a race with enable/disable_vblank().
1144        */
1145        spin_lock_irqsave(&vop->irq_lock, flags);
1146        intr0_reg = vop_readl(vop, INTR_CTRL0);
1147        active_irqs = intr0_reg & INTR_MASK;
1148        /* Clear all active interrupt sources */
1149        if (active_irqs)
1150                vop_writel(vop, INTR_CTRL0,
1151                           intr0_reg | (active_irqs << INTR_CLR_SHIFT));
1152        spin_unlock_irqrestore(&vop->irq_lock, flags);
1153
1154        /* This is expected for vop iommu irqs, since the irq is shared */
1155        if (!active_irqs)
1156                return IRQ_NONE;
1157
1158        if (active_irqs & DSP_HOLD_VALID_INTR) {
1159                complete(&vop->dsp_hold_completion);
1160                active_irqs &= ~DSP_HOLD_VALID_INTR;
1161                ret = IRQ_HANDLED;
1162        }
1163
1164        if (active_irqs & FS_INTR) {
1165                drm_handle_vblank(vop->drm_dev, vop->pipe);
1166                active_irqs &= ~FS_INTR;
1167                ret = (vop->vsync_work_pending) ? IRQ_WAKE_THREAD : IRQ_HANDLED;
1168        }
1169
1170        /* Unhandled irqs are spurious. */
1171        if (active_irqs)
1172                DRM_ERROR("Unknown VOP IRQs: %#02x\n", active_irqs);
1173
1174        return ret;
1175}
1176
1177static int vop_create_crtc(struct vop *vop)
1178{
1179        const struct vop_data *vop_data = vop->data;
1180        struct device *dev = vop->dev;
1181        struct drm_device *drm_dev = vop->drm_dev;
1182        struct drm_plane *primary = NULL, *cursor = NULL, *plane;
1183        struct drm_crtc *crtc = &vop->crtc;
1184        struct device_node *port;
1185        int ret;
1186        int i;
1187
1188        /*
1189         * Create drm_plane for primary and cursor planes first, since we need
1190         * to pass them to drm_crtc_init_with_planes, which sets the
1191         * "possible_crtcs" to the newly initialized crtc.
1192         */
1193        for (i = 0; i < vop_data->win_size; i++) {
1194                struct vop_win *vop_win = &vop->win[i];
1195                const struct vop_win_data *win_data = vop_win->data;
1196
1197                if (win_data->type != DRM_PLANE_TYPE_PRIMARY &&
1198                    win_data->type != DRM_PLANE_TYPE_CURSOR)
1199                        continue;
1200
1201                ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base,
1202                                               0, &vop_plane_funcs,
1203                                               win_data->phy->data_formats,
1204                                               win_data->phy->nformats,
1205                                               win_data->type);
1206                if (ret) {
1207                        DRM_ERROR("failed to initialize plane\n");
1208                        goto err_cleanup_planes;
1209                }
1210
1211                plane = &vop_win->base;
1212                if (plane->type == DRM_PLANE_TYPE_PRIMARY)
1213                        primary = plane;
1214                else if (plane->type == DRM_PLANE_TYPE_CURSOR)
1215                        cursor = plane;
1216        }
1217
1218        ret = drm_crtc_init_with_planes(drm_dev, crtc, primary, cursor,
1219                                        &vop_crtc_funcs);
1220        if (ret)
1221                return ret;
1222
1223        drm_crtc_helper_add(crtc, &vop_crtc_helper_funcs);
1224
1225        /*
1226         * Create drm_planes for overlay windows with possible_crtcs restricted
1227         * to the newly created crtc.
1228         */
1229        for (i = 0; i < vop_data->win_size; i++) {
1230                struct vop_win *vop_win = &vop->win[i];
1231                const struct vop_win_data *win_data = vop_win->data;
1232                unsigned long possible_crtcs = 1 << drm_crtc_index(crtc);
1233
1234                if (win_data->type != DRM_PLANE_TYPE_OVERLAY)
1235                        continue;
1236
1237                ret = drm_universal_plane_init(vop->drm_dev, &vop_win->base,
1238                                               possible_crtcs,
1239                                               &vop_plane_funcs,
1240                                               win_data->phy->data_formats,
1241                                               win_data->phy->nformats,
1242                                               win_data->type);
1243                if (ret) {
1244                        DRM_ERROR("failed to initialize overlay plane\n");
1245                        goto err_cleanup_crtc;
1246                }
1247        }
1248
1249        port = of_get_child_by_name(dev->of_node, "port");
1250        if (!port) {
1251                DRM_ERROR("no port node found in %s\n",
1252                          dev->of_node->full_name);
1253                goto err_cleanup_crtc;
1254        }
1255
1256        init_completion(&vop->dsp_hold_completion);
1257        crtc->port = port;
1258        vop->pipe = drm_crtc_index(crtc);
1259        rockchip_register_crtc_funcs(drm_dev, &private_crtc_funcs, vop->pipe);
1260
1261        return 0;
1262
1263err_cleanup_crtc:
1264        drm_crtc_cleanup(crtc);
1265err_cleanup_planes:
1266        list_for_each_entry(plane, &drm_dev->mode_config.plane_list, head)
1267                drm_plane_cleanup(plane);
1268        return ret;
1269}
1270
1271static void vop_destroy_crtc(struct vop *vop)
1272{
1273        struct drm_crtc *crtc = &vop->crtc;
1274
1275        rockchip_unregister_crtc_funcs(vop->drm_dev, vop->pipe);
1276        of_node_put(crtc->port);
1277        drm_crtc_cleanup(crtc);
1278}
1279
1280static int vop_initial(struct vop *vop)
1281{
1282        const struct vop_data *vop_data = vop->data;
1283        const struct vop_reg_data *init_table = vop_data->init_table;
1284        struct reset_control *ahb_rst;
1285        int i, ret;
1286
1287        vop->hclk = devm_clk_get(vop->dev, "hclk_vop");
1288        if (IS_ERR(vop->hclk)) {
1289                dev_err(vop->dev, "failed to get hclk source\n");
1290                return PTR_ERR(vop->hclk);
1291        }
1292        vop->aclk = devm_clk_get(vop->dev, "aclk_vop");
1293        if (IS_ERR(vop->aclk)) {
1294                dev_err(vop->dev, "failed to get aclk source\n");
1295                return PTR_ERR(vop->aclk);
1296        }
1297        vop->dclk = devm_clk_get(vop->dev, "dclk_vop");
1298        if (IS_ERR(vop->dclk)) {
1299                dev_err(vop->dev, "failed to get dclk source\n");
1300                return PTR_ERR(vop->dclk);
1301        }
1302
1303        ret = clk_prepare(vop->hclk);
1304        if (ret < 0) {
1305                dev_err(vop->dev, "failed to prepare hclk\n");
1306                return ret;
1307        }
1308
1309        ret = clk_prepare(vop->dclk);
1310        if (ret < 0) {
1311                dev_err(vop->dev, "failed to prepare dclk\n");
1312                goto err_unprepare_hclk;
1313        }
1314
1315        ret = clk_prepare(vop->aclk);
1316        if (ret < 0) {
1317                dev_err(vop->dev, "failed to prepare aclk\n");
1318                goto err_unprepare_dclk;
1319        }
1320
1321        /*
1322         * enable hclk, so that we can config vop register.
1323         */
1324        ret = clk_enable(vop->hclk);
1325        if (ret < 0) {
1326                dev_err(vop->dev, "failed to prepare aclk\n");
1327                goto err_unprepare_aclk;
1328        }
1329        /*
1330         * do hclk_reset, reset all vop registers.
1331         */
1332        ahb_rst = devm_reset_control_get(vop->dev, "ahb");
1333        if (IS_ERR(ahb_rst)) {
1334                dev_err(vop->dev, "failed to get ahb reset\n");
1335                ret = PTR_ERR(ahb_rst);
1336                goto err_disable_hclk;
1337        }
1338        reset_control_assert(ahb_rst);
1339        usleep_range(10, 20);
1340        reset_control_deassert(ahb_rst);
1341
1342        memcpy(vop->regsbak, vop->regs, vop->len);
1343
1344        for (i = 0; i < vop_data->table_size; i++)
1345                vop_writel(vop, init_table[i].offset, init_table[i].value);
1346
1347        for (i = 0; i < vop_data->win_size; i++) {
1348                const struct vop_win_data *win = &vop_data->win[i];
1349
1350                VOP_WIN_SET(vop, win, enable, 0);
1351        }
1352
1353        vop_cfg_done(vop);
1354
1355        /*
1356         * do dclk_reset, let all config take affect.
1357         */
1358        vop->dclk_rst = devm_reset_control_get(vop->dev, "dclk");
1359        if (IS_ERR(vop->dclk_rst)) {
1360                dev_err(vop->dev, "failed to get dclk reset\n");
1361                ret = PTR_ERR(vop->dclk_rst);
1362                goto err_unprepare_aclk;
1363        }
1364        reset_control_assert(vop->dclk_rst);
1365        usleep_range(10, 20);
1366        reset_control_deassert(vop->dclk_rst);
1367
1368        clk_disable(vop->hclk);
1369
1370        vop->is_enabled = false;
1371
1372        return 0;
1373
1374err_disable_hclk:
1375        clk_disable(vop->hclk);
1376err_unprepare_aclk:
1377        clk_unprepare(vop->aclk);
1378err_unprepare_dclk:
1379        clk_unprepare(vop->dclk);
1380err_unprepare_hclk:
1381        clk_unprepare(vop->hclk);
1382        return ret;
1383}
1384
1385/*
1386 * Initialize the vop->win array elements.
1387 */
1388static void vop_win_init(struct vop *vop)
1389{
1390        const struct vop_data *vop_data = vop->data;
1391        unsigned int i;
1392
1393        for (i = 0; i < vop_data->win_size; i++) {
1394                struct vop_win *vop_win = &vop->win[i];
1395                const struct vop_win_data *win_data = &vop_data->win[i];
1396
1397                vop_win->data = win_data;
1398                vop_win->vop = vop;
1399                INIT_LIST_HEAD(&vop_win->pending);
1400        }
1401}
1402
1403static int vop_bind(struct device *dev, struct device *master, void *data)
1404{
1405        struct platform_device *pdev = to_platform_device(dev);
1406        const struct of_device_id *of_id;
1407        const struct vop_data *vop_data;
1408        struct drm_device *drm_dev = data;
1409        struct vop *vop;
1410        struct resource *res;
1411        size_t alloc_size;
1412        int ret, irq;
1413
1414        of_id = of_match_device(vop_driver_dt_match, dev);
1415        vop_data = of_id->data;
1416        if (!vop_data)
1417                return -ENODEV;
1418
1419        /* Allocate vop struct and its vop_win array */
1420        alloc_size = sizeof(*vop) + sizeof(*vop->win) * vop_data->win_size;
1421        vop = devm_kzalloc(dev, alloc_size, GFP_KERNEL);
1422        if (!vop)
1423                return -ENOMEM;
1424
1425        vop->dev = dev;
1426        vop->data = vop_data;
1427        vop->drm_dev = drm_dev;
1428        dev_set_drvdata(dev, vop);
1429
1430        vop_win_init(vop);
1431
1432        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1433        vop->len = resource_size(res);
1434        vop->regs = devm_ioremap_resource(dev, res);
1435        if (IS_ERR(vop->regs))
1436                return PTR_ERR(vop->regs);
1437
1438        vop->regsbak = devm_kzalloc(dev, vop->len, GFP_KERNEL);
1439        if (!vop->regsbak)
1440                return -ENOMEM;
1441
1442        ret = vop_initial(vop);
1443        if (ret < 0) {
1444                dev_err(&pdev->dev, "cannot initial vop dev - err %d\n", ret);
1445                return ret;
1446        }
1447
1448        irq = platform_get_irq(pdev, 0);
1449        if (irq < 0) {
1450                dev_err(dev, "cannot find irq for vop\n");
1451                return irq;
1452        }
1453        vop->irq = (unsigned int)irq;
1454
1455        spin_lock_init(&vop->reg_lock);
1456        spin_lock_init(&vop->irq_lock);
1457
1458        mutex_init(&vop->vsync_mutex);
1459
1460        ret = devm_request_threaded_irq(dev, vop->irq, vop_isr, vop_isr_thread,
1461                                        IRQF_SHARED, dev_name(dev), vop);
1462        if (ret)
1463                return ret;
1464
1465        /* IRQ is initially disabled; it gets enabled in power_on */
1466        disable_irq(vop->irq);
1467
1468        ret = vop_create_crtc(vop);
1469        if (ret)
1470                return ret;
1471
1472        pm_runtime_enable(&pdev->dev);
1473        return 0;
1474}
1475
1476static void vop_unbind(struct device *dev, struct device *master, void *data)
1477{
1478        struct vop *vop = dev_get_drvdata(dev);
1479
1480        pm_runtime_disable(dev);
1481        vop_destroy_crtc(vop);
1482}
1483
1484static const struct component_ops vop_component_ops = {
1485        .bind = vop_bind,
1486        .unbind = vop_unbind,
1487};
1488
1489static int vop_probe(struct platform_device *pdev)
1490{
1491        struct device *dev = &pdev->dev;
1492
1493        if (!dev->of_node) {
1494                dev_err(dev, "can't find vop devices\n");
1495                return -ENODEV;
1496        }
1497
1498        return component_add(dev, &vop_component_ops);
1499}
1500
1501static int vop_remove(struct platform_device *pdev)
1502{
1503        component_del(&pdev->dev, &vop_component_ops);
1504
1505        return 0;
1506}
1507
1508struct platform_driver vop_platform_driver = {
1509        .probe = vop_probe,
1510        .remove = vop_remove,
1511        .driver = {
1512                .name = "rockchip-vop",
1513                .owner = THIS_MODULE,
1514                .of_match_table = of_match_ptr(vop_driver_dt_match),
1515        },
1516};
1517
1518module_platform_driver(vop_platform_driver);
1519
1520MODULE_AUTHOR("Mark Yao <mark.yao@rock-chips.com>");
1521MODULE_DESCRIPTION("ROCKCHIP VOP Driver");
1522MODULE_LICENSE("GPL v2");
1523