cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rockchip_vop_reg.c (41738B)


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