root/drivers/gpu/drm/rockchip/rockchip_vop_reg.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vop_probe
  2. vop_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
   4  * Author:Mark Yao <mark.yao@rock-chips.com>
   5  */
   6 
   7 #include <linux/component.h>
   8 #include <linux/mod_devicetable.h>
   9 #include <linux/module.h>
  10 #include <linux/of.h>
  11 #include <linux/platform_device.h>
  12 
  13 #include <drm/drm_fourcc.h>
  14 #include <drm/drm_plane.h>
  15 #include <drm/drm_print.h>
  16 
  17 #include "rockchip_drm_vop.h"
  18 #include "rockchip_vop_reg.h"
  19 
  20 #define _VOP_REG(off, _mask, _shift, _write_mask, _relaxed) \
  21                 { \
  22                  .offset = off, \
  23                  .mask = _mask, \
  24                  .shift = _shift, \
  25                  .write_mask = _write_mask, \
  26                  .relaxed = _relaxed, \
  27                 }
  28 
  29 #define VOP_REG(off, _mask, _shift) \
  30                 _VOP_REG(off, _mask, _shift, false, true)
  31 
  32 #define VOP_REG_SYNC(off, _mask, _shift) \
  33                 _VOP_REG(off, _mask, _shift, false, false)
  34 
  35 #define VOP_REG_MASK_SYNC(off, _mask, _shift) \
  36                 _VOP_REG(off, _mask, _shift, true, false)
  37 
  38 static const uint32_t formats_win_full[] = {
  39         DRM_FORMAT_XRGB8888,
  40         DRM_FORMAT_ARGB8888,
  41         DRM_FORMAT_XBGR8888,
  42         DRM_FORMAT_ABGR8888,
  43         DRM_FORMAT_RGB888,
  44         DRM_FORMAT_BGR888,
  45         DRM_FORMAT_RGB565,
  46         DRM_FORMAT_BGR565,
  47         DRM_FORMAT_NV12,
  48         DRM_FORMAT_NV16,
  49         DRM_FORMAT_NV24,
  50 };
  51 
  52 static const uint32_t formats_win_lite[] = {
  53         DRM_FORMAT_XRGB8888,
  54         DRM_FORMAT_ARGB8888,
  55         DRM_FORMAT_XBGR8888,
  56         DRM_FORMAT_ABGR8888,
  57         DRM_FORMAT_RGB888,
  58         DRM_FORMAT_BGR888,
  59         DRM_FORMAT_RGB565,
  60         DRM_FORMAT_BGR565,
  61 };
  62 
  63 static const struct vop_scl_regs rk3036_win_scl = {
  64         .scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
  65         .scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
  66         .scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
  67         .scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
  68 };
  69 
  70 static const struct vop_win_phy rk3036_win0_data = {
  71         .scl = &rk3036_win_scl,
  72         .data_formats = formats_win_full,
  73         .nformats = ARRAY_SIZE(formats_win_full),
  74         .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0),
  75         .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3),
  76         .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15),
  77         .act_info = VOP_REG(RK3036_WIN0_ACT_INFO, 0x1fff1fff, 0),
  78         .dsp_info = VOP_REG(RK3036_WIN0_DSP_INFO, 0x0fff0fff, 0),
  79         .dsp_st = VOP_REG(RK3036_WIN0_DSP_ST, 0x1fff1fff, 0),
  80         .yrgb_mst = VOP_REG(RK3036_WIN0_YRGB_MST, 0xffffffff, 0),
  81         .uv_mst = VOP_REG(RK3036_WIN0_CBR_MST, 0xffffffff, 0),
  82         .yrgb_vir = VOP_REG(RK3036_WIN0_VIR, 0xffff, 0),
  83         .uv_vir = VOP_REG(RK3036_WIN0_VIR, 0x1fff, 16),
  84 };
  85 
  86 static const struct vop_win_phy rk3036_win1_data = {
  87         .data_formats = formats_win_lite,
  88         .nformats = ARRAY_SIZE(formats_win_lite),
  89         .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
  90         .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
  91         .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
  92         .act_info = VOP_REG(RK3036_WIN1_ACT_INFO, 0x1fff1fff, 0),
  93         .dsp_info = VOP_REG(RK3036_WIN1_DSP_INFO, 0x0fff0fff, 0),
  94         .dsp_st = VOP_REG(RK3036_WIN1_DSP_ST, 0x1fff1fff, 0),
  95         .yrgb_mst = VOP_REG(RK3036_WIN1_MST, 0xffffffff, 0),
  96         .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
  97 };
  98 
  99 static const struct vop_win_data rk3036_vop_win_data[] = {
 100         { .base = 0x00, .phy = &rk3036_win0_data,
 101           .type = DRM_PLANE_TYPE_PRIMARY },
 102         { .base = 0x00, .phy = &rk3036_win1_data,
 103           .type = DRM_PLANE_TYPE_CURSOR },
 104 };
 105 
 106 static const int rk3036_vop_intrs[] = {
 107         DSP_HOLD_VALID_INTR,
 108         FS_INTR,
 109         LINE_FLAG_INTR,
 110         BUS_ERROR_INTR,
 111 };
 112 
 113 static const struct vop_intr rk3036_intr = {
 114         .intrs = rk3036_vop_intrs,
 115         .nintrs = ARRAY_SIZE(rk3036_vop_intrs),
 116         .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
 117         .status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0),
 118         .enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4),
 119         .clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8),
 120 };
 121 
 122 static const struct vop_modeset rk3036_modeset = {
 123         .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
 124         .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
 125         .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
 126         .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
 127 };
 128 
 129 static const struct vop_output rk3036_output = {
 130         .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
 131 };
 132 
 133 static const struct vop_common rk3036_common = {
 134         .standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30),
 135         .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
 136         .dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24),
 137         .dither_down_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 27),
 138         .dither_down_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 11),
 139         .dither_down_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 10),
 140         .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0),
 141 };
 142 
 143 static const struct vop_data rk3036_vop = {
 144         .intr = &rk3036_intr,
 145         .common = &rk3036_common,
 146         .modeset = &rk3036_modeset,
 147         .output = &rk3036_output,
 148         .win = rk3036_vop_win_data,
 149         .win_size = ARRAY_SIZE(rk3036_vop_win_data),
 150 };
 151 
 152 static const struct vop_win_phy rk3126_win1_data = {
 153         .data_formats = formats_win_lite,
 154         .nformats = ARRAY_SIZE(formats_win_lite),
 155         .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
 156         .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
 157         .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
 158         .dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0),
 159         .dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0),
 160         .yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0xffffffff, 0),
 161         .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
 162 };
 163 
 164 static const struct vop_win_data rk3126_vop_win_data[] = {
 165         { .base = 0x00, .phy = &rk3036_win0_data,
 166           .type = DRM_PLANE_TYPE_PRIMARY },
 167         { .base = 0x00, .phy = &rk3126_win1_data,
 168           .type = DRM_PLANE_TYPE_CURSOR },
 169 };
 170 
 171 static const struct vop_data rk3126_vop = {
 172         .intr = &rk3036_intr,
 173         .common = &rk3036_common,
 174         .modeset = &rk3036_modeset,
 175         .output = &rk3036_output,
 176         .win = rk3126_vop_win_data,
 177         .win_size = ARRAY_SIZE(rk3126_vop_win_data),
 178 };
 179 
 180 static const int px30_vop_intrs[] = {
 181         FS_INTR,
 182         0, 0,
 183         LINE_FLAG_INTR,
 184         0,
 185         BUS_ERROR_INTR,
 186         0, 0,
 187         DSP_HOLD_VALID_INTR,
 188 };
 189 
 190 static const struct vop_intr px30_intr = {
 191         .intrs = px30_vop_intrs,
 192         .nintrs = ARRAY_SIZE(px30_vop_intrs),
 193         .line_flag_num[0] = VOP_REG(PX30_LINE_FLAG, 0xfff, 0),
 194         .status = VOP_REG_MASK_SYNC(PX30_INTR_STATUS, 0xffff, 0),
 195         .enable = VOP_REG_MASK_SYNC(PX30_INTR_EN, 0xffff, 0),
 196         .clear = VOP_REG_MASK_SYNC(PX30_INTR_CLEAR, 0xffff, 0),
 197 };
 198 
 199 static const struct vop_common px30_common = {
 200         .standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1),
 201         .out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16),
 202         .dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14),
 203         .dither_down_en = VOP_REG(PX30_DSP_CTRL2, 0x1, 8),
 204         .dither_down_sel = VOP_REG(PX30_DSP_CTRL2, 0x1, 7),
 205         .dither_down_mode = VOP_REG(PX30_DSP_CTRL2, 0x1, 6),
 206         .cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0),
 207 };
 208 
 209 static const struct vop_modeset px30_modeset = {
 210         .htotal_pw = VOP_REG(PX30_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
 211         .hact_st_end = VOP_REG(PX30_DSP_HACT_ST_END, 0x0fff0fff, 0),
 212         .vtotal_pw = VOP_REG(PX30_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
 213         .vact_st_end = VOP_REG(PX30_DSP_VACT_ST_END, 0x0fff0fff, 0),
 214 };
 215 
 216 static const struct vop_output px30_output = {
 217         .rgb_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0xf, 1),
 218         .mipi_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0xf, 25),
 219         .rgb_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 0),
 220         .mipi_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 24),
 221 };
 222 
 223 static const struct vop_scl_regs px30_win_scl = {
 224         .scale_yrgb_x = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
 225         .scale_yrgb_y = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
 226         .scale_cbcr_x = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
 227         .scale_cbcr_y = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
 228 };
 229 
 230 static const struct vop_win_phy px30_win0_data = {
 231         .scl = &px30_win_scl,
 232         .data_formats = formats_win_full,
 233         .nformats = ARRAY_SIZE(formats_win_full),
 234         .enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0),
 235         .format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1),
 236         .rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12),
 237         .act_info = VOP_REG(PX30_WIN0_ACT_INFO, 0xffffffff, 0),
 238         .dsp_info = VOP_REG(PX30_WIN0_DSP_INFO, 0xffffffff, 0),
 239         .dsp_st = VOP_REG(PX30_WIN0_DSP_ST, 0xffffffff, 0),
 240         .yrgb_mst = VOP_REG(PX30_WIN0_YRGB_MST0, 0xffffffff, 0),
 241         .uv_mst = VOP_REG(PX30_WIN0_CBR_MST0, 0xffffffff, 0),
 242         .yrgb_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 0),
 243         .uv_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 16),
 244 };
 245 
 246 static const struct vop_win_phy px30_win1_data = {
 247         .data_formats = formats_win_lite,
 248         .nformats = ARRAY_SIZE(formats_win_lite),
 249         .enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0),
 250         .format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4),
 251         .rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12),
 252         .dsp_info = VOP_REG(PX30_WIN1_DSP_INFO, 0xffffffff, 0),
 253         .dsp_st = VOP_REG(PX30_WIN1_DSP_ST, 0xffffffff, 0),
 254         .yrgb_mst = VOP_REG(PX30_WIN1_MST, 0xffffffff, 0),
 255         .yrgb_vir = VOP_REG(PX30_WIN1_VIR, 0x1fff, 0),
 256 };
 257 
 258 static const struct vop_win_phy px30_win2_data = {
 259         .data_formats = formats_win_lite,
 260         .nformats = ARRAY_SIZE(formats_win_lite),
 261         .gate = VOP_REG(PX30_WIN2_CTRL0, 0x1, 4),
 262         .enable = VOP_REG(PX30_WIN2_CTRL0, 0x1, 0),
 263         .format = VOP_REG(PX30_WIN2_CTRL0, 0x3, 5),
 264         .rb_swap = VOP_REG(PX30_WIN2_CTRL0, 0x1, 20),
 265         .dsp_info = VOP_REG(PX30_WIN2_DSP_INFO0, 0x0fff0fff, 0),
 266         .dsp_st = VOP_REG(PX30_WIN2_DSP_ST0, 0x1fff1fff, 0),
 267         .yrgb_mst = VOP_REG(PX30_WIN2_MST0, 0xffffffff, 0),
 268         .yrgb_vir = VOP_REG(PX30_WIN2_VIR0_1, 0x1fff, 0),
 269 };
 270 
 271 static const struct vop_win_data px30_vop_big_win_data[] = {
 272         { .base = 0x00, .phy = &px30_win0_data,
 273           .type = DRM_PLANE_TYPE_PRIMARY },
 274         { .base = 0x00, .phy = &px30_win1_data,
 275           .type = DRM_PLANE_TYPE_OVERLAY },
 276         { .base = 0x00, .phy = &px30_win2_data,
 277           .type = DRM_PLANE_TYPE_CURSOR },
 278 };
 279 
 280 static const struct vop_data px30_vop_big = {
 281         .intr = &px30_intr,
 282         .feature = VOP_FEATURE_INTERNAL_RGB,
 283         .common = &px30_common,
 284         .modeset = &px30_modeset,
 285         .output = &px30_output,
 286         .win = px30_vop_big_win_data,
 287         .win_size = ARRAY_SIZE(px30_vop_big_win_data),
 288 };
 289 
 290 static const struct vop_win_data px30_vop_lit_win_data[] = {
 291         { .base = 0x00, .phy = &px30_win1_data,
 292           .type = DRM_PLANE_TYPE_PRIMARY },
 293 };
 294 
 295 static const struct vop_data px30_vop_lit = {
 296         .intr = &px30_intr,
 297         .feature = VOP_FEATURE_INTERNAL_RGB,
 298         .common = &px30_common,
 299         .modeset = &px30_modeset,
 300         .output = &px30_output,
 301         .win = px30_vop_lit_win_data,
 302         .win_size = ARRAY_SIZE(px30_vop_lit_win_data),
 303 };
 304 
 305 static const struct vop_scl_regs rk3066_win_scl = {
 306         .scale_yrgb_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
 307         .scale_yrgb_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
 308         .scale_cbcr_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
 309         .scale_cbcr_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
 310 };
 311 
 312 static const struct vop_win_phy rk3066_win0_data = {
 313         .scl = &rk3066_win_scl,
 314         .data_formats = formats_win_full,
 315         .nformats = ARRAY_SIZE(formats_win_full),
 316         .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0),
 317         .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 4),
 318         .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 19),
 319         .act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0),
 320         .dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0),
 321         .dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0),
 322         .yrgb_mst = VOP_REG(RK3066_WIN0_YRGB_MST0, 0xffffffff, 0),
 323         .uv_mst = VOP_REG(RK3066_WIN0_CBR_MST0, 0xffffffff, 0),
 324         .yrgb_vir = VOP_REG(RK3066_WIN0_VIR, 0xffff, 0),
 325         .uv_vir = VOP_REG(RK3066_WIN0_VIR, 0x1fff, 16),
 326 };
 327 
 328 static const struct vop_win_phy rk3066_win1_data = {
 329         .scl = &rk3066_win_scl,
 330         .data_formats = formats_win_full,
 331         .nformats = ARRAY_SIZE(formats_win_full),
 332         .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1),
 333         .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 7),
 334         .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 23),
 335         .act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0),
 336         .dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0),
 337         .dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0),
 338         .yrgb_mst = VOP_REG(RK3066_WIN1_YRGB_MST, 0xffffffff, 0),
 339         .uv_mst = VOP_REG(RK3066_WIN1_CBR_MST, 0xffffffff, 0),
 340         .yrgb_vir = VOP_REG(RK3066_WIN1_VIR, 0xffff, 0),
 341         .uv_vir = VOP_REG(RK3066_WIN1_VIR, 0x1fff, 16),
 342 };
 343 
 344 static const struct vop_win_phy rk3066_win2_data = {
 345         .data_formats = formats_win_lite,
 346         .nformats = ARRAY_SIZE(formats_win_lite),
 347         .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2),
 348         .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 10),
 349         .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 27),
 350         .dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0),
 351         .dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0),
 352         .yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0),
 353         .yrgb_vir = VOP_REG(RK3066_WIN2_VIR, 0xffff, 0),
 354 };
 355 
 356 static const struct vop_modeset rk3066_modeset = {
 357         .htotal_pw = VOP_REG(RK3066_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
 358         .hact_st_end = VOP_REG(RK3066_DSP_HACT_ST_END, 0x1fff1fff, 0),
 359         .vtotal_pw = VOP_REG(RK3066_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
 360         .vact_st_end = VOP_REG(RK3066_DSP_VACT_ST_END, 0x1fff1fff, 0),
 361 };
 362 
 363 static const struct vop_output rk3066_output = {
 364         .pin_pol = VOP_REG(RK3066_DSP_CTRL0, 0x7, 4),
 365 };
 366 
 367 static const struct vop_common rk3066_common = {
 368         .standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1),
 369         .out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0),
 370         .cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0),
 371         .dither_down_en = VOP_REG(RK3066_DSP_CTRL0, 0x1, 11),
 372         .dither_down_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 10),
 373         .dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24),
 374 };
 375 
 376 static const struct vop_win_data rk3066_vop_win_data[] = {
 377         { .base = 0x00, .phy = &rk3066_win0_data,
 378           .type = DRM_PLANE_TYPE_PRIMARY },
 379         { .base = 0x00, .phy = &rk3066_win1_data,
 380           .type = DRM_PLANE_TYPE_OVERLAY },
 381         { .base = 0x00, .phy = &rk3066_win2_data,
 382           .type = DRM_PLANE_TYPE_CURSOR },
 383 };
 384 
 385 static const int rk3066_vop_intrs[] = {
 386         /*
 387          * hs_start interrupt fires at frame-start, so serves
 388          * the same purpose as dsp_hold in the driver.
 389          */
 390         DSP_HOLD_VALID_INTR,
 391         FS_INTR,
 392         LINE_FLAG_INTR,
 393         BUS_ERROR_INTR,
 394 };
 395 
 396 static const struct vop_intr rk3066_intr = {
 397         .intrs = rk3066_vop_intrs,
 398         .nintrs = ARRAY_SIZE(rk3066_vop_intrs),
 399         .line_flag_num[0] = VOP_REG(RK3066_INT_STATUS, 0xfff, 12),
 400         .status = VOP_REG(RK3066_INT_STATUS, 0xf, 0),
 401         .enable = VOP_REG(RK3066_INT_STATUS, 0xf, 4),
 402         .clear = VOP_REG(RK3066_INT_STATUS, 0xf, 8),
 403 };
 404 
 405 static const struct vop_data rk3066_vop = {
 406         .version = VOP_VERSION(2, 1),
 407         .intr = &rk3066_intr,
 408         .common = &rk3066_common,
 409         .modeset = &rk3066_modeset,
 410         .output = &rk3066_output,
 411         .win = rk3066_vop_win_data,
 412         .win_size = ARRAY_SIZE(rk3066_vop_win_data),
 413 };
 414 
 415 static const struct vop_scl_regs rk3188_win_scl = {
 416         .scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
 417         .scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
 418         .scale_cbcr_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
 419         .scale_cbcr_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
 420 };
 421 
 422 static const struct vop_win_phy rk3188_win0_data = {
 423         .scl = &rk3188_win_scl,
 424         .data_formats = formats_win_full,
 425         .nformats = ARRAY_SIZE(formats_win_full),
 426         .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0),
 427         .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3),
 428         .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15),
 429         .act_info = VOP_REG(RK3188_WIN0_ACT_INFO, 0x1fff1fff, 0),
 430         .dsp_info = VOP_REG(RK3188_WIN0_DSP_INFO, 0x0fff0fff, 0),
 431         .dsp_st = VOP_REG(RK3188_WIN0_DSP_ST, 0x1fff1fff, 0),
 432         .yrgb_mst = VOP_REG(RK3188_WIN0_YRGB_MST0, 0xffffffff, 0),
 433         .uv_mst = VOP_REG(RK3188_WIN0_CBR_MST0, 0xffffffff, 0),
 434         .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 0),
 435 };
 436 
 437 static const struct vop_win_phy rk3188_win1_data = {
 438         .data_formats = formats_win_lite,
 439         .nformats = ARRAY_SIZE(formats_win_lite),
 440         .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1),
 441         .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6),
 442         .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19),
 443         /* no act_info on window1 */
 444         .dsp_info = VOP_REG(RK3188_WIN1_DSP_INFO, 0x07ff07ff, 0),
 445         .dsp_st = VOP_REG(RK3188_WIN1_DSP_ST, 0x0fff0fff, 0),
 446         .yrgb_mst = VOP_REG(RK3188_WIN1_MST, 0xffffffff, 0),
 447         .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 16),
 448 };
 449 
 450 static const struct vop_modeset rk3188_modeset = {
 451         .htotal_pw = VOP_REG(RK3188_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
 452         .hact_st_end = VOP_REG(RK3188_DSP_HACT_ST_END, 0x0fff0fff, 0),
 453         .vtotal_pw = VOP_REG(RK3188_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
 454         .vact_st_end = VOP_REG(RK3188_DSP_VACT_ST_END, 0x0fff0fff, 0),
 455 };
 456 
 457 static const struct vop_output rk3188_output = {
 458         .pin_pol = VOP_REG(RK3188_DSP_CTRL0, 0xf, 4),
 459 };
 460 
 461 static const struct vop_common rk3188_common = {
 462         .gate_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 31),
 463         .standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30),
 464         .out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0),
 465         .cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0),
 466         .dither_down_sel = VOP_REG(RK3188_DSP_CTRL0, 0x1, 27),
 467         .dither_down_en = VOP_REG(RK3188_DSP_CTRL0, 0x1, 11),
 468         .dither_down_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 10),
 469         .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x3, 24),
 470 };
 471 
 472 static const struct vop_win_data rk3188_vop_win_data[] = {
 473         { .base = 0x00, .phy = &rk3188_win0_data,
 474           .type = DRM_PLANE_TYPE_PRIMARY },
 475         { .base = 0x00, .phy = &rk3188_win1_data,
 476           .type = DRM_PLANE_TYPE_CURSOR },
 477 };
 478 
 479 static const int rk3188_vop_intrs[] = {
 480         /*
 481          * hs_start interrupt fires at frame-start, so serves
 482          * the same purpose as dsp_hold in the driver.
 483          */
 484         DSP_HOLD_VALID_INTR,
 485         FS_INTR,
 486         LINE_FLAG_INTR,
 487         BUS_ERROR_INTR,
 488 };
 489 
 490 static const struct vop_intr rk3188_vop_intr = {
 491         .intrs = rk3188_vop_intrs,
 492         .nintrs = ARRAY_SIZE(rk3188_vop_intrs),
 493         .line_flag_num[0] = VOP_REG(RK3188_INT_STATUS, 0xfff, 12),
 494         .status = VOP_REG(RK3188_INT_STATUS, 0xf, 0),
 495         .enable = VOP_REG(RK3188_INT_STATUS, 0xf, 4),
 496         .clear = VOP_REG(RK3188_INT_STATUS, 0xf, 8),
 497 };
 498 
 499 static const struct vop_data rk3188_vop = {
 500         .intr = &rk3188_vop_intr,
 501         .common = &rk3188_common,
 502         .modeset = &rk3188_modeset,
 503         .output = &rk3188_output,
 504         .win = rk3188_vop_win_data,
 505         .win_size = ARRAY_SIZE(rk3188_vop_win_data),
 506         .feature = VOP_FEATURE_INTERNAL_RGB,
 507 };
 508 
 509 static const struct vop_scl_extension rk3288_win_full_scl_ext = {
 510         .cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31),
 511         .cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30),
 512         .cbcr_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 28),
 513         .cbcr_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 26),
 514         .cbcr_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 24),
 515         .yrgb_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 23),
 516         .yrgb_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 22),
 517         .yrgb_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 20),
 518         .yrgb_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 18),
 519         .yrgb_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 16),
 520         .line_load_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 15),
 521         .cbcr_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0x7, 12),
 522         .yrgb_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0xf, 8),
 523         .vsd_cbcr_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 7),
 524         .vsd_cbcr_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 6),
 525         .vsd_yrgb_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 5),
 526         .vsd_yrgb_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 4),
 527         .bic_coe_sel = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 2),
 528         .cbcr_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 1),
 529         .yrgb_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 0),
 530         .lb_mode = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 5),
 531 };
 532 
 533 static const struct vop_scl_regs rk3288_win_full_scl = {
 534         .ext = &rk3288_win_full_scl_ext,
 535         .scale_yrgb_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
 536         .scale_yrgb_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
 537         .scale_cbcr_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
 538         .scale_cbcr_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
 539 };
 540 
 541 static const struct vop_win_phy rk3288_win01_data = {
 542         .scl = &rk3288_win_full_scl,
 543         .data_formats = formats_win_full,
 544         .nformats = ARRAY_SIZE(formats_win_full),
 545         .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
 546         .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
 547         .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
 548         .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
 549         .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
 550         .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
 551         .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
 552         .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
 553         .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
 554         .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
 555         .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
 556         .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
 557         .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
 558 };
 559 
 560 static const struct vop_win_phy rk3288_win23_data = {
 561         .data_formats = formats_win_lite,
 562         .nformats = ARRAY_SIZE(formats_win_lite),
 563         .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
 564         .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
 565         .format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
 566         .rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
 567         .dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
 568         .dsp_st = VOP_REG(RK3288_WIN2_DSP_ST0, 0x1fff1fff, 0),
 569         .yrgb_mst = VOP_REG(RK3288_WIN2_MST0, 0xffffffff, 0),
 570         .yrgb_vir = VOP_REG(RK3288_WIN2_VIR0_1, 0x1fff, 0),
 571         .src_alpha_ctl = VOP_REG(RK3288_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
 572         .dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0),
 573 };
 574 
 575 static const struct vop_modeset rk3288_modeset = {
 576         .htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
 577         .hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
 578         .vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
 579         .vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
 580         .hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
 581         .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
 582 };
 583 
 584 static const struct vop_output rk3288_output = {
 585         .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
 586         .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
 587         .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
 588         .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
 589         .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
 590 };
 591 
 592 static const struct vop_common rk3288_common = {
 593         .standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22),
 594         .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
 595         .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
 596         .dither_down_sel = VOP_REG(RK3288_DSP_CTRL1, 0x1, 4),
 597         .dither_down_mode = VOP_REG(RK3288_DSP_CTRL1, 0x1, 3),
 598         .dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 2),
 599         .pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1),
 600         .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
 601         .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
 602         .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
 603         .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
 604         .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0),
 605 };
 606 
 607 /*
 608  * Note: rk3288 has a dedicated 'cursor' window, however, that window requires
 609  * special support to get alpha blending working.  For now, just use overlay
 610  * window 3 for the drm cursor.
 611  *
 612  */
 613 static const struct vop_win_data rk3288_vop_win_data[] = {
 614         { .base = 0x00, .phy = &rk3288_win01_data,
 615           .type = DRM_PLANE_TYPE_PRIMARY },
 616         { .base = 0x40, .phy = &rk3288_win01_data,
 617           .type = DRM_PLANE_TYPE_OVERLAY },
 618         { .base = 0x00, .phy = &rk3288_win23_data,
 619           .type = DRM_PLANE_TYPE_OVERLAY },
 620         { .base = 0x50, .phy = &rk3288_win23_data,
 621           .type = DRM_PLANE_TYPE_CURSOR },
 622 };
 623 
 624 static const int rk3288_vop_intrs[] = {
 625         DSP_HOLD_VALID_INTR,
 626         FS_INTR,
 627         LINE_FLAG_INTR,
 628         BUS_ERROR_INTR,
 629 };
 630 
 631 static const struct vop_intr rk3288_vop_intr = {
 632         .intrs = rk3288_vop_intrs,
 633         .nintrs = ARRAY_SIZE(rk3288_vop_intrs),
 634         .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
 635         .status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
 636         .enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
 637         .clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
 638 };
 639 
 640 static const struct vop_data rk3288_vop = {
 641         .version = VOP_VERSION(3, 1),
 642         .feature = VOP_FEATURE_OUTPUT_RGB10,
 643         .intr = &rk3288_vop_intr,
 644         .common = &rk3288_common,
 645         .modeset = &rk3288_modeset,
 646         .output = &rk3288_output,
 647         .win = rk3288_vop_win_data,
 648         .win_size = ARRAY_SIZE(rk3288_vop_win_data),
 649 };
 650 
 651 static const int rk3368_vop_intrs[] = {
 652         FS_INTR,
 653         0, 0,
 654         LINE_FLAG_INTR,
 655         0,
 656         BUS_ERROR_INTR,
 657         0, 0, 0, 0, 0, 0, 0,
 658         DSP_HOLD_VALID_INTR,
 659 };
 660 
 661 static const struct vop_intr rk3368_vop_intr = {
 662         .intrs = rk3368_vop_intrs,
 663         .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
 664         .line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0),
 665         .line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16),
 666         .status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0),
 667         .enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0),
 668         .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0),
 669 };
 670 
 671 static const struct vop_win_phy rk3368_win01_data = {
 672         .scl = &rk3288_win_full_scl,
 673         .data_formats = formats_win_full,
 674         .nformats = ARRAY_SIZE(formats_win_full),
 675         .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
 676         .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
 677         .rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
 678         .x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21),
 679         .y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22),
 680         .act_info = VOP_REG(RK3368_WIN0_ACT_INFO, 0x1fff1fff, 0),
 681         .dsp_info = VOP_REG(RK3368_WIN0_DSP_INFO, 0x0fff0fff, 0),
 682         .dsp_st = VOP_REG(RK3368_WIN0_DSP_ST, 0x1fff1fff, 0),
 683         .yrgb_mst = VOP_REG(RK3368_WIN0_YRGB_MST, 0xffffffff, 0),
 684         .uv_mst = VOP_REG(RK3368_WIN0_CBR_MST, 0xffffffff, 0),
 685         .yrgb_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 0),
 686         .uv_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 16),
 687         .src_alpha_ctl = VOP_REG(RK3368_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
 688         .dst_alpha_ctl = VOP_REG(RK3368_WIN0_DST_ALPHA_CTRL, 0xff, 0),
 689         .channel = VOP_REG(RK3368_WIN0_CTRL2, 0xff, 0),
 690 };
 691 
 692 static const struct vop_win_phy rk3368_win23_data = {
 693         .data_formats = formats_win_lite,
 694         .nformats = ARRAY_SIZE(formats_win_lite),
 695         .gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
 696         .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
 697         .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
 698         .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
 699         .y_mir_en = VOP_REG(RK3368_WIN2_CTRL1, 0x1, 15),
 700         .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
 701         .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
 702         .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
 703         .yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
 704         .src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
 705         .dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0),
 706 };
 707 
 708 static const struct vop_win_data rk3368_vop_win_data[] = {
 709         { .base = 0x00, .phy = &rk3368_win01_data,
 710           .type = DRM_PLANE_TYPE_PRIMARY },
 711         { .base = 0x40, .phy = &rk3368_win01_data,
 712           .type = DRM_PLANE_TYPE_OVERLAY },
 713         { .base = 0x00, .phy = &rk3368_win23_data,
 714           .type = DRM_PLANE_TYPE_OVERLAY },
 715         { .base = 0x50, .phy = &rk3368_win23_data,
 716           .type = DRM_PLANE_TYPE_CURSOR },
 717 };
 718 
 719 static const struct vop_output rk3368_output = {
 720         .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16),
 721         .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20),
 722         .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24),
 723         .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28),
 724         .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
 725         .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
 726         .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
 727         .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
 728 };
 729 
 730 static const struct vop_misc rk3368_misc = {
 731         .global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11),
 732 };
 733 
 734 static const struct vop_data rk3368_vop = {
 735         .version = VOP_VERSION(3, 2),
 736         .intr = &rk3368_vop_intr,
 737         .common = &rk3288_common,
 738         .modeset = &rk3288_modeset,
 739         .output = &rk3368_output,
 740         .misc = &rk3368_misc,
 741         .win = rk3368_vop_win_data,
 742         .win_size = ARRAY_SIZE(rk3368_vop_win_data),
 743 };
 744 
 745 static const struct vop_intr rk3366_vop_intr = {
 746         .intrs = rk3368_vop_intrs,
 747         .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
 748         .line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0),
 749         .line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16),
 750         .status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0),
 751         .enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0),
 752         .clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0),
 753 };
 754 
 755 static const struct vop_data rk3366_vop = {
 756         .version = VOP_VERSION(3, 4),
 757         .intr = &rk3366_vop_intr,
 758         .common = &rk3288_common,
 759         .modeset = &rk3288_modeset,
 760         .output = &rk3368_output,
 761         .misc = &rk3368_misc,
 762         .win = rk3368_vop_win_data,
 763         .win_size = ARRAY_SIZE(rk3368_vop_win_data),
 764 };
 765 
 766 static const struct vop_output rk3399_output = {
 767         .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
 768         .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16),
 769         .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20),
 770         .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24),
 771         .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28),
 772         .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
 773         .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
 774         .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
 775         .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
 776         .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
 777         .mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3),
 778 };
 779 
 780 static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = {
 781         .y2r_coefficients = {
 782                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0),
 783                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 16),
 784                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 0),
 785                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 16),
 786                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 0),
 787                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 16),
 788                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 0),
 789                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 16),
 790                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 16, 0xffff, 0),
 791                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 20, 0xffffffff, 0),
 792                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 24, 0xffffffff, 0),
 793                 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 28, 0xffffffff, 0),
 794         },
 795 };
 796 
 797 static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win23_data = { };
 798 
 799 static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
 800         { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
 801           .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1) },
 802         { .base = 0x60, .phy = &rk3399_yuv2yuv_win01_data,
 803           .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9) },
 804         { .base = 0xC0, .phy = &rk3399_yuv2yuv_win23_data },
 805         { .base = 0x120, .phy = &rk3399_yuv2yuv_win23_data },
 806 };
 807 
 808 static const struct vop_data rk3399_vop_big = {
 809         .version = VOP_VERSION(3, 5),
 810         .feature = VOP_FEATURE_OUTPUT_RGB10,
 811         .intr = &rk3366_vop_intr,
 812         .common = &rk3288_common,
 813         .modeset = &rk3288_modeset,
 814         .output = &rk3399_output,
 815         .misc = &rk3368_misc,
 816         .win = rk3368_vop_win_data,
 817         .win_size = ARRAY_SIZE(rk3368_vop_win_data),
 818         .win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data,
 819 };
 820 
 821 static const struct vop_win_data rk3399_vop_lit_win_data[] = {
 822         { .base = 0x00, .phy = &rk3368_win01_data,
 823           .type = DRM_PLANE_TYPE_PRIMARY },
 824         { .base = 0x00, .phy = &rk3368_win23_data,
 825           .type = DRM_PLANE_TYPE_CURSOR},
 826 };
 827 
 828 static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = {
 829         { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
 830           .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1)},
 831         { .base = 0x60, .phy = &rk3399_yuv2yuv_win23_data },
 832 };
 833 
 834 static const struct vop_data rk3399_vop_lit = {
 835         .version = VOP_VERSION(3, 6),
 836         .intr = &rk3366_vop_intr,
 837         .common = &rk3288_common,
 838         .modeset = &rk3288_modeset,
 839         .output = &rk3399_output,
 840         .misc = &rk3368_misc,
 841         .win = rk3399_vop_lit_win_data,
 842         .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
 843         .win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data,
 844 };
 845 
 846 static const struct vop_win_data rk3228_vop_win_data[] = {
 847         { .base = 0x00, .phy = &rk3288_win01_data,
 848           .type = DRM_PLANE_TYPE_PRIMARY },
 849         { .base = 0x40, .phy = &rk3288_win01_data,
 850           .type = DRM_PLANE_TYPE_CURSOR },
 851 };
 852 
 853 static const struct vop_data rk3228_vop = {
 854         .version = VOP_VERSION(3, 7),
 855         .feature = VOP_FEATURE_OUTPUT_RGB10,
 856         .intr = &rk3366_vop_intr,
 857         .common = &rk3288_common,
 858         .modeset = &rk3288_modeset,
 859         .output = &rk3399_output,
 860         .misc = &rk3368_misc,
 861         .win = rk3228_vop_win_data,
 862         .win_size = ARRAY_SIZE(rk3228_vop_win_data),
 863 };
 864 
 865 static const struct vop_modeset rk3328_modeset = {
 866         .htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
 867         .hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0),
 868         .vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
 869         .vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0),
 870         .hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
 871         .vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
 872 };
 873 
 874 static const struct vop_output rk3328_output = {
 875         .rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12),
 876         .hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13),
 877         .edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14),
 878         .mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15),
 879         .rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 16),
 880         .hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 20),
 881         .edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 24),
 882         .mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 28),
 883 };
 884 
 885 static const struct vop_misc rk3328_misc = {
 886         .global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11),
 887 };
 888 
 889 static const struct vop_common rk3328_common = {
 890         .standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22),
 891         .dither_down_sel = VOP_REG(RK3328_DSP_CTRL1, 0x1, 4),
 892         .dither_down_mode = VOP_REG(RK3328_DSP_CTRL1, 0x1, 3),
 893         .dither_down_en = VOP_REG(RK3328_DSP_CTRL1, 0x1, 2),
 894         .pre_dither_down = VOP_REG(RK3328_DSP_CTRL1, 0x1, 1),
 895         .dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6),
 896         .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
 897         .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
 898         .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0),
 899 };
 900 
 901 static const struct vop_intr rk3328_vop_intr = {
 902         .intrs = rk3368_vop_intrs,
 903         .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
 904         .line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0),
 905         .line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16),
 906         .status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0),
 907         .enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0),
 908         .clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0),
 909 };
 910 
 911 static const struct vop_win_data rk3328_vop_win_data[] = {
 912         { .base = 0xd0, .phy = &rk3368_win01_data,
 913           .type = DRM_PLANE_TYPE_PRIMARY },
 914         { .base = 0x1d0, .phy = &rk3368_win01_data,
 915           .type = DRM_PLANE_TYPE_OVERLAY },
 916         { .base = 0x2d0, .phy = &rk3368_win01_data,
 917           .type = DRM_PLANE_TYPE_CURSOR },
 918 };
 919 
 920 static const struct vop_data rk3328_vop = {
 921         .version = VOP_VERSION(3, 8),
 922         .feature = VOP_FEATURE_OUTPUT_RGB10,
 923         .intr = &rk3328_vop_intr,
 924         .common = &rk3328_common,
 925         .modeset = &rk3328_modeset,
 926         .output = &rk3328_output,
 927         .misc = &rk3328_misc,
 928         .win = rk3328_vop_win_data,
 929         .win_size = ARRAY_SIZE(rk3328_vop_win_data),
 930 };
 931 
 932 static const struct of_device_id vop_driver_dt_match[] = {
 933         { .compatible = "rockchip,rk3036-vop",
 934           .data = &rk3036_vop },
 935         { .compatible = "rockchip,rk3126-vop",
 936           .data = &rk3126_vop },
 937         { .compatible = "rockchip,px30-vop-big",
 938           .data = &px30_vop_big },
 939         { .compatible = "rockchip,px30-vop-lit",
 940           .data = &px30_vop_lit },
 941         { .compatible = "rockchip,rk3066-vop",
 942           .data = &rk3066_vop },
 943         { .compatible = "rockchip,rk3188-vop",
 944           .data = &rk3188_vop },
 945         { .compatible = "rockchip,rk3288-vop",
 946           .data = &rk3288_vop },
 947         { .compatible = "rockchip,rk3368-vop",
 948           .data = &rk3368_vop },
 949         { .compatible = "rockchip,rk3366-vop",
 950           .data = &rk3366_vop },
 951         { .compatible = "rockchip,rk3399-vop-big",
 952           .data = &rk3399_vop_big },
 953         { .compatible = "rockchip,rk3399-vop-lit",
 954           .data = &rk3399_vop_lit },
 955         { .compatible = "rockchip,rk3228-vop",
 956           .data = &rk3228_vop },
 957         { .compatible = "rockchip,rk3328-vop",
 958           .data = &rk3328_vop },
 959         {},
 960 };
 961 MODULE_DEVICE_TABLE(of, vop_driver_dt_match);
 962 
 963 static int vop_probe(struct platform_device *pdev)
 964 {
 965         struct device *dev = &pdev->dev;
 966 
 967         if (!dev->of_node) {
 968                 DRM_DEV_ERROR(dev, "can't find vop devices\n");
 969                 return -ENODEV;
 970         }
 971 
 972         return component_add(dev, &vop_component_ops);
 973 }
 974 
 975 static int vop_remove(struct platform_device *pdev)
 976 {
 977         component_del(&pdev->dev, &vop_component_ops);
 978 
 979         return 0;
 980 }
 981 
 982 struct platform_driver vop_platform_driver = {
 983         .probe = vop_probe,
 984         .remove = vop_remove,
 985         .driver = {
 986                 .name = "rockchip-vop",
 987                 .of_match_table = of_match_ptr(vop_driver_dt_match),
 988         },
 989 };

/* [<][>][^][v][top][bottom][index][help] */