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