1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) Rockchip Electronics Co., Ltd. 4 * Author: Andy Yan <andy.yan@rock-chips.com> 5 */ 6 7 #include <linux/bitfield.h> 8 #include <linux/kernel.h> 9 #include <linux/component.h> 10 #include <linux/hw_bitfield.h> 11 #include <linux/mod_devicetable.h> 12 #include <linux/platform_device.h> 13 #include <linux/of.h> 14 #include <drm/drm_blend.h> 15 #include <drm/drm_fourcc.h> 16 #include <drm/drm_framebuffer.h> 17 #include <drm/drm_plane.h> 18 #include <drm/drm_print.h> 19 20 #include "rockchip_drm_vop2.h" 21 22 union vop2_alpha_ctrl { 23 u32 val; 24 struct { 25 /* [0:1] */ 26 u32 color_mode:1; 27 u32 alpha_mode:1; 28 /* [2:3] */ 29 u32 blend_mode:2; 30 u32 alpha_cal_mode:1; 31 /* [5:7] */ 32 u32 factor_mode:3; 33 /* [8:9] */ 34 u32 alpha_en:1; 35 u32 src_dst_swap:1; 36 u32 reserved:6; 37 /* [16:23] */ 38 u32 glb_alpha:8; 39 } bits; 40 }; 41 42 struct vop2_alpha { 43 union vop2_alpha_ctrl src_color_ctrl; 44 union vop2_alpha_ctrl dst_color_ctrl; 45 union vop2_alpha_ctrl src_alpha_ctrl; 46 union vop2_alpha_ctrl dst_alpha_ctrl; 47 }; 48 49 struct vop2_alpha_config { 50 bool src_premulti_en; 51 bool dst_premulti_en; 52 bool src_pixel_alpha_en; 53 bool dst_pixel_alpha_en; 54 u16 src_glb_alpha_value; 55 u16 dst_glb_alpha_value; 56 }; 57 58 static const uint32_t formats_cluster[] = { 59 DRM_FORMAT_XRGB2101010, 60 DRM_FORMAT_XBGR2101010, 61 DRM_FORMAT_XRGB8888, 62 DRM_FORMAT_ARGB8888, 63 DRM_FORMAT_XBGR8888, 64 DRM_FORMAT_ABGR8888, 65 DRM_FORMAT_RGB888, 66 DRM_FORMAT_BGR888, 67 DRM_FORMAT_RGB565, 68 DRM_FORMAT_BGR565, 69 DRM_FORMAT_YUV420_8BIT, /* yuv420_8bit non-Linear mode only */ 70 DRM_FORMAT_YUV420_10BIT, /* yuv420_10bit non-Linear mode only */ 71 DRM_FORMAT_YUYV, /* yuv422_8bit non-Linear mode only*/ 72 DRM_FORMAT_Y210, /* yuv422_10bit non-Linear mode only */ 73 }; 74 75 /* 76 * The cluster windows on rk3576 support: 77 * RGB: linear mode and afbc 78 * YUV: linear mode and rfbc 79 * rfbc is a rockchip defined non-linear mode, produced by 80 * Video decoder 81 */ 82 static const uint32_t formats_rk3576_cluster[] = { 83 DRM_FORMAT_XRGB2101010, 84 DRM_FORMAT_XBGR2101010, 85 DRM_FORMAT_ARGB2101010, 86 DRM_FORMAT_ABGR2101010, 87 DRM_FORMAT_XRGB8888, 88 DRM_FORMAT_ARGB8888, 89 DRM_FORMAT_XBGR8888, 90 DRM_FORMAT_ABGR8888, 91 DRM_FORMAT_RGB888, 92 DRM_FORMAT_BGR888, 93 DRM_FORMAT_RGB565, 94 DRM_FORMAT_BGR565, 95 DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */ 96 DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */ 97 DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */ 98 DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */ 99 DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */ 100 DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */ 101 DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */ 102 DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */ 103 DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */ 104 }; 105 106 static const uint32_t formats_esmart[] = { 107 DRM_FORMAT_XRGB8888, 108 DRM_FORMAT_ARGB8888, 109 DRM_FORMAT_XBGR8888, 110 DRM_FORMAT_ABGR8888, 111 DRM_FORMAT_RGB888, 112 DRM_FORMAT_BGR888, 113 DRM_FORMAT_RGB565, 114 DRM_FORMAT_BGR565, 115 DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */ 116 DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */ 117 DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */ 118 DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */ 119 DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */ 120 DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */ 121 DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */ 122 DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */ 123 DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */ 124 DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */ 125 DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */ 126 DRM_FORMAT_YUYV, /* yuv422_8bit[YUYV] linear mode */ 127 DRM_FORMAT_UYVY, /* yuv422_8bit[UYVY] linear mode */ 128 }; 129 130 static const uint32_t formats_rk356x_esmart[] = { 131 DRM_FORMAT_XRGB8888, 132 DRM_FORMAT_ARGB8888, 133 DRM_FORMAT_XBGR8888, 134 DRM_FORMAT_ABGR8888, 135 DRM_FORMAT_RGB888, 136 DRM_FORMAT_BGR888, 137 DRM_FORMAT_RGB565, 138 DRM_FORMAT_BGR565, 139 DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */ 140 DRM_FORMAT_NV21, /* yuv420_8bit linear mode, 2 plane */ 141 DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */ 142 DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */ 143 DRM_FORMAT_NV61, /* yuv422_8bit linear mode, 2 plane */ 144 DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */ 145 DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */ 146 DRM_FORMAT_NV42, /* yuv444_8bit linear mode, 2 plane */ 147 DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */ 148 DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */ 149 DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */ 150 }; 151 152 /* 153 * Add XRGB2101010/ARGB2101010ARGB1555/XRGB1555 154 */ 155 static const uint32_t formats_rk3576_esmart[] = { 156 DRM_FORMAT_XRGB2101010, 157 DRM_FORMAT_XBGR2101010, 158 DRM_FORMAT_ARGB2101010, 159 DRM_FORMAT_ABGR2101010, 160 DRM_FORMAT_XRGB8888, 161 DRM_FORMAT_ARGB8888, 162 DRM_FORMAT_XBGR8888, 163 DRM_FORMAT_ABGR8888, 164 DRM_FORMAT_RGB888, 165 DRM_FORMAT_BGR888, 166 DRM_FORMAT_RGB565, 167 DRM_FORMAT_BGR565, 168 DRM_FORMAT_ARGB1555, 169 DRM_FORMAT_ABGR1555, 170 DRM_FORMAT_XRGB1555, 171 DRM_FORMAT_XBGR1555, 172 DRM_FORMAT_NV12, /* yuv420_8bit linear mode, 2 plane */ 173 DRM_FORMAT_NV21, /* yvu420_8bit linear mode, 2 plane */ 174 DRM_FORMAT_NV16, /* yuv422_8bit linear mode, 2 plane */ 175 DRM_FORMAT_NV61, /* yvu422_8bit linear mode, 2 plane */ 176 DRM_FORMAT_NV20, /* yuv422_10bit linear mode, 2 plane, no padding */ 177 DRM_FORMAT_NV24, /* yuv444_8bit linear mode, 2 plane */ 178 DRM_FORMAT_NV42, /* yvu444_8bit linear mode, 2 plane */ 179 DRM_FORMAT_NV30, /* yuv444_10bit linear mode, 2 plane, no padding */ 180 DRM_FORMAT_NV15, /* yuv420_10bit linear mode, 2 plane, no padding */ 181 DRM_FORMAT_YVYU, /* yuv422_8bit[YVYU] linear mode */ 182 DRM_FORMAT_VYUY, /* yuv422_8bit[VYUY] linear mode */ 183 DRM_FORMAT_YUYV, /* yuv422_8bit[YUYV] linear mode */ 184 DRM_FORMAT_UYVY, /* yuv422_8bit[UYVY] linear mode */ 185 }; 186 187 static const uint32_t formats_smart[] = { 188 DRM_FORMAT_XRGB8888, 189 DRM_FORMAT_ARGB8888, 190 DRM_FORMAT_XBGR8888, 191 DRM_FORMAT_ABGR8888, 192 DRM_FORMAT_RGB888, 193 DRM_FORMAT_BGR888, 194 DRM_FORMAT_RGB565, 195 DRM_FORMAT_BGR565, 196 }; 197 198 static const uint64_t format_modifiers[] = { 199 DRM_FORMAT_MOD_LINEAR, 200 DRM_FORMAT_MOD_INVALID, 201 }; 202 203 static const uint64_t format_modifiers_afbc[] = { 204 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16), 205 206 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 207 AFBC_FORMAT_MOD_SPARSE), 208 209 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 210 AFBC_FORMAT_MOD_YTR), 211 212 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 213 AFBC_FORMAT_MOD_CBR), 214 215 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 216 AFBC_FORMAT_MOD_YTR | 217 AFBC_FORMAT_MOD_SPARSE), 218 219 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 220 AFBC_FORMAT_MOD_CBR | 221 AFBC_FORMAT_MOD_SPARSE), 222 223 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 224 AFBC_FORMAT_MOD_YTR | 225 AFBC_FORMAT_MOD_CBR), 226 227 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 228 AFBC_FORMAT_MOD_YTR | 229 AFBC_FORMAT_MOD_CBR | 230 AFBC_FORMAT_MOD_SPARSE), 231 232 /* SPLIT mandates SPARSE, RGB modes mandates YTR */ 233 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | 234 AFBC_FORMAT_MOD_YTR | 235 AFBC_FORMAT_MOD_SPARSE | 236 AFBC_FORMAT_MOD_SPLIT), 237 DRM_FORMAT_MOD_INVALID, 238 }; 239 240 /* used from rk3576, afbc 32*8 half mode */ 241 static const uint64_t format_modifiers_rk3576_afbc[] = { 242 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | 243 AFBC_FORMAT_MOD_SPLIT), 244 245 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | 246 AFBC_FORMAT_MOD_SPARSE | 247 AFBC_FORMAT_MOD_SPLIT), 248 249 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | 250 AFBC_FORMAT_MOD_YTR | 251 AFBC_FORMAT_MOD_SPLIT), 252 253 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | 254 AFBC_FORMAT_MOD_CBR | 255 AFBC_FORMAT_MOD_SPLIT), 256 257 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | 258 AFBC_FORMAT_MOD_CBR | 259 AFBC_FORMAT_MOD_SPARSE | 260 AFBC_FORMAT_MOD_SPLIT), 261 262 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | 263 AFBC_FORMAT_MOD_YTR | 264 AFBC_FORMAT_MOD_CBR | 265 AFBC_FORMAT_MOD_SPLIT), 266 267 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | 268 AFBC_FORMAT_MOD_YTR | 269 AFBC_FORMAT_MOD_CBR | 270 AFBC_FORMAT_MOD_SPARSE | 271 AFBC_FORMAT_MOD_SPLIT), 272 273 /* SPLIT mandates SPARSE, RGB modes mandates YTR */ 274 DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | 275 AFBC_FORMAT_MOD_YTR | 276 AFBC_FORMAT_MOD_SPARSE | 277 AFBC_FORMAT_MOD_SPLIT), 278 DRM_FORMAT_MOD_LINEAR, 279 DRM_FORMAT_MOD_INVALID, 280 }; 281 282 static const struct reg_field rk3568_vop_cluster_regs[VOP2_WIN_MAX_REG] = { 283 [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0), 284 [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5), 285 [VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14), 286 [VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18), 287 [VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31), 288 [VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31), 289 [VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31), 290 [VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31), 291 [VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31), 292 [VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19), 293 [VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15), 294 [VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31), 295 [VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8), 296 [VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9), 297 [VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11), 298 [VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3), 299 [VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8), 300 /* RK3588 only, reserved bit on rk3568*/ 301 [VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13), 302 303 /* Scale */ 304 [VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15), 305 [VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31), 306 [VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15), 307 [VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13), 308 [VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3), 309 [VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28), 310 [VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29), 311 312 /* cluster regs */ 313 [VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1), 314 [VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0), 315 [VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7), 316 317 /* afbc regs */ 318 [VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6), 319 [VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9), 320 [VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10), 321 [VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4), 322 [VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7), 323 [VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8), 324 [VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31), 325 [VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31), 326 [VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15), 327 [VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31), 328 [VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31), 329 [VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31), 330 [VOP2_WIN_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_TRANSFORM_OFFSET, 0, 31), 331 [VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0), 332 [VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1), 333 [VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2), 334 [VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3), 335 [VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff }, 336 [VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff }, 337 [VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff }, 338 [VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff }, 339 [VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff }, 340 [VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff }, 341 [VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff }, 342 [VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff }, 343 [VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff }, 344 [VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff }, 345 [VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff }, 346 [VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff }, 347 [VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff }, 348 }; 349 350 static const struct reg_field rk3568_vop_smart_regs[VOP2_WIN_MAX_REG] = { 351 [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0), 352 [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5), 353 [VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12), 354 [VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14), 355 [VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16), 356 [VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31), 357 [VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31), 358 [VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28), 359 [VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31), 360 [VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31), 361 [VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17), 362 [VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15), 363 [VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31), 364 [VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0), 365 [VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1), 366 [VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3), 367 [VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31), 368 [VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29), 369 [VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31), 370 [VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8), 371 [VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16), 372 /* RK3588 only, reserved register on rk3568 */ 373 [VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1), 374 375 /* Scale */ 376 [VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15), 377 [VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31), 378 [VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15), 379 [VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31), 380 [VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1), 381 [VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3), 382 [VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5), 383 [VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7), 384 [VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9), 385 [VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11), 386 [VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13), 387 [VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15), 388 [VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17), 389 [VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8), 390 [VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9), 391 [VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10), 392 [VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11), 393 [VOP2_WIN_XMIRROR] = { .reg = 0xffffffff }, 394 [VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff }, 395 [VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff }, 396 [VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff }, 397 [VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff }, 398 [VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff }, 399 [VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff }, 400 [VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff }, 401 [VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff }, 402 [VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff }, 403 [VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff }, 404 [VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff }, 405 [VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff }, 406 [VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff }, 407 [VOP2_WIN_TRANSFORM_OFFSET] = { .reg = 0xffffffff }, 408 [VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff }, 409 [VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff }, 410 [VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff }, 411 [VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff }, 412 }; 413 414 static const struct reg_field rk3576_vop_cluster_regs[VOP2_WIN_MAX_REG] = { 415 [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0), 416 [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5), 417 [VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14), 418 [VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 17, 17), 419 [VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18), 420 [VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31), 421 [VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31), 422 [VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31), 423 [VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31), 424 [VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31), 425 [VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19), 426 [VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15), 427 [VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31), 428 [VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8), 429 [VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9), 430 [VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11), 431 [VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 4), 432 [VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 9), 433 /* Read only bit on rk3576, writing on this bit have no effect.*/ 434 [VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13), 435 436 [VOP2_WIN_VP_SEL] = REG_FIELD(RK3576_CLUSTER_PORT_SEL_IMD, 0, 1), 437 [VOP2_WIN_DLY_NUM] = REG_FIELD(RK3576_CLUSTER_DLY_NUM, 0, 7), 438 439 /* Scale */ 440 [VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15), 441 [VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31), 442 [VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3), 443 [VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15), 444 [VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 22, 23), 445 [VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28), 446 [VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29), 447 448 /* cluster regs */ 449 [VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1), 450 [VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0), 451 [VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7), 452 453 /* afbc regs */ 454 [VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6), 455 [VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9), 456 [VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10), 457 [VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4), 458 [VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7), 459 [VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8), 460 [VOP2_WIN_AFBC_PLD_OFFSET_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 16, 16), 461 [VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31), 462 [VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31), 463 [VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15), 464 [VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31), 465 [VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31), 466 [VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31), 467 [VOP2_WIN_AFBC_PLD_OFFSET] = REG_FIELD(RK3576_CLUSTER_WIN_AFBCD_PLD_PTR_OFFSET, 0, 31), 468 [VOP2_WIN_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_TRANSFORM_OFFSET, 0, 31), 469 [VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0), 470 [VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1), 471 [VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2), 472 [VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3), 473 [VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff }, 474 [VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff }, 475 [VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff }, 476 [VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff }, 477 [VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff }, 478 [VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff }, 479 [VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff }, 480 [VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff }, 481 [VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff }, 482 [VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff }, 483 [VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff }, 484 [VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff }, 485 }; 486 487 static const struct reg_field rk3576_vop_smart_regs[VOP2_WIN_MAX_REG] = { 488 [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0), 489 [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5), 490 [VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12), 491 [VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14), 492 [VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16), 493 [VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31), 494 [VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31), 495 [VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28), 496 [VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31), 497 [VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31), 498 [VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17), 499 [VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15), 500 [VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31), 501 [VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0), 502 [VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1), 503 [VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3), 504 [VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31), 505 [VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29), 506 [VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31), 507 [VOP2_WIN_VP_SEL] = REG_FIELD(RK3576_SMART_PORT_SEL_IMD, 0, 1), 508 [VOP2_WIN_DLY_NUM] = REG_FIELD(RK3576_SMART_DLY_NUM, 0, 7), 509 [VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8), 510 [VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16), 511 [VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1), 512 513 /* Scale */ 514 [VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15), 515 [VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31), 516 [VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1), 517 [VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3), 518 [VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5), 519 [VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7), 520 [VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17), 521 [VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8), 522 [VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9), 523 [VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10), 524 [VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11), 525 [VOP2_WIN_XMIRROR] = { .reg = 0xffffffff }, 526 527 /* CBCR share the same scale factor as YRGB */ 528 [VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff }, 529 [VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff }, 530 [VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff }, 531 [VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff}, 532 [VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff}, 533 [VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff}, 534 535 [VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff }, 536 [VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff }, 537 [VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff }, 538 [VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff }, 539 [VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff }, 540 [VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff }, 541 [VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff }, 542 [VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff }, 543 [VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff }, 544 [VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff }, 545 [VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff }, 546 [VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff }, 547 [VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff }, 548 [VOP2_WIN_TRANSFORM_OFFSET] = { .reg = 0xffffffff }, 549 [VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff }, 550 [VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff }, 551 [VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff }, 552 [VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff }, 553 }; 554 555 static const struct vop2_video_port_data rk3568_vop_video_ports[] = { 556 { 557 .id = 0, 558 .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, 559 .gamma_lut_len = 1024, 560 .cubic_lut_len = 9 * 9 * 9, 561 .max_output = { 4096, 2304 }, 562 .pre_scan_max_dly = { 69, 53, 53, 42 }, 563 .offset = 0xc00, 564 }, { 565 .id = 1, 566 .gamma_lut_len = 1024, 567 .max_output = { 2048, 1536 }, 568 .pre_scan_max_dly = { 40, 40, 40, 40 }, 569 .offset = 0xd00, 570 }, { 571 .id = 2, 572 .gamma_lut_len = 1024, 573 .max_output = { 1920, 1080 }, 574 .pre_scan_max_dly = { 40, 40, 40, 40 }, 575 .offset = 0xe00, 576 }, 577 }; 578 579 /* 580 * rk3568 vop with 2 cluster, 2 esmart win, 2 smart win. 581 * Every cluster can work as 4K win or split into two win. 582 * All win in cluster support AFBCD. 583 * 584 * Every esmart win and smart win support 4 Multi-region. 585 * 586 * Scale filter mode: 587 * 588 * * Cluster: bicubic for horizontal scale up, others use bilinear 589 * * ESmart: 590 * * nearest-neighbor/bilinear/bicubic for scale up 591 * * nearest-neighbor/bilinear/average for scale down 592 * 593 * 594 * @TODO describe the wind like cpu-map dt nodes; 595 */ 596 static const struct vop2_win_data rk3568_vop_win_data[] = { 597 { 598 .name = "Smart0-win0", 599 .phys_id = ROCKCHIP_VOP2_SMART0, 600 .base = 0x1c00, 601 .possible_vp_mask = BIT(0) | BIT(1) | BIT(2), 602 .formats = formats_smart, 603 .nformats = ARRAY_SIZE(formats_smart), 604 .format_modifiers = format_modifiers, 605 /* 0xf means this layer can't attached to this VP */ 606 .layer_sel_id = { 3, 3, 3, 0xf }, 607 .supported_rotations = DRM_MODE_REFLECT_Y, 608 .type = DRM_PLANE_TYPE_PRIMARY, 609 .max_upscale_factor = 8, 610 .max_downscale_factor = 8, 611 .dly = { 20, 47, 41 }, 612 }, { 613 .name = "Smart1-win0", 614 .phys_id = ROCKCHIP_VOP2_SMART1, 615 .possible_vp_mask = BIT(0) | BIT(1) | BIT(2), 616 .formats = formats_smart, 617 .nformats = ARRAY_SIZE(formats_smart), 618 .format_modifiers = format_modifiers, 619 .base = 0x1e00, 620 .layer_sel_id = { 7, 7, 7, 0xf }, 621 .supported_rotations = DRM_MODE_REFLECT_Y, 622 .type = DRM_PLANE_TYPE_PRIMARY, 623 .max_upscale_factor = 8, 624 .max_downscale_factor = 8, 625 .dly = { 20, 47, 41 }, 626 }, { 627 .name = "Esmart1-win0", 628 .phys_id = ROCKCHIP_VOP2_ESMART1, 629 .possible_vp_mask = BIT(0) | BIT(1) | BIT(2), 630 .formats = formats_rk356x_esmart, 631 .nformats = ARRAY_SIZE(formats_rk356x_esmart), 632 .format_modifiers = format_modifiers, 633 .base = 0x1a00, 634 .layer_sel_id = { 6, 6, 6, 0xf }, 635 .supported_rotations = DRM_MODE_REFLECT_Y, 636 .type = DRM_PLANE_TYPE_PRIMARY, 637 .max_upscale_factor = 8, 638 .max_downscale_factor = 8, 639 .dly = { 20, 47, 41 }, 640 }, { 641 .name = "Esmart0-win0", 642 .phys_id = ROCKCHIP_VOP2_ESMART0, 643 .possible_vp_mask = BIT(0) | BIT(1) | BIT(2), 644 .formats = formats_rk356x_esmart, 645 .nformats = ARRAY_SIZE(formats_rk356x_esmart), 646 .format_modifiers = format_modifiers, 647 .base = 0x1800, 648 .layer_sel_id = { 2, 2, 2, 0xf }, 649 .supported_rotations = DRM_MODE_REFLECT_Y, 650 .type = DRM_PLANE_TYPE_PRIMARY, 651 .max_upscale_factor = 8, 652 .max_downscale_factor = 8, 653 .dly = { 20, 47, 41 }, 654 }, { 655 .name = "Cluster0-win0", 656 .phys_id = ROCKCHIP_VOP2_CLUSTER0, 657 .base = 0x1000, 658 .possible_vp_mask = BIT(0) | BIT(1) | BIT(2), 659 .formats = formats_cluster, 660 .nformats = ARRAY_SIZE(formats_cluster), 661 .format_modifiers = format_modifiers_afbc, 662 .layer_sel_id = { 0, 0, 0, 0xf }, 663 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 664 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 665 .max_upscale_factor = 4, 666 .max_downscale_factor = 4, 667 .dly = { 0, 27, 21 }, 668 .type = DRM_PLANE_TYPE_OVERLAY, 669 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 670 }, { 671 .name = "Cluster1-win0", 672 .phys_id = ROCKCHIP_VOP2_CLUSTER1, 673 .base = 0x1200, 674 .possible_vp_mask = BIT(0) | BIT(1) | BIT(2), 675 .formats = formats_cluster, 676 .nformats = ARRAY_SIZE(formats_cluster), 677 .format_modifiers = format_modifiers_afbc, 678 .layer_sel_id = { 1, 1, 1, 0xf }, 679 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 680 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 681 .type = DRM_PLANE_TYPE_OVERLAY, 682 .max_upscale_factor = 4, 683 .max_downscale_factor = 4, 684 .dly = { 0, 27, 21 }, 685 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 686 }, 687 }; 688 689 static const struct vop2_regs_dump rk3568_regs_dump[] = { 690 { 691 .name = "SYS", 692 .base = RK3568_REG_CFG_DONE, 693 .size = 0x100, 694 .en_reg = 0, 695 .en_val = 0, 696 .en_mask = 0 697 }, { 698 .name = "OVL", 699 .base = RK3568_OVL_CTRL, 700 .size = 0x100, 701 .en_reg = 0, 702 .en_val = 0, 703 .en_mask = 0, 704 }, { 705 .name = "VP0", 706 .base = RK3568_VP0_CTRL_BASE, 707 .size = 0x100, 708 .en_reg = RK3568_VP_DSP_CTRL, 709 .en_val = 0, 710 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 711 }, { 712 .name = "VP1", 713 .base = RK3568_VP1_CTRL_BASE, 714 .size = 0x100, 715 .en_reg = RK3568_VP_DSP_CTRL, 716 .en_val = 0, 717 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 718 }, { 719 .name = "VP2", 720 .base = RK3568_VP2_CTRL_BASE, 721 .size = 0x100, 722 .en_reg = RK3568_VP_DSP_CTRL, 723 .en_val = 0, 724 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 725 726 }, { 727 .name = "Cluster0", 728 .base = RK3568_CLUSTER0_CTRL_BASE, 729 .size = 0x110, 730 .en_reg = RK3568_CLUSTER_WIN_CTRL0, 731 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 732 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 733 }, { 734 .name = "Cluster1", 735 .base = RK3568_CLUSTER1_CTRL_BASE, 736 .size = 0x110, 737 .en_reg = RK3568_CLUSTER_WIN_CTRL0, 738 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 739 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 740 }, { 741 .name = "Esmart0", 742 .base = RK3568_ESMART0_CTRL_BASE, 743 .size = 0xf0, 744 .en_reg = RK3568_SMART_REGION0_CTRL, 745 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 746 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 747 }, { 748 .name = "Esmart1", 749 .base = RK3568_ESMART1_CTRL_BASE, 750 .size = 0xf0, 751 .en_reg = RK3568_SMART_REGION0_CTRL, 752 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 753 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 754 }, { 755 .name = "Smart0", 756 .base = RK3568_SMART0_CTRL_BASE, 757 .size = 0xf0, 758 .en_reg = RK3568_SMART_REGION0_CTRL, 759 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 760 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 761 }, { 762 .name = "Smart1", 763 .base = RK3568_SMART1_CTRL_BASE, 764 .size = 0xf0, 765 .en_reg = RK3568_SMART_REGION0_CTRL, 766 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 767 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 768 }, 769 }; 770 771 static const struct vop2_video_port_data rk3576_vop_video_ports[] = { 772 { 773 .id = 0, 774 .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, 775 .gamma_lut_len = 1024, 776 .cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */ 777 .max_output = { 4096, 2304 }, 778 /* win layer_mix hdr */ 779 .pre_scan_max_dly = { 10, 8, 2, 0 }, 780 .offset = 0xc00, 781 .pixel_rate = 2, 782 }, { 783 .id = 1, 784 .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, 785 .gamma_lut_len = 1024, 786 .cubic_lut_len = 729, /* 9x9x9 */ 787 .max_output = { 2560, 1600 }, 788 /* win layer_mix hdr */ 789 .pre_scan_max_dly = { 10, 6, 0, 0 }, 790 .offset = 0xd00, 791 .pixel_rate = 1, 792 }, { 793 .id = 2, 794 .gamma_lut_len = 1024, 795 .max_output = { 1920, 1080 }, 796 /* win layer_mix hdr */ 797 .pre_scan_max_dly = { 10, 6, 0, 0 }, 798 .offset = 0xe00, 799 .pixel_rate = 1, 800 }, 801 }; 802 803 /* 804 * rk3576 vop with 2 cluster, 4 esmart win. 805 * Every cluster can work as 4K win or split into two 2K win. 806 * All win in cluster support AFBCD. 807 * 808 * Every esmart win support 4 Multi-region. 809 * 810 * VP0 can use Cluster0/1 and Esmart0/2 811 * VP1 can use Cluster0/1 and Esmart1/3 812 * VP2 can use Esmart0/1/2/3 813 * 814 * Scale filter mode: 815 * 816 * * Cluster: 817 * * Support prescale down: 818 * * H/V: gt2/avg2 or gt4/avg4 819 * * After prescale down: 820 * * nearest-neighbor/bilinear/multi-phase filter for scale up 821 * * nearest-neighbor/bilinear/multi-phase filter for scale down 822 * 823 * * Esmart: 824 * * Support prescale down: 825 * * H: gt2/avg2 or gt4/avg4 826 * * V: gt2 or gt4 827 * * After prescale down: 828 * * nearest-neighbor/bilinear/bicubic for scale up 829 * * nearest-neighbor/bilinear for scale down 830 * 831 * AXI config:: 832 * 833 * * Cluster0 win0: 0xa, 0xb [AXI0] 834 * * Cluster0 win1: 0xc, 0xd [AXI0] 835 * * Cluster1 win0: 0x6, 0x7 [AXI0] 836 * * Cluster1 win1: 0x8, 0x9 [AXI0] 837 * * Esmart0: 0x10, 0x11 [AXI0] 838 * * Esmart1: 0x12, 0x13 [AXI0] 839 * * Esmart2: 0xa, 0xb [AXI1] 840 * * Esmart3: 0xc, 0xd [AXI1] 841 * * Lut dma rid: 0x1, 0x2, 0x3 [AXI0] 842 * * DCI dma rid: 0x4 [AXI0] 843 * * Metadata rid: 0x5 [AXI0] 844 * 845 * * Limit: 846 * * (1) Cluster0/1 are fixed on AXI0 by IC design 847 * * (2) 0x0 and 0xf can't be used; 848 * * (3) 5 Bits ID for eache axi bus 849 * * (3) cluster and lut/dci/metadata rid must smaller than 0xf, 850 * * if Cluster rid is bigger than 0xf, VOP will dead at the 851 * * system bandwidth very terrible scene. 852 */ 853 static const struct vop2_win_data rk3576_vop_win_data[] = { 854 { 855 .name = "Cluster0-win0", 856 .phys_id = ROCKCHIP_VOP2_CLUSTER0, 857 .base = 0x1000, 858 .possible_vp_mask = BIT(0) | BIT(1), 859 .formats = formats_rk3576_cluster, 860 .nformats = ARRAY_SIZE(formats_rk3576_cluster), 861 .format_modifiers = format_modifiers_rk3576_afbc, 862 .layer_sel_id = { 0, 0, 0xf, 0xf }, 863 .supported_rotations = DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 864 .type = DRM_PLANE_TYPE_PRIMARY, 865 .axi_bus_id = 0, 866 .axi_yrgb_r_id = 0xa, 867 .axi_uv_r_id = 0xb, 868 .max_upscale_factor = 4, 869 .max_downscale_factor = 4, 870 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 871 }, { 872 .name = "Cluster1-win0", 873 .phys_id = ROCKCHIP_VOP2_CLUSTER1, 874 .base = 0x1200, 875 .possible_vp_mask = BIT(0) | BIT(1), 876 .formats = formats_rk3576_cluster, 877 .nformats = ARRAY_SIZE(formats_rk3576_cluster), 878 .format_modifiers = format_modifiers_rk3576_afbc, 879 .layer_sel_id = { 1, 1, 0xf, 0xf }, 880 .supported_rotations = DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 881 .type = DRM_PLANE_TYPE_PRIMARY, 882 .axi_bus_id = 0, 883 .axi_yrgb_r_id = 6, 884 .axi_uv_r_id = 7, 885 .max_upscale_factor = 4, 886 .max_downscale_factor = 4, 887 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 888 }, { 889 .name = "Esmart0-win0", 890 .phys_id = ROCKCHIP_VOP2_ESMART0, 891 .base = 0x1800, 892 .possible_vp_mask = BIT(0) | BIT(2), 893 .formats = formats_rk3576_esmart, 894 .nformats = ARRAY_SIZE(formats_rk3576_esmart), 895 .format_modifiers = format_modifiers, 896 .layer_sel_id = { 2, 0xf, 0, 0xf }, 897 .supported_rotations = DRM_MODE_REFLECT_Y, 898 .type = DRM_PLANE_TYPE_OVERLAY, 899 .axi_bus_id = 0, 900 .axi_yrgb_r_id = 0x10, 901 .axi_uv_r_id = 0x11, 902 .max_upscale_factor = 8, 903 .max_downscale_factor = 8, 904 }, { 905 .name = "Esmart1-win0", 906 .phys_id = ROCKCHIP_VOP2_ESMART1, 907 .base = 0x1a00, 908 .possible_vp_mask = BIT(1) | BIT(2), 909 .formats = formats_rk3576_esmart, 910 .nformats = ARRAY_SIZE(formats_rk3576_esmart), 911 .format_modifiers = format_modifiers, 912 .layer_sel_id = { 0xf, 2, 1, 0xf }, 913 .supported_rotations = DRM_MODE_REFLECT_Y, 914 .type = DRM_PLANE_TYPE_OVERLAY, 915 .axi_bus_id = 0, 916 .axi_yrgb_r_id = 0x12, 917 .axi_uv_r_id = 0x13, 918 .max_upscale_factor = 8, 919 .max_downscale_factor = 8, 920 }, { 921 .name = "Esmart2-win0", 922 .phys_id = ROCKCHIP_VOP2_ESMART2, 923 .base = 0x1c00, 924 .possible_vp_mask = BIT(0) | BIT(2), 925 .formats = formats_rk3576_esmart, 926 .nformats = ARRAY_SIZE(formats_rk3576_esmart), 927 .format_modifiers = format_modifiers, 928 .layer_sel_id = { 3, 0xf, 2, 0xf }, 929 .supported_rotations = DRM_MODE_REFLECT_Y, 930 .type = DRM_PLANE_TYPE_OVERLAY, 931 .axi_bus_id = 1, 932 .axi_yrgb_r_id = 0x0a, 933 .axi_uv_r_id = 0x0b, 934 .max_upscale_factor = 8, 935 .max_downscale_factor = 8, 936 }, { 937 .name = "Esmart3-win0", 938 .phys_id = ROCKCHIP_VOP2_ESMART3, 939 .base = 0x1e00, 940 .possible_vp_mask = BIT(1) | BIT(2), 941 .formats = formats_rk3576_esmart, 942 .nformats = ARRAY_SIZE(formats_rk3576_esmart), 943 .format_modifiers = format_modifiers, 944 .layer_sel_id = { 0xf, 3, 3, 0xf }, 945 .supported_rotations = DRM_MODE_REFLECT_Y, 946 .type = DRM_PLANE_TYPE_OVERLAY, 947 .axi_bus_id = 1, 948 .axi_yrgb_r_id = 0x0c, 949 .axi_uv_r_id = 0x0d, 950 .max_upscale_factor = 8, 951 .max_downscale_factor = 8, 952 }, 953 }; 954 955 static const struct vop2_regs_dump rk3576_regs_dump[] = { 956 { 957 .name = "SYS", 958 .base = RK3568_REG_CFG_DONE, 959 .size = 0x200, 960 .en_reg = 0, 961 .en_val = 0, 962 .en_mask = 0 963 }, { 964 .name = "OVL_SYS", 965 .base = RK3576_SYS_EXTRA_ALPHA_CTRL, 966 .size = 0x50, 967 .en_reg = 0, 968 .en_val = 0, 969 .en_mask = 0, 970 }, { 971 .name = "OVL_VP0", 972 .base = RK3576_OVL_CTRL(0), 973 .size = 0x80, 974 .en_reg = 0, 975 .en_val = 0, 976 .en_mask = 0, 977 }, { 978 .name = "OVL_VP1", 979 .base = RK3576_OVL_CTRL(1), 980 .size = 0x80, 981 .en_reg = 0, 982 .en_val = 0, 983 .en_mask = 0, 984 }, { 985 .name = "OVL_VP2", 986 .base = RK3576_OVL_CTRL(2), 987 .size = 0x80, 988 .en_reg = 0, 989 .en_val = 0, 990 .en_mask = 0, 991 }, { 992 .name = "VP0", 993 .base = RK3568_VP0_CTRL_BASE, 994 .size = 0x100, 995 .en_reg = RK3568_VP_DSP_CTRL, 996 .en_val = 0, 997 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 998 }, { 999 .name = "VP1", 1000 .base = RK3568_VP1_CTRL_BASE, 1001 .size = 0x100, 1002 .en_reg = RK3568_VP_DSP_CTRL, 1003 .en_val = 0, 1004 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 1005 }, { 1006 .name = "VP2", 1007 .base = RK3568_VP2_CTRL_BASE, 1008 .size = 0x100, 1009 .en_reg = RK3568_VP_DSP_CTRL, 1010 .en_val = 0, 1011 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 1012 }, { 1013 .name = "Cluster0", 1014 .base = RK3568_CLUSTER0_CTRL_BASE, 1015 .size = 0x200, 1016 .en_reg = RK3568_CLUSTER_WIN_CTRL0, 1017 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 1018 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 1019 }, { 1020 .name = "Cluster1", 1021 .base = RK3568_CLUSTER1_CTRL_BASE, 1022 .size = 0x200, 1023 .en_reg = RK3568_CLUSTER_WIN_CTRL0, 1024 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 1025 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 1026 }, { 1027 .name = "Esmart0", 1028 .base = RK3568_ESMART0_CTRL_BASE, 1029 .size = 0xf0, 1030 .en_reg = RK3568_SMART_REGION0_CTRL, 1031 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1032 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1033 }, { 1034 .name = "Esmart1", 1035 .base = RK3568_ESMART1_CTRL_BASE, 1036 .size = 0xf0, 1037 .en_reg = RK3568_SMART_REGION0_CTRL, 1038 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1039 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1040 }, { 1041 .name = "Esmart2", 1042 .base = RK3588_ESMART2_CTRL_BASE, 1043 .size = 0xf0, 1044 .en_reg = RK3568_SMART_REGION0_CTRL, 1045 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1046 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1047 }, { 1048 .name = "Esmart3", 1049 .base = RK3588_ESMART3_CTRL_BASE, 1050 .size = 0xf0, 1051 .en_reg = RK3568_SMART_REGION0_CTRL, 1052 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1053 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1054 }, 1055 }; 1056 1057 static const struct vop2_video_port_data rk3588_vop_video_ports[] = { 1058 { 1059 .id = 0, 1060 .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, 1061 .gamma_lut_len = 1024, 1062 .cubic_lut_len = 9 * 9 * 9, /* 9x9x9 */ 1063 .max_output = { 4096, 2304 }, 1064 /* hdr2sdr sdr2hdr hdr2hdr sdr2sdr */ 1065 .pre_scan_max_dly = { 76, 65, 65, 54 }, 1066 .offset = 0xc00, 1067 }, { 1068 .id = 1, 1069 .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, 1070 .gamma_lut_len = 1024, 1071 .cubic_lut_len = 729, /* 9x9x9 */ 1072 .max_output = { 4096, 2304 }, 1073 .pre_scan_max_dly = { 76, 65, 65, 54 }, 1074 .offset = 0xd00, 1075 }, { 1076 .id = 2, 1077 .feature = VOP2_VP_FEATURE_OUTPUT_10BIT, 1078 .gamma_lut_len = 1024, 1079 .cubic_lut_len = 17 * 17 * 17, /* 17x17x17 */ 1080 .max_output = { 4096, 2304 }, 1081 .pre_scan_max_dly = { 52, 52, 52, 52 }, 1082 .offset = 0xe00, 1083 }, { 1084 .id = 3, 1085 .gamma_lut_len = 1024, 1086 .max_output = { 2048, 1536 }, 1087 .pre_scan_max_dly = { 52, 52, 52, 52 }, 1088 .offset = 0xf00, 1089 }, 1090 }; 1091 1092 /* 1093 * rk3588 vop with 4 cluster, 4 esmart win. 1094 * Every cluster can work as 4K win or split into two win. 1095 * All win in cluster support AFBCD. 1096 * 1097 * Every esmart win and smart win support 4 Multi-region. 1098 * 1099 * Scale filter mode: 1100 * 1101 * * Cluster: bicubic for horizontal scale up, others use bilinear 1102 * * ESmart: 1103 * * nearest-neighbor/bilinear/bicubic for scale up 1104 * * nearest-neighbor/bilinear/average for scale down 1105 * 1106 * AXI Read ID assignment: 1107 * Two AXI bus: 1108 * AXI0 is a read/write bus with a higher performance. 1109 * AXI1 is a read only bus. 1110 * 1111 * Every window on a AXI bus must assigned two unique 1112 * read id(yrgb_r_id/uv_r_id, valid id are 0x1~0xe). 1113 * 1114 * AXI0: 1115 * Cluster0/1, Esmart0/1, WriteBack 1116 * 1117 * AXI 1: 1118 * Cluster2/3, Esmart2/3 1119 * 1120 */ 1121 static const struct vop2_win_data rk3588_vop_win_data[] = { 1122 { 1123 .name = "Cluster0-win0", 1124 .phys_id = ROCKCHIP_VOP2_CLUSTER0, 1125 .base = 0x1000, 1126 .possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), 1127 .formats = formats_cluster, 1128 .nformats = ARRAY_SIZE(formats_cluster), 1129 .format_modifiers = format_modifiers_afbc, 1130 .layer_sel_id = { 0, 0, 0, 0 }, 1131 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 1132 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 1133 .axi_bus_id = 0, 1134 .axi_yrgb_r_id = 2, 1135 .axi_uv_r_id = 3, 1136 .max_upscale_factor = 4, 1137 .max_downscale_factor = 4, 1138 .dly = { 4, 26, 29 }, 1139 .type = DRM_PLANE_TYPE_PRIMARY, 1140 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 1141 }, { 1142 .name = "Cluster1-win0", 1143 .phys_id = ROCKCHIP_VOP2_CLUSTER1, 1144 .base = 0x1200, 1145 .possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), 1146 .formats = formats_cluster, 1147 .nformats = ARRAY_SIZE(formats_cluster), 1148 .format_modifiers = format_modifiers_afbc, 1149 .layer_sel_id = { 1, 1, 1, 1 }, 1150 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 1151 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 1152 .type = DRM_PLANE_TYPE_PRIMARY, 1153 .axi_bus_id = 0, 1154 .axi_yrgb_r_id = 6, 1155 .axi_uv_r_id = 7, 1156 .max_upscale_factor = 4, 1157 .max_downscale_factor = 4, 1158 .dly = { 4, 26, 29 }, 1159 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 1160 }, { 1161 .name = "Cluster2-win0", 1162 .phys_id = ROCKCHIP_VOP2_CLUSTER2, 1163 .base = 0x1400, 1164 .possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), 1165 .formats = formats_cluster, 1166 .nformats = ARRAY_SIZE(formats_cluster), 1167 .format_modifiers = format_modifiers_afbc, 1168 .layer_sel_id = { 4, 4, 4, 4 }, 1169 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 1170 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 1171 .type = DRM_PLANE_TYPE_PRIMARY, 1172 .axi_bus_id = 1, 1173 .axi_yrgb_r_id = 2, 1174 .axi_uv_r_id = 3, 1175 .max_upscale_factor = 4, 1176 .max_downscale_factor = 4, 1177 .dly = { 4, 26, 29 }, 1178 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 1179 }, { 1180 .name = "Cluster3-win0", 1181 .phys_id = ROCKCHIP_VOP2_CLUSTER3, 1182 .base = 0x1600, 1183 .possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), 1184 .formats = formats_cluster, 1185 .nformats = ARRAY_SIZE(formats_cluster), 1186 .format_modifiers = format_modifiers_afbc, 1187 .layer_sel_id = { 5, 5, 5, 5 }, 1188 .supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 | 1189 DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y, 1190 .type = DRM_PLANE_TYPE_PRIMARY, 1191 .axi_bus_id = 1, 1192 .axi_yrgb_r_id = 6, 1193 .axi_uv_r_id = 7, 1194 .max_upscale_factor = 4, 1195 .max_downscale_factor = 4, 1196 .dly = { 4, 26, 29 }, 1197 .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER, 1198 }, { 1199 .name = "Esmart0-win0", 1200 .phys_id = ROCKCHIP_VOP2_ESMART0, 1201 .possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), 1202 .formats = formats_esmart, 1203 .nformats = ARRAY_SIZE(formats_esmart), 1204 .format_modifiers = format_modifiers, 1205 .base = 0x1800, 1206 .layer_sel_id = { 2, 2, 2, 2 }, 1207 .supported_rotations = DRM_MODE_REFLECT_Y, 1208 .type = DRM_PLANE_TYPE_OVERLAY, 1209 .axi_bus_id = 0, 1210 .axi_yrgb_r_id = 0x0a, 1211 .axi_uv_r_id = 0x0b, 1212 .max_upscale_factor = 8, 1213 .max_downscale_factor = 8, 1214 .dly = { 23, 45, 48 }, 1215 }, { 1216 .name = "Esmart1-win0", 1217 .phys_id = ROCKCHIP_VOP2_ESMART1, 1218 .possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), 1219 .formats = formats_esmart, 1220 .nformats = ARRAY_SIZE(formats_esmart), 1221 .format_modifiers = format_modifiers, 1222 .base = 0x1a00, 1223 .layer_sel_id = { 3, 3, 3, 3 }, 1224 .supported_rotations = DRM_MODE_REFLECT_Y, 1225 .type = DRM_PLANE_TYPE_OVERLAY, 1226 .axi_bus_id = 0, 1227 .axi_yrgb_r_id = 0x0c, 1228 .axi_uv_r_id = 0x01, 1229 .max_upscale_factor = 8, 1230 .max_downscale_factor = 8, 1231 .dly = { 23, 45, 48 }, 1232 }, { 1233 .name = "Esmart2-win0", 1234 .phys_id = ROCKCHIP_VOP2_ESMART2, 1235 .base = 0x1c00, 1236 .possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), 1237 .formats = formats_esmart, 1238 .nformats = ARRAY_SIZE(formats_esmart), 1239 .format_modifiers = format_modifiers, 1240 .layer_sel_id = { 6, 6, 6, 6 }, 1241 .supported_rotations = DRM_MODE_REFLECT_Y, 1242 .type = DRM_PLANE_TYPE_OVERLAY, 1243 .axi_bus_id = 1, 1244 .axi_yrgb_r_id = 0x0a, 1245 .axi_uv_r_id = 0x0b, 1246 .max_upscale_factor = 8, 1247 .max_downscale_factor = 8, 1248 .dly = { 23, 45, 48 }, 1249 }, { 1250 .name = "Esmart3-win0", 1251 .phys_id = ROCKCHIP_VOP2_ESMART3, 1252 .possible_vp_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), 1253 .formats = formats_esmart, 1254 .nformats = ARRAY_SIZE(formats_esmart), 1255 .format_modifiers = format_modifiers, 1256 .base = 0x1e00, 1257 .layer_sel_id = { 7, 7, 7, 7 }, 1258 .supported_rotations = DRM_MODE_REFLECT_Y, 1259 .type = DRM_PLANE_TYPE_OVERLAY, 1260 .axi_bus_id = 1, 1261 .axi_yrgb_r_id = 0x0c, 1262 .axi_uv_r_id = 0x0d, 1263 .max_upscale_factor = 8, 1264 .max_downscale_factor = 8, 1265 .dly = { 23, 45, 48 }, 1266 }, 1267 }; 1268 1269 static const struct vop2_regs_dump rk3588_regs_dump[] = { 1270 { 1271 .name = "SYS", 1272 .base = RK3568_REG_CFG_DONE, 1273 .size = 0x100, 1274 .en_reg = 0, 1275 .en_val = 0, 1276 .en_mask = 0 1277 }, { 1278 .name = "OVL", 1279 .base = RK3568_OVL_CTRL, 1280 .size = 0x100, 1281 .en_reg = 0, 1282 .en_val = 0, 1283 .en_mask = 0, 1284 }, { 1285 .name = "VP0", 1286 .base = RK3568_VP0_CTRL_BASE, 1287 .size = 0x100, 1288 .en_reg = RK3568_VP_DSP_CTRL, 1289 .en_val = 0, 1290 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 1291 }, { 1292 .name = "VP1", 1293 .base = RK3568_VP1_CTRL_BASE, 1294 .size = 0x100, 1295 .en_reg = RK3568_VP_DSP_CTRL, 1296 .en_val = 0, 1297 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 1298 }, { 1299 .name = "VP2", 1300 .base = RK3568_VP2_CTRL_BASE, 1301 .size = 0x100, 1302 .en_reg = RK3568_VP_DSP_CTRL, 1303 .en_val = 0, 1304 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 1305 1306 }, { 1307 .name = "VP3", 1308 .base = RK3588_VP3_CTRL_BASE, 1309 .size = 0x100, 1310 .en_reg = RK3568_VP_DSP_CTRL, 1311 .en_val = 0, 1312 .en_mask = RK3568_VP_DSP_CTRL__STANDBY, 1313 }, { 1314 .name = "Cluster0", 1315 .base = RK3568_CLUSTER0_CTRL_BASE, 1316 .size = 0x110, 1317 .en_reg = RK3568_CLUSTER_WIN_CTRL0, 1318 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 1319 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 1320 }, { 1321 .name = "Cluster1", 1322 .base = RK3568_CLUSTER1_CTRL_BASE, 1323 .size = 0x110, 1324 .en_reg = RK3568_CLUSTER_WIN_CTRL0, 1325 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 1326 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 1327 }, { 1328 .name = "Cluster2", 1329 .base = RK3588_CLUSTER2_CTRL_BASE, 1330 .size = 0x110, 1331 .en_reg = RK3568_CLUSTER_WIN_CTRL0, 1332 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 1333 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 1334 }, { 1335 .name = "Cluster3", 1336 .base = RK3588_CLUSTER3_CTRL_BASE, 1337 .size = 0x110, 1338 .en_reg = RK3568_CLUSTER_WIN_CTRL0, 1339 .en_val = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 1340 .en_mask = RK3568_CLUSTER_WIN_CTRL0__WIN0_EN, 1341 }, { 1342 .name = "Esmart0", 1343 .base = RK3568_ESMART0_CTRL_BASE, 1344 .size = 0xf0, 1345 .en_reg = RK3568_SMART_REGION0_CTRL, 1346 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1347 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1348 }, { 1349 .name = "Esmart1", 1350 .base = RK3568_ESMART1_CTRL_BASE, 1351 .size = 0xf0, 1352 .en_reg = RK3568_SMART_REGION0_CTRL, 1353 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1354 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1355 }, { 1356 .name = "Esmart2", 1357 .base = RK3588_ESMART2_CTRL_BASE, 1358 .size = 0xf0, 1359 .en_reg = RK3568_SMART_REGION0_CTRL, 1360 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1361 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1362 }, { 1363 .name = "Esmart3", 1364 .base = RK3588_ESMART3_CTRL_BASE, 1365 .size = 0xf0, 1366 .en_reg = RK3568_SMART_REGION0_CTRL, 1367 .en_val = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1368 .en_mask = RK3568_SMART_REGION0_CTRL__WIN0_EN, 1369 }, 1370 }; 1371 1372 /* 1373 * phys_id is used to identify a main window(Cluster Win/Smart Win, not 1374 * include the sub win of a cluster or the multi area) that can do overlay 1375 * in main overlay stage. 1376 */ 1377 static struct vop2_win *vop2_find_win_by_phys_id(struct vop2 *vop2, uint8_t phys_id) 1378 { 1379 struct vop2_win *win; 1380 int i; 1381 1382 for (i = 0; i < vop2->data->win_size; i++) { 1383 win = &vop2->win[i]; 1384 if (win->data->phys_id == phys_id) 1385 return win; 1386 } 1387 1388 return NULL; 1389 } 1390 1391 static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags) 1392 { 1393 struct vop2 *vop2 = vp->vop2; 1394 struct drm_crtc *crtc = &vp->crtc; 1395 u32 die, dip; 1396 1397 die = vop2_readl(vop2, RK3568_DSP_IF_EN); 1398 dip = vop2_readl(vop2, RK3568_DSP_IF_POL); 1399 1400 switch (id) { 1401 case ROCKCHIP_VOP2_EP_RGB0: 1402 die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX; 1403 die |= RK3568_SYS_DSP_INFACE_EN_RGB | 1404 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id); 1405 dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL; 1406 dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags); 1407 if (polflags & POLFLAG_DCLK_INV) 1408 regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3)); 1409 else 1410 regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16)); 1411 break; 1412 case ROCKCHIP_VOP2_EP_HDMI0: 1413 die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX; 1414 die |= RK3568_SYS_DSP_INFACE_EN_HDMI | 1415 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id); 1416 dip &= ~RK3568_DSP_IF_POL__HDMI_PIN_POL; 1417 dip |= FIELD_PREP(RK3568_DSP_IF_POL__HDMI_PIN_POL, polflags); 1418 break; 1419 case ROCKCHIP_VOP2_EP_EDP0: 1420 die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX; 1421 die |= RK3568_SYS_DSP_INFACE_EN_EDP | 1422 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id); 1423 dip &= ~RK3568_DSP_IF_POL__EDP_PIN_POL; 1424 dip |= FIELD_PREP(RK3568_DSP_IF_POL__EDP_PIN_POL, polflags); 1425 break; 1426 case ROCKCHIP_VOP2_EP_MIPI0: 1427 die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX; 1428 die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 | 1429 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id); 1430 dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL; 1431 dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags); 1432 break; 1433 case ROCKCHIP_VOP2_EP_MIPI1: 1434 die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX; 1435 die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 | 1436 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id); 1437 dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL; 1438 dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags); 1439 break; 1440 case ROCKCHIP_VOP2_EP_LVDS0: 1441 die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX; 1442 die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 | 1443 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id); 1444 dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL; 1445 dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags); 1446 break; 1447 case ROCKCHIP_VOP2_EP_LVDS1: 1448 die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX; 1449 die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 | 1450 FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id); 1451 dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL; 1452 dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags); 1453 break; 1454 default: 1455 drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id); 1456 return 0; 1457 } 1458 1459 dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD; 1460 1461 vop2_writel(vop2, RK3568_DSP_IF_EN, die); 1462 vop2_writel(vop2, RK3568_DSP_IF_POL, dip); 1463 1464 return crtc->state->adjusted_mode.crtc_clock * 1000LL; 1465 } 1466 1467 static unsigned long rk3576_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags) 1468 { 1469 struct vop2 *vop2 = vp->vop2; 1470 struct drm_crtc *crtc = &vp->crtc; 1471 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; 1472 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); 1473 u8 port_pix_rate = vp->data->pixel_rate; 1474 int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_sel; 1475 u32 ctrl, vp_clk_div, reg, dclk_div; 1476 unsigned long dclk_in_rate, dclk_core_rate; 1477 1478 if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV420 || adjusted_mode->crtc_clock > 600000) 1479 dclk_div = 2; 1480 else 1481 dclk_div = 1; 1482 1483 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) 1484 dclk_core_rate = adjusted_mode->crtc_clock / 2; 1485 else 1486 dclk_core_rate = adjusted_mode->crtc_clock / port_pix_rate; 1487 1488 dclk_in_rate = adjusted_mode->crtc_clock / dclk_div; 1489 1490 dclk_core_div = dclk_in_rate > dclk_core_rate ? 1 : 0; 1491 1492 if (vop2_output_if_is_edp(id)) 1493 if_pixclk_div = port_pix_rate == 2 ? RK3576_DSP_IF_PCLK_DIV : 0; 1494 else 1495 if_pixclk_div = port_pix_rate == 1 ? RK3576_DSP_IF_PCLK_DIV : 0; 1496 1497 if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV420) { 1498 if_dclk_sel = RK3576_DSP_IF_DCLK_SEL_OUT; 1499 dclk_out_div = 1; 1500 } else { 1501 if_dclk_sel = 0; 1502 dclk_out_div = 0; 1503 } 1504 1505 switch (id) { 1506 case ROCKCHIP_VOP2_EP_HDMI0: 1507 reg = RK3576_HDMI0_IF_CTRL; 1508 break; 1509 case ROCKCHIP_VOP2_EP_EDP0: 1510 reg = RK3576_EDP0_IF_CTRL; 1511 break; 1512 case ROCKCHIP_VOP2_EP_MIPI0: 1513 reg = RK3576_MIPI0_IF_CTRL; 1514 break; 1515 case ROCKCHIP_VOP2_EP_DP0: 1516 reg = RK3576_DP0_IF_CTRL; 1517 break; 1518 case ROCKCHIP_VOP2_EP_DP1: 1519 reg = RK3576_DP1_IF_CTRL; 1520 break; 1521 default: 1522 drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id); 1523 return 0; 1524 } 1525 1526 ctrl = vop2_readl(vop2, reg); 1527 ctrl &= ~RK3576_DSP_IF_DCLK_SEL_OUT; 1528 ctrl &= ~RK3576_DSP_IF_PCLK_DIV; 1529 ctrl &= ~RK3576_DSP_IF_MUX; 1530 ctrl |= RK3576_DSP_IF_CFG_DONE_IMD; 1531 ctrl |= if_dclk_sel | if_pixclk_div; 1532 ctrl |= RK3576_DSP_IF_CLK_OUT_EN | RK3576_DSP_IF_EN; 1533 ctrl |= FIELD_PREP(RK3576_DSP_IF_MUX, vp->id); 1534 ctrl |= FIELD_PREP(RK3576_DSP_IF_PIN_POL, polflags); 1535 vop2_writel(vop2, reg, ctrl); 1536 1537 vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div); 1538 vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div); 1539 1540 vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div); 1541 1542 return dclk_in_rate * 1000LL; 1543 } 1544 1545 /* 1546 * calc the dclk on rk3588 1547 * the available div of dclk is 1, 2, 4 1548 */ 1549 static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max_dclk) 1550 { 1551 if (child_clk * 4 <= max_dclk) 1552 return child_clk * 4; 1553 else if (child_clk * 2 <= max_dclk) 1554 return child_clk * 2; 1555 else if (child_clk <= max_dclk) 1556 return child_clk; 1557 else 1558 return 0; 1559 } 1560 1561 /* 1562 * 4 pixclk/cycle on rk3588 1563 * RGB/eDP/HDMI: if_pixclk >= dclk_core 1564 * DP: dp_pixclk = dclk_out <= dclk_core 1565 * DSI: mipi_pixclk <= dclk_out <= dclk_core 1566 */ 1567 static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id, 1568 int *dclk_core_div, int *dclk_out_div, 1569 int *if_pixclk_div, int *if_dclk_div) 1570 { 1571 struct vop2 *vop2 = vp->vop2; 1572 struct drm_crtc *crtc = &vp->crtc; 1573 struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; 1574 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); 1575 int output_mode = vcstate->output_mode; 1576 unsigned long v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */ 1577 unsigned long dclk_core_rate = v_pixclk >> 2; 1578 unsigned long dclk_rate = v_pixclk; 1579 unsigned long dclk_out_rate; 1580 unsigned long if_pixclk_rate; 1581 int K = 1; 1582 1583 if (vop2_output_if_is_hdmi(id)) { 1584 /* 1585 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate 1586 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate 1587 */ 1588 if (output_mode == ROCKCHIP_OUT_MODE_YUV420) { 1589 dclk_rate = dclk_rate >> 1; 1590 K = 2; 1591 } 1592 1593 /* 1594 * if_pixclk_rate = (dclk_core_rate << 1) / K; 1595 * if_dclk_rate = dclk_core_rate / K; 1596 * *if_pixclk_div = dclk_rate / if_pixclk_rate; 1597 * *if_dclk_div = dclk_rate / if_dclk_rate; 1598 */ 1599 *if_pixclk_div = 2; 1600 *if_dclk_div = 4; 1601 } else if (vop2_output_if_is_edp(id)) { 1602 /* 1603 * edp_pixclk = edp_dclk > dclk_core 1604 */ 1605 if_pixclk_rate = v_pixclk / K; 1606 dclk_rate = if_pixclk_rate * K; 1607 /* 1608 * *if_pixclk_div = dclk_rate / if_pixclk_rate; 1609 * *if_dclk_div = *if_pixclk_div; 1610 */ 1611 *if_pixclk_div = K; 1612 *if_dclk_div = K; 1613 } else if (vop2_output_if_is_dp(id)) { 1614 if (output_mode == ROCKCHIP_OUT_MODE_YUV420) 1615 dclk_out_rate = v_pixclk >> 3; 1616 else 1617 dclk_out_rate = v_pixclk >> 2; 1618 1619 dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000); 1620 if (!dclk_rate) { 1621 drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld Hz\n", 1622 dclk_out_rate); 1623 return 0; 1624 } 1625 *dclk_out_div = dclk_rate / dclk_out_rate; 1626 } else if (vop2_output_if_is_mipi(id)) { 1627 if_pixclk_rate = dclk_core_rate / K; 1628 /* 1629 * dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4 1630 */ 1631 dclk_out_rate = if_pixclk_rate; 1632 /* 1633 * dclk_rate = N * dclk_core_rate N = (1,2,4 ), 1634 * we get a little factor here 1635 */ 1636 dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000); 1637 if (!dclk_rate) { 1638 drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld Hz\n", 1639 dclk_out_rate); 1640 return 0; 1641 } 1642 *dclk_out_div = dclk_rate / dclk_out_rate; 1643 /* 1644 * mipi pixclk == dclk_out 1645 */ 1646 *if_pixclk_div = 1; 1647 } else if (vop2_output_if_is_dpi(id)) { 1648 dclk_rate = v_pixclk; 1649 } 1650 1651 *dclk_core_div = dclk_rate / dclk_core_rate; 1652 *if_pixclk_div = ilog2(*if_pixclk_div); 1653 *if_dclk_div = ilog2(*if_dclk_div); 1654 *dclk_core_div = ilog2(*dclk_core_div); 1655 *dclk_out_div = ilog2(*dclk_out_div); 1656 1657 drm_dbg(vop2->drm, "dclk: %ld, pixclk_div: %d, dclk_div: %d\n", 1658 dclk_rate, *if_pixclk_div, *if_dclk_div); 1659 1660 return dclk_rate; 1661 } 1662 1663 /* 1664 * MIPI port mux on rk3588: 1665 * 0: Video Port2 1666 * 1: Video Port3 1667 * 3: Video Port 1(MIPI1 only) 1668 */ 1669 static u32 rk3588_get_mipi_port_mux(int vp_id) 1670 { 1671 if (vp_id == 1) 1672 return 3; 1673 else if (vp_id == 3) 1674 return 1; 1675 else 1676 return 0; 1677 } 1678 1679 static u32 rk3588_get_hdmi_pol(u32 flags) 1680 { 1681 u32 val; 1682 1683 val = (flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0; 1684 val |= (flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0; 1685 1686 return val; 1687 } 1688 1689 static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags) 1690 { 1691 struct vop2 *vop2 = vp->vop2; 1692 int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_div; 1693 unsigned long clock; 1694 u32 die, dip, div, vp_clk_div, val; 1695 1696 clock = rk3588_calc_cru_cfg(vp, id, &dclk_core_div, &dclk_out_div, 1697 &if_pixclk_div, &if_dclk_div); 1698 if (!clock) 1699 return 0; 1700 1701 vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div); 1702 vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div); 1703 1704 die = vop2_readl(vop2, RK3568_DSP_IF_EN); 1705 dip = vop2_readl(vop2, RK3568_DSP_IF_POL); 1706 div = vop2_readl(vop2, RK3568_DSP_IF_CTRL); 1707 1708 switch (id) { 1709 case ROCKCHIP_VOP2_EP_HDMI0: 1710 div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV; 1711 div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV; 1712 div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div); 1713 div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div); 1714 die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX; 1715 die |= RK3588_SYS_DSP_INFACE_EN_HDMI0 | 1716 FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id); 1717 val = rk3588_get_hdmi_pol(polflags); 1718 regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, FIELD_PREP_WM16(BIT(1), 1)); 1719 regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, 1720 FIELD_PREP_WM16(GENMASK(6, 5), val)); 1721 break; 1722 case ROCKCHIP_VOP2_EP_HDMI1: 1723 div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV; 1724 div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV; 1725 div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV, if_dclk_div); 1726 div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV, if_pixclk_div); 1727 die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX; 1728 die |= RK3588_SYS_DSP_INFACE_EN_HDMI1 | 1729 FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id); 1730 val = rk3588_get_hdmi_pol(polflags); 1731 regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, FIELD_PREP_WM16(BIT(4), 1)); 1732 regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, 1733 FIELD_PREP_WM16(GENMASK(8, 7), val)); 1734 break; 1735 case ROCKCHIP_VOP2_EP_EDP0: 1736 div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV; 1737 div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV; 1738 div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div); 1739 div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div); 1740 die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX; 1741 die |= RK3588_SYS_DSP_INFACE_EN_EDP0 | 1742 FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id); 1743 regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, FIELD_PREP_WM16(BIT(0), 1)); 1744 break; 1745 case ROCKCHIP_VOP2_EP_EDP1: 1746 div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV; 1747 div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV; 1748 div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div); 1749 div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div); 1750 die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX; 1751 die |= RK3588_SYS_DSP_INFACE_EN_EDP1 | 1752 FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id); 1753 regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, FIELD_PREP_WM16(BIT(3), 1)); 1754 break; 1755 case ROCKCHIP_VOP2_EP_MIPI0: 1756 div &= ~RK3588_DSP_IF_MIPI0_PCLK_DIV; 1757 div |= FIELD_PREP(RK3588_DSP_IF_MIPI0_PCLK_DIV, if_pixclk_div); 1758 die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX; 1759 val = rk3588_get_mipi_port_mux(vp->id); 1760 die |= RK3588_SYS_DSP_INFACE_EN_MIPI0 | 1761 FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX, !!val); 1762 break; 1763 case ROCKCHIP_VOP2_EP_MIPI1: 1764 div &= ~RK3588_DSP_IF_MIPI1_PCLK_DIV; 1765 div |= FIELD_PREP(RK3588_DSP_IF_MIPI1_PCLK_DIV, if_pixclk_div); 1766 die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX; 1767 val = rk3588_get_mipi_port_mux(vp->id); 1768 die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 | 1769 FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, val); 1770 break; 1771 case ROCKCHIP_VOP2_EP_DP0: 1772 die &= ~RK3588_SYS_DSP_INFACE_EN_DP0_MUX; 1773 die |= RK3588_SYS_DSP_INFACE_EN_DP0 | 1774 FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP0_MUX, vp->id); 1775 dip &= ~RK3588_DSP_IF_POL__DP0_PIN_POL; 1776 dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP0_PIN_POL, polflags); 1777 break; 1778 case ROCKCHIP_VOP2_EP_DP1: 1779 die &= ~RK3588_SYS_DSP_INFACE_EN_DP1_MUX; 1780 die |= RK3588_SYS_DSP_INFACE_EN_DP1 | 1781 FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP1_MUX, vp->id); 1782 dip &= ~RK3588_DSP_IF_POL__DP1_PIN_POL; 1783 dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP1_PIN_POL, polflags); 1784 break; 1785 default: 1786 drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id); 1787 return 0; 1788 } 1789 1790 dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD; 1791 1792 vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div); 1793 vop2_writel(vop2, RK3568_DSP_IF_EN, die); 1794 vop2_writel(vop2, RK3568_DSP_IF_CTRL, div); 1795 vop2_writel(vop2, RK3568_DSP_IF_POL, dip); 1796 1797 return clock; 1798 } 1799 1800 static bool is_opaque(u16 alpha) 1801 { 1802 return (alpha >> 8) == 0xff; 1803 } 1804 1805 static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config, 1806 struct vop2_alpha *alpha) 1807 { 1808 int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1; 1809 int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1; 1810 int src_color_mode = alpha_config->src_premulti_en ? 1811 ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL; 1812 int dst_color_mode = alpha_config->dst_premulti_en ? 1813 ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL; 1814 1815 alpha->src_color_ctrl.val = 0; 1816 alpha->dst_color_ctrl.val = 0; 1817 alpha->src_alpha_ctrl.val = 0; 1818 alpha->dst_alpha_ctrl.val = 0; 1819 1820 if (!alpha_config->src_pixel_alpha_en) 1821 alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL; 1822 else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en) 1823 alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX; 1824 else 1825 alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL; 1826 1827 alpha->src_color_ctrl.bits.alpha_en = 1; 1828 1829 if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) { 1830 alpha->src_color_ctrl.bits.color_mode = src_color_mode; 1831 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL; 1832 } else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) { 1833 alpha->src_color_ctrl.bits.color_mode = src_color_mode; 1834 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE; 1835 } else { 1836 alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL; 1837 alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL; 1838 } 1839 alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8; 1840 alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; 1841 alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; 1842 1843 alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; 1844 alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; 1845 alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL; 1846 alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8; 1847 alpha->dst_color_ctrl.bits.color_mode = dst_color_mode; 1848 alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE; 1849 1850 alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; 1851 alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode; 1852 alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION; 1853 alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE; 1854 1855 alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT; 1856 if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en) 1857 alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX; 1858 else 1859 alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL; 1860 alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION; 1861 alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE; 1862 } 1863 1864 static int vop2_find_start_mixer_id_for_vp(struct vop2_video_port *vp) 1865 { 1866 struct vop2 *vop2 = vp->vop2; 1867 struct vop2_win *win; 1868 u32 layer_sel = vop2->old_layer_sel; 1869 u32 used_layer = 0; 1870 unsigned long win_mask = vp->win_mask; 1871 unsigned long phys_id; 1872 bool match; 1873 int i; 1874 1875 for (i = 0; i < 31; i += 4) { 1876 match = false; 1877 for_each_set_bit(phys_id, &win_mask, ROCKCHIP_VOP2_ESMART3) { 1878 win = vop2_find_win_by_phys_id(vop2, phys_id); 1879 if (win->data->layer_sel_id[vp->id] == ((layer_sel >> i) & 0xf)) { 1880 match = true; 1881 break; 1882 } 1883 } 1884 1885 if (!match) 1886 used_layer += 1; 1887 else 1888 break; 1889 } 1890 1891 return used_layer; 1892 } 1893 1894 static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win) 1895 { 1896 struct vop2_alpha_config alpha_config; 1897 struct vop2_alpha alpha; 1898 struct drm_plane_state *bottom_win_pstate; 1899 bool src_pixel_alpha_en = false; 1900 u16 src_glb_alpha_val, dst_glb_alpha_val; 1901 u32 src_color_ctrl_reg, dst_color_ctrl_reg, src_alpha_ctrl_reg, dst_alpha_ctrl_reg; 1902 u32 offset = 0; 1903 bool premulti_en = false; 1904 bool swap = false; 1905 1906 /* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */ 1907 bottom_win_pstate = main_win->base.state; 1908 src_glb_alpha_val = 0; 1909 dst_glb_alpha_val = main_win->base.state->alpha; 1910 1911 if (!bottom_win_pstate->fb) 1912 return; 1913 1914 alpha_config.src_premulti_en = premulti_en; 1915 alpha_config.dst_premulti_en = false; 1916 alpha_config.src_pixel_alpha_en = src_pixel_alpha_en; 1917 alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */ 1918 alpha_config.src_glb_alpha_value = src_glb_alpha_val; 1919 alpha_config.dst_glb_alpha_value = dst_glb_alpha_val; 1920 vop2_parse_alpha(&alpha_config, &alpha); 1921 1922 alpha.src_color_ctrl.bits.src_dst_swap = swap; 1923 1924 switch (main_win->data->phys_id) { 1925 case ROCKCHIP_VOP2_CLUSTER0: 1926 offset = 0x0; 1927 break; 1928 case ROCKCHIP_VOP2_CLUSTER1: 1929 offset = 0x10; 1930 break; 1931 case ROCKCHIP_VOP2_CLUSTER2: 1932 offset = 0x20; 1933 break; 1934 case ROCKCHIP_VOP2_CLUSTER3: 1935 offset = 0x30; 1936 break; 1937 } 1938 1939 if (vop2->version <= VOP_VERSION_RK3588) { 1940 src_color_ctrl_reg = RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL; 1941 dst_color_ctrl_reg = RK3568_CLUSTER0_MIX_DST_COLOR_CTRL; 1942 src_alpha_ctrl_reg = RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL; 1943 dst_alpha_ctrl_reg = RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL; 1944 } else { 1945 src_color_ctrl_reg = RK3576_CLUSTER0_MIX_SRC_COLOR_CTRL; 1946 dst_color_ctrl_reg = RK3576_CLUSTER0_MIX_DST_COLOR_CTRL; 1947 src_alpha_ctrl_reg = RK3576_CLUSTER0_MIX_SRC_ALPHA_CTRL; 1948 dst_alpha_ctrl_reg = RK3576_CLUSTER0_MIX_DST_ALPHA_CTRL; 1949 } 1950 1951 vop2_writel(vop2, src_color_ctrl_reg + offset, alpha.src_color_ctrl.val); 1952 vop2_writel(vop2, dst_color_ctrl_reg + offset, alpha.dst_color_ctrl.val); 1953 vop2_writel(vop2, src_alpha_ctrl_reg + offset, alpha.src_alpha_ctrl.val); 1954 vop2_writel(vop2, dst_alpha_ctrl_reg + offset, alpha.dst_alpha_ctrl.val); 1955 } 1956 1957 static void vop2_setup_alpha(struct vop2_video_port *vp) 1958 { 1959 struct vop2 *vop2 = vp->vop2; 1960 struct drm_framebuffer *fb; 1961 struct vop2_alpha_config alpha_config; 1962 struct vop2_alpha alpha; 1963 struct drm_plane *plane; 1964 int pixel_alpha_en; 1965 int premulti_en, gpremulti_en = 0; 1966 int mixer_id; 1967 u32 src_color_ctrl_reg, dst_color_ctrl_reg, src_alpha_ctrl_reg, dst_alpha_ctrl_reg; 1968 u32 offset; 1969 bool bottom_layer_alpha_en = false; 1970 u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE; 1971 1972 if (vop2->version <= VOP_VERSION_RK3588) 1973 mixer_id = vop2_find_start_mixer_id_for_vp(vp); 1974 else 1975 mixer_id = 0; 1976 1977 alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */ 1978 1979 drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { 1980 struct vop2_win *win = to_vop2_win(plane); 1981 1982 if (plane->state->normalized_zpos == 0 && 1983 !is_opaque(plane->state->alpha) && 1984 !vop2_cluster_window(win)) { 1985 /* 1986 * If bottom layer have global alpha effect [except cluster layer, 1987 * because cluster have deal with bottom layer global alpha value 1988 * at cluster mix], bottom layer mix need deal with global alpha. 1989 */ 1990 bottom_layer_alpha_en = true; 1991 dst_global_alpha = plane->state->alpha; 1992 } 1993 } 1994 1995 if (vop2->version <= VOP_VERSION_RK3588) { 1996 src_color_ctrl_reg = RK3568_MIX0_SRC_COLOR_CTRL; 1997 dst_color_ctrl_reg = RK3568_MIX0_DST_COLOR_CTRL; 1998 src_alpha_ctrl_reg = RK3568_MIX0_SRC_ALPHA_CTRL; 1999 dst_alpha_ctrl_reg = RK3568_MIX0_DST_ALPHA_CTRL; 2000 } else { 2001 src_color_ctrl_reg = RK3576_OVL_MIX0_SRC_COLOR_CTRL(vp->id); 2002 dst_color_ctrl_reg = RK3576_OVL_MIX0_DST_COLOR_CTRL(vp->id); 2003 src_alpha_ctrl_reg = RK3576_OVL_MIX0_SRC_ALPHA_CTRL(vp->id); 2004 dst_alpha_ctrl_reg = RK3576_OVL_MIX0_DST_ALPHA_CTRL(vp->id); 2005 } 2006 2007 drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { 2008 struct vop2_win *win = to_vop2_win(plane); 2009 int zpos = plane->state->normalized_zpos; 2010 2011 /* 2012 * Need to configure alpha from second layer. 2013 */ 2014 if (zpos == 0) 2015 continue; 2016 2017 if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) 2018 premulti_en = 1; 2019 else 2020 premulti_en = 0; 2021 2022 plane = &win->base; 2023 fb = plane->state->fb; 2024 2025 pixel_alpha_en = fb->format->has_alpha; 2026 2027 alpha_config.src_premulti_en = premulti_en; 2028 2029 if (bottom_layer_alpha_en && zpos == 1) { 2030 gpremulti_en = premulti_en; 2031 /* Cd = Cs + (1 - As) * Cd * Agd */ 2032 alpha_config.dst_premulti_en = false; 2033 alpha_config.src_pixel_alpha_en = pixel_alpha_en; 2034 alpha_config.src_glb_alpha_value = plane->state->alpha; 2035 alpha_config.dst_glb_alpha_value = dst_global_alpha; 2036 } else if (vop2_cluster_window(win)) { 2037 /* Mix output data only have pixel alpha */ 2038 alpha_config.dst_premulti_en = true; 2039 alpha_config.src_pixel_alpha_en = true; 2040 alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; 2041 alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; 2042 } else { 2043 /* Cd = Cs + (1 - As) * Cd */ 2044 alpha_config.dst_premulti_en = true; 2045 alpha_config.src_pixel_alpha_en = pixel_alpha_en; 2046 alpha_config.src_glb_alpha_value = plane->state->alpha; 2047 alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; 2048 } 2049 2050 vop2_parse_alpha(&alpha_config, &alpha); 2051 2052 offset = (mixer_id + zpos - 1) * 0x10; 2053 2054 vop2_writel(vop2, src_color_ctrl_reg + offset, alpha.src_color_ctrl.val); 2055 vop2_writel(vop2, dst_color_ctrl_reg + offset, alpha.dst_color_ctrl.val); 2056 vop2_writel(vop2, src_alpha_ctrl_reg + offset, alpha.src_alpha_ctrl.val); 2057 vop2_writel(vop2, dst_alpha_ctrl_reg + offset, alpha.dst_alpha_ctrl.val); 2058 } 2059 2060 if (vp->id == 0) { 2061 if (vop2->version <= VOP_VERSION_RK3588) { 2062 src_color_ctrl_reg = RK3568_HDR0_SRC_COLOR_CTRL; 2063 dst_color_ctrl_reg = RK3568_HDR0_DST_COLOR_CTRL; 2064 src_alpha_ctrl_reg = RK3568_HDR0_SRC_ALPHA_CTRL; 2065 dst_alpha_ctrl_reg = RK3568_HDR0_DST_ALPHA_CTRL; 2066 } else { 2067 src_color_ctrl_reg = RK3576_OVL_HDR_SRC_COLOR_CTRL(vp->id); 2068 dst_color_ctrl_reg = RK3576_OVL_HDR_DST_COLOR_CTRL(vp->id); 2069 src_alpha_ctrl_reg = RK3576_OVL_HDR_SRC_ALPHA_CTRL(vp->id); 2070 dst_alpha_ctrl_reg = RK3576_OVL_HDR_DST_ALPHA_CTRL(vp->id); 2071 } 2072 2073 if (bottom_layer_alpha_en) { 2074 /* Transfer pixel alpha to hdr mix */ 2075 alpha_config.src_premulti_en = gpremulti_en; 2076 alpha_config.dst_premulti_en = true; 2077 alpha_config.src_pixel_alpha_en = true; 2078 alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; 2079 alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE; 2080 2081 vop2_parse_alpha(&alpha_config, &alpha); 2082 2083 vop2_writel(vop2, src_color_ctrl_reg, alpha.src_color_ctrl.val); 2084 vop2_writel(vop2, dst_color_ctrl_reg, alpha.dst_color_ctrl.val); 2085 vop2_writel(vop2, src_alpha_ctrl_reg, alpha.src_alpha_ctrl.val); 2086 vop2_writel(vop2, dst_alpha_ctrl_reg, alpha.dst_alpha_ctrl.val); 2087 } else { 2088 vop2_writel(vop2, src_color_ctrl_reg, 0); 2089 } 2090 } 2091 } 2092 2093 static u32 rk3568_vop2_read_port_mux(struct vop2 *vop2) 2094 { 2095 return vop2_readl(vop2, RK3568_OVL_PORT_SEL); 2096 } 2097 2098 static void rk3568_vop2_wait_for_port_mux_done(struct vop2 *vop2) 2099 { 2100 u32 port_mux_sel; 2101 int ret; 2102 2103 /* 2104 * Spin until the previous port_mux figuration is done. 2105 */ 2106 ret = readx_poll_timeout_atomic(rk3568_vop2_read_port_mux, vop2, port_mux_sel, 2107 port_mux_sel == vop2->old_port_sel, 10, 50 * 1000); 2108 if (ret) 2109 DRM_DEV_ERROR(vop2->dev, "wait port_mux done timeout: 0x%x--0x%x\n", 2110 port_mux_sel, vop2->old_port_sel); 2111 } 2112 2113 static u32 rk3568_vop2_read_layer_cfg(struct vop2 *vop2) 2114 { 2115 return vop2_readl(vop2, RK3568_OVL_LAYER_SEL); 2116 } 2117 2118 static void rk3568_vop2_wait_for_layer_cfg_done(struct vop2 *vop2, u32 cfg) 2119 { 2120 u32 atv_layer_cfg; 2121 int ret; 2122 2123 /* 2124 * Spin until the previous layer configuration is done. 2125 */ 2126 ret = readx_poll_timeout_atomic(rk3568_vop2_read_layer_cfg, vop2, atv_layer_cfg, 2127 atv_layer_cfg == cfg, 10, 50 * 1000); 2128 if (ret) 2129 DRM_DEV_ERROR(vop2->dev, "wait layer cfg done timeout: 0x%x--0x%x\n", 2130 atv_layer_cfg, cfg); 2131 } 2132 2133 static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp) 2134 { 2135 struct vop2 *vop2 = vp->vop2; 2136 struct drm_plane *plane; 2137 u32 layer_sel = 0; 2138 u32 port_sel; 2139 u32 old_layer_sel = 0; 2140 u32 atv_layer_sel = 0; 2141 u32 old_port_sel = 0; 2142 u8 layer_id; 2143 u8 old_layer_id; 2144 u8 layer_sel_id; 2145 unsigned int ofs; 2146 u32 ovl_ctrl; 2147 u32 cfg_done; 2148 int i; 2149 struct vop2_video_port *vp0 = &vop2->vps[0]; 2150 struct vop2_video_port *vp1 = &vop2->vps[1]; 2151 struct vop2_video_port *vp2 = &vop2->vps[2]; 2152 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state); 2153 2154 mutex_lock(&vop2->ovl_lock); 2155 ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL); 2156 ovl_ctrl &= ~RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD; 2157 ovl_ctrl &= ~RK3568_OVL_CTRL__LAYERSEL_REGDONE_SEL; 2158 2159 if (vcstate->yuv_overlay) 2160 ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id); 2161 else 2162 ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id); 2163 2164 old_port_sel = vop2->old_port_sel; 2165 port_sel = old_port_sel; 2166 port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT; 2167 2168 if (vp0->nlayers) 2169 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 2170 vp0->nlayers - 1); 2171 else 2172 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8); 2173 2174 if (vp1->nlayers) 2175 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 2176 (vp0->nlayers + vp1->nlayers - 1)); 2177 else 2178 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8); 2179 2180 if (vp2->nlayers) 2181 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 2182 (vp2->nlayers + vp1->nlayers + vp0->nlayers - 1)); 2183 else 2184 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8); 2185 2186 /* Fixed value for rk3588 */ 2187 if (vop2->version == VOP_VERSION_RK3588) 2188 port_sel |= FIELD_PREP(RK3588_OVL_PORT_SET__PORT3_MUX, 7); 2189 2190 atv_layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL); 2191 old_layer_sel = vop2->old_layer_sel; 2192 layer_sel = old_layer_sel; 2193 2194 ofs = 0; 2195 for (i = 0; i < vp->id; i++) 2196 ofs += vop2->vps[i].nlayers; 2197 2198 drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { 2199 struct vop2_win *win = to_vop2_win(plane); 2200 struct vop2_win *old_win; 2201 2202 layer_id = (u8)(plane->state->normalized_zpos + ofs); 2203 /* 2204 * Find the layer this win bind in old state. 2205 */ 2206 for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) { 2207 layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf; 2208 if (layer_sel_id == win->data->layer_sel_id[vp->id]) 2209 break; 2210 } 2211 2212 /* 2213 * Find the win bind to this layer in old state 2214 */ 2215 for (i = 0; i < vop2->data->win_size; i++) { 2216 old_win = &vop2->win[i]; 2217 layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf; 2218 if (layer_sel_id == old_win->data->layer_sel_id[vp->id]) 2219 break; 2220 } 2221 2222 switch (win->data->phys_id) { 2223 case ROCKCHIP_VOP2_CLUSTER0: 2224 port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0; 2225 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id); 2226 break; 2227 case ROCKCHIP_VOP2_CLUSTER1: 2228 port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1; 2229 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id); 2230 break; 2231 case ROCKCHIP_VOP2_CLUSTER2: 2232 port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER2; 2233 port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER2, vp->id); 2234 break; 2235 case ROCKCHIP_VOP2_CLUSTER3: 2236 port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER3; 2237 port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER3, vp->id); 2238 break; 2239 case ROCKCHIP_VOP2_ESMART0: 2240 port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0; 2241 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id); 2242 break; 2243 case ROCKCHIP_VOP2_ESMART1: 2244 port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1; 2245 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id); 2246 break; 2247 case ROCKCHIP_VOP2_ESMART2: 2248 port_sel &= ~RK3588_OVL_PORT_SEL__ESMART2; 2249 port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART2, vp->id); 2250 break; 2251 case ROCKCHIP_VOP2_ESMART3: 2252 port_sel &= ~RK3588_OVL_PORT_SEL__ESMART3; 2253 port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART3, vp->id); 2254 break; 2255 case ROCKCHIP_VOP2_SMART0: 2256 port_sel &= ~RK3568_OVL_PORT_SEL__SMART0; 2257 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id); 2258 break; 2259 case ROCKCHIP_VOP2_SMART1: 2260 port_sel &= ~RK3568_OVL_PORT_SEL__SMART1; 2261 port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id); 2262 break; 2263 } 2264 2265 layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7); 2266 layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id[vp->id]); 2267 /* 2268 * When we bind a window from layerM to layerN, we also need to move the old 2269 * window on layerN to layerM to avoid one window selected by two or more layers. 2270 */ 2271 layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7); 2272 layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 2273 old_win->data->layer_sel_id[vp->id]); 2274 } 2275 2276 vop2->old_layer_sel = layer_sel; 2277 vop2->old_port_sel = port_sel; 2278 /* 2279 * As the RK3568_OVL_LAYER_SEL and RK3568_OVL_PORT_SEL are shared by all Video Ports, 2280 * and the configuration take effect by one Video Port's vsync. 2281 * When performing layer migration or change the zpos of layers, there are two things 2282 * to be observed and followed: 2283 * 1. When a layer is migrated from one VP to another, the configuration of the layer 2284 * can only take effect after the Port mux configuration is enabled. 2285 * 2286 * 2. When we change the zpos of layers, we must ensure that the change for the previous 2287 * VP takes effect before we proceed to change the next VP. Otherwise, the new 2288 * configuration might overwrite the previous one for the previous VP, or it could 2289 * lead to the configuration of the previous VP being take effect along with the VSYNC 2290 * of the new VP. 2291 */ 2292 if (layer_sel != old_layer_sel || port_sel != old_port_sel) 2293 ovl_ctrl |= FIELD_PREP(RK3568_OVL_CTRL__LAYERSEL_REGDONE_SEL, vp->id); 2294 vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl); 2295 2296 if (port_sel != old_port_sel) { 2297 vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel); 2298 vop2_cfg_done(vp); 2299 rk3568_vop2_wait_for_port_mux_done(vop2); 2300 } 2301 2302 if (layer_sel != old_layer_sel && atv_layer_sel != old_layer_sel) { 2303 cfg_done = vop2_readl(vop2, RK3568_REG_CFG_DONE); 2304 cfg_done &= (BIT(vop2->data->nr_vps) - 1); 2305 cfg_done &= ~BIT(vp->id); 2306 /* 2307 * Changes of other VPs' overlays have not taken effect 2308 */ 2309 if (cfg_done) 2310 rk3568_vop2_wait_for_layer_cfg_done(vop2, vop2->old_layer_sel); 2311 } 2312 2313 vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel); 2314 mutex_unlock(&vop2->ovl_lock); 2315 } 2316 2317 static void rk3568_vop2_setup_dly_for_windows(struct vop2_video_port *vp) 2318 { 2319 struct vop2 *vop2 = vp->vop2; 2320 struct vop2_win *win; 2321 int i = 0; 2322 u32 cdly = 0, sdly = 0; 2323 2324 for (i = 0; i < vop2->data->win_size; i++) { 2325 u32 dly; 2326 2327 win = &vop2->win[i]; 2328 dly = win->delay; 2329 2330 switch (win->data->phys_id) { 2331 case ROCKCHIP_VOP2_CLUSTER0: 2332 cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly); 2333 cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly); 2334 break; 2335 case ROCKCHIP_VOP2_CLUSTER1: 2336 cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly); 2337 cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly); 2338 break; 2339 case ROCKCHIP_VOP2_ESMART0: 2340 sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly); 2341 break; 2342 case ROCKCHIP_VOP2_ESMART1: 2343 sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly); 2344 break; 2345 case ROCKCHIP_VOP2_SMART0: 2346 case ROCKCHIP_VOP2_ESMART2: 2347 sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly); 2348 break; 2349 case ROCKCHIP_VOP2_SMART1: 2350 case ROCKCHIP_VOP2_ESMART3: 2351 sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly); 2352 break; 2353 } 2354 } 2355 2356 vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly); 2357 vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly); 2358 } 2359 2360 static void rk3568_vop2_setup_overlay(struct vop2_video_port *vp) 2361 { 2362 struct vop2 *vop2 = vp->vop2; 2363 struct drm_crtc *crtc = &vp->crtc; 2364 struct drm_plane *plane; 2365 2366 vp->win_mask = 0; 2367 2368 drm_atomic_crtc_for_each_plane(plane, crtc) { 2369 struct vop2_win *win = to_vop2_win(plane); 2370 2371 win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT]; 2372 2373 vp->win_mask |= BIT(win->data->phys_id); 2374 2375 if (vop2_cluster_window(win)) 2376 vop2_setup_cluster_alpha(vop2, win); 2377 } 2378 2379 if (!vp->win_mask) 2380 return; 2381 2382 rk3568_vop2_setup_layer_mixer(vp); 2383 vop2_setup_alpha(vp); 2384 rk3568_vop2_setup_dly_for_windows(vp); 2385 } 2386 2387 static void rk3576_vop2_setup_layer_mixer(struct vop2_video_port *vp) 2388 { 2389 struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state); 2390 struct vop2 *vop2 = vp->vop2; 2391 struct drm_plane *plane; 2392 u32 layer_sel = 0xffff; /* 0xf means this layer is disabled */ 2393 u32 ovl_ctrl; 2394 2395 ovl_ctrl = vop2_readl(vop2, RK3576_OVL_CTRL(vp->id)); 2396 if (vcstate->yuv_overlay) 2397 ovl_ctrl |= RK3576_OVL_CTRL__YUV_MODE; 2398 else 2399 ovl_ctrl &= ~RK3576_OVL_CTRL__YUV_MODE; 2400 2401 vop2_writel(vop2, RK3576_OVL_CTRL(vp->id), ovl_ctrl); 2402 2403 drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { 2404 struct vop2_win *win = to_vop2_win(plane); 2405 2406 layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos, 2407 0xf); 2408 layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos, 2409 win->data->layer_sel_id[vp->id]); 2410 } 2411 2412 vop2_writel(vop2, RK3576_OVL_LAYER_SEL(vp->id), layer_sel); 2413 } 2414 2415 static void rk3576_vop2_setup_dly_for_windows(struct vop2_video_port *vp) 2416 { 2417 struct drm_plane *plane; 2418 struct vop2_win *win; 2419 2420 drm_atomic_crtc_for_each_plane(plane, &vp->crtc) { 2421 win = to_vop2_win(plane); 2422 vop2_win_write(win, VOP2_WIN_DLY_NUM, 0); 2423 } 2424 } 2425 2426 static void rk3576_vop2_setup_overlay(struct vop2_video_port *vp) 2427 { 2428 struct vop2 *vop2 = vp->vop2; 2429 struct drm_crtc *crtc = &vp->crtc; 2430 struct drm_plane *plane; 2431 2432 vp->win_mask = 0; 2433 2434 drm_atomic_crtc_for_each_plane(plane, crtc) { 2435 struct vop2_win *win = to_vop2_win(plane); 2436 2437 win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT]; 2438 vp->win_mask |= BIT(win->data->phys_id); 2439 2440 if (vop2_cluster_window(win)) 2441 vop2_setup_cluster_alpha(vop2, win); 2442 } 2443 2444 if (!vp->win_mask) 2445 return; 2446 2447 rk3576_vop2_setup_layer_mixer(vp); 2448 vop2_setup_alpha(vp); 2449 rk3576_vop2_setup_dly_for_windows(vp); 2450 } 2451 2452 static void rk3568_vop2_setup_bg_dly(struct vop2_video_port *vp) 2453 { 2454 struct drm_crtc *crtc = &vp->crtc; 2455 struct drm_display_mode *mode = &crtc->state->adjusted_mode; 2456 u16 hdisplay = mode->crtc_hdisplay; 2457 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 2458 u32 bg_dly; 2459 u32 pre_scan_dly; 2460 2461 bg_dly = vp->data->pre_scan_max_dly[3]; 2462 vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id), 2463 FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly)); 2464 2465 pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len; 2466 vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly); 2467 } 2468 2469 static void rk3576_vop2_setup_bg_dly(struct vop2_video_port *vp) 2470 { 2471 struct drm_crtc *crtc = &vp->crtc; 2472 struct drm_display_mode *mode = &crtc->state->adjusted_mode; 2473 u16 hdisplay = mode->crtc_hdisplay; 2474 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 2475 u32 bg_dly; 2476 u32 pre_scan_dly; 2477 2478 bg_dly = vp->data->pre_scan_max_dly[VOP2_DLY_WIN] + 2479 vp->data->pre_scan_max_dly[VOP2_DLY_LAYER_MIX] + 2480 vp->data->pre_scan_max_dly[VOP2_DLY_HDR_MIX]; 2481 2482 vop2_writel(vp->vop2, RK3576_OVL_BG_MIX_CTRL(vp->id), 2483 FIELD_PREP(RK3576_OVL_BG_MIX_CTRL__BG_DLY, bg_dly)); 2484 2485 pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len; 2486 vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly); 2487 } 2488 2489 static const struct vop2_ops rk3568_vop_ops = { 2490 .setup_intf_mux = rk3568_set_intf_mux, 2491 .setup_bg_dly = rk3568_vop2_setup_bg_dly, 2492 .setup_overlay = rk3568_vop2_setup_overlay, 2493 }; 2494 2495 static const struct vop2_ops rk3576_vop_ops = { 2496 .setup_intf_mux = rk3576_set_intf_mux, 2497 .setup_bg_dly = rk3576_vop2_setup_bg_dly, 2498 .setup_overlay = rk3576_vop2_setup_overlay, 2499 }; 2500 2501 static const struct vop2_ops rk3588_vop_ops = { 2502 .setup_intf_mux = rk3588_set_intf_mux, 2503 .setup_bg_dly = rk3568_vop2_setup_bg_dly, 2504 .setup_overlay = rk3568_vop2_setup_overlay, 2505 }; 2506 2507 static const struct vop2_data rk3566_vop = { 2508 .version = VOP_VERSION_RK3568, 2509 .feature = VOP2_FEATURE_HAS_SYS_GRF, 2510 .nr_vps = 3, 2511 .max_input = { 4096, 2304 }, 2512 .max_output = { 4096, 2304 }, 2513 .vp = rk3568_vop_video_ports, 2514 .win = rk3568_vop_win_data, 2515 .win_size = ARRAY_SIZE(rk3568_vop_win_data), 2516 .cluster_reg = rk3568_vop_cluster_regs, 2517 .nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs), 2518 .smart_reg = rk3568_vop_smart_regs, 2519 .nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs), 2520 .regs_dump = rk3568_regs_dump, 2521 .regs_dump_size = ARRAY_SIZE(rk3568_regs_dump), 2522 .ops = &rk3568_vop_ops, 2523 .soc_id = 3566, 2524 }; 2525 2526 static const struct vop2_data rk3568_vop = { 2527 .version = VOP_VERSION_RK3568, 2528 .feature = VOP2_FEATURE_HAS_SYS_GRF, 2529 .nr_vps = 3, 2530 .max_input = { 4096, 2304 }, 2531 .max_output = { 4096, 2304 }, 2532 .vp = rk3568_vop_video_ports, 2533 .win = rk3568_vop_win_data, 2534 .win_size = ARRAY_SIZE(rk3568_vop_win_data), 2535 .cluster_reg = rk3568_vop_cluster_regs, 2536 .nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs), 2537 .smart_reg = rk3568_vop_smart_regs, 2538 .nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs), 2539 .regs_dump = rk3568_regs_dump, 2540 .regs_dump_size = ARRAY_SIZE(rk3568_regs_dump), 2541 .ops = &rk3568_vop_ops, 2542 .soc_id = 3568, 2543 }; 2544 2545 static const struct vop2_data rk3576_vop = { 2546 .version = VOP_VERSION_RK3576, 2547 .feature = VOP2_FEATURE_HAS_SYS_PMU, 2548 .nr_vps = 3, 2549 .max_input = { 4096, 4320 }, 2550 .max_output = { 4096, 4320 }, 2551 .vp = rk3576_vop_video_ports, 2552 .win = rk3576_vop_win_data, 2553 .win_size = ARRAY_SIZE(rk3576_vop_win_data), 2554 .cluster_reg = rk3576_vop_cluster_regs, 2555 .nr_cluster_regs = ARRAY_SIZE(rk3576_vop_cluster_regs), 2556 .smart_reg = rk3576_vop_smart_regs, 2557 .nr_smart_regs = ARRAY_SIZE(rk3576_vop_smart_regs), 2558 .regs_dump = rk3576_regs_dump, 2559 .regs_dump_size = ARRAY_SIZE(rk3576_regs_dump), 2560 .ops = &rk3576_vop_ops, 2561 .soc_id = 3576, 2562 }; 2563 2564 static const struct vop2_data rk3588_vop = { 2565 .version = VOP_VERSION_RK3588, 2566 .feature = VOP2_FEATURE_HAS_SYS_GRF | VOP2_FEATURE_HAS_VO1_GRF | 2567 VOP2_FEATURE_HAS_VOP_GRF | VOP2_FEATURE_HAS_SYS_PMU, 2568 .nr_vps = 4, 2569 .max_input = { 4096, 4320 }, 2570 .max_output = { 4096, 4320 }, 2571 .vp = rk3588_vop_video_ports, 2572 .win = rk3588_vop_win_data, 2573 .win_size = ARRAY_SIZE(rk3588_vop_win_data), 2574 .cluster_reg = rk3568_vop_cluster_regs, 2575 .nr_cluster_regs = ARRAY_SIZE(rk3568_vop_cluster_regs), 2576 .smart_reg = rk3568_vop_smart_regs, 2577 .nr_smart_regs = ARRAY_SIZE(rk3568_vop_smart_regs), 2578 .regs_dump = rk3588_regs_dump, 2579 .regs_dump_size = ARRAY_SIZE(rk3588_regs_dump), 2580 .ops = &rk3588_vop_ops, 2581 .soc_id = 3588, 2582 }; 2583 2584 static const struct of_device_id vop2_dt_match[] = { 2585 { 2586 .compatible = "rockchip,rk3566-vop", 2587 .data = &rk3566_vop, 2588 }, { 2589 .compatible = "rockchip,rk3568-vop", 2590 .data = &rk3568_vop, 2591 }, { 2592 .compatible = "rockchip,rk3576-vop", 2593 .data = &rk3576_vop, 2594 }, { 2595 .compatible = "rockchip,rk3588-vop", 2596 .data = &rk3588_vop 2597 }, { 2598 }, 2599 }; 2600 MODULE_DEVICE_TABLE(of, vop2_dt_match); 2601 2602 static int vop2_probe(struct platform_device *pdev) 2603 { 2604 struct device *dev = &pdev->dev; 2605 2606 return component_add(dev, &vop2_component_ops); 2607 } 2608 2609 static void vop2_remove(struct platform_device *pdev) 2610 { 2611 component_del(&pdev->dev, &vop2_component_ops); 2612 } 2613 2614 struct platform_driver vop2_platform_driver = { 2615 .probe = vop2_probe, 2616 .remove = vop2_remove, 2617 .driver = { 2618 .name = "rockchip-vop2", 2619 .of_match_table = vop2_dt_match, 2620 }, 2621 }; 2622