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