0001
0002
0003
0004
0005
0006
0007 #include <linux/component.h>
0008 #include <linux/mod_devicetable.h>
0009 #include <linux/module.h>
0010 #include <linux/of.h>
0011 #include <linux/platform_device.h>
0012
0013 #include <drm/drm_fourcc.h>
0014 #include <drm/drm_plane.h>
0015 #include <drm/drm_print.h>
0016
0017 #include "rockchip_drm_vop.h"
0018 #include "rockchip_vop_reg.h"
0019 #include "rockchip_drm_drv.h"
0020
0021 #define _VOP_REG(off, _mask, _shift, _write_mask, _relaxed) \
0022 { \
0023 .offset = off, \
0024 .mask = _mask, \
0025 .shift = _shift, \
0026 .write_mask = _write_mask, \
0027 .relaxed = _relaxed, \
0028 }
0029
0030 #define VOP_REG(off, _mask, _shift) \
0031 _VOP_REG(off, _mask, _shift, false, true)
0032
0033 #define VOP_REG_SYNC(off, _mask, _shift) \
0034 _VOP_REG(off, _mask, _shift, false, false)
0035
0036 #define VOP_REG_MASK_SYNC(off, _mask, _shift) \
0037 _VOP_REG(off, _mask, _shift, true, false)
0038
0039 static const uint32_t formats_win_full[] = {
0040 DRM_FORMAT_XRGB8888,
0041 DRM_FORMAT_ARGB8888,
0042 DRM_FORMAT_XBGR8888,
0043 DRM_FORMAT_ABGR8888,
0044 DRM_FORMAT_RGB888,
0045 DRM_FORMAT_BGR888,
0046 DRM_FORMAT_RGB565,
0047 DRM_FORMAT_BGR565,
0048 DRM_FORMAT_NV12,
0049 DRM_FORMAT_NV21,
0050 DRM_FORMAT_NV16,
0051 DRM_FORMAT_NV61,
0052 DRM_FORMAT_NV24,
0053 DRM_FORMAT_NV42,
0054 };
0055
0056 static const uint64_t format_modifiers_win_full[] = {
0057 DRM_FORMAT_MOD_LINEAR,
0058 DRM_FORMAT_MOD_INVALID,
0059 };
0060
0061 static const uint64_t format_modifiers_win_full_afbc[] = {
0062 ROCKCHIP_AFBC_MOD,
0063 DRM_FORMAT_MOD_LINEAR,
0064 DRM_FORMAT_MOD_INVALID,
0065 };
0066
0067 static const uint32_t formats_win_lite[] = {
0068 DRM_FORMAT_XRGB8888,
0069 DRM_FORMAT_ARGB8888,
0070 DRM_FORMAT_XBGR8888,
0071 DRM_FORMAT_ABGR8888,
0072 DRM_FORMAT_RGB888,
0073 DRM_FORMAT_BGR888,
0074 DRM_FORMAT_RGB565,
0075 DRM_FORMAT_BGR565,
0076 };
0077
0078 static const uint64_t format_modifiers_win_lite[] = {
0079 DRM_FORMAT_MOD_LINEAR,
0080 DRM_FORMAT_MOD_INVALID,
0081 };
0082
0083 static const struct vop_scl_regs rk3036_win0_scl = {
0084 .scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
0085 .scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
0086 .scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
0087 .scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
0088 };
0089
0090 static const struct vop_scl_regs rk3036_win1_scl = {
0091 .scale_yrgb_x = VOP_REG(RK3036_WIN1_SCL_FACTOR_YRGB, 0xffff, 0x0),
0092 .scale_yrgb_y = VOP_REG(RK3036_WIN1_SCL_FACTOR_YRGB, 0xffff, 16),
0093 };
0094
0095 static const struct vop_win_phy rk3036_win0_data = {
0096 .scl = &rk3036_win0_scl,
0097 .data_formats = formats_win_full,
0098 .nformats = ARRAY_SIZE(formats_win_full),
0099 .format_modifiers = format_modifiers_win_full,
0100 .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0),
0101 .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3),
0102 .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15),
0103 .act_info = VOP_REG(RK3036_WIN0_ACT_INFO, 0x1fff1fff, 0),
0104 .dsp_info = VOP_REG(RK3036_WIN0_DSP_INFO, 0x0fff0fff, 0),
0105 .dsp_st = VOP_REG(RK3036_WIN0_DSP_ST, 0x1fff1fff, 0),
0106 .yrgb_mst = VOP_REG(RK3036_WIN0_YRGB_MST, 0xffffffff, 0),
0107 .uv_mst = VOP_REG(RK3036_WIN0_CBR_MST, 0xffffffff, 0),
0108 .yrgb_vir = VOP_REG(RK3036_WIN0_VIR, 0xffff, 0),
0109 .uv_vir = VOP_REG(RK3036_WIN0_VIR, 0x1fff, 16),
0110 .alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 18),
0111 .alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 0),
0112 .alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29),
0113 };
0114
0115 static const struct vop_win_phy rk3036_win1_data = {
0116 .scl = &rk3036_win1_scl,
0117 .data_formats = formats_win_lite,
0118 .nformats = ARRAY_SIZE(formats_win_lite),
0119 .format_modifiers = format_modifiers_win_lite,
0120 .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
0121 .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
0122 .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
0123 .act_info = VOP_REG(RK3036_WIN1_ACT_INFO, 0x1fff1fff, 0),
0124 .dsp_info = VOP_REG(RK3036_WIN1_DSP_INFO, 0x0fff0fff, 0),
0125 .dsp_st = VOP_REG(RK3036_WIN1_DSP_ST, 0x1fff1fff, 0),
0126 .yrgb_mst = VOP_REG(RK3036_WIN1_MST, 0xffffffff, 0),
0127 .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
0128 .alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 19),
0129 .alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 1),
0130 .alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29),
0131 };
0132
0133 static const struct vop_win_data rk3036_vop_win_data[] = {
0134 { .base = 0x00, .phy = &rk3036_win0_data,
0135 .type = DRM_PLANE_TYPE_PRIMARY },
0136 { .base = 0x00, .phy = &rk3036_win1_data,
0137 .type = DRM_PLANE_TYPE_CURSOR },
0138 };
0139
0140 static const int rk3036_vop_intrs[] = {
0141 DSP_HOLD_VALID_INTR,
0142 FS_INTR,
0143 LINE_FLAG_INTR,
0144 BUS_ERROR_INTR,
0145 };
0146
0147 static const struct vop_intr rk3036_intr = {
0148 .intrs = rk3036_vop_intrs,
0149 .nintrs = ARRAY_SIZE(rk3036_vop_intrs),
0150 .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
0151 .status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0),
0152 .enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4),
0153 .clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8),
0154 };
0155
0156 static const struct vop_modeset rk3036_modeset = {
0157 .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
0158 .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
0159 .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
0160 .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
0161 };
0162
0163 static const struct vop_output rk3036_output = {
0164 .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
0165 };
0166
0167 static const struct vop_common rk3036_common = {
0168 .standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30),
0169 .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
0170 .dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24),
0171 .dither_down_sel = VOP_REG(RK3036_DSP_CTRL0, 0x1, 27),
0172 .dither_down_en = VOP_REG(RK3036_DSP_CTRL0, 0x1, 11),
0173 .dither_down_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 10),
0174 .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0),
0175 };
0176
0177 static const struct vop_data rk3036_vop = {
0178 .intr = &rk3036_intr,
0179 .common = &rk3036_common,
0180 .modeset = &rk3036_modeset,
0181 .output = &rk3036_output,
0182 .win = rk3036_vop_win_data,
0183 .win_size = ARRAY_SIZE(rk3036_vop_win_data),
0184 };
0185
0186 static const struct vop_win_phy rk3126_win1_data = {
0187 .data_formats = formats_win_lite,
0188 .nformats = ARRAY_SIZE(formats_win_lite),
0189 .format_modifiers = format_modifiers_win_lite,
0190 .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
0191 .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
0192 .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
0193 .dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0),
0194 .dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0),
0195 .yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0xffffffff, 0),
0196 .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
0197 .alpha_mode = VOP_REG(RK3036_DSP_CTRL0, 0x1, 19),
0198 .alpha_en = VOP_REG(RK3036_ALPHA_CTRL, 0x1, 1),
0199 .alpha_pre_mul = VOP_REG(RK3036_DSP_CTRL0, 0x1, 29),
0200 };
0201
0202 static const struct vop_win_data rk3126_vop_win_data[] = {
0203 { .base = 0x00, .phy = &rk3036_win0_data,
0204 .type = DRM_PLANE_TYPE_PRIMARY },
0205 { .base = 0x00, .phy = &rk3126_win1_data,
0206 .type = DRM_PLANE_TYPE_CURSOR },
0207 };
0208
0209 static const struct vop_data rk3126_vop = {
0210 .intr = &rk3036_intr,
0211 .common = &rk3036_common,
0212 .modeset = &rk3036_modeset,
0213 .output = &rk3036_output,
0214 .win = rk3126_vop_win_data,
0215 .win_size = ARRAY_SIZE(rk3126_vop_win_data),
0216 };
0217
0218 static const int px30_vop_intrs[] = {
0219 FS_INTR,
0220 0, 0,
0221 LINE_FLAG_INTR,
0222 0,
0223 BUS_ERROR_INTR,
0224 0, 0,
0225 DSP_HOLD_VALID_INTR,
0226 };
0227
0228 static const struct vop_intr px30_intr = {
0229 .intrs = px30_vop_intrs,
0230 .nintrs = ARRAY_SIZE(px30_vop_intrs),
0231 .line_flag_num[0] = VOP_REG(PX30_LINE_FLAG, 0xfff, 0),
0232 .status = VOP_REG_MASK_SYNC(PX30_INTR_STATUS, 0xffff, 0),
0233 .enable = VOP_REG_MASK_SYNC(PX30_INTR_EN, 0xffff, 0),
0234 .clear = VOP_REG_MASK_SYNC(PX30_INTR_CLEAR, 0xffff, 0),
0235 };
0236
0237 static const struct vop_common px30_common = {
0238 .standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1),
0239 .out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16),
0240 .dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14),
0241 .dither_down_en = VOP_REG(PX30_DSP_CTRL2, 0x1, 8),
0242 .dither_down_sel = VOP_REG(PX30_DSP_CTRL2, 0x1, 7),
0243 .dither_down_mode = VOP_REG(PX30_DSP_CTRL2, 0x1, 6),
0244 .cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0),
0245 };
0246
0247 static const struct vop_modeset px30_modeset = {
0248 .htotal_pw = VOP_REG(PX30_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
0249 .hact_st_end = VOP_REG(PX30_DSP_HACT_ST_END, 0x0fff0fff, 0),
0250 .vtotal_pw = VOP_REG(PX30_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
0251 .vact_st_end = VOP_REG(PX30_DSP_VACT_ST_END, 0x0fff0fff, 0),
0252 };
0253
0254 static const struct vop_output px30_output = {
0255 .rgb_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 1),
0256 .rgb_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 2),
0257 .rgb_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 0),
0258 .mipi_dclk_pol = VOP_REG(PX30_DSP_CTRL0, 0x1, 25),
0259 .mipi_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0x7, 26),
0260 .mipi_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 24),
0261 };
0262
0263 static const struct vop_scl_regs px30_win_scl = {
0264 .scale_yrgb_x = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
0265 .scale_yrgb_y = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
0266 .scale_cbcr_x = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
0267 .scale_cbcr_y = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
0268 };
0269
0270 static const struct vop_win_phy px30_win0_data = {
0271 .scl = &px30_win_scl,
0272 .data_formats = formats_win_full,
0273 .nformats = ARRAY_SIZE(formats_win_full),
0274 .format_modifiers = format_modifiers_win_full,
0275 .enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0),
0276 .format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1),
0277 .rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12),
0278 .uv_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 15),
0279 .act_info = VOP_REG(PX30_WIN0_ACT_INFO, 0xffffffff, 0),
0280 .dsp_info = VOP_REG(PX30_WIN0_DSP_INFO, 0xffffffff, 0),
0281 .dsp_st = VOP_REG(PX30_WIN0_DSP_ST, 0xffffffff, 0),
0282 .yrgb_mst = VOP_REG(PX30_WIN0_YRGB_MST0, 0xffffffff, 0),
0283 .uv_mst = VOP_REG(PX30_WIN0_CBR_MST0, 0xffffffff, 0),
0284 .yrgb_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 0),
0285 .uv_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 16),
0286 .alpha_pre_mul = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 2),
0287 .alpha_mode = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 1),
0288 .alpha_en = VOP_REG(PX30_WIN0_ALPHA_CTRL, 0x1, 0),
0289 };
0290
0291 static const struct vop_win_phy px30_win1_data = {
0292 .data_formats = formats_win_lite,
0293 .nformats = ARRAY_SIZE(formats_win_lite),
0294 .format_modifiers = format_modifiers_win_lite,
0295 .enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0),
0296 .format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4),
0297 .rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12),
0298 .uv_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 15),
0299 .dsp_info = VOP_REG(PX30_WIN1_DSP_INFO, 0xffffffff, 0),
0300 .dsp_st = VOP_REG(PX30_WIN1_DSP_ST, 0xffffffff, 0),
0301 .yrgb_mst = VOP_REG(PX30_WIN1_MST, 0xffffffff, 0),
0302 .yrgb_vir = VOP_REG(PX30_WIN1_VIR, 0x1fff, 0),
0303 .alpha_pre_mul = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 2),
0304 .alpha_mode = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 1),
0305 .alpha_en = VOP_REG(PX30_WIN1_ALPHA_CTRL, 0x1, 0),
0306 };
0307
0308 static const struct vop_win_phy px30_win2_data = {
0309 .data_formats = formats_win_lite,
0310 .nformats = ARRAY_SIZE(formats_win_lite),
0311 .format_modifiers = format_modifiers_win_lite,
0312 .gate = VOP_REG(PX30_WIN2_CTRL0, 0x1, 4),
0313 .enable = VOP_REG(PX30_WIN2_CTRL0, 0x1, 0),
0314 .format = VOP_REG(PX30_WIN2_CTRL0, 0x3, 5),
0315 .rb_swap = VOP_REG(PX30_WIN2_CTRL0, 0x1, 20),
0316 .dsp_info = VOP_REG(PX30_WIN2_DSP_INFO0, 0x0fff0fff, 0),
0317 .dsp_st = VOP_REG(PX30_WIN2_DSP_ST0, 0x1fff1fff, 0),
0318 .yrgb_mst = VOP_REG(PX30_WIN2_MST0, 0xffffffff, 0),
0319 .yrgb_vir = VOP_REG(PX30_WIN2_VIR0_1, 0x1fff, 0),
0320 .alpha_pre_mul = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 2),
0321 .alpha_mode = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 1),
0322 .alpha_en = VOP_REG(PX30_WIN2_ALPHA_CTRL, 0x1, 0),
0323 };
0324
0325 static const struct vop_win_data px30_vop_big_win_data[] = {
0326 { .base = 0x00, .phy = &px30_win0_data,
0327 .type = DRM_PLANE_TYPE_PRIMARY },
0328 { .base = 0x00, .phy = &px30_win1_data,
0329 .type = DRM_PLANE_TYPE_OVERLAY },
0330 { .base = 0x00, .phy = &px30_win2_data,
0331 .type = DRM_PLANE_TYPE_CURSOR },
0332 };
0333
0334 static const struct vop_data px30_vop_big = {
0335 .version = VOP_VERSION(2, 6),
0336 .intr = &px30_intr,
0337 .feature = VOP_FEATURE_INTERNAL_RGB,
0338 .common = &px30_common,
0339 .modeset = &px30_modeset,
0340 .output = &px30_output,
0341 .win = px30_vop_big_win_data,
0342 .win_size = ARRAY_SIZE(px30_vop_big_win_data),
0343 };
0344
0345 static const struct vop_win_data px30_vop_lit_win_data[] = {
0346 { .base = 0x00, .phy = &px30_win1_data,
0347 .type = DRM_PLANE_TYPE_PRIMARY },
0348 };
0349
0350 static const struct vop_data px30_vop_lit = {
0351 .version = VOP_VERSION(2, 5),
0352 .intr = &px30_intr,
0353 .feature = VOP_FEATURE_INTERNAL_RGB,
0354 .common = &px30_common,
0355 .modeset = &px30_modeset,
0356 .output = &px30_output,
0357 .win = px30_vop_lit_win_data,
0358 .win_size = ARRAY_SIZE(px30_vop_lit_win_data),
0359 };
0360
0361 static const struct vop_scl_regs rk3066_win_scl = {
0362 .scale_yrgb_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
0363 .scale_yrgb_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
0364 .scale_cbcr_x = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
0365 .scale_cbcr_y = VOP_REG(RK3066_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
0366 };
0367
0368 static const struct vop_win_phy rk3066_win0_data = {
0369 .scl = &rk3066_win_scl,
0370 .data_formats = formats_win_full,
0371 .nformats = ARRAY_SIZE(formats_win_full),
0372 .format_modifiers = format_modifiers_win_full,
0373 .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0),
0374 .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 4),
0375 .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 19),
0376 .uv_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 22),
0377 .act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0),
0378 .dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0),
0379 .dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0),
0380 .yrgb_mst = VOP_REG(RK3066_WIN0_YRGB_MST0, 0xffffffff, 0),
0381 .uv_mst = VOP_REG(RK3066_WIN0_CBR_MST0, 0xffffffff, 0),
0382 .yrgb_vir = VOP_REG(RK3066_WIN0_VIR, 0xffff, 0),
0383 .uv_vir = VOP_REG(RK3066_WIN0_VIR, 0x1fff, 16),
0384 .alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 21),
0385 .alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 0),
0386 };
0387
0388 static const struct vop_win_phy rk3066_win1_data = {
0389 .data_formats = formats_win_full,
0390 .nformats = ARRAY_SIZE(formats_win_full),
0391 .format_modifiers = format_modifiers_win_full,
0392 .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1),
0393 .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 7),
0394 .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 23),
0395 .uv_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 26),
0396 .act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0),
0397 .dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0),
0398 .dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0),
0399 .yrgb_mst = VOP_REG(RK3066_WIN1_YRGB_MST, 0xffffffff, 0),
0400 .uv_mst = VOP_REG(RK3066_WIN1_CBR_MST, 0xffffffff, 0),
0401 .yrgb_vir = VOP_REG(RK3066_WIN1_VIR, 0xffff, 0),
0402 .uv_vir = VOP_REG(RK3066_WIN1_VIR, 0x1fff, 16),
0403 .alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 22),
0404 .alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 1),
0405 };
0406
0407 static const struct vop_win_phy rk3066_win2_data = {
0408 .data_formats = formats_win_lite,
0409 .nformats = ARRAY_SIZE(formats_win_lite),
0410 .format_modifiers = format_modifiers_win_lite,
0411 .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2),
0412 .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 10),
0413 .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 27),
0414 .dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0),
0415 .dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0),
0416 .yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0),
0417 .yrgb_vir = VOP_REG(RK3066_WIN2_VIR, 0xffff, 0),
0418 .alpha_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 23),
0419 .alpha_en = VOP_REG(RK3066_BLEND_CTRL, 0x1, 2),
0420 };
0421
0422 static const struct vop_modeset rk3066_modeset = {
0423 .htotal_pw = VOP_REG(RK3066_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
0424 .hact_st_end = VOP_REG(RK3066_DSP_HACT_ST_END, 0x1fff1fff, 0),
0425 .vtotal_pw = VOP_REG(RK3066_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
0426 .vact_st_end = VOP_REG(RK3066_DSP_VACT_ST_END, 0x1fff1fff, 0),
0427 };
0428
0429 static const struct vop_output rk3066_output = {
0430 .pin_pol = VOP_REG(RK3066_DSP_CTRL0, 0x7, 4),
0431 };
0432
0433 static const struct vop_common rk3066_common = {
0434 .standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1),
0435 .out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0),
0436 .cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0),
0437 .dither_down_en = VOP_REG(RK3066_DSP_CTRL0, 0x1, 11),
0438 .dither_down_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 10),
0439 .dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24),
0440 .dither_up = VOP_REG(RK3066_DSP_CTRL0, 0x1, 9),
0441 .dsp_lut_en = VOP_REG(RK3066_SYS_CTRL1, 0x1, 31),
0442 .data_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 25),
0443 };
0444
0445 static const struct vop_win_data rk3066_vop_win_data[] = {
0446 { .base = 0x00, .phy = &rk3066_win0_data,
0447 .type = DRM_PLANE_TYPE_PRIMARY },
0448 { .base = 0x00, .phy = &rk3066_win1_data,
0449 .type = DRM_PLANE_TYPE_OVERLAY },
0450 { .base = 0x00, .phy = &rk3066_win2_data,
0451 .type = DRM_PLANE_TYPE_CURSOR },
0452 };
0453
0454 static const int rk3066_vop_intrs[] = {
0455
0456
0457
0458
0459 DSP_HOLD_VALID_INTR,
0460 FS_INTR,
0461 LINE_FLAG_INTR,
0462 BUS_ERROR_INTR,
0463 };
0464
0465 static const struct vop_intr rk3066_intr = {
0466 .intrs = rk3066_vop_intrs,
0467 .nintrs = ARRAY_SIZE(rk3066_vop_intrs),
0468 .line_flag_num[0] = VOP_REG(RK3066_INT_STATUS, 0xfff, 12),
0469 .status = VOP_REG(RK3066_INT_STATUS, 0xf, 0),
0470 .enable = VOP_REG(RK3066_INT_STATUS, 0xf, 4),
0471 .clear = VOP_REG(RK3066_INT_STATUS, 0xf, 8),
0472 };
0473
0474 static const struct vop_data rk3066_vop = {
0475 .version = VOP_VERSION(2, 1),
0476 .intr = &rk3066_intr,
0477 .common = &rk3066_common,
0478 .modeset = &rk3066_modeset,
0479 .output = &rk3066_output,
0480 .win = rk3066_vop_win_data,
0481 .win_size = ARRAY_SIZE(rk3066_vop_win_data),
0482 };
0483
0484 static const struct vop_scl_regs rk3188_win_scl = {
0485 .scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
0486 .scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
0487 .scale_cbcr_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
0488 .scale_cbcr_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
0489 };
0490
0491 static const struct vop_win_phy rk3188_win0_data = {
0492 .scl = &rk3188_win_scl,
0493 .data_formats = formats_win_full,
0494 .nformats = ARRAY_SIZE(formats_win_full),
0495 .format_modifiers = format_modifiers_win_full,
0496 .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0),
0497 .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3),
0498 .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15),
0499 .uv_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 18),
0500 .act_info = VOP_REG(RK3188_WIN0_ACT_INFO, 0x1fff1fff, 0),
0501 .dsp_info = VOP_REG(RK3188_WIN0_DSP_INFO, 0x0fff0fff, 0),
0502 .dsp_st = VOP_REG(RK3188_WIN0_DSP_ST, 0x1fff1fff, 0),
0503 .yrgb_mst = VOP_REG(RK3188_WIN0_YRGB_MST0, 0xffffffff, 0),
0504 .uv_mst = VOP_REG(RK3188_WIN0_CBR_MST0, 0xffffffff, 0),
0505 .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 0),
0506 .alpha_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 18),
0507 .alpha_en = VOP_REG(RK3188_ALPHA_CTRL, 0x1, 0),
0508 .alpha_pre_mul = VOP_REG(RK3188_DSP_CTRL0, 0x1, 29),
0509 };
0510
0511 static const struct vop_win_phy rk3188_win1_data = {
0512 .data_formats = formats_win_lite,
0513 .nformats = ARRAY_SIZE(formats_win_lite),
0514 .format_modifiers = format_modifiers_win_lite,
0515 .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1),
0516 .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6),
0517 .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19),
0518
0519 .dsp_info = VOP_REG(RK3188_WIN1_DSP_INFO, 0x07ff07ff, 0),
0520 .dsp_st = VOP_REG(RK3188_WIN1_DSP_ST, 0x0fff0fff, 0),
0521 .yrgb_mst = VOP_REG(RK3188_WIN1_MST, 0xffffffff, 0),
0522 .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 16),
0523 .alpha_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 19),
0524 .alpha_en = VOP_REG(RK3188_ALPHA_CTRL, 0x1, 1),
0525 .alpha_pre_mul = VOP_REG(RK3188_DSP_CTRL0, 0x1, 29),
0526 };
0527
0528 static const struct vop_modeset rk3188_modeset = {
0529 .htotal_pw = VOP_REG(RK3188_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
0530 .hact_st_end = VOP_REG(RK3188_DSP_HACT_ST_END, 0x0fff0fff, 0),
0531 .vtotal_pw = VOP_REG(RK3188_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
0532 .vact_st_end = VOP_REG(RK3188_DSP_VACT_ST_END, 0x0fff0fff, 0),
0533 };
0534
0535 static const struct vop_output rk3188_output = {
0536 .pin_pol = VOP_REG(RK3188_DSP_CTRL0, 0xf, 4),
0537 };
0538
0539 static const struct vop_common rk3188_common = {
0540 .gate_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 31),
0541 .standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30),
0542 .out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0),
0543 .cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0),
0544 .dither_down_sel = VOP_REG(RK3188_DSP_CTRL0, 0x1, 27),
0545 .dither_down_en = VOP_REG(RK3188_DSP_CTRL0, 0x1, 11),
0546 .dither_down_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 10),
0547 .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 24),
0548 .dither_up = VOP_REG(RK3188_DSP_CTRL0, 0x1, 9),
0549 .dsp_lut_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 28),
0550 .data_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 25),
0551 };
0552
0553 static const struct vop_win_data rk3188_vop_win_data[] = {
0554 { .base = 0x00, .phy = &rk3188_win0_data,
0555 .type = DRM_PLANE_TYPE_PRIMARY },
0556 { .base = 0x00, .phy = &rk3188_win1_data,
0557 .type = DRM_PLANE_TYPE_CURSOR },
0558 };
0559
0560 static const int rk3188_vop_intrs[] = {
0561
0562
0563
0564
0565 DSP_HOLD_VALID_INTR,
0566 FS_INTR,
0567 LINE_FLAG_INTR,
0568 BUS_ERROR_INTR,
0569 };
0570
0571 static const struct vop_intr rk3188_vop_intr = {
0572 .intrs = rk3188_vop_intrs,
0573 .nintrs = ARRAY_SIZE(rk3188_vop_intrs),
0574 .line_flag_num[0] = VOP_REG(RK3188_INT_STATUS, 0xfff, 12),
0575 .status = VOP_REG(RK3188_INT_STATUS, 0xf, 0),
0576 .enable = VOP_REG(RK3188_INT_STATUS, 0xf, 4),
0577 .clear = VOP_REG(RK3188_INT_STATUS, 0xf, 8),
0578 };
0579
0580 static const struct vop_data rk3188_vop = {
0581 .intr = &rk3188_vop_intr,
0582 .common = &rk3188_common,
0583 .modeset = &rk3188_modeset,
0584 .output = &rk3188_output,
0585 .win = rk3188_vop_win_data,
0586 .win_size = ARRAY_SIZE(rk3188_vop_win_data),
0587 .feature = VOP_FEATURE_INTERNAL_RGB,
0588 };
0589
0590 static const struct vop_scl_extension rk3288_win_full_scl_ext = {
0591 .cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31),
0592 .cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30),
0593 .cbcr_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 28),
0594 .cbcr_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 26),
0595 .cbcr_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 24),
0596 .yrgb_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 23),
0597 .yrgb_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 22),
0598 .yrgb_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 20),
0599 .yrgb_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 18),
0600 .yrgb_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 16),
0601 .line_load_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 15),
0602 .cbcr_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0x7, 12),
0603 .yrgb_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0xf, 8),
0604 .vsd_cbcr_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 7),
0605 .vsd_cbcr_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 6),
0606 .vsd_yrgb_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 5),
0607 .vsd_yrgb_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 4),
0608 .bic_coe_sel = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 2),
0609 .cbcr_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 1),
0610 .yrgb_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 0),
0611 .lb_mode = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 5),
0612 };
0613
0614 static const struct vop_scl_regs rk3288_win_full_scl = {
0615 .ext = &rk3288_win_full_scl_ext,
0616 .scale_yrgb_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
0617 .scale_yrgb_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
0618 .scale_cbcr_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
0619 .scale_cbcr_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
0620 };
0621
0622 static const struct vop_win_phy rk3288_win01_data = {
0623 .scl = &rk3288_win_full_scl,
0624 .data_formats = formats_win_full,
0625 .nformats = ARRAY_SIZE(formats_win_full),
0626 .format_modifiers = format_modifiers_win_full,
0627 .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
0628 .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
0629 .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
0630 .uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15),
0631 .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
0632 .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
0633 .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
0634 .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
0635 .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
0636 .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
0637 .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
0638 .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
0639 .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
0640 .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
0641 };
0642
0643 static const struct vop_win_phy rk3288_win23_data = {
0644 .data_formats = formats_win_lite,
0645 .nformats = ARRAY_SIZE(formats_win_lite),
0646 .format_modifiers = format_modifiers_win_lite,
0647 .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
0648 .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
0649 .format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
0650 .rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
0651 .dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
0652 .dsp_st = VOP_REG(RK3288_WIN2_DSP_ST0, 0x1fff1fff, 0),
0653 .yrgb_mst = VOP_REG(RK3288_WIN2_MST0, 0xffffffff, 0),
0654 .yrgb_vir = VOP_REG(RK3288_WIN2_VIR0_1, 0x1fff, 0),
0655 .src_alpha_ctl = VOP_REG(RK3288_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
0656 .dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0),
0657 };
0658
0659 static const struct vop_modeset rk3288_modeset = {
0660 .htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
0661 .hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
0662 .vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
0663 .vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
0664 .hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
0665 .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
0666 };
0667
0668 static const struct vop_output rk3288_output = {
0669 .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
0670 .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
0671 .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
0672 .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
0673 .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
0674 };
0675
0676 static const struct vop_common rk3288_common = {
0677 .standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22),
0678 .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
0679 .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
0680 .dither_down_sel = VOP_REG(RK3288_DSP_CTRL1, 0x1, 4),
0681 .dither_down_mode = VOP_REG(RK3288_DSP_CTRL1, 0x1, 3),
0682 .dither_down_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 2),
0683 .pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1),
0684 .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
0685 .dsp_lut_en = VOP_REG(RK3288_DSP_CTRL1, 0x1, 0),
0686 .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
0687 .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
0688 .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
0689 .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0),
0690 };
0691
0692
0693
0694
0695
0696
0697
0698 static const struct vop_win_data rk3288_vop_win_data[] = {
0699 { .base = 0x00, .phy = &rk3288_win01_data,
0700 .type = DRM_PLANE_TYPE_PRIMARY },
0701 { .base = 0x40, .phy = &rk3288_win01_data,
0702 .type = DRM_PLANE_TYPE_OVERLAY },
0703 { .base = 0x00, .phy = &rk3288_win23_data,
0704 .type = DRM_PLANE_TYPE_OVERLAY },
0705 { .base = 0x50, .phy = &rk3288_win23_data,
0706 .type = DRM_PLANE_TYPE_CURSOR },
0707 };
0708
0709 static const int rk3288_vop_intrs[] = {
0710 DSP_HOLD_VALID_INTR,
0711 FS_INTR,
0712 LINE_FLAG_INTR,
0713 BUS_ERROR_INTR,
0714 };
0715
0716 static const struct vop_intr rk3288_vop_intr = {
0717 .intrs = rk3288_vop_intrs,
0718 .nintrs = ARRAY_SIZE(rk3288_vop_intrs),
0719 .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
0720 .status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
0721 .enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
0722 .clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
0723 };
0724
0725 static const struct vop_data rk3288_vop = {
0726 .version = VOP_VERSION(3, 1),
0727 .feature = VOP_FEATURE_OUTPUT_RGB10,
0728 .intr = &rk3288_vop_intr,
0729 .common = &rk3288_common,
0730 .modeset = &rk3288_modeset,
0731 .output = &rk3288_output,
0732 .win = rk3288_vop_win_data,
0733 .win_size = ARRAY_SIZE(rk3288_vop_win_data),
0734 .lut_size = 1024,
0735 };
0736
0737 static const int rk3368_vop_intrs[] = {
0738 FS_INTR,
0739 0, 0,
0740 LINE_FLAG_INTR,
0741 0,
0742 BUS_ERROR_INTR,
0743 0, 0, 0, 0, 0, 0, 0,
0744 DSP_HOLD_VALID_INTR,
0745 };
0746
0747 static const struct vop_intr rk3368_vop_intr = {
0748 .intrs = rk3368_vop_intrs,
0749 .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
0750 .line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0),
0751 .line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16),
0752 .status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0),
0753 .enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0),
0754 .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0),
0755 };
0756
0757 static const struct vop_win_phy rk3368_win01_data = {
0758 .scl = &rk3288_win_full_scl,
0759 .data_formats = formats_win_full,
0760 .nformats = ARRAY_SIZE(formats_win_full),
0761 .format_modifiers = format_modifiers_win_full,
0762 .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
0763 .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
0764 .rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
0765 .uv_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 15),
0766 .x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21),
0767 .y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22),
0768 .act_info = VOP_REG(RK3368_WIN0_ACT_INFO, 0x1fff1fff, 0),
0769 .dsp_info = VOP_REG(RK3368_WIN0_DSP_INFO, 0x0fff0fff, 0),
0770 .dsp_st = VOP_REG(RK3368_WIN0_DSP_ST, 0x1fff1fff, 0),
0771 .yrgb_mst = VOP_REG(RK3368_WIN0_YRGB_MST, 0xffffffff, 0),
0772 .uv_mst = VOP_REG(RK3368_WIN0_CBR_MST, 0xffffffff, 0),
0773 .yrgb_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 0),
0774 .uv_vir = VOP_REG(RK3368_WIN0_VIR, 0x3fff, 16),
0775 .src_alpha_ctl = VOP_REG(RK3368_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
0776 .dst_alpha_ctl = VOP_REG(RK3368_WIN0_DST_ALPHA_CTRL, 0xff, 0),
0777 .channel = VOP_REG(RK3368_WIN0_CTRL2, 0xff, 0),
0778 };
0779
0780 static const struct vop_win_phy rk3368_win23_data = {
0781 .data_formats = formats_win_lite,
0782 .nformats = ARRAY_SIZE(formats_win_lite),
0783 .format_modifiers = format_modifiers_win_lite,
0784 .gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
0785 .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
0786 .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
0787 .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
0788 .y_mir_en = VOP_REG(RK3368_WIN2_CTRL1, 0x1, 15),
0789 .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
0790 .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
0791 .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
0792 .yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
0793 .src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
0794 .dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0),
0795 };
0796
0797 static const struct vop_win_data rk3368_vop_win_data[] = {
0798 { .base = 0x00, .phy = &rk3368_win01_data,
0799 .type = DRM_PLANE_TYPE_PRIMARY },
0800 { .base = 0x40, .phy = &rk3368_win01_data,
0801 .type = DRM_PLANE_TYPE_OVERLAY },
0802 { .base = 0x00, .phy = &rk3368_win23_data,
0803 .type = DRM_PLANE_TYPE_OVERLAY },
0804 { .base = 0x50, .phy = &rk3368_win23_data,
0805 .type = DRM_PLANE_TYPE_CURSOR },
0806 };
0807
0808 static const struct vop_output rk3368_output = {
0809 .rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19),
0810 .hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23),
0811 .edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27),
0812 .mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31),
0813 .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16),
0814 .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20),
0815 .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24),
0816 .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28),
0817 .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
0818 .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
0819 .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
0820 .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
0821 };
0822
0823 static const struct vop_misc rk3368_misc = {
0824 .global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11),
0825 };
0826
0827 static const struct vop_data rk3368_vop = {
0828 .version = VOP_VERSION(3, 2),
0829 .intr = &rk3368_vop_intr,
0830 .common = &rk3288_common,
0831 .modeset = &rk3288_modeset,
0832 .output = &rk3368_output,
0833 .misc = &rk3368_misc,
0834 .win = rk3368_vop_win_data,
0835 .win_size = ARRAY_SIZE(rk3368_vop_win_data),
0836 };
0837
0838 static const struct vop_intr rk3366_vop_intr = {
0839 .intrs = rk3368_vop_intrs,
0840 .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
0841 .line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0),
0842 .line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16),
0843 .status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0),
0844 .enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0),
0845 .clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0),
0846 };
0847
0848 static const struct vop_data rk3366_vop = {
0849 .version = VOP_VERSION(3, 4),
0850 .intr = &rk3366_vop_intr,
0851 .common = &rk3288_common,
0852 .modeset = &rk3288_modeset,
0853 .output = &rk3368_output,
0854 .misc = &rk3368_misc,
0855 .win = rk3368_vop_win_data,
0856 .win_size = ARRAY_SIZE(rk3368_vop_win_data),
0857 };
0858
0859 static const struct vop_output rk3399_output = {
0860 .dp_dclk_pol = VOP_REG(RK3399_DSP_CTRL1, 0x1, 19),
0861 .rgb_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 19),
0862 .hdmi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 23),
0863 .edp_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 27),
0864 .mipi_dclk_pol = VOP_REG(RK3368_DSP_CTRL1, 0x1, 31),
0865 .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0x7, 16),
0866 .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 16),
0867 .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 20),
0868 .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 24),
0869 .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0x7, 28),
0870 .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
0871 .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
0872 .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
0873 .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
0874 .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
0875 .mipi_dual_channel_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 3),
0876 };
0877
0878 static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win01_data = {
0879 .y2r_coefficients = {
0880 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 0),
0881 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 0, 0xffff, 16),
0882 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 0),
0883 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 4, 0xffff, 16),
0884 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 0),
0885 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 8, 0xffff, 16),
0886 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 0),
0887 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 12, 0xffff, 16),
0888 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 16, 0xffff, 0),
0889 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 20, 0xffffffff, 0),
0890 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 24, 0xffffffff, 0),
0891 VOP_REG(RK3399_WIN0_YUV2YUV_Y2R + 28, 0xffffffff, 0),
0892 },
0893 };
0894
0895 static const struct vop_yuv2yuv_phy rk3399_yuv2yuv_win23_data = { };
0896
0897 static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
0898 { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
0899 .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1) },
0900 { .base = 0x60, .phy = &rk3399_yuv2yuv_win01_data,
0901 .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9) },
0902 { .base = 0xC0, .phy = &rk3399_yuv2yuv_win23_data },
0903 { .base = 0x120, .phy = &rk3399_yuv2yuv_win23_data },
0904
0905 };
0906
0907 static const struct vop_win_phy rk3399_win01_data = {
0908 .scl = &rk3288_win_full_scl,
0909 .data_formats = formats_win_full,
0910 .nformats = ARRAY_SIZE(formats_win_full),
0911 .format_modifiers = format_modifiers_win_full_afbc,
0912 .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
0913 .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
0914 .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
0915 .uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15),
0916 .x_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 21),
0917 .y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
0918 .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
0919 .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
0920 .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
0921 .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
0922 .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
0923 .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
0924 .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
0925 .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
0926 .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
0927 .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
0928 };
0929
0930
0931
0932
0933
0934
0935 static const struct vop_win_data rk3399_vop_win_data[] = {
0936 { .base = 0x00, .phy = &rk3399_win01_data,
0937 .type = DRM_PLANE_TYPE_PRIMARY },
0938 { .base = 0x40, .phy = &rk3368_win01_data,
0939 .type = DRM_PLANE_TYPE_OVERLAY },
0940 { .base = 0x00, .phy = &rk3368_win23_data,
0941 .type = DRM_PLANE_TYPE_OVERLAY },
0942 { .base = 0x50, .phy = &rk3368_win23_data,
0943 .type = DRM_PLANE_TYPE_CURSOR },
0944 };
0945
0946 static const struct vop_afbc rk3399_vop_afbc = {
0947 .rstn = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 3),
0948 .enable = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 0),
0949 .win_sel = VOP_REG(RK3399_AFBCD0_CTRL, 0x3, 1),
0950 .format = VOP_REG(RK3399_AFBCD0_CTRL, 0x1f, 16),
0951 .hreg_block_split = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 21),
0952 .hdr_ptr = VOP_REG(RK3399_AFBCD0_HDR_PTR, 0xffffffff, 0),
0953 .pic_size = VOP_REG(RK3399_AFBCD0_PIC_SIZE, 0xffffffff, 0),
0954 };
0955
0956 static const struct vop_data rk3399_vop_big = {
0957 .version = VOP_VERSION(3, 5),
0958 .feature = VOP_FEATURE_OUTPUT_RGB10,
0959 .intr = &rk3366_vop_intr,
0960 .common = &rk3288_common,
0961 .modeset = &rk3288_modeset,
0962 .output = &rk3399_output,
0963 .afbc = &rk3399_vop_afbc,
0964 .misc = &rk3368_misc,
0965 .win = rk3399_vop_win_data,
0966 .win_size = ARRAY_SIZE(rk3399_vop_win_data),
0967 .win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data,
0968 };
0969
0970 static const struct vop_win_data rk3399_vop_lit_win_data[] = {
0971 { .base = 0x00, .phy = &rk3368_win01_data,
0972 .type = DRM_PLANE_TYPE_PRIMARY },
0973 { .base = 0x00, .phy = &rk3368_win23_data,
0974 .type = DRM_PLANE_TYPE_CURSOR},
0975 };
0976
0977 static const struct vop_win_yuv2yuv_data rk3399_vop_lit_win_yuv2yuv_data[] = {
0978 { .base = 0x00, .phy = &rk3399_yuv2yuv_win01_data,
0979 .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 1)},
0980 { .base = 0x60, .phy = &rk3399_yuv2yuv_win23_data },
0981 };
0982
0983 static const struct vop_data rk3399_vop_lit = {
0984 .version = VOP_VERSION(3, 6),
0985 .intr = &rk3366_vop_intr,
0986 .common = &rk3288_common,
0987 .modeset = &rk3288_modeset,
0988 .output = &rk3399_output,
0989 .misc = &rk3368_misc,
0990 .win = rk3399_vop_lit_win_data,
0991 .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
0992 .win_yuv2yuv = rk3399_vop_lit_win_yuv2yuv_data,
0993 };
0994
0995 static const struct vop_win_data rk3228_vop_win_data[] = {
0996 { .base = 0x00, .phy = &rk3288_win01_data,
0997 .type = DRM_PLANE_TYPE_PRIMARY },
0998 { .base = 0x40, .phy = &rk3288_win01_data,
0999 .type = DRM_PLANE_TYPE_CURSOR },
1000 };
1001
1002 static 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
1014 static 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
1023 static 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
1038 static const struct vop_misc rk3328_misc = {
1039 .global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11),
1040 };
1041
1042 static 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
1054 static 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
1064 static 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
1073 static 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
1085 static 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 };
1114 MODULE_DEVICE_TABLE(of, vop_driver_dt_match);
1115
1116 static 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
1128 static int vop_remove(struct platform_device *pdev)
1129 {
1130 component_del(&pdev->dev, &vop_component_ops);
1131
1132 return 0;
1133 }
1134
1135 struct 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 };