Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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