1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd 4 * 5 */ 6 7 #include <config.h> 8 #include <common.h> 9 #include <errno.h> 10 #include <malloc.h> 11 #include <fdtdec.h> 12 #include <fdt_support.h> 13 #include <regmap.h> 14 #include <asm/arch/cpu.h> 15 #include <asm/unaligned.h> 16 #include <asm/io.h> 17 #include <linux/list.h> 18 #include <linux/log2.h> 19 #include <linux/media-bus-format.h> 20 #include <asm/arch/clock.h> 21 #include <asm/gpio.h> 22 #include <linux/err.h> 23 #include <linux/ioport.h> 24 #include <dm/device.h> 25 #include <dm/read.h> 26 #include <dm/ofnode.h> 27 #include <fixp-arith.h> 28 #include <syscon.h> 29 #include <linux/iopoll.h> 30 #include <dm/uclass-internal.h> 31 #include <stdlib.h> 32 33 #include "rockchip_display.h" 34 #include "rockchip_crtc.h" 35 #include "rockchip_connector.h" 36 #include "rockchip_phy.h" 37 #include "rockchip_post_csc.h" 38 39 /* System registers definition */ 40 #define RK3568_REG_CFG_DONE 0x000 41 #define CFG_DONE_EN BIT(15) 42 43 #define RK3568_VERSION_INFO 0x004 44 #define EN_MASK 1 45 46 #define RK3568_AUTO_GATING_CTRL 0x008 47 #define AUTO_GATING_EN_SHIFT 31 48 #define PORT_DCLK_AUTO_GATING_EN_SHIFT 14 49 50 #define RK3568_SYS_AXI_LUT_CTRL 0x024 51 #define LUT_DMA_EN_SHIFT 0 52 #define DSP_VS_T_SEL_SHIFT 16 53 54 #define RK3568_DSP_IF_EN 0x028 55 #define RGB_EN_SHIFT 0 56 #define RK3588_DP0_EN_SHIFT 0 57 #define RK3588_DP1_EN_SHIFT 1 58 #define RK3588_RGB_EN_SHIFT 8 59 #define HDMI0_EN_SHIFT 1 60 #define EDP0_EN_SHIFT 3 61 #define RK3588_EDP0_EN_SHIFT 2 62 #define RK3588_HDMI0_EN_SHIFT 3 63 #define MIPI0_EN_SHIFT 4 64 #define RK3588_EDP1_EN_SHIFT 4 65 #define RK3588_HDMI1_EN_SHIFT 5 66 #define RK3588_MIPI0_EN_SHIFT 6 67 #define MIPI1_EN_SHIFT 20 68 #define RK3588_MIPI1_EN_SHIFT 7 69 #define LVDS0_EN_SHIFT 5 70 #define LVDS1_EN_SHIFT 24 71 #define BT1120_EN_SHIFT 6 72 #define BT656_EN_SHIFT 7 73 #define IF_MUX_MASK 3 74 #define RGB_MUX_SHIFT 8 75 #define HDMI0_MUX_SHIFT 10 76 #define RK3588_DP0_MUX_SHIFT 12 77 #define RK3588_DP1_MUX_SHIFT 14 78 #define EDP0_MUX_SHIFT 14 79 #define RK3588_HDMI_EDP0_MUX_SHIFT 16 80 #define RK3588_HDMI_EDP1_MUX_SHIFT 18 81 #define MIPI0_MUX_SHIFT 16 82 #define RK3588_MIPI0_MUX_SHIFT 20 83 #define MIPI1_MUX_SHIFT 21 84 #define LVDS0_MUX_SHIFT 18 85 #define LVDS1_MUX_SHIFT 25 86 87 #define RK3568_DSP_IF_CTRL 0x02c 88 #define LVDS_DUAL_EN_SHIFT 0 89 #define LVDS_DUAL_LEFT_RIGHT_EN_SHIFT 1 90 #define LVDS_DUAL_SWAP_EN_SHIFT 2 91 #define BT656_UV_SWAP 4 92 #define BT656_YC_SWAP 5 93 #define BT656_DCLK_POL 6 94 #define RK3588_HDMI_DUAL_EN_SHIFT 8 95 #define RK3588_EDP_DUAL_EN_SHIFT 8 96 #define RK3588_DP_DUAL_EN_SHIFT 9 97 #define RK3568_MIPI_DUAL_EN_SHIFT 10 98 #define RK3588_MIPI_DSI0_MODE_SEL_SHIFT 11 99 #define RK3588_MIPI_DSI1_MODE_SEL_SHIFT 12 100 101 #define RK3568_DSP_IF_POL 0x030 102 #define IF_CTRL_REG_DONE_IMD_MASK 1 103 #define IF_CTRL_REG_DONE_IMD_SHIFT 28 104 #define IF_CRTL_MIPI_DCLK_POL_SHIT 19 105 #define IF_CRTL_EDP_DCLK_POL_SHIT 15 106 #define IF_CTRL_EDP_PIN_POL_MASK 0x7 107 #define IF_CTRL_EDP_PIN_POL_SHIFT 12 108 #define IF_CRTL_HDMI_DCLK_POL_SHIT 7 109 #define IF_CRTL_HDMI_PIN_POL_MASK 0x7 110 #define IF_CRTL_HDMI_PIN_POL_SHIT 4 111 #define IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT 3 112 #define IF_CTRL_RGB_LVDS_PIN_POL_MASK 0x7 113 #define IF_CTRL_RGB_LVDS_PIN_POL_SHIFT 0 114 115 #define RK3562_MIPI_DCLK_POL_SHIFT 15 116 #define RK3562_MIPI_PIN_POL_SHIFT 12 117 #define RK3562_IF_PIN_POL_MASK 0x7 118 119 #define RK3588_DP0_PIN_POL_SHIFT 8 120 #define RK3588_DP1_PIN_POL_SHIFT 12 121 #define RK3588_IF_PIN_POL_MASK 0x7 122 123 #define HDMI_EDP0_DCLK_DIV_SHIFT 16 124 #define HDMI_EDP0_PIXCLK_DIV_SHIFT 18 125 #define HDMI_EDP1_DCLK_DIV_SHIFT 20 126 #define HDMI_EDP1_PIXCLK_DIV_SHIFT 22 127 #define MIPI0_PIXCLK_DIV_SHIFT 24 128 #define MIPI1_PIXCLK_DIV_SHIFT 26 129 130 #define RK3568_SYS_OTP_WIN_EN 0x50 131 #define OTP_WIN_EN_SHIFT 0 132 #define RK3568_SYS_LUT_PORT_SEL 0x58 133 #define GAMMA_PORT_SEL_MASK 0x3 134 #define GAMMA_PORT_SEL_SHIFT 0 135 #define GAMMA_AHB_WRITE_SEL_MASK 0x3 136 #define GAMMA_AHB_WRITE_SEL_SHIFT 12 137 #define PORT_MERGE_EN_SHIFT 16 138 #define ESMART_LB_MODE_SEL_MASK 0x3 139 #define ESMART_LB_MODE_SEL_SHIFT 26 140 141 #define RK3568_SYS_PD_CTRL 0x034 142 #define RK3568_VP0_LINE_FLAG 0x70 143 #define RK3568_VP1_LINE_FLAG 0x74 144 #define RK3568_VP2_LINE_FLAG 0x78 145 #define RK3568_SYS0_INT_EN 0x80 146 #define RK3568_SYS0_INT_CLR 0x84 147 #define RK3568_SYS0_INT_STATUS 0x88 148 #define RK3568_SYS1_INT_EN 0x90 149 #define RK3568_SYS1_INT_CLR 0x94 150 #define RK3568_SYS1_INT_STATUS 0x98 151 #define RK3568_VP0_INT_EN 0xA0 152 #define RK3568_VP0_INT_CLR 0xA4 153 #define RK3568_VP0_INT_STATUS 0xA8 154 #define RK3568_VP1_INT_EN 0xB0 155 #define RK3568_VP1_INT_CLR 0xB4 156 #define RK3568_VP1_INT_STATUS 0xB8 157 #define RK3568_VP2_INT_EN 0xC0 158 #define RK3568_VP2_INT_CLR 0xC4 159 #define RK3568_VP2_INT_STATUS 0xC8 160 #define RK3588_CLUSTER0_PD_EN_SHIFT 0 161 #define RK3588_CLUSTER1_PD_EN_SHIFT 1 162 #define RK3588_CLUSTER2_PD_EN_SHIFT 2 163 #define RK3588_CLUSTER3_PD_EN_SHIFT 3 164 #define RK3588_DSC_8K_PD_EN_SHIFT 5 165 #define RK3588_DSC_4K_PD_EN_SHIFT 6 166 #define RK3588_ESMART_PD_EN_SHIFT 7 167 168 #define RK3588_SYS_VAR_FREQ_CTRL 0x038 169 #define RK3588_VP0_LINE_FLAG_OR_EN_SHIFT 20 170 #define RK3588_VP0_DSP_HOLD_OR_EN_SHIFT 24 171 #define RK3588_VP0_ALMOST_FULL_OR_EN_SHIFT 28 172 173 #define RK3568_SYS_STATUS0 0x60 174 #define RK3588_CLUSTER0_PD_STATUS_SHIFT 8 175 #define RK3588_CLUSTER1_PD_STATUS_SHIFT 9 176 #define RK3588_CLUSTER2_PD_STATUS_SHIFT 10 177 #define RK3588_CLUSTER3_PD_STATUS_SHIFT 11 178 #define RK3588_DSC_8K_PD_STATUS_SHIFT 13 179 #define RK3588_DSC_4K_PD_STATUS_SHIFT 14 180 #define RK3588_ESMART_PD_STATUS_SHIFT 15 181 182 #define RK3568_SYS_CTRL_LINE_FLAG0 0x70 183 #define LINE_FLAG_NUM_MASK 0x1fff 184 #define RK3568_DSP_LINE_FLAG_NUM0_SHIFT 0 185 #define RK3568_DSP_LINE_FLAG_NUM1_SHIFT 16 186 187 /* DSC CTRL registers definition */ 188 #define RK3588_DSC_8K_SYS_CTRL 0x200 189 #define DSC_PORT_SEL_MASK 0x3 190 #define DSC_PORT_SEL_SHIFT 0 191 #define DSC_MAN_MODE_MASK 0x1 192 #define DSC_MAN_MODE_SHIFT 2 193 #define DSC_INTERFACE_MODE_MASK 0x3 194 #define DSC_INTERFACE_MODE_SHIFT 4 195 #define DSC_PIXEL_NUM_MASK 0x3 196 #define DSC_PIXEL_NUM_SHIFT 6 197 #define DSC_PXL_CLK_DIV_MASK 0x1 198 #define DSC_PXL_CLK_DIV_SHIFT 8 199 #define DSC_CDS_CLK_DIV_MASK 0x3 200 #define DSC_CDS_CLK_DIV_SHIFT 12 201 #define DSC_TXP_CLK_DIV_MASK 0x3 202 #define DSC_TXP_CLK_DIV_SHIFT 14 203 #define DSC_INIT_DLY_MODE_MASK 0x1 204 #define DSC_INIT_DLY_MODE_SHIFT 16 205 #define DSC_SCAN_EN_SHIFT 17 206 #define DSC_HALT_EN_SHIFT 18 207 208 #define RK3588_DSC_8K_RST 0x204 209 #define RST_DEASSERT_MASK 0x1 210 #define RST_DEASSERT_SHIFT 0 211 212 #define RK3588_DSC_8K_CFG_DONE 0x208 213 #define DSC_CFG_DONE_SHIFT 0 214 215 #define RK3588_DSC_8K_INIT_DLY 0x20C 216 #define DSC_INIT_DLY_NUM_MASK 0xffff 217 #define DSC_INIT_DLY_NUM_SHIFT 0 218 #define SCAN_TIMING_PARA_IMD_EN_SHIFT 16 219 220 #define RK3588_DSC_8K_HTOTAL_HS_END 0x210 221 #define DSC_HTOTAL_PW_MASK 0xffffffff 222 #define DSC_HTOTAL_PW_SHIFT 0 223 224 #define RK3588_DSC_8K_HACT_ST_END 0x214 225 #define DSC_HACT_ST_END_MASK 0xffffffff 226 #define DSC_HACT_ST_END_SHIFT 0 227 228 #define RK3588_DSC_8K_VTOTAL_VS_END 0x218 229 #define DSC_VTOTAL_PW_MASK 0xffffffff 230 #define DSC_VTOTAL_PW_SHIFT 0 231 232 #define RK3588_DSC_8K_VACT_ST_END 0x21C 233 #define DSC_VACT_ST_END_MASK 0xffffffff 234 #define DSC_VACT_ST_END_SHIFT 0 235 236 #define RK3588_DSC_8K_STATUS 0x220 237 238 /* Overlay registers definition */ 239 #define RK3528_OVL_SYS 0x500 240 #define RK3528_OVL_SYS_PORT_SEL_IMD 0x504 241 #define RK3528_OVL_SYS_GATING_EN_IMD 0x508 242 #define RK3528_OVL_SYS_CLUSTER0_CTRL 0x510 243 #define RK3528_OVL_SYS_ESMART0_CTRL 0x520 244 #define ESMART_DLY_NUM_MASK 0xff 245 #define ESMART_DLY_NUM_SHIFT 0 246 #define RK3528_OVL_SYS_ESMART1_CTRL 0x524 247 #define RK3528_OVL_SYS_ESMART2_CTRL 0x528 248 #define RK3528_OVL_SYS_ESMART3_CTRL 0x52C 249 #define RK3528_CLUSTER0_MIX_SRC_COLOR_CTRL 0x530 250 #define RK3528_CLUSTER0_MIX_DST_COLOR_CTRL 0x534 251 #define RK3528_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x538 252 #define RK3528_CLUSTER0_MIX_DST_ALPHA_CTRL 0x53c 253 254 #define RK3528_OVL_PORT0_CTRL 0x600 255 #define RK3568_OVL_CTRL 0x600 256 #define OVL_MODE_SEL_MASK 0x1 257 #define OVL_MODE_SEL_SHIFT 0 258 #define OVL_PORT_MUX_REG_DONE_IMD_SHIFT 28 259 #define RK3528_OVL_PORT0_LAYER_SEL 0x604 260 #define RK3568_OVL_LAYER_SEL 0x604 261 #define LAYER_SEL_MASK 0xf 262 263 #define RK3568_OVL_PORT_SEL 0x608 264 #define PORT_MUX_MASK 0xf 265 #define PORT_MUX_SHIFT 0 266 #define LAYER_SEL_PORT_MASK 0x3 267 #define LAYER_SEL_PORT_SHIFT 16 268 269 #define RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL 0x610 270 #define RK3568_CLUSTER0_MIX_DST_COLOR_CTRL 0x614 271 #define RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x618 272 #define RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL 0x61C 273 #define RK3528_OVL_PORT0_MIX0_SRC_COLOR_CTRL 0x620 274 #define RK3528_OVL_PORT0_MIX0_DST_COLOR_CTRL 0x624 275 #define RK3528_OVL_PORT0_MIX0_SRC_ALPHA_CTRL 0x628 276 #define RK3528_OVL_PORT0_MIX0_DST_ALPHA_CTRL 0x62C 277 #define RK3528_OVL_PORT0_MIX1_SRC_COLOR_CTRL 0x630 278 #define RK3528_OVL_PORT0_MIX1_DST_COLOR_CTRL 0x634 279 #define RK3528_OVL_PORT0_MIX1_SRC_ALPHA_CTRL 0x638 280 #define RK3528_OVL_PORT0_MIX1_DST_ALPHA_CTRL 0x63C 281 #define RK3528_OVL_PORT0_MIX2_SRC_COLOR_CTRL 0x640 282 #define RK3528_OVL_PORT0_MIX2_DST_COLOR_CTRL 0x644 283 #define RK3528_OVL_PORT0_MIX2_SRC_ALPHA_CTRL 0x648 284 #define RK3528_OVL_PORT0_MIX2_DST_ALPHA_CTRL 0x64C 285 #define RK3568_MIX0_SRC_COLOR_CTRL 0x650 286 #define RK3568_MIX0_DST_COLOR_CTRL 0x654 287 #define RK3568_MIX0_SRC_ALPHA_CTRL 0x658 288 #define RK3568_MIX0_DST_ALPHA_CTRL 0x65C 289 #define RK3528_HDR_SRC_COLOR_CTRL 0x660 290 #define RK3528_HDR_DST_COLOR_CTRL 0x664 291 #define RK3528_HDR_SRC_ALPHA_CTRL 0x668 292 #define RK3528_HDR_DST_ALPHA_CTRL 0x66C 293 #define RK3528_OVL_PORT0_BG_MIX_CTRL 0x670 294 #define RK3568_HDR0_SRC_COLOR_CTRL 0x6C0 295 #define RK3568_HDR0_DST_COLOR_CTRL 0x6C4 296 #define RK3568_HDR0_SRC_ALPHA_CTRL 0x6C8 297 #define RK3568_HDR0_DST_ALPHA_CTRL 0x6CC 298 #define RK3568_VP0_BG_MIX_CTRL 0x6E0 299 #define BG_MIX_CTRL_MASK 0xff 300 #define BG_MIX_CTRL_SHIFT 24 301 #define RK3568_VP1_BG_MIX_CTRL 0x6E4 302 #define RK3568_VP2_BG_MIX_CTRL 0x6E8 303 #define RK3568_CLUSTER_DLY_NUM 0x6F0 304 #define RK3568_SMART_DLY_NUM 0x6F8 305 306 #define RK3528_OVL_PORT1_CTRL 0x700 307 #define RK3528_OVL_PORT1_LAYER_SEL 0x704 308 #define RK3528_OVL_PORT1_MIX0_SRC_COLOR_CTRL 0x720 309 #define RK3528_OVL_PORT1_MIX0_DST_COLOR_CTRL 0x724 310 #define RK3528_OVL_PORT1_MIX0_SRC_ALPHA_CTRL 0x728 311 #define RK3528_OVL_PORT1_MIX0_DST_ALPHA_CTRL 0x72C 312 #define RK3528_OVL_PORT1_MIX1_SRC_COLOR_CTRL 0x730 313 #define RK3528_OVL_PORT1_MIX1_DST_COLOR_CTRL 0x734 314 #define RK3528_OVL_PORT1_MIX1_SRC_ALPHA_CTRL 0x738 315 #define RK3528_OVL_PORT1_MIX1_DST_ALPHA_CTRL 0x73C 316 #define RK3528_OVL_PORT1_MIX2_SRC_COLOR_CTRL 0x740 317 #define RK3528_OVL_PORT1_MIX2_DST_COLOR_CTRL 0x744 318 #define RK3528_OVL_PORT1_MIX2_SRC_ALPHA_CTRL 0x748 319 #define RK3528_OVL_PORT1_MIX2_DST_ALPHA_CTRL 0x74C 320 #define RK3528_OVL_PORT1_BG_MIX_CTRL 0x770 321 322 /* Video Port registers definition */ 323 #define RK3568_VP0_DSP_CTRL 0xC00 324 #define OUT_MODE_MASK 0xf 325 #define OUT_MODE_SHIFT 0 326 #define DATA_SWAP_MASK 0x1f 327 #define DATA_SWAP_SHIFT 8 328 #define DSP_BG_SWAP 0x1 329 #define DSP_RB_SWAP 0x2 330 #define DSP_RG_SWAP 0x4 331 #define DSP_DELTA_SWAP 0x8 332 #define CORE_DCLK_DIV_EN_SHIFT 4 333 #define P2I_EN_SHIFT 5 334 #define DSP_FILED_POL 6 335 #define INTERLACE_EN_SHIFT 7 336 #define DSP_X_MIR_EN_SHIFT 13 337 #define POST_DSP_OUT_R2Y_SHIFT 15 338 #define PRE_DITHER_DOWN_EN_SHIFT 16 339 #define DITHER_DOWN_EN_SHIFT 17 340 #define DITHER_DOWN_MODE_SHIFT 20 341 #define GAMMA_UPDATE_EN_SHIFT 22 342 #define DSP_LUT_EN_SHIFT 28 343 344 #define STANDBY_EN_SHIFT 31 345 346 #define RK3568_VP0_MIPI_CTRL 0xC04 347 #define DCLK_DIV2_SHIFT 4 348 #define DCLK_DIV2_MASK 0x3 349 #define MIPI_DUAL_EN_SHIFT 20 350 #define MIPI_DUAL_SWAP_EN_SHIFT 21 351 #define EDPI_TE_EN 28 352 #define EDPI_WMS_HOLD_EN 30 353 #define EDPI_WMS_FS 31 354 355 356 #define RK3568_VP0_COLOR_BAR_CTRL 0xC08 357 358 #define RK3568_VP0_DCLK_SEL 0xC0C 359 360 #define RK3568_VP0_3D_LUT_CTRL 0xC10 361 #define VP0_3D_LUT_EN_SHIFT 0 362 #define VP0_3D_LUT_UPDATE_SHIFT 2 363 364 #define RK3588_VP0_CLK_CTRL 0xC0C 365 #define DCLK_CORE_DIV_SHIFT 0 366 #define DCLK_OUT_DIV_SHIFT 2 367 368 #define RK3568_VP0_3D_LUT_MST 0xC20 369 370 #define RK3568_VP0_DSP_BG 0xC2C 371 #define RK3568_VP0_PRE_SCAN_HTIMING 0xC30 372 #define RK3568_VP0_POST_DSP_HACT_INFO 0xC34 373 #define RK3568_VP0_POST_DSP_VACT_INFO 0xC38 374 #define RK3568_VP0_POST_SCL_FACTOR_YRGB 0xC3C 375 #define RK3568_VP0_POST_SCL_CTRL 0xC40 376 #define RK3568_VP0_POST_DSP_VACT_INFO_F1 0xC44 377 #define RK3568_VP0_DSP_HTOTAL_HS_END 0xC48 378 #define RK3568_VP0_DSP_HACT_ST_END 0xC4C 379 #define RK3568_VP0_DSP_VTOTAL_VS_END 0xC50 380 #define RK3568_VP0_DSP_VACT_ST_END 0xC54 381 #define RK3568_VP0_DSP_VS_ST_END_F1 0xC58 382 #define RK3568_VP0_DSP_VACT_ST_END_F1 0xC5C 383 384 #define RK3568_VP0_BCSH_CTRL 0xC60 385 #define BCSH_CTRL_Y2R_SHIFT 0 386 #define BCSH_CTRL_Y2R_MASK 0x1 387 #define BCSH_CTRL_Y2R_CSC_MODE_SHIFT 2 388 #define BCSH_CTRL_Y2R_CSC_MODE_MASK 0x3 389 #define BCSH_CTRL_R2Y_SHIFT 4 390 #define BCSH_CTRL_R2Y_MASK 0x1 391 #define BCSH_CTRL_R2Y_CSC_MODE_SHIFT 6 392 #define BCSH_CTRL_R2Y_CSC_MODE_MASK 0x3 393 394 #define RK3568_VP0_BCSH_BCS 0xC64 395 #define BCSH_BRIGHTNESS_SHIFT 0 396 #define BCSH_BRIGHTNESS_MASK 0xFF 397 #define BCSH_CONTRAST_SHIFT 8 398 #define BCSH_CONTRAST_MASK 0x1FF 399 #define BCSH_SATURATION_SHIFT 20 400 #define BCSH_SATURATION_MASK 0x3FF 401 #define BCSH_OUT_MODE_SHIFT 30 402 #define BCSH_OUT_MODE_MASK 0x3 403 404 #define RK3568_VP0_BCSH_H 0xC68 405 #define BCSH_SIN_HUE_SHIFT 0 406 #define BCSH_SIN_HUE_MASK 0x1FF 407 #define BCSH_COS_HUE_SHIFT 16 408 #define BCSH_COS_HUE_MASK 0x1FF 409 410 #define RK3568_VP0_BCSH_COLOR 0xC6C 411 #define BCSH_EN_SHIFT 31 412 #define BCSH_EN_MASK 1 413 414 #define RK3528_VP0_ACM_CTRL 0xCD0 415 #define POST_CSC_COE00_MASK 0xFFFF 416 #define POST_CSC_COE00_SHIFT 16 417 #define POST_R2Y_MODE_MASK 0x7 418 #define POST_R2Y_MODE_SHIFT 8 419 #define POST_CSC_MODE_MASK 0x7 420 #define POST_CSC_MODE_SHIFT 3 421 #define POST_R2Y_EN_MASK 0x1 422 #define POST_R2Y_EN_SHIFT 2 423 #define POST_CSC_EN_MASK 0x1 424 #define POST_CSC_EN_SHIFT 1 425 #define POST_ACM_BYPASS_EN_MASK 0x1 426 #define POST_ACM_BYPASS_EN_SHIFT 0 427 #define RK3528_VP0_CSC_COE01_02 0xCD4 428 #define RK3528_VP0_CSC_COE10_11 0xCD8 429 #define RK3528_VP0_CSC_COE12_20 0xCDC 430 #define RK3528_VP0_CSC_COE21_22 0xCE0 431 #define RK3528_VP0_CSC_OFFSET0 0xCE4 432 #define RK3528_VP0_CSC_OFFSET1 0xCE8 433 #define RK3528_VP0_CSC_OFFSET2 0xCEC 434 435 #define RK3562_VP0_MCU_CTRL 0xCF8 436 #define MCU_TYPE_SHIFT 31 437 #define MCU_BYPASS_SHIFT 30 438 #define MCU_RS_SHIFT 29 439 #define MCU_FRAME_ST_SHIFT 28 440 #define MCU_HOLD_MODE_SHIFT 27 441 #define MCU_CLK_SEL_SHIFT 26 442 #define MCU_CLK_SEL_MASK 0x1 443 #define MCU_RW_PEND_SHIFT 20 444 #define MCU_RW_PEND_MASK 0x3F 445 #define MCU_RW_PST_SHIFT 16 446 #define MCU_RW_PST_MASK 0xF 447 #define MCU_CS_PEND_SHIFT 10 448 #define MCU_CS_PEND_MASK 0x3F 449 #define MCU_CS_PST_SHIFT 6 450 #define MCU_CS_PST_MASK 0xF 451 #define MCU_PIX_TOTAL_SHIFT 0 452 #define MCU_PIX_TOTAL_MASK 0x3F 453 454 #define RK3562_VP0_MCU_RW_BYPASS_PORT 0xCFC 455 #define MCU_WRITE_DATA_BYPASS_SHIFT 0 456 #define MCU_WRITE_DATA_BYPASS_MASK 0xFFFFFFFF 457 458 #define RK3568_VP1_DSP_CTRL 0xD00 459 #define RK3568_VP1_MIPI_CTRL 0xD04 460 #define RK3568_VP1_COLOR_BAR_CTRL 0xD08 461 #define RK3568_VP1_PRE_SCAN_HTIMING 0xD30 462 #define RK3568_VP1_POST_DSP_HACT_INFO 0xD34 463 #define RK3568_VP1_POST_DSP_VACT_INFO 0xD38 464 #define RK3568_VP1_POST_SCL_FACTOR_YRGB 0xD3C 465 #define RK3568_VP1_POST_SCL_CTRL 0xD40 466 #define RK3568_VP1_DSP_HACT_INFO 0xD34 467 #define RK3568_VP1_DSP_VACT_INFO 0xD38 468 #define RK3568_VP1_POST_DSP_VACT_INFO_F1 0xD44 469 #define RK3568_VP1_DSP_HTOTAL_HS_END 0xD48 470 #define RK3568_VP1_DSP_HACT_ST_END 0xD4C 471 #define RK3568_VP1_DSP_VTOTAL_VS_END 0xD50 472 #define RK3568_VP1_DSP_VACT_ST_END 0xD54 473 #define RK3568_VP1_DSP_VS_ST_END_F1 0xD58 474 #define RK3568_VP1_DSP_VACT_ST_END_F1 0xD5C 475 476 #define RK3568_VP2_DSP_CTRL 0xE00 477 #define RK3568_VP2_MIPI_CTRL 0xE04 478 #define RK3568_VP2_COLOR_BAR_CTRL 0xE08 479 #define RK3568_VP2_PRE_SCAN_HTIMING 0xE30 480 #define RK3568_VP2_POST_DSP_HACT_INFO 0xE34 481 #define RK3568_VP2_POST_DSP_VACT_INFO 0xE38 482 #define RK3568_VP2_POST_SCL_FACTOR_YRGB 0xE3C 483 #define RK3568_VP2_POST_SCL_CTRL 0xE40 484 #define RK3568_VP2_DSP_HACT_INFO 0xE34 485 #define RK3568_VP2_DSP_VACT_INFO 0xE38 486 #define RK3568_VP2_POST_DSP_VACT_INFO_F1 0xE44 487 #define RK3568_VP2_DSP_HTOTAL_HS_END 0xE48 488 #define RK3568_VP2_DSP_HACT_ST_END 0xE4C 489 #define RK3568_VP2_DSP_VTOTAL_VS_END 0xE50 490 #define RK3568_VP2_DSP_VACT_ST_END 0xE54 491 #define RK3568_VP2_DSP_VS_ST_END_F1 0xE58 492 #define RK3568_VP2_DSP_VACT_ST_END_F1 0xE5C 493 494 /* Cluster0 register definition */ 495 #define RK3568_CLUSTER0_WIN0_CTRL0 0x1000 496 #define CLUSTER_YUV2RGB_EN_SHIFT 8 497 #define CLUSTER_RGB2YUV_EN_SHIFT 9 498 #define CLUSTER_CSC_MODE_SHIFT 10 499 #define RK3568_CLUSTER0_WIN0_CTRL1 0x1004 500 #define RK3568_CLUSTER_YRGB_XSCL_MODE_SHIFT 12 501 #define RK3568_CLUSTER_YRGB_YSCL_MODE_SHIFT 14 502 #define RK3528_CLUSTER_YRGB_YSCL_MODE_SHIFT 14 503 #define AVG2_MASK 0x1 504 #define CLUSTER_AVG2_SHIFT 18 505 #define AVG4_MASK 0x1 506 #define CLUSTER_AVG4_SHIFT 19 507 #define RK3528_CLUSTER_YRGB_XSCL_MODE_SHIFT 22 508 #define CLUSTER_XGT_EN_SHIFT 24 509 #define XGT_MODE_MASK 0x3 510 #define CLUSTER_XGT_MODE_SHIFT 25 511 #define CLUSTER_XAVG_EN_SHIFT 27 512 #define CLUSTER_YRGB_GT2_SHIFT 28 513 #define CLUSTER_YRGB_GT4_SHIFT 29 514 #define RK3568_CLUSTER0_WIN0_CTRL2 0x1008 515 #define CLUSTER_AXI_YRGB_ID_MASK 0x1f 516 #define CLUSTER_AXI_YRGB_ID_SHIFT 0 517 #define CLUSTER_AXI_UV_ID_MASK 0x1f 518 #define CLUSTER_AXI_UV_ID_SHIFT 5 519 520 #define RK3568_CLUSTER0_WIN0_YRGB_MST 0x1010 521 #define RK3568_CLUSTER0_WIN0_CBR_MST 0x1014 522 #define RK3568_CLUSTER0_WIN0_VIR 0x1018 523 #define RK3568_CLUSTER0_WIN0_ACT_INFO 0x1020 524 #define RK3568_CLUSTER0_WIN0_DSP_INFO 0x1024 525 #define RK3568_CLUSTER0_WIN0_DSP_ST 0x1028 526 #define RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB 0x1030 527 #define RK3568_CLUSTER0_WIN0_AFBCD_ROTATE_MODE 0x1054 528 #define RK3568_CLUSTER0_WIN0_AFBCD_HDR_PTR 0x1058 529 #define RK3568_CLUSTER0_WIN0_AFBCD_VIR_WIDTH 0x105C 530 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_SIZE 0x1060 531 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_OFFSET 0x1064 532 #define RK3568_CLUSTER0_WIN0_AFBCD_DSP_OFFSET 0x1068 533 #define RK3568_CLUSTER0_WIN0_AFBCD_CTRL 0x106C 534 #define CLUSTER_AFBCD_HALF_BLOCK_SHIFT 7 535 536 #define RK3568_CLUSTER0_WIN1_CTRL0 0x1080 537 #define RK3568_CLUSTER0_WIN1_CTRL1 0x1084 538 #define RK3568_CLUSTER0_WIN1_YRGB_MST 0x1090 539 #define RK3568_CLUSTER0_WIN1_CBR_MST 0x1094 540 #define RK3568_CLUSTER0_WIN1_VIR 0x1098 541 #define RK3568_CLUSTER0_WIN1_ACT_INFO 0x10A0 542 #define RK3568_CLUSTER0_WIN1_DSP_INFO 0x10A4 543 #define RK3568_CLUSTER0_WIN1_DSP_ST 0x10A8 544 #define RK3568_CLUSTER0_WIN1_SCL_FACTOR_YRGB 0x10B0 545 #define RK3568_CLUSTER0_WIN1_AFBCD_ROTATE_MODE 0x10D4 546 #define RK3568_CLUSTER0_WIN1_AFBCD_HDR_PTR 0x10D8 547 #define RK3568_CLUSTER0_WIN1_AFBCD_VIR_WIDTH 0x10DC 548 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_SIZE 0x10E0 549 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_OFFSET 0x10E4 550 #define RK3568_CLUSTER0_WIN1_AFBCD_DSP_OFFSET 0x10E8 551 #define RK3568_CLUSTER0_WIN1_AFBCD_CTRL 0x10EC 552 553 #define RK3568_CLUSTER0_CTRL 0x1100 554 #define CLUSTER_EN_SHIFT 0 555 #define CLUSTER_AXI_ID_MASK 0x1 556 #define CLUSTER_AXI_ID_SHIFT 13 557 558 #define RK3568_CLUSTER1_WIN0_CTRL0 0x1200 559 #define RK3568_CLUSTER1_WIN0_CTRL1 0x1204 560 #define RK3568_CLUSTER1_WIN0_YRGB_MST 0x1210 561 #define RK3568_CLUSTER1_WIN0_CBR_MST 0x1214 562 #define RK3568_CLUSTER1_WIN0_VIR 0x1218 563 #define RK3568_CLUSTER1_WIN0_ACT_INFO 0x1220 564 #define RK3568_CLUSTER1_WIN0_DSP_INFO 0x1224 565 #define RK3568_CLUSTER1_WIN0_DSP_ST 0x1228 566 #define RK3568_CLUSTER1_WIN0_SCL_FACTOR_YRGB 0x1230 567 #define RK3568_CLUSTER1_WIN0_AFBCD_ROTATE_MODE 0x1254 568 #define RK3568_CLUSTER1_WIN0_AFBCD_HDR_PTR 0x1258 569 #define RK3568_CLUSTER1_WIN0_AFBCD_VIR_WIDTH 0x125C 570 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_SIZE 0x1260 571 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_OFFSET 0x1264 572 #define RK3568_CLUSTER1_WIN0_AFBCD_DSP_OFFSET 0x1268 573 #define RK3568_CLUSTER1_WIN0_AFBCD_CTRL 0x126C 574 575 #define RK3568_CLUSTER1_WIN1_CTRL0 0x1280 576 #define RK3568_CLUSTER1_WIN1_CTRL1 0x1284 577 #define RK3568_CLUSTER1_WIN1_YRGB_MST 0x1290 578 #define RK3568_CLUSTER1_WIN1_CBR_MST 0x1294 579 #define RK3568_CLUSTER1_WIN1_VIR 0x1298 580 #define RK3568_CLUSTER1_WIN1_ACT_INFO 0x12A0 581 #define RK3568_CLUSTER1_WIN1_DSP_INFO 0x12A4 582 #define RK3568_CLUSTER1_WIN1_DSP_ST 0x12A8 583 #define RK3568_CLUSTER1_WIN1_SCL_FACTOR_YRGB 0x12B0 584 #define RK3568_CLUSTER1_WIN1_AFBCD_ROTATE_MODE 0x12D4 585 #define RK3568_CLUSTER1_WIN1_AFBCD_HDR_PTR 0x12D8 586 #define RK3568_CLUSTER1_WIN1_AFBCD_VIR_WIDTH 0x12DC 587 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_SIZE 0x12E0 588 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_OFFSET 0x12E4 589 #define RK3568_CLUSTER1_WIN1_AFBCD_DSP_OFFSET 0x12E8 590 #define RK3568_CLUSTER1_WIN1_AFBCD_CTRL 0x12EC 591 592 #define RK3568_CLUSTER1_CTRL 0x1300 593 594 /* Esmart register definition */ 595 #define RK3568_ESMART0_CTRL0 0x1800 596 #define RGB2YUV_EN_SHIFT 1 597 #define CSC_MODE_SHIFT 2 598 #define CSC_MODE_MASK 0x3 599 #define ESMART_LB_SELECT_SHIFT 12 600 #define ESMART_LB_SELECT_MASK 0x3 601 602 #define RK3568_ESMART0_CTRL1 0x1804 603 #define ESMART_AXI_YRGB_ID_MASK 0x1f 604 #define ESMART_AXI_YRGB_ID_SHIFT 4 605 #define ESMART_AXI_UV_ID_MASK 0x1f 606 #define ESMART_AXI_UV_ID_SHIFT 12 607 #define YMIRROR_EN_SHIFT 31 608 609 #define RK3568_ESMART0_AXI_CTRL 0x1808 610 #define ESMART_AXI_ID_MASK 0x1 611 #define ESMART_AXI_ID_SHIFT 1 612 613 #define RK3568_ESMART0_REGION0_CTRL 0x1810 614 #define WIN_EN_SHIFT 0 615 #define WIN_FORMAT_MASK 0x1f 616 #define WIN_FORMAT_SHIFT 1 617 #define REGION0_RB_SWAP_SHIFT 14 618 #define ESMART_XAVG_EN_SHIFT 20 619 #define ESMART_XGT_EN_SHIFT 21 620 #define ESMART_XGT_MODE_SHIFT 22 621 622 #define RK3568_ESMART0_REGION0_YRGB_MST 0x1814 623 #define RK3568_ESMART0_REGION0_CBR_MST 0x1818 624 #define RK3568_ESMART0_REGION0_VIR 0x181C 625 #define RK3568_ESMART0_REGION0_ACT_INFO 0x1820 626 #define RK3568_ESMART0_REGION0_DSP_INFO 0x1824 627 #define RK3568_ESMART0_REGION0_DSP_ST 0x1828 628 #define RK3568_ESMART0_REGION0_SCL_CTRL 0x1830 629 #define YRGB_XSCL_MODE_MASK 0x3 630 #define YRGB_XSCL_MODE_SHIFT 0 631 #define YRGB_XSCL_FILTER_MODE_MASK 0x3 632 #define YRGB_XSCL_FILTER_MODE_SHIFT 2 633 #define YRGB_YSCL_MODE_MASK 0x3 634 #define YRGB_YSCL_MODE_SHIFT 4 635 #define YRGB_YSCL_FILTER_MODE_MASK 0x3 636 #define YRGB_YSCL_FILTER_MODE_SHIFT 6 637 638 #define RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB 0x1834 639 #define RK3568_ESMART0_REGION0_SCL_FACTOR_CBR 0x1838 640 #define RK3568_ESMART0_REGION0_SCL_OFFSET 0x183C 641 #define RK3568_ESMART0_REGION1_CTRL 0x1840 642 #define YRGB_GT2_MASK 0x1 643 #define YRGB_GT2_SHIFT 8 644 #define YRGB_GT4_MASK 0x1 645 #define YRGB_GT4_SHIFT 9 646 647 #define RK3568_ESMART0_REGION1_YRGB_MST 0x1844 648 #define RK3568_ESMART0_REGION1_CBR_MST 0x1848 649 #define RK3568_ESMART0_REGION1_VIR 0x184C 650 #define RK3568_ESMART0_REGION1_ACT_INFO 0x1850 651 #define RK3568_ESMART0_REGION1_DSP_INFO 0x1854 652 #define RK3568_ESMART0_REGION1_DSP_ST 0x1858 653 #define RK3568_ESMART0_REGION1_SCL_CTRL 0x1860 654 #define RK3568_ESMART0_REGION1_SCL_FACTOR_YRGB 0x1864 655 #define RK3568_ESMART0_REGION1_SCL_FACTOR_CBR 0x1868 656 #define RK3568_ESMART0_REGION1_SCL_OFFSET 0x186C 657 #define RK3568_ESMART0_REGION2_CTRL 0x1870 658 #define RK3568_ESMART0_REGION2_YRGB_MST 0x1874 659 #define RK3568_ESMART0_REGION2_CBR_MST 0x1878 660 #define RK3568_ESMART0_REGION2_VIR 0x187C 661 #define RK3568_ESMART0_REGION2_ACT_INFO 0x1880 662 #define RK3568_ESMART0_REGION2_DSP_INFO 0x1884 663 #define RK3568_ESMART0_REGION2_DSP_ST 0x1888 664 #define RK3568_ESMART0_REGION2_SCL_CTRL 0x1890 665 #define RK3568_ESMART0_REGION2_SCL_FACTOR_YRGB 0x1894 666 #define RK3568_ESMART0_REGION2_SCL_FACTOR_CBR 0x1898 667 #define RK3568_ESMART0_REGION2_SCL_OFFSET 0x189C 668 #define RK3568_ESMART0_REGION3_CTRL 0x18A0 669 #define RK3568_ESMART0_REGION3_YRGB_MST 0x18A4 670 #define RK3568_ESMART0_REGION3_CBR_MST 0x18A8 671 #define RK3568_ESMART0_REGION3_VIR 0x18AC 672 #define RK3568_ESMART0_REGION3_ACT_INFO 0x18B0 673 #define RK3568_ESMART0_REGION3_DSP_INFO 0x18B4 674 #define RK3568_ESMART0_REGION3_DSP_ST 0x18B8 675 #define RK3568_ESMART0_REGION3_SCL_CTRL 0x18C0 676 #define RK3568_ESMART0_REGION3_SCL_FACTOR_YRGB 0x18C4 677 #define RK3568_ESMART0_REGION3_SCL_FACTOR_CBR 0x18C8 678 #define RK3568_ESMART0_REGION3_SCL_OFFSET 0x18CC 679 680 #define RK3568_ESMART1_CTRL0 0x1A00 681 #define RK3568_ESMART1_CTRL1 0x1A04 682 #define RK3568_ESMART1_REGION0_CTRL 0x1A10 683 #define RK3568_ESMART1_REGION0_YRGB_MST 0x1A14 684 #define RK3568_ESMART1_REGION0_CBR_MST 0x1A18 685 #define RK3568_ESMART1_REGION0_VIR 0x1A1C 686 #define RK3568_ESMART1_REGION0_ACT_INFO 0x1A20 687 #define RK3568_ESMART1_REGION0_DSP_INFO 0x1A24 688 #define RK3568_ESMART1_REGION0_DSP_ST 0x1A28 689 #define RK3568_ESMART1_REGION0_SCL_CTRL 0x1A30 690 #define RK3568_ESMART1_REGION0_SCL_FACTOR_YRGB 0x1A34 691 #define RK3568_ESMART1_REGION0_SCL_FACTOR_CBR 0x1A38 692 #define RK3568_ESMART1_REGION0_SCL_OFFSET 0x1A3C 693 #define RK3568_ESMART1_REGION1_CTRL 0x1A40 694 #define RK3568_ESMART1_REGION1_YRGB_MST 0x1A44 695 #define RK3568_ESMART1_REGION1_CBR_MST 0x1A48 696 #define RK3568_ESMART1_REGION1_VIR 0x1A4C 697 #define RK3568_ESMART1_REGION1_ACT_INFO 0x1A50 698 #define RK3568_ESMART1_REGION1_DSP_INFO 0x1A54 699 #define RK3568_ESMART1_REGION1_DSP_ST 0x1A58 700 #define RK3568_ESMART1_REGION1_SCL_CTRL 0x1A60 701 #define RK3568_ESMART1_REGION1_SCL_FACTOR_YRGB 0x1A64 702 #define RK3568_ESMART1_REGION1_SCL_FACTOR_CBR 0x1A68 703 #define RK3568_ESMART1_REGION1_SCL_OFFSET 0x1A6C 704 #define RK3568_ESMART1_REGION2_CTRL 0x1A70 705 #define RK3568_ESMART1_REGION2_YRGB_MST 0x1A74 706 #define RK3568_ESMART1_REGION2_CBR_MST 0x1A78 707 #define RK3568_ESMART1_REGION2_VIR 0x1A7C 708 #define RK3568_ESMART1_REGION2_ACT_INFO 0x1A80 709 #define RK3568_ESMART1_REGION2_DSP_INFO 0x1A84 710 #define RK3568_ESMART1_REGION2_DSP_ST 0x1A88 711 #define RK3568_ESMART1_REGION2_SCL_CTRL 0x1A90 712 #define RK3568_ESMART1_REGION2_SCL_FACTOR_YRGB 0x1A94 713 #define RK3568_ESMART1_REGION2_SCL_FACTOR_CBR 0x1A98 714 #define RK3568_ESMART1_REGION2_SCL_OFFSET 0x1A9C 715 #define RK3568_ESMART1_REGION3_CTRL 0x1AA0 716 #define RK3568_ESMART1_REGION3_YRGB_MST 0x1AA4 717 #define RK3568_ESMART1_REGION3_CBR_MST 0x1AA8 718 #define RK3568_ESMART1_REGION3_VIR 0x1AAC 719 #define RK3568_ESMART1_REGION3_ACT_INFO 0x1AB0 720 #define RK3568_ESMART1_REGION3_DSP_INFO 0x1AB4 721 #define RK3568_ESMART1_REGION3_DSP_ST 0x1AB8 722 #define RK3568_ESMART1_REGION3_SCL_CTRL 0x1AC0 723 #define RK3568_ESMART1_REGION3_SCL_FACTOR_YRGB 0x1AC4 724 #define RK3568_ESMART1_REGION3_SCL_FACTOR_CBR 0x1AC8 725 #define RK3568_ESMART1_REGION3_SCL_OFFSET 0x1ACC 726 727 #define RK3568_SMART0_CTRL0 0x1C00 728 #define RK3568_SMART0_CTRL1 0x1C04 729 #define RK3568_SMART0_REGION0_CTRL 0x1C10 730 #define RK3568_SMART0_REGION0_YRGB_MST 0x1C14 731 #define RK3568_SMART0_REGION0_CBR_MST 0x1C18 732 #define RK3568_SMART0_REGION0_VIR 0x1C1C 733 #define RK3568_SMART0_REGION0_ACT_INFO 0x1C20 734 #define RK3568_SMART0_REGION0_DSP_INFO 0x1C24 735 #define RK3568_SMART0_REGION0_DSP_ST 0x1C28 736 #define RK3568_SMART0_REGION0_SCL_CTRL 0x1C30 737 #define RK3568_SMART0_REGION0_SCL_FACTOR_YRGB 0x1C34 738 #define RK3568_SMART0_REGION0_SCL_FACTOR_CBR 0x1C38 739 #define RK3568_SMART0_REGION0_SCL_OFFSET 0x1C3C 740 #define RK3568_SMART0_REGION1_CTRL 0x1C40 741 #define RK3568_SMART0_REGION1_YRGB_MST 0x1C44 742 #define RK3568_SMART0_REGION1_CBR_MST 0x1C48 743 #define RK3568_SMART0_REGION1_VIR 0x1C4C 744 #define RK3568_SMART0_REGION1_ACT_INFO 0x1C50 745 #define RK3568_SMART0_REGION1_DSP_INFO 0x1C54 746 #define RK3568_SMART0_REGION1_DSP_ST 0x1C58 747 #define RK3568_SMART0_REGION1_SCL_CTRL 0x1C60 748 #define RK3568_SMART0_REGION1_SCL_FACTOR_YRGB 0x1C64 749 #define RK3568_SMART0_REGION1_SCL_FACTOR_CBR 0x1C68 750 #define RK3568_SMART0_REGION1_SCL_OFFSET 0x1C6C 751 #define RK3568_SMART0_REGION2_CTRL 0x1C70 752 #define RK3568_SMART0_REGION2_YRGB_MST 0x1C74 753 #define RK3568_SMART0_REGION2_CBR_MST 0x1C78 754 #define RK3568_SMART0_REGION2_VIR 0x1C7C 755 #define RK3568_SMART0_REGION2_ACT_INFO 0x1C80 756 #define RK3568_SMART0_REGION2_DSP_INFO 0x1C84 757 #define RK3568_SMART0_REGION2_DSP_ST 0x1C88 758 #define RK3568_SMART0_REGION2_SCL_CTRL 0x1C90 759 #define RK3568_SMART0_REGION2_SCL_FACTOR_YRGB 0x1C94 760 #define RK3568_SMART0_REGION2_SCL_FACTOR_CBR 0x1C98 761 #define RK3568_SMART0_REGION2_SCL_OFFSET 0x1C9C 762 #define RK3568_SMART0_REGION3_CTRL 0x1CA0 763 #define RK3568_SMART0_REGION3_YRGB_MST 0x1CA4 764 #define RK3568_SMART0_REGION3_CBR_MST 0x1CA8 765 #define RK3568_SMART0_REGION3_VIR 0x1CAC 766 #define RK3568_SMART0_REGION3_ACT_INFO 0x1CB0 767 #define RK3568_SMART0_REGION3_DSP_INFO 0x1CB4 768 #define RK3568_SMART0_REGION3_DSP_ST 0x1CB8 769 #define RK3568_SMART0_REGION3_SCL_CTRL 0x1CC0 770 #define RK3568_SMART0_REGION3_SCL_FACTOR_YRGB 0x1CC4 771 #define RK3568_SMART0_REGION3_SCL_FACTOR_CBR 0x1CC8 772 #define RK3568_SMART0_REGION3_SCL_OFFSET 0x1CCC 773 774 #define RK3568_SMART1_CTRL0 0x1E00 775 #define RK3568_SMART1_CTRL1 0x1E04 776 #define RK3568_SMART1_REGION0_CTRL 0x1E10 777 #define RK3568_SMART1_REGION0_YRGB_MST 0x1E14 778 #define RK3568_SMART1_REGION0_CBR_MST 0x1E18 779 #define RK3568_SMART1_REGION0_VIR 0x1E1C 780 #define RK3568_SMART1_REGION0_ACT_INFO 0x1E20 781 #define RK3568_SMART1_REGION0_DSP_INFO 0x1E24 782 #define RK3568_SMART1_REGION0_DSP_ST 0x1E28 783 #define RK3568_SMART1_REGION0_SCL_CTRL 0x1E30 784 #define RK3568_SMART1_REGION0_SCL_FACTOR_YRGB 0x1E34 785 #define RK3568_SMART1_REGION0_SCL_FACTOR_CBR 0x1E38 786 #define RK3568_SMART1_REGION0_SCL_OFFSET 0x1E3C 787 #define RK3568_SMART1_REGION1_CTRL 0x1E40 788 #define RK3568_SMART1_REGION1_YRGB_MST 0x1E44 789 #define RK3568_SMART1_REGION1_CBR_MST 0x1E48 790 #define RK3568_SMART1_REGION1_VIR 0x1E4C 791 #define RK3568_SMART1_REGION1_ACT_INFO 0x1E50 792 #define RK3568_SMART1_REGION1_DSP_INFO 0x1E54 793 #define RK3568_SMART1_REGION1_DSP_ST 0x1E58 794 #define RK3568_SMART1_REGION1_SCL_CTRL 0x1E60 795 #define RK3568_SMART1_REGION1_SCL_FACTOR_YRGB 0x1E64 796 #define RK3568_SMART1_REGION1_SCL_FACTOR_CBR 0x1E68 797 #define RK3568_SMART1_REGION1_SCL_OFFSET 0x1E6C 798 #define RK3568_SMART1_REGION2_CTRL 0x1E70 799 #define RK3568_SMART1_REGION2_YRGB_MST 0x1E74 800 #define RK3568_SMART1_REGION2_CBR_MST 0x1E78 801 #define RK3568_SMART1_REGION2_VIR 0x1E7C 802 #define RK3568_SMART1_REGION2_ACT_INFO 0x1E80 803 #define RK3568_SMART1_REGION2_DSP_INFO 0x1E84 804 #define RK3568_SMART1_REGION2_DSP_ST 0x1E88 805 #define RK3568_SMART1_REGION2_SCL_CTRL 0x1E90 806 #define RK3568_SMART1_REGION2_SCL_FACTOR_YRGB 0x1E94 807 #define RK3568_SMART1_REGION2_SCL_FACTOR_CBR 0x1E98 808 #define RK3568_SMART1_REGION2_SCL_OFFSET 0x1E9C 809 #define RK3568_SMART1_REGION3_CTRL 0x1EA0 810 #define RK3568_SMART1_REGION3_YRGB_MST 0x1EA4 811 #define RK3568_SMART1_REGION3_CBR_MST 0x1EA8 812 #define RK3568_SMART1_REGION3_VIR 0x1EAC 813 #define RK3568_SMART1_REGION3_ACT_INFO 0x1EB0 814 #define RK3568_SMART1_REGION3_DSP_INFO 0x1EB4 815 #define RK3568_SMART1_REGION3_DSP_ST 0x1EB8 816 #define RK3568_SMART1_REGION3_SCL_CTRL 0x1EC0 817 #define RK3568_SMART1_REGION3_SCL_FACTOR_YRGB 0x1EC4 818 #define RK3568_SMART1_REGION3_SCL_FACTOR_CBR 0x1EC8 819 #define RK3568_SMART1_REGION3_SCL_OFFSET 0x1ECC 820 821 /* HDR register definition */ 822 #define RK3568_HDR_LUT_CTRL 0x2000 823 824 #define RK3588_VP3_DSP_CTRL 0xF00 825 #define RK3588_CLUSTER2_WIN0_CTRL0 0x1400 826 #define RK3588_CLUSTER3_WIN0_CTRL0 0x1600 827 828 /* DSC 8K/4K register definition */ 829 #define RK3588_DSC_8K_PPS0_3 0x4000 830 #define RK3588_DSC_8K_CTRL0 0x40A0 831 #define DSC_EN_SHIFT 0 832 #define DSC_RBIT_SHIFT 2 833 #define DSC_RBYT_SHIFT 3 834 #define DSC_FLAL_SHIFT 4 835 #define DSC_MER_SHIFT 5 836 #define DSC_EPB_SHIFT 6 837 #define DSC_EPL_SHIFT 7 838 #define DSC_NSLC_MASK 0x7 839 #define DSC_NSLC_SHIFT 16 840 #define DSC_SBO_SHIFT 28 841 #define DSC_IFEP_SHIFT 29 842 #define DSC_PPS_UPD_SHIFT 31 843 #define DSC_CTRL0_DEF_CON ((1 << DSC_EN_SHIFT) | (1 << DSC_RBIT_SHIFT) | (0 << DSC_RBYT_SHIFT) | \ 844 (1 << DSC_FLAL_SHIFT) | (1 << DSC_MER_SHIFT) | (0 << DSC_EPB_SHIFT) | \ 845 (1 << DSC_EPL_SHIFT) | (1 << DSC_SBO_SHIFT)) 846 847 #define RK3588_DSC_8K_CTRL1 0x40A4 848 #define RK3588_DSC_8K_STS0 0x40A8 849 #define RK3588_DSC_8K_ERS 0x40C4 850 851 #define RK3588_DSC_4K_PPS0_3 0x4100 852 #define RK3588_DSC_4K_CTRL0 0x41A0 853 #define RK3588_DSC_4K_CTRL1 0x41A4 854 #define RK3588_DSC_4K_STS0 0x41A8 855 #define RK3588_DSC_4K_ERS 0x41C4 856 857 /* RK3528 HDR register definition */ 858 #define RK3528_HDR_LUT_CTRL 0x2000 859 860 /* RK3528 ACM register definition */ 861 #define RK3528_ACM_CTRL 0x6400 862 #define RK3528_ACM_DELTA_RANGE 0x6404 863 #define RK3528_ACM_FETCH_START 0x6408 864 #define RK3528_ACM_FETCH_DONE 0x6420 865 #define RK3528_ACM_YHS_DEL_HY_SEG0 0x6500 866 #define RK3528_ACM_YHS_DEL_HY_SEG152 0x6760 867 #define RK3528_ACM_YHS_DEL_HS_SEG0 0x6764 868 #define RK3528_ACM_YHS_DEL_HS_SEG220 0x6ad4 869 #define RK3528_ACM_YHS_DEL_HGAIN_SEG0 0x6ad8 870 #define RK3528_ACM_YHS_DEL_HGAIN_SEG64 0x6bd8 871 872 #define RK3568_MAX_REG 0x1ED0 873 874 #define RK3562_GRF_IOC_VO_IO_CON 0x10500 875 #define RK3568_GRF_VO_CON1 0x0364 876 #define GRF_BT656_CLK_INV_SHIFT 1 877 #define GRF_BT1120_CLK_INV_SHIFT 2 878 #define GRF_RGB_DCLK_INV_SHIFT 3 879 880 #define RK3588_GRF_VOP_CON2 0x0008 881 #define RK3588_GRF_EDP0_ENABLE_SHIFT 0 882 #define RK3588_GRF_HDMITX0_ENABLE_SHIFT 1 883 #define RK3588_GRF_EDP1_ENABLE_SHIFT 3 884 #define RK3588_GRF_HDMITX1_ENABLE_SHIFT 4 885 886 #define RK3588_GRF_VO1_CON0 0x0000 887 #define HDMI_SYNC_POL_MASK 0x3 888 #define HDMI0_SYNC_POL_SHIFT 5 889 #define HDMI1_SYNC_POL_SHIFT 7 890 891 #define RK3588_PMU_BISR_CON3 0x20C 892 #define RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT 9 893 #define RK3588_PD_CLUSTER1_REPAIR_EN_SHIFT 10 894 #define RK3588_PD_CLUSTER2_REPAIR_EN_SHIFT 11 895 #define RK3588_PD_CLUSTER3_REPAIR_EN_SHIFT 12 896 #define RK3588_PD_DSC_8K_REPAIR_EN_SHIFT 13 897 #define RK3588_PD_DSC_4K_REPAIR_EN_SHIFT 14 898 #define RK3588_PD_ESMART_REPAIR_EN_SHIFT 15 899 900 #define RK3588_PMU_BISR_STATUS5 0x294 901 #define RK3588_PD_CLUSTER0_PWR_STAT_SHIFI 9 902 #define RK3588_PD_CLUSTER1_PWR_STAT_SHIFI 10 903 #define RK3588_PD_CLUSTER2_PWR_STAT_SHIFI 11 904 #define RK3588_PD_CLUSTER3_PWR_STAT_SHIFI 12 905 #define RK3588_PD_DSC_8K_PWR_STAT_SHIFI 13 906 #define RK3588_PD_DSC_4K_PWR_STAT_SHIFI 14 907 #define RK3588_PD_ESMART_PWR_STAT_SHIFI 15 908 909 #define VOP2_LAYER_MAX 8 910 911 #define VOP2_MAX_VP_OUTPUT_WIDTH 4096 912 913 #define VOP_FEATURE_OUTPUT_10BIT BIT(0) 914 915 /* KHz */ 916 #define VOP2_MAX_DCLK_RATE 600000 917 918 /* 919 * vop2 dsc id 920 */ 921 #define ROCKCHIP_VOP2_DSC_8K 0 922 #define ROCKCHIP_VOP2_DSC_4K 1 923 924 /* 925 * vop2 internal power domain id, 926 * should be all none zero, 0 will be 927 * treat as invalid; 928 */ 929 #define VOP2_PD_CLUSTER0 BIT(0) 930 #define VOP2_PD_CLUSTER1 BIT(1) 931 #define VOP2_PD_CLUSTER2 BIT(2) 932 #define VOP2_PD_CLUSTER3 BIT(3) 933 #define VOP2_PD_DSC_8K BIT(5) 934 #define VOP2_PD_DSC_4K BIT(6) 935 #define VOP2_PD_ESMART BIT(7) 936 937 #define VOP2_PLANE_NO_SCALING BIT(16) 938 939 #define VOP_FEATURE_OUTPUT_10BIT BIT(0) 940 #define VOP_FEATURE_AFBDC BIT(1) 941 #define VOP_FEATURE_ALPHA_SCALE BIT(2) 942 #define VOP_FEATURE_HDR10 BIT(3) 943 #define VOP_FEATURE_NEXT_HDR BIT(4) 944 /* a feature to splice two windows and two vps to support resolution > 4096 */ 945 #define VOP_FEATURE_SPLICE BIT(5) 946 #define VOP_FEATURE_OVERSCAN BIT(6) 947 #define VOP_FEATURE_VIVID_HDR BIT(7) 948 #define VOP_FEATURE_POST_ACM BIT(8) 949 #define VOP_FEATURE_POST_CSC BIT(9) 950 951 #define WIN_FEATURE_HDR2SDR BIT(0) 952 #define WIN_FEATURE_SDR2HDR BIT(1) 953 #define WIN_FEATURE_PRE_OVERLAY BIT(2) 954 #define WIN_FEATURE_AFBDC BIT(3) 955 #define WIN_FEATURE_CLUSTER_MAIN BIT(4) 956 #define WIN_FEATURE_CLUSTER_SUB BIT(5) 957 /* a mirror win can only get fb address 958 * from source win: 959 * Cluster1---->Cluster0 960 * Esmart1 ---->Esmart0 961 * Smart1 ---->Smart0 962 * This is a feather on rk3566 963 */ 964 #define WIN_FEATURE_MIRROR BIT(6) 965 #define WIN_FEATURE_MULTI_AREA BIT(7) 966 #define WIN_FEATURE_Y2R_13BIT_DEPTH BIT(8) 967 968 #define V4L2_COLORSPACE_BT709F 0xfe 969 #define V4L2_COLORSPACE_BT2020F 0xff 970 971 enum vop_csc_format { 972 CSC_BT601L, 973 CSC_BT709L, 974 CSC_BT601F, 975 CSC_BT2020, 976 CSC_BT709L_13BIT, 977 CSC_BT709F_13BIT, 978 CSC_BT2020L_13BIT, 979 CSC_BT2020F_13BIT, 980 }; 981 982 enum vop_csc_bit_depth { 983 CSC_10BIT_DEPTH, 984 CSC_13BIT_DEPTH, 985 }; 986 987 enum vop2_pol { 988 HSYNC_POSITIVE = 0, 989 VSYNC_POSITIVE = 1, 990 DEN_NEGATIVE = 2, 991 DCLK_INVERT = 3 992 }; 993 994 enum vop2_bcsh_out_mode { 995 BCSH_OUT_MODE_BLACK, 996 BCSH_OUT_MODE_BLUE, 997 BCSH_OUT_MODE_COLOR_BAR, 998 BCSH_OUT_MODE_NORMAL_VIDEO, 999 }; 1000 1001 #define _VOP_REG(off, _mask, _shift, _write_mask) \ 1002 { \ 1003 .offset = off, \ 1004 .mask = _mask, \ 1005 .shift = _shift, \ 1006 .write_mask = _write_mask, \ 1007 } 1008 1009 #define VOP_REG(off, _mask, _shift) \ 1010 _VOP_REG(off, _mask, _shift, false) 1011 enum dither_down_mode { 1012 RGB888_TO_RGB565 = 0x0, 1013 RGB888_TO_RGB666 = 0x1 1014 }; 1015 1016 enum vop2_video_ports_id { 1017 VOP2_VP0, 1018 VOP2_VP1, 1019 VOP2_VP2, 1020 VOP2_VP3, 1021 VOP2_VP_MAX, 1022 }; 1023 1024 enum vop2_layer_type { 1025 CLUSTER_LAYER = 0, 1026 ESMART_LAYER = 1, 1027 SMART_LAYER = 2, 1028 }; 1029 1030 /* This define must same with kernel win phy id */ 1031 enum vop2_layer_phy_id { 1032 ROCKCHIP_VOP2_CLUSTER0 = 0, 1033 ROCKCHIP_VOP2_CLUSTER1, 1034 ROCKCHIP_VOP2_ESMART0, 1035 ROCKCHIP_VOP2_ESMART1, 1036 ROCKCHIP_VOP2_SMART0, 1037 ROCKCHIP_VOP2_SMART1, 1038 ROCKCHIP_VOP2_CLUSTER2, 1039 ROCKCHIP_VOP2_CLUSTER3, 1040 ROCKCHIP_VOP2_ESMART2, 1041 ROCKCHIP_VOP2_ESMART3, 1042 ROCKCHIP_VOP2_LAYER_MAX, 1043 }; 1044 1045 enum vop2_scale_up_mode { 1046 VOP2_SCALE_UP_NRST_NBOR, 1047 VOP2_SCALE_UP_BIL, 1048 VOP2_SCALE_UP_BIC, 1049 }; 1050 1051 enum vop2_scale_down_mode { 1052 VOP2_SCALE_DOWN_NRST_NBOR, 1053 VOP2_SCALE_DOWN_BIL, 1054 VOP2_SCALE_DOWN_AVG, 1055 }; 1056 1057 enum scale_mode { 1058 SCALE_NONE = 0x0, 1059 SCALE_UP = 0x1, 1060 SCALE_DOWN = 0x2 1061 }; 1062 1063 enum vop_dsc_interface_mode { 1064 VOP_DSC_IF_DISABLE = 0, 1065 VOP_DSC_IF_HDMI = 1, 1066 VOP_DSC_IF_MIPI_DS_MODE = 2, 1067 VOP_DSC_IF_MIPI_VIDEO_MODE = 3, 1068 }; 1069 1070 enum vop3_pre_scale_down_mode { 1071 VOP3_PRE_SCALE_UNSPPORT, 1072 VOP3_PRE_SCALE_DOWN_GT, 1073 VOP3_PRE_SCALE_DOWN_AVG, 1074 }; 1075 1076 enum vop3_esmart_lb_mode { 1077 VOP3_ESMART_8K_MODE, 1078 VOP3_ESMART_4K_4K_MODE, 1079 VOP3_ESMART_4K_2K_2K_MODE, 1080 VOP3_ESMART_2K_2K_2K_2K_MODE, 1081 }; 1082 1083 struct vop2_layer { 1084 u8 id; 1085 /** 1086 * @win_phys_id: window id of the layer selected. 1087 * Every layer must make sure to select different 1088 * windows of others. 1089 */ 1090 u8 win_phys_id; 1091 }; 1092 1093 struct vop2_power_domain_data { 1094 u8 id; 1095 u8 parent_id; 1096 /* 1097 * @module_id_mask: module id of which module this power domain is belongs to. 1098 * PD_CLUSTER0,1,2,3 only belongs to CLUSTER0/1/2/3, PD_Esmart0 shared by Esmart1/2/3 1099 */ 1100 u32 module_id_mask; 1101 }; 1102 1103 struct vop2_win_data { 1104 char *name; 1105 u8 phys_id; 1106 enum vop2_layer_type type; 1107 u8 win_sel_port_offset; 1108 u8 layer_sel_win_id[VOP2_VP_MAX]; 1109 u8 axi_id; 1110 u8 axi_uv_id; 1111 u8 axi_yrgb_id; 1112 u8 splice_win_id; 1113 u8 pd_id; 1114 u8 hsu_filter_mode; 1115 u8 hsd_filter_mode; 1116 u8 vsu_filter_mode; 1117 u8 vsd_filter_mode; 1118 u8 hsd_pre_filter_mode; 1119 u8 vsd_pre_filter_mode; 1120 u8 scale_engine_num; 1121 u32 reg_offset; 1122 u32 max_upscale_factor; 1123 u32 max_downscale_factor; 1124 bool splice_mode_right; 1125 }; 1126 1127 struct vop2_vp_data { 1128 u32 feature; 1129 u8 pre_scan_max_dly; 1130 u8 layer_mix_dly; 1131 u8 hdr_mix_dly; 1132 u8 win_dly; 1133 u8 splice_vp_id; 1134 struct vop_rect max_output; 1135 u32 max_dclk; 1136 }; 1137 1138 struct vop2_plane_table { 1139 enum vop2_layer_phy_id plane_id; 1140 enum vop2_layer_type plane_type; 1141 }; 1142 1143 struct vop2_vp_plane_mask { 1144 u8 primary_plane_id; /* use this win to show logo */ 1145 u8 attached_layers_nr; /* number layers attach to this vp */ 1146 u8 attached_layers[VOP2_LAYER_MAX]; /* the layers attached to this vp */ 1147 u32 plane_mask; 1148 int cursor_plane_id; 1149 }; 1150 1151 struct vop2_dsc_data { 1152 u8 id; 1153 u8 pd_id; 1154 u8 max_slice_num; 1155 u8 max_linebuf_depth; /* used to generate the bitstream */ 1156 u8 min_bits_per_pixel; /* bit num after encoder compress */ 1157 const char *dsc_txp_clk_src_name; 1158 const char *dsc_txp_clk_name; 1159 const char *dsc_pxl_clk_name; 1160 const char *dsc_cds_clk_name; 1161 }; 1162 1163 struct dsc_error_info { 1164 u32 dsc_error_val; 1165 char dsc_error_info[50]; 1166 }; 1167 1168 struct vop2_dump_regs { 1169 u32 offset; 1170 const char *name; 1171 u32 state_base; 1172 u32 state_mask; 1173 u32 state_shift; 1174 bool enable_state; 1175 }; 1176 1177 struct vop2_data { 1178 u32 version; 1179 u32 esmart_lb_mode; 1180 struct vop2_vp_data *vp_data; 1181 struct vop2_win_data *win_data; 1182 struct vop2_vp_plane_mask *plane_mask; 1183 struct vop2_plane_table *plane_table; 1184 struct vop2_power_domain_data *pd; 1185 struct vop2_dsc_data *dsc; 1186 struct dsc_error_info *dsc_error_ecw; 1187 struct dsc_error_info *dsc_error_buffer_flow; 1188 struct vop2_dump_regs *dump_regs; 1189 u8 *vp_primary_plane_order; 1190 u8 nr_vps; 1191 u8 nr_layers; 1192 u8 nr_mixers; 1193 u8 nr_gammas; 1194 u8 nr_pd; 1195 u8 nr_dscs; 1196 u8 nr_dsc_ecw; 1197 u8 nr_dsc_buffer_flow; 1198 u32 reg_len; 1199 u32 dump_regs_size; 1200 }; 1201 1202 struct vop2 { 1203 u32 *regsbak; 1204 void *regs; 1205 void *grf; 1206 void *vop_grf; 1207 void *vo1_grf; 1208 void *sys_pmu; 1209 u32 reg_len; 1210 u32 version; 1211 u32 esmart_lb_mode; 1212 bool global_init; 1213 const struct vop2_data *data; 1214 struct vop2_vp_plane_mask vp_plane_mask[VOP2_VP_MAX]; 1215 }; 1216 1217 static struct vop2 *rockchip_vop2; 1218 1219 static inline bool is_vop3(struct vop2 *vop2) 1220 { 1221 if (vop2->version == VOP_VERSION_RK3568 || vop2->version == VOP_VERSION_RK3588) 1222 return false; 1223 else 1224 return true; 1225 } 1226 1227 /* 1228 * bli_sd_factor = (src - 1) / (dst - 1) << 12; 1229 * avg_sd_factor: 1230 * bli_su_factor: 1231 * bic_su_factor: 1232 * = (src - 1) / (dst - 1) << 16; 1233 * 1234 * ygt2 enable: dst get one line from two line of the src 1235 * ygt4 enable: dst get one line from four line of the src. 1236 * 1237 */ 1238 #define VOP2_BILI_SCL_DN(src, dst) (((src - 1) << 12) / (dst - 1)) 1239 #define VOP2_COMMON_SCL(src, dst) (((src - 1) << 16) / (dst - 1)) 1240 1241 #define VOP2_BILI_SCL_FAC_CHECK(src, dst, fac) \ 1242 (fac * (dst - 1) >> 12 < (src - 1)) 1243 #define VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac) \ 1244 (fac * (dst - 1) >> 16 < (src - 1)) 1245 #define VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac) \ 1246 (fac * (dst - 1) >> 16 < (src - 1)) 1247 1248 static uint16_t vop2_scale_factor(enum scale_mode mode, 1249 int32_t filter_mode, 1250 uint32_t src, uint32_t dst) 1251 { 1252 uint32_t fac = 0; 1253 int i = 0; 1254 1255 if (mode == SCALE_NONE) 1256 return 0; 1257 1258 /* 1259 * A workaround to avoid zero div. 1260 */ 1261 if ((dst == 1) || (src == 1)) { 1262 dst = dst + 1; 1263 src = src + 1; 1264 } 1265 1266 if ((mode == SCALE_DOWN) && (filter_mode == VOP2_SCALE_DOWN_BIL)) { 1267 fac = VOP2_BILI_SCL_DN(src, dst); 1268 for (i = 0; i < 100; i++) { 1269 if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac)) 1270 break; 1271 fac -= 1; 1272 printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 1273 } 1274 } else { 1275 fac = VOP2_COMMON_SCL(src, dst); 1276 for (i = 0; i < 100; i++) { 1277 if (VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac)) 1278 break; 1279 fac -= 1; 1280 printf("up fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 1281 } 1282 } 1283 1284 return fac; 1285 } 1286 1287 static bool vop3_scale_up_fac_check(uint32_t src, uint32_t dst, uint32_t fac, bool is_hor) 1288 { 1289 if (is_hor) 1290 return VOP3_COMMON_HOR_SCL_FAC_CHECK(src, dst, fac); 1291 return VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac); 1292 } 1293 1294 static uint16_t vop3_scale_factor(enum scale_mode mode, 1295 uint32_t src, uint32_t dst, bool is_hor) 1296 { 1297 uint32_t fac = 0; 1298 int i = 0; 1299 1300 if (mode == SCALE_NONE) 1301 return 0; 1302 1303 /* 1304 * A workaround to avoid zero div. 1305 */ 1306 if ((dst == 1) || (src == 1)) { 1307 dst = dst + 1; 1308 src = src + 1; 1309 } 1310 1311 if (mode == SCALE_DOWN) { 1312 fac = VOP2_BILI_SCL_DN(src, dst); 1313 for (i = 0; i < 100; i++) { 1314 if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac)) 1315 break; 1316 fac -= 1; 1317 printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 1318 } 1319 } else { 1320 fac = VOP2_COMMON_SCL(src, dst); 1321 for (i = 0; i < 100; i++) { 1322 if (vop3_scale_up_fac_check(src, dst, fac, is_hor)) 1323 break; 1324 fac -= 1; 1325 printf("up fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 1326 } 1327 } 1328 1329 return fac; 1330 } 1331 1332 static inline enum scale_mode scl_get_scl_mode(int src, int dst) 1333 { 1334 if (src < dst) 1335 return SCALE_UP; 1336 else if (src > dst) 1337 return SCALE_DOWN; 1338 1339 return SCALE_NONE; 1340 } 1341 1342 static inline int interpolate(int x1, int y1, int x2, int y2, int x) 1343 { 1344 return y1 + (y2 - y1) * (x - x1) / (x2 - x1); 1345 } 1346 1347 static int vop2_get_primary_plane(struct vop2 *vop2, u32 plane_mask) 1348 { 1349 int i = 0; 1350 1351 for (i = 0; i < vop2->data->nr_layers; i++) { 1352 if (plane_mask & BIT(vop2->data->vp_primary_plane_order[i])) 1353 return vop2->data->vp_primary_plane_order[i]; 1354 } 1355 1356 return vop2->data->vp_primary_plane_order[0]; 1357 } 1358 1359 static inline u16 scl_cal_scale(int src, int dst, int shift) 1360 { 1361 return ((src * 2 - 3) << (shift - 1)) / (dst - 1); 1362 } 1363 1364 static inline u16 scl_cal_scale2(int src, int dst) 1365 { 1366 return ((src - 1) << 12) / (dst - 1); 1367 } 1368 1369 static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v) 1370 { 1371 writel(v, vop2->regs + offset); 1372 vop2->regsbak[offset >> 2] = v; 1373 } 1374 1375 static inline u32 vop2_readl(struct vop2 *vop2, u32 offset) 1376 { 1377 return readl(vop2->regs + offset); 1378 } 1379 1380 static inline void vop2_mask_write(struct vop2 *vop2, u32 offset, 1381 u32 mask, u32 shift, u32 v, 1382 bool write_mask) 1383 { 1384 if (!mask) 1385 return; 1386 1387 if (write_mask) { 1388 v = ((v & mask) << shift) | (mask << (shift + 16)); 1389 } else { 1390 u32 cached_val = vop2->regsbak[offset >> 2]; 1391 1392 v = (cached_val & ~(mask << shift)) | ((v & mask) << shift); 1393 vop2->regsbak[offset >> 2] = v; 1394 } 1395 1396 writel(v, vop2->regs + offset); 1397 } 1398 1399 static inline void vop2_grf_writel(struct vop2 *vop, void *grf_base, u32 offset, 1400 u32 mask, u32 shift, u32 v) 1401 { 1402 u32 val = 0; 1403 1404 val = (v << shift) | (mask << (shift + 16)); 1405 writel(val, grf_base + offset); 1406 } 1407 1408 static inline u32 vop2_grf_readl(struct vop2 *vop, void *grf_base, u32 offset, 1409 u32 mask, u32 shift) 1410 { 1411 return (readl(grf_base + offset) >> shift) & mask; 1412 } 1413 1414 static char* get_output_if_name(u32 output_if, char *name) 1415 { 1416 if (output_if & VOP_OUTPUT_IF_RGB) 1417 strcat(name, " RGB"); 1418 if (output_if & VOP_OUTPUT_IF_BT1120) 1419 strcat(name, " BT1120"); 1420 if (output_if & VOP_OUTPUT_IF_BT656) 1421 strcat(name, " BT656"); 1422 if (output_if & VOP_OUTPUT_IF_LVDS0) 1423 strcat(name, " LVDS0"); 1424 if (output_if & VOP_OUTPUT_IF_LVDS1) 1425 strcat(name, " LVDS1"); 1426 if (output_if & VOP_OUTPUT_IF_MIPI0) 1427 strcat(name, " MIPI0"); 1428 if (output_if & VOP_OUTPUT_IF_MIPI1) 1429 strcat(name, " MIPI1"); 1430 if (output_if & VOP_OUTPUT_IF_eDP0) 1431 strcat(name, " eDP0"); 1432 if (output_if & VOP_OUTPUT_IF_eDP1) 1433 strcat(name, " eDP1"); 1434 if (output_if & VOP_OUTPUT_IF_DP0) 1435 strcat(name, " DP0"); 1436 if (output_if & VOP_OUTPUT_IF_DP1) 1437 strcat(name, " DP1"); 1438 if (output_if & VOP_OUTPUT_IF_HDMI0) 1439 strcat(name, " HDMI0"); 1440 if (output_if & VOP_OUTPUT_IF_HDMI1) 1441 strcat(name, " HDMI1"); 1442 1443 return name; 1444 } 1445 1446 static char *get_plane_name(int plane_id, char *name) 1447 { 1448 switch (plane_id) { 1449 case ROCKCHIP_VOP2_CLUSTER0: 1450 strcat(name, "Cluster0"); 1451 break; 1452 case ROCKCHIP_VOP2_CLUSTER1: 1453 strcat(name, "Cluster1"); 1454 break; 1455 case ROCKCHIP_VOP2_ESMART0: 1456 strcat(name, "Esmart0"); 1457 break; 1458 case ROCKCHIP_VOP2_ESMART1: 1459 strcat(name, "Esmart1"); 1460 break; 1461 case ROCKCHIP_VOP2_SMART0: 1462 strcat(name, "Smart0"); 1463 break; 1464 case ROCKCHIP_VOP2_SMART1: 1465 strcat(name, "Smart1"); 1466 break; 1467 case ROCKCHIP_VOP2_CLUSTER2: 1468 strcat(name, "Cluster2"); 1469 break; 1470 case ROCKCHIP_VOP2_CLUSTER3: 1471 strcat(name, "Cluster3"); 1472 break; 1473 case ROCKCHIP_VOP2_ESMART2: 1474 strcat(name, "Esmart2"); 1475 break; 1476 case ROCKCHIP_VOP2_ESMART3: 1477 strcat(name, "Esmart3"); 1478 break; 1479 } 1480 1481 return name; 1482 } 1483 1484 static bool is_yuv_output(u32 bus_format) 1485 { 1486 switch (bus_format) { 1487 case MEDIA_BUS_FMT_YUV8_1X24: 1488 case MEDIA_BUS_FMT_YUV10_1X30: 1489 case MEDIA_BUS_FMT_YUYV10_1X20: 1490 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 1491 case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 1492 case MEDIA_BUS_FMT_YUYV8_2X8: 1493 case MEDIA_BUS_FMT_YVYU8_2X8: 1494 case MEDIA_BUS_FMT_UYVY8_2X8: 1495 case MEDIA_BUS_FMT_VYUY8_2X8: 1496 case MEDIA_BUS_FMT_YUYV8_1X16: 1497 case MEDIA_BUS_FMT_YVYU8_1X16: 1498 case MEDIA_BUS_FMT_UYVY8_1X16: 1499 case MEDIA_BUS_FMT_VYUY8_1X16: 1500 return true; 1501 default: 1502 return false; 1503 } 1504 } 1505 1506 static int vop2_convert_csc_mode(int csc_mode, int bit_depth) 1507 { 1508 switch (csc_mode) { 1509 case V4L2_COLORSPACE_SMPTE170M: 1510 case V4L2_COLORSPACE_470_SYSTEM_M: 1511 case V4L2_COLORSPACE_470_SYSTEM_BG: 1512 return CSC_BT601L; 1513 case V4L2_COLORSPACE_REC709: 1514 case V4L2_COLORSPACE_SMPTE240M: 1515 case V4L2_COLORSPACE_DEFAULT: 1516 if (bit_depth == CSC_13BIT_DEPTH) 1517 return CSC_BT709L_13BIT; 1518 else 1519 return CSC_BT709L; 1520 case V4L2_COLORSPACE_JPEG: 1521 return CSC_BT601F; 1522 case V4L2_COLORSPACE_BT2020: 1523 if (bit_depth == CSC_13BIT_DEPTH) 1524 return CSC_BT2020L_13BIT; 1525 else 1526 return CSC_BT2020; 1527 case V4L2_COLORSPACE_BT709F: 1528 if (bit_depth == CSC_10BIT_DEPTH) { 1529 printf("WARN: Unsupported bt709f at 10bit csc depth, use bt601f instead\n"); 1530 return CSC_BT601F; 1531 } else { 1532 return CSC_BT709F_13BIT; 1533 } 1534 case V4L2_COLORSPACE_BT2020F: 1535 if (bit_depth == CSC_10BIT_DEPTH) { 1536 printf("WARN: Unsupported bt2020f at 10bit csc depth, use bt601f instead\n"); 1537 return CSC_BT601F; 1538 } else { 1539 return CSC_BT2020F_13BIT; 1540 } 1541 default: 1542 return CSC_BT709L; 1543 } 1544 } 1545 1546 static bool is_uv_swap(u32 bus_format, u32 output_mode) 1547 { 1548 /* 1549 * FIXME: 1550 * 1551 * There is no media type for YUV444 output, 1552 * so when out_mode is AAAA or P888, assume output is YUV444 on 1553 * yuv format. 1554 * 1555 * From H/W testing, YUV444 mode need a rb swap. 1556 */ 1557 if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 || 1558 bus_format == MEDIA_BUS_FMT_VYUY8_1X16 || 1559 bus_format == MEDIA_BUS_FMT_YVYU8_2X8 || 1560 bus_format == MEDIA_BUS_FMT_VYUY8_2X8 || 1561 ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 || 1562 bus_format == MEDIA_BUS_FMT_YUV10_1X30) && 1563 (output_mode == ROCKCHIP_OUT_MODE_AAAA || 1564 output_mode == ROCKCHIP_OUT_MODE_P888))) 1565 return true; 1566 else 1567 return false; 1568 } 1569 1570 static bool is_rb_swap(u32 bus_format, u32 output_mode) 1571 { 1572 /* 1573 * The default component order of serial rgb3x8 formats 1574 * is BGR. So it is needed to enable RB swap. 1575 */ 1576 if (bus_format == MEDIA_BUS_FMT_SRGB888_3X8 || 1577 bus_format == MEDIA_BUS_FMT_SRGB888_DUMMY_4X8) 1578 return true; 1579 else 1580 return false; 1581 } 1582 1583 static inline bool is_hot_plug_devices(int output_type) 1584 { 1585 switch (output_type) { 1586 case DRM_MODE_CONNECTOR_HDMIA: 1587 case DRM_MODE_CONNECTOR_HDMIB: 1588 case DRM_MODE_CONNECTOR_TV: 1589 case DRM_MODE_CONNECTOR_DisplayPort: 1590 case DRM_MODE_CONNECTOR_VGA: 1591 case DRM_MODE_CONNECTOR_Unknown: 1592 return true; 1593 default: 1594 return false; 1595 } 1596 } 1597 1598 static struct vop2_win_data *vop2_find_win_by_phys_id(struct vop2 *vop2, int phys_id) 1599 { 1600 int i = 0; 1601 1602 for (i = 0; i < vop2->data->nr_layers; i++) { 1603 if (vop2->data->win_data[i].phys_id == phys_id) 1604 return &vop2->data->win_data[i]; 1605 } 1606 1607 return NULL; 1608 } 1609 1610 static struct vop2_power_domain_data *vop2_find_pd_data_by_id(struct vop2 *vop2, int pd_id) 1611 { 1612 int i = 0; 1613 1614 for (i = 0; i < vop2->data->nr_pd; i++) { 1615 if (vop2->data->pd[i].id == pd_id) 1616 return &vop2->data->pd[i]; 1617 } 1618 1619 return NULL; 1620 } 1621 1622 static void rk3568_vop2_load_lut(struct vop2 *vop2, int crtc_id, 1623 u32 *lut_regs, u32 *lut_val, int lut_len) 1624 { 1625 u32 vp_offset = crtc_id * 0x100; 1626 int i; 1627 1628 vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, 1629 GAMMA_PORT_SEL_MASK, GAMMA_PORT_SEL_SHIFT, 1630 crtc_id, false); 1631 1632 for (i = 0; i < lut_len; i++) 1633 writel(lut_val[i], lut_regs + i); 1634 1635 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 1636 EN_MASK, DSP_LUT_EN_SHIFT, 1, false); 1637 } 1638 1639 static void rk3588_vop2_load_lut(struct vop2 *vop2, int crtc_id, 1640 u32 *lut_regs, u32 *lut_val, int lut_len) 1641 { 1642 u32 vp_offset = crtc_id * 0x100; 1643 int i; 1644 1645 vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, 1646 GAMMA_AHB_WRITE_SEL_MASK, GAMMA_AHB_WRITE_SEL_SHIFT, 1647 crtc_id, false); 1648 1649 for (i = 0; i < lut_len; i++) 1650 writel(lut_val[i], lut_regs + i); 1651 1652 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 1653 EN_MASK, DSP_LUT_EN_SHIFT, 1, false); 1654 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 1655 EN_MASK, GAMMA_UPDATE_EN_SHIFT, 1, false); 1656 } 1657 1658 static int rockchip_vop2_gamma_lut_init(struct vop2 *vop2, 1659 struct display_state *state) 1660 { 1661 struct connector_state *conn_state = &state->conn_state; 1662 struct crtc_state *cstate = &state->crtc_state; 1663 struct resource gamma_res; 1664 fdt_size_t lut_size; 1665 int i, lut_len, ret = 0; 1666 u32 *lut_regs; 1667 u32 *lut_val; 1668 u32 r, g, b; 1669 struct base2_disp_info *disp_info = conn_state->disp_info; 1670 static int gamma_lut_en_num = 1; 1671 1672 if (gamma_lut_en_num > vop2->data->nr_gammas) { 1673 printf("warn: only %d vp support gamma\n", vop2->data->nr_gammas); 1674 return 0; 1675 } 1676 1677 if (!disp_info) 1678 return 0; 1679 1680 if (!disp_info->gamma_lut_data.size) 1681 return 0; 1682 1683 ret = ofnode_read_resource_byname(cstate->node, "gamma_lut", &gamma_res); 1684 if (ret) 1685 printf("failed to get gamma lut res\n"); 1686 lut_regs = (u32 *)gamma_res.start; 1687 lut_size = gamma_res.end - gamma_res.start + 1; 1688 if (lut_regs == (u32 *)FDT_ADDR_T_NONE) { 1689 printf("failed to get gamma lut register\n"); 1690 return 0; 1691 } 1692 lut_len = lut_size / 4; 1693 if (lut_len != 256 && lut_len != 1024) { 1694 printf("Warning: unsupport gamma lut table[%d]\n", lut_len); 1695 return 0; 1696 } 1697 lut_val = (u32 *)calloc(1, lut_size); 1698 for (i = 0; i < lut_len; i++) { 1699 r = disp_info->gamma_lut_data.lred[i] * (lut_len - 1) / 0xffff; 1700 g = disp_info->gamma_lut_data.lgreen[i] * (lut_len - 1) / 0xffff; 1701 b = disp_info->gamma_lut_data.lblue[i] * (lut_len - 1) / 0xffff; 1702 1703 lut_val[i] = b * lut_len * lut_len + g * lut_len + r; 1704 } 1705 1706 if (vop2->version == VOP_VERSION_RK3568) { 1707 rk3568_vop2_load_lut(vop2, cstate->crtc_id, lut_regs, lut_val, lut_len); 1708 gamma_lut_en_num++; 1709 } else if (vop2->version == VOP_VERSION_RK3588) { 1710 rk3588_vop2_load_lut(vop2, cstate->crtc_id, lut_regs, lut_val, lut_len); 1711 if (cstate->splice_mode) { 1712 rk3588_vop2_load_lut(vop2, cstate->splice_crtc_id, lut_regs, lut_val, lut_len); 1713 gamma_lut_en_num++; 1714 } 1715 gamma_lut_en_num++; 1716 } 1717 1718 return 0; 1719 } 1720 1721 static int rockchip_vop2_cubic_lut_init(struct vop2 *vop2, 1722 struct display_state *state) 1723 { 1724 struct connector_state *conn_state = &state->conn_state; 1725 struct crtc_state *cstate = &state->crtc_state; 1726 int i, cubic_lut_len; 1727 u32 vp_offset = cstate->crtc_id * 0x100; 1728 struct base2_disp_info *disp_info = conn_state->disp_info; 1729 struct base2_cubic_lut_data *lut = &conn_state->disp_info->cubic_lut_data; 1730 u32 *cubic_lut_addr; 1731 1732 if (!disp_info || CONFIG_ROCKCHIP_CUBIC_LUT_SIZE == 0) 1733 return 0; 1734 1735 if (!disp_info->cubic_lut_data.size) 1736 return 0; 1737 1738 cubic_lut_addr = (u32 *)get_cubic_lut_buffer(cstate->crtc_id); 1739 cubic_lut_len = disp_info->cubic_lut_data.size; 1740 1741 for (i = 0; i < cubic_lut_len / 2; i++) { 1742 *cubic_lut_addr++ = ((lut->lred[2 * i]) & 0xfff) + 1743 ((lut->lgreen[2 * i] & 0xfff) << 12) + 1744 ((lut->lblue[2 * i] & 0xff) << 24); 1745 *cubic_lut_addr++ = ((lut->lblue[2 * i] & 0xf00) >> 8) + 1746 ((lut->lred[2 * i + 1] & 0xfff) << 4) + 1747 ((lut->lgreen[2 * i + 1] & 0xfff) << 16) + 1748 ((lut->lblue[2 * i + 1] & 0xf) << 28); 1749 *cubic_lut_addr++ = (lut->lblue[2 * i + 1] & 0xff0) >> 4; 1750 *cubic_lut_addr++ = 0; 1751 } 1752 1753 if (cubic_lut_len % 2) { 1754 *cubic_lut_addr++ = (lut->lred[2 * i] & 0xfff) + 1755 ((lut->lgreen[2 * i] & 0xfff) << 12) + 1756 ((lut->lblue[2 * i] & 0xff) << 24); 1757 *cubic_lut_addr++ = (lut->lblue[2 * i] & 0xf00) >> 8; 1758 *cubic_lut_addr++ = 0; 1759 *cubic_lut_addr = 0; 1760 } 1761 1762 vop2_writel(vop2, RK3568_VP0_3D_LUT_MST + vp_offset, 1763 get_cubic_lut_buffer(cstate->crtc_id)); 1764 vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL, 1765 EN_MASK, LUT_DMA_EN_SHIFT, 1, false); 1766 vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset, 1767 EN_MASK, VP0_3D_LUT_EN_SHIFT, 1, false); 1768 vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset, 1769 EN_MASK, VP0_3D_LUT_UPDATE_SHIFT, 1, false); 1770 1771 return 0; 1772 } 1773 1774 static void vop2_bcsh_reg_update(struct display_state *state, struct vop2 *vop2, 1775 struct bcsh_state *bcsh_state, int crtc_id) 1776 { 1777 struct crtc_state *cstate = &state->crtc_state; 1778 u32 vp_offset = crtc_id * 0x100; 1779 1780 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_MASK, 1781 BCSH_CTRL_R2Y_SHIFT, cstate->post_r2y_en, false); 1782 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_MASK, 1783 BCSH_CTRL_Y2R_SHIFT, cstate->post_y2r_en, false); 1784 1785 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_CSC_MODE_MASK, 1786 BCSH_CTRL_R2Y_CSC_MODE_SHIFT, cstate->post_csc_mode, false); 1787 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_CSC_MODE_MASK, 1788 BCSH_CTRL_Y2R_CSC_MODE_SHIFT, cstate->post_csc_mode, false); 1789 1790 if (!cstate->bcsh_en) { 1791 vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset, 1792 BCSH_EN_MASK, BCSH_EN_SHIFT, 0, false); 1793 return; 1794 } 1795 1796 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1797 BCSH_BRIGHTNESS_MASK, BCSH_BRIGHTNESS_SHIFT, 1798 bcsh_state->brightness, false); 1799 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1800 BCSH_CONTRAST_MASK, BCSH_CONTRAST_SHIFT, bcsh_state->contrast, false); 1801 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1802 BCSH_SATURATION_MASK, BCSH_SATURATION_SHIFT, 1803 bcsh_state->saturation * bcsh_state->contrast / 0x100, false); 1804 vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset, 1805 BCSH_SIN_HUE_MASK, BCSH_SIN_HUE_SHIFT, bcsh_state->sin_hue, false); 1806 vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset, 1807 BCSH_COS_HUE_MASK, BCSH_COS_HUE_SHIFT, bcsh_state->cos_hue, false); 1808 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1809 BCSH_OUT_MODE_MASK, BCSH_OUT_MODE_SHIFT, 1810 BCSH_OUT_MODE_NORMAL_VIDEO, false); 1811 vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset, 1812 BCSH_EN_MASK, BCSH_EN_SHIFT, 1, false); 1813 } 1814 1815 static void vop2_tv_config_update(struct display_state *state, struct vop2 *vop2) 1816 { 1817 struct connector_state *conn_state = &state->conn_state; 1818 struct base_bcsh_info *bcsh_info; 1819 struct crtc_state *cstate = &state->crtc_state; 1820 struct bcsh_state bcsh_state; 1821 int brightness, contrast, saturation, hue, sin_hue, cos_hue; 1822 1823 if (!conn_state->disp_info) 1824 return; 1825 bcsh_info = &conn_state->disp_info->bcsh_info; 1826 if (!bcsh_info) 1827 return; 1828 1829 if (bcsh_info->brightness != 50 || 1830 bcsh_info->contrast != 50 || 1831 bcsh_info->saturation != 50 || bcsh_info->hue != 50) 1832 cstate->bcsh_en = true; 1833 1834 if (cstate->bcsh_en) { 1835 if (!cstate->yuv_overlay) 1836 cstate->post_r2y_en = 1; 1837 if (!is_yuv_output(conn_state->bus_format)) 1838 cstate->post_y2r_en = 1; 1839 } else { 1840 if (!cstate->yuv_overlay && is_yuv_output(conn_state->bus_format)) 1841 cstate->post_r2y_en = 1; 1842 if (cstate->yuv_overlay && !is_yuv_output(conn_state->bus_format)) 1843 cstate->post_y2r_en = 1; 1844 } 1845 1846 cstate->post_csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_10BIT_DEPTH); 1847 1848 if (cstate->feature & VOP_FEATURE_OUTPUT_10BIT) 1849 brightness = interpolate(0, -128, 100, 127, 1850 bcsh_info->brightness); 1851 else 1852 brightness = interpolate(0, -32, 100, 31, 1853 bcsh_info->brightness); 1854 contrast = interpolate(0, 0, 100, 511, bcsh_info->contrast); 1855 saturation = interpolate(0, 0, 100, 511, bcsh_info->saturation); 1856 hue = interpolate(0, -30, 100, 30, bcsh_info->hue); 1857 1858 1859 /* 1860 * a:[-30~0): 1861 * sin_hue = 0x100 - sin(a)*256; 1862 * cos_hue = cos(a)*256; 1863 * a:[0~30] 1864 * sin_hue = sin(a)*256; 1865 * cos_hue = cos(a)*256; 1866 */ 1867 sin_hue = fixp_sin32(hue) >> 23; 1868 cos_hue = fixp_cos32(hue) >> 23; 1869 1870 bcsh_state.brightness = brightness; 1871 bcsh_state.contrast = contrast; 1872 bcsh_state.saturation = saturation; 1873 bcsh_state.sin_hue = sin_hue; 1874 bcsh_state.cos_hue = cos_hue; 1875 1876 vop2_bcsh_reg_update(state, vop2, &bcsh_state, cstate->crtc_id); 1877 if (cstate->splice_mode) 1878 vop2_bcsh_reg_update(state, vop2, &bcsh_state, cstate->splice_crtc_id); 1879 } 1880 1881 static void vop2_setup_dly_for_vp(struct display_state *state, struct vop2 *vop2, int crtc_id) 1882 { 1883 struct connector_state *conn_state = &state->conn_state; 1884 struct drm_display_mode *mode = &conn_state->mode; 1885 struct crtc_state *cstate = &state->crtc_state; 1886 u32 bg_ovl_dly, bg_dly, pre_scan_dly; 1887 u16 hdisplay = mode->crtc_hdisplay; 1888 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 1889 1890 bg_ovl_dly = cstate->crtc->vps[crtc_id].bg_ovl_dly; 1891 bg_dly = vop2->data->vp_data[crtc_id].pre_scan_max_dly; 1892 bg_dly -= bg_ovl_dly; 1893 1894 if (cstate->splice_mode) 1895 pre_scan_dly = bg_dly + (hdisplay >> 2) - 1; 1896 else 1897 pre_scan_dly = bg_dly + (hdisplay >> 1) - 1; 1898 1899 if (vop2->version == VOP_VERSION_RK3588 && hsync_len < 8) 1900 hsync_len = 8; 1901 pre_scan_dly = (pre_scan_dly << 16) | hsync_len; 1902 vop2_mask_write(vop2, RK3568_VP0_BG_MIX_CTRL + crtc_id * 4, 1903 BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false); 1904 vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + (crtc_id * 0x100), pre_scan_dly); 1905 } 1906 1907 static void vop3_setup_pipe_dly(struct display_state *state, struct vop2 *vop2, int crtc_id) 1908 { 1909 struct connector_state *conn_state = &state->conn_state; 1910 struct drm_display_mode *mode = &conn_state->mode; 1911 struct crtc_state *cstate = &state->crtc_state; 1912 struct vop2_win_data *win_data; 1913 u32 bg_dly, pre_scan_dly; 1914 u16 hdisplay = mode->crtc_hdisplay; 1915 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 1916 u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id; 1917 u8 win_id; 1918 1919 win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id); 1920 win_id = atoi(&win_data->name[strlen(win_data->name) - 1]); 1921 vop2_mask_write(vop2, RK3528_OVL_SYS_ESMART0_CTRL + win_id * 4, 1922 ESMART_DLY_NUM_MASK, ESMART_DLY_NUM_SHIFT, 0, false); 1923 1924 bg_dly = vop2->data->vp_data[crtc_id].win_dly + 1925 vop2->data->vp_data[crtc_id].layer_mix_dly + 1926 vop2->data->vp_data[crtc_id].hdr_mix_dly; 1927 pre_scan_dly = bg_dly + (hdisplay >> 1) - 1; 1928 pre_scan_dly = (pre_scan_dly << 16) | hsync_len; 1929 vop2_mask_write(vop2, RK3528_OVL_PORT0_BG_MIX_CTRL + crtc_id * 0x100, 1930 BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false); 1931 vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + (crtc_id * 0x100), pre_scan_dly); 1932 } 1933 1934 static void vop2_post_config(struct display_state *state, struct vop2 *vop2) 1935 { 1936 struct connector_state *conn_state = &state->conn_state; 1937 struct drm_display_mode *mode = &conn_state->mode; 1938 struct crtc_state *cstate = &state->crtc_state; 1939 u32 vp_offset = (cstate->crtc_id * 0x100); 1940 u16 vtotal = mode->crtc_vtotal; 1941 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 1942 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 1943 u16 hdisplay = mode->crtc_hdisplay; 1944 u16 vdisplay = mode->crtc_vdisplay; 1945 u16 hsize = 1946 hdisplay * (conn_state->overscan.left_margin + 1947 conn_state->overscan.right_margin) / 200; 1948 u16 vsize = 1949 vdisplay * (conn_state->overscan.top_margin + 1950 conn_state->overscan.bottom_margin) / 200; 1951 u16 hact_end, vact_end; 1952 u32 val; 1953 1954 hsize = round_down(hsize, 2); 1955 vsize = round_down(vsize, 2); 1956 1957 hact_st += hdisplay * (100 - conn_state->overscan.left_margin) / 200; 1958 hact_end = hact_st + hsize; 1959 val = hact_st << 16; 1960 val |= hact_end; 1961 1962 vop2_writel(vop2, RK3568_VP0_POST_DSP_HACT_INFO + vp_offset, val); 1963 vact_st += vdisplay * (100 - conn_state->overscan.top_margin) / 200; 1964 vact_end = vact_st + vsize; 1965 val = vact_st << 16; 1966 val |= vact_end; 1967 vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO + vp_offset, val); 1968 val = scl_cal_scale2(vdisplay, vsize) << 16; 1969 val |= scl_cal_scale2(hdisplay, hsize); 1970 vop2_writel(vop2, RK3568_VP0_POST_SCL_FACTOR_YRGB + vp_offset, val); 1971 #define POST_HORIZONTAL_SCALEDOWN_EN(x) ((x) << 0) 1972 #define POST_VERTICAL_SCALEDOWN_EN(x) ((x) << 1) 1973 vop2_writel(vop2, RK3568_VP0_POST_SCL_CTRL + vp_offset, 1974 POST_HORIZONTAL_SCALEDOWN_EN(hdisplay != hsize) | 1975 POST_VERTICAL_SCALEDOWN_EN(vdisplay != vsize)); 1976 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 1977 u16 vact_st_f1 = vtotal + vact_st + 1; 1978 u16 vact_end_f1 = vact_st_f1 + vsize; 1979 1980 val = vact_st_f1 << 16 | vact_end_f1; 1981 vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO_F1 + vp_offset, val); 1982 } 1983 1984 if (is_vop3(vop2)) { 1985 vop3_setup_pipe_dly(state, vop2, cstate->crtc_id); 1986 } else { 1987 vop2_setup_dly_for_vp(state, vop2, cstate->crtc_id); 1988 if (cstate->splice_mode) 1989 vop2_setup_dly_for_vp(state, vop2, cstate->splice_crtc_id); 1990 } 1991 } 1992 1993 static void vop3_post_acm_config(struct display_state *state, struct vop2 *vop2) 1994 { 1995 struct connector_state *conn_state = &state->conn_state; 1996 struct crtc_state *cstate = &state->crtc_state; 1997 struct acm_data *acm = &conn_state->disp_info->acm_data; 1998 struct drm_display_mode *mode = &conn_state->mode; 1999 u32 vp_offset = (cstate->crtc_id * 0x100); 2000 s16 *lut_y; 2001 s16 *lut_h; 2002 s16 *lut_s; 2003 u32 value; 2004 int i; 2005 2006 vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset, 2007 POST_ACM_BYPASS_EN_MASK, POST_ACM_BYPASS_EN_SHIFT, 0, false); 2008 if (!acm->acm_enable) { 2009 writel(0, vop2->regs + RK3528_ACM_CTRL); 2010 return; 2011 } 2012 2013 printf("post acm enable\n"); 2014 2015 writel(1, vop2->regs + RK3528_ACM_FETCH_START); 2016 2017 value = (acm->acm_enable & 0x1) + ((mode->hdisplay & 0xfff) << 8) + 2018 ((mode->vdisplay & 0xfff) << 20); 2019 writel(value, vop2->regs + RK3528_ACM_CTRL); 2020 2021 value = (acm->y_gain & 0x3ff) + ((acm->h_gain << 10) & 0xffc00) + 2022 ((acm->s_gain << 20) & 0x3ff00000); 2023 writel(value, vop2->regs + RK3528_ACM_DELTA_RANGE); 2024 2025 lut_y = &acm->gain_lut_hy[0]; 2026 lut_h = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH]; 2027 lut_s = &acm->gain_lut_hy[ACM_GAIN_LUT_HY_LENGTH * 2]; 2028 for (i = 0; i < ACM_GAIN_LUT_HY_LENGTH; i++) { 2029 value = (lut_y[i] & 0xff) + ((lut_h[i] << 8) & 0xff00) + 2030 ((lut_s[i] << 16) & 0xff0000); 2031 writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HY_SEG0 + (i << 2)); 2032 } 2033 2034 lut_y = &acm->gain_lut_hs[0]; 2035 lut_h = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH]; 2036 lut_s = &acm->gain_lut_hs[ACM_GAIN_LUT_HS_LENGTH * 2]; 2037 for (i = 0; i < ACM_GAIN_LUT_HS_LENGTH; i++) { 2038 value = (lut_y[i] & 0xff) + ((lut_h[i] << 8) & 0xff00) + 2039 ((lut_s[i] << 16) & 0xff0000); 2040 writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HS_SEG0 + (i << 2)); 2041 } 2042 2043 lut_y = &acm->delta_lut_h[0]; 2044 lut_h = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH]; 2045 lut_s = &acm->delta_lut_h[ACM_DELTA_LUT_H_LENGTH * 2]; 2046 for (i = 0; i < ACM_DELTA_LUT_H_LENGTH; i++) { 2047 value = (lut_y[i] & 0x3ff) + ((lut_h[i] << 12) & 0xff000) + 2048 ((lut_s[i] << 20) & 0x3ff00000); 2049 writel(value, vop2->regs + RK3528_ACM_YHS_DEL_HGAIN_SEG0 + (i << 2)); 2050 } 2051 2052 writel(1, vop2->regs + RK3528_ACM_FETCH_DONE); 2053 } 2054 2055 static void vop3_post_csc_config(struct display_state *state, struct vop2 *vop2) 2056 { 2057 struct connector_state *conn_state = &state->conn_state; 2058 struct crtc_state *cstate = &state->crtc_state; 2059 struct acm_data *acm = &conn_state->disp_info->acm_data; 2060 struct csc_info *csc = &conn_state->disp_info->csc_info; 2061 struct post_csc_coef csc_coef; 2062 bool is_input_yuv = false; 2063 bool is_output_yuv = false; 2064 bool post_r2y_en = false; 2065 bool post_csc_en = false; 2066 u32 vp_offset = (cstate->crtc_id * 0x100); 2067 u32 value; 2068 int range_type; 2069 2070 printf("post csc enable\n"); 2071 2072 if (acm->acm_enable) { 2073 if (!cstate->yuv_overlay) 2074 post_r2y_en = true; 2075 2076 /* do y2r in csc module */ 2077 if (!is_yuv_output(conn_state->bus_format)) 2078 post_csc_en = true; 2079 } else { 2080 if (!cstate->yuv_overlay && is_yuv_output(conn_state->bus_format)) 2081 post_r2y_en = true; 2082 2083 /* do y2r in csc module */ 2084 if (cstate->yuv_overlay && !is_yuv_output(conn_state->bus_format)) 2085 post_csc_en = true; 2086 } 2087 2088 if (csc->csc_enable) 2089 post_csc_en = true; 2090 2091 if (cstate->yuv_overlay || post_r2y_en) 2092 is_input_yuv = true; 2093 2094 if (is_yuv_output(conn_state->bus_format)) 2095 is_output_yuv = true; 2096 2097 cstate->post_csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_13BIT_DEPTH); 2098 2099 if (post_csc_en) { 2100 rockchip_calc_post_csc(csc, &csc_coef, cstate->post_csc_mode, is_input_yuv, 2101 is_output_yuv); 2102 2103 vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset, 2104 POST_CSC_COE00_MASK, POST_CSC_COE00_SHIFT, 2105 csc_coef.csc_coef00, false); 2106 value = csc_coef.csc_coef01 & 0xffff; 2107 value |= (csc_coef.csc_coef02 << 16) & 0xffff0000; 2108 writel(value, vop2->regs + RK3528_VP0_CSC_COE01_02); 2109 value = csc_coef.csc_coef10 & 0xffff; 2110 value |= (csc_coef.csc_coef11 << 16) & 0xffff0000; 2111 writel(value, vop2->regs + RK3528_VP0_CSC_COE10_11); 2112 value = csc_coef.csc_coef12 & 0xffff; 2113 value |= (csc_coef.csc_coef20 << 16) & 0xffff0000; 2114 writel(value, vop2->regs + RK3528_VP0_CSC_COE12_20); 2115 value = csc_coef.csc_coef21 & 0xffff; 2116 value |= (csc_coef.csc_coef22 << 16) & 0xffff0000; 2117 writel(value, vop2->regs + RK3528_VP0_CSC_COE21_22); 2118 writel(csc_coef.csc_dc0, vop2->regs + RK3528_VP0_CSC_OFFSET0); 2119 writel(csc_coef.csc_dc1, vop2->regs + RK3528_VP0_CSC_OFFSET1); 2120 writel(csc_coef.csc_dc2, vop2->regs + RK3528_VP0_CSC_OFFSET2); 2121 2122 range_type = csc_coef.range_type ? 0 : 1; 2123 range_type <<= is_input_yuv ? 0 : 1; 2124 vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset, 2125 POST_CSC_MODE_MASK, POST_CSC_MODE_SHIFT, range_type, false); 2126 } 2127 2128 vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset, 2129 POST_R2Y_EN_MASK, POST_R2Y_EN_SHIFT, post_r2y_en ? 1 : 0, false); 2130 vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset, 2131 POST_CSC_EN_MASK, POST_CSC_EN_SHIFT, post_csc_en ? 1 : 0, false); 2132 vop2_mask_write(vop2, RK3528_VP0_ACM_CTRL + vp_offset, 2133 POST_R2Y_MODE_MASK, POST_R2Y_MODE_SHIFT, cstate->post_csc_mode, false); 2134 } 2135 2136 static void vop3_post_config(struct display_state *state, struct vop2 *vop2) 2137 { 2138 struct connector_state *conn_state = &state->conn_state; 2139 struct base2_disp_info *disp_info = conn_state->disp_info; 2140 const char *enable_flag; 2141 if (!disp_info) { 2142 printf("disp_info is empty\n"); 2143 return; 2144 } 2145 2146 enable_flag = (const char *)&disp_info->cacm_header; 2147 if (strncasecmp(enable_flag, "CACM", 4)) { 2148 printf("acm and csc is not support\n"); 2149 return; 2150 } 2151 2152 vop3_post_acm_config(state, vop2); 2153 vop3_post_csc_config(state, vop2); 2154 } 2155 2156 /* 2157 * Read VOP internal power domain on/off status. 2158 * We should query BISR_STS register in PMU for 2159 * power up/down status when memory repair is enabled. 2160 * Return value: 1 for power on, 0 for power off; 2161 */ 2162 static int vop2_wait_power_domain_on(struct vop2 *vop2, struct vop2_power_domain_data *pd_data) 2163 { 2164 int val = 0; 2165 int shift = 0; 2166 int shift_factor = 0; 2167 bool is_bisr_en = false; 2168 2169 /* 2170 * The order of pd status bits in BISR_STS register 2171 * is different from that in VOP SYS_STS register. 2172 */ 2173 if (pd_data->id == VOP2_PD_DSC_8K || 2174 pd_data->id == VOP2_PD_DSC_4K || 2175 pd_data->id == VOP2_PD_ESMART) 2176 shift_factor = 1; 2177 2178 shift = RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT + generic_ffs(pd_data->id) - 1 - shift_factor; 2179 is_bisr_en = vop2_grf_readl(vop2, vop2->sys_pmu, RK3588_PMU_BISR_CON3, EN_MASK, shift); 2180 if (is_bisr_en) { 2181 shift = RK3588_PD_CLUSTER0_PWR_STAT_SHIFI + generic_ffs(pd_data->id) - 1 - shift_factor; 2182 2183 return readl_poll_timeout(vop2->sys_pmu + RK3588_PMU_BISR_STATUS5, val, 2184 ((val >> shift) & 0x1), 50 * 1000); 2185 } else { 2186 shift = RK3588_CLUSTER0_PD_STATUS_SHIFT + generic_ffs(pd_data->id) - 1; 2187 2188 return readl_poll_timeout(vop2->regs + RK3568_SYS_STATUS0, val, 2189 !((val >> shift) & 0x1), 50 * 1000); 2190 } 2191 } 2192 2193 static int vop2_power_domain_on(struct vop2 *vop2, int pd_id) 2194 { 2195 struct vop2_power_domain_data *pd_data; 2196 int ret = 0; 2197 2198 if (!pd_id) 2199 return 0; 2200 2201 pd_data = vop2_find_pd_data_by_id(vop2, pd_id); 2202 if (!pd_data) { 2203 printf("can't find pd_data by id\n"); 2204 return -EINVAL; 2205 } 2206 2207 if (pd_data->parent_id) { 2208 ret = vop2_power_domain_on(vop2, pd_data->parent_id); 2209 if (ret) { 2210 printf("can't open parent power domain\n"); 2211 return -EINVAL; 2212 } 2213 } 2214 2215 vop2_mask_write(vop2, RK3568_SYS_PD_CTRL, EN_MASK, 2216 RK3588_CLUSTER0_PD_EN_SHIFT + generic_ffs(pd_id) - 1, 0, false); 2217 ret = vop2_wait_power_domain_on(vop2, pd_data); 2218 if (ret) { 2219 printf("wait vop2 power domain timeout\n"); 2220 return ret; 2221 } 2222 2223 return 0; 2224 } 2225 2226 static void rk3588_vop2_regsbak(struct vop2 *vop2) 2227 { 2228 u32 *base = vop2->regs; 2229 int i = 0; 2230 2231 /* 2232 * No need to backup HDR/DSC/GAMMA_LUT/BPP_LUT/MMU 2233 */ 2234 for (i = 0; i < (vop2->reg_len >> 2); i++) 2235 vop2->regsbak[i] = base[i]; 2236 } 2237 2238 static void vop3_overlay_init(struct vop2 *vop2, struct display_state *state) 2239 { 2240 struct vop2_win_data *win_data; 2241 int layer_phy_id = 0; 2242 int i, j; 2243 u32 ovl_port_offset = 0; 2244 u32 layer_nr = 0; 2245 u8 shift = 0; 2246 2247 /* layer sel win id */ 2248 for (i = 0; i < vop2->data->nr_vps; i++) { 2249 shift = 0; 2250 ovl_port_offset = 0x100 * i; 2251 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 2252 for (j = 0; j < layer_nr; j++) { 2253 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 2254 win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 2255 vop2_mask_write(vop2, RK3528_OVL_PORT0_LAYER_SEL + ovl_port_offset, LAYER_SEL_MASK, 2256 shift, win_data->layer_sel_win_id[i], false); 2257 shift += 4; 2258 } 2259 } 2260 2261 /* win sel port */ 2262 for (i = 0; i < vop2->data->nr_vps; i++) { 2263 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 2264 for (j = 0; j < layer_nr; j++) { 2265 if (!vop2->vp_plane_mask[i].attached_layers[j]) 2266 continue; 2267 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 2268 win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 2269 shift = win_data->win_sel_port_offset * 2; 2270 vop2_mask_write(vop2, RK3528_OVL_SYS_PORT_SEL_IMD, LAYER_SEL_PORT_MASK, 2271 shift, i, false); 2272 } 2273 } 2274 } 2275 2276 static void vop2_overlay_init(struct vop2 *vop2, struct display_state *state) 2277 { 2278 struct crtc_state *cstate = &state->crtc_state; 2279 struct vop2_win_data *win_data; 2280 int layer_phy_id = 0; 2281 int total_used_layer = 0; 2282 int port_mux = 0; 2283 int i, j; 2284 u32 layer_nr = 0; 2285 u8 shift = 0; 2286 2287 /* layer sel win id */ 2288 for (i = 0; i < vop2->data->nr_vps; i++) { 2289 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 2290 for (j = 0; j < layer_nr; j++) { 2291 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 2292 win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 2293 vop2_mask_write(vop2, RK3568_OVL_LAYER_SEL, LAYER_SEL_MASK, 2294 shift, win_data->layer_sel_win_id[i], false); 2295 shift += 4; 2296 } 2297 } 2298 2299 /* win sel port */ 2300 for (i = 0; i < vop2->data->nr_vps; i++) { 2301 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 2302 for (j = 0; j < layer_nr; j++) { 2303 if (!vop2->vp_plane_mask[i].attached_layers[j]) 2304 continue; 2305 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 2306 win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 2307 shift = win_data->win_sel_port_offset * 2; 2308 vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, LAYER_SEL_PORT_MASK, 2309 LAYER_SEL_PORT_SHIFT + shift, i, false); 2310 } 2311 } 2312 2313 /** 2314 * port mux config 2315 */ 2316 for (i = 0; i < vop2->data->nr_vps; i++) { 2317 shift = i * 4; 2318 if (vop2->vp_plane_mask[i].attached_layers_nr) { 2319 total_used_layer += vop2->vp_plane_mask[i].attached_layers_nr; 2320 port_mux = total_used_layer - 1; 2321 } else { 2322 port_mux = 8; 2323 } 2324 2325 if (i == vop2->data->nr_vps - 1) 2326 port_mux = vop2->data->nr_mixers; 2327 2328 cstate->crtc->vps[i].bg_ovl_dly = (vop2->data->nr_mixers - port_mux) << 1; 2329 vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, PORT_MUX_MASK, 2330 PORT_MUX_SHIFT + shift, port_mux, false); 2331 } 2332 } 2333 2334 static bool vop3_ignore_plane(struct vop2 *vop2, struct vop2_win_data *win) 2335 { 2336 if (!is_vop3(vop2)) 2337 return false; 2338 2339 if (vop2->esmart_lb_mode == VOP3_ESMART_8K_MODE && 2340 win->phys_id != ROCKCHIP_VOP2_ESMART0) 2341 return true; 2342 else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_4K_MODE && 2343 (win->phys_id == ROCKCHIP_VOP2_ESMART1 || win->phys_id == ROCKCHIP_VOP2_ESMART3)) 2344 return true; 2345 else if (vop2->esmart_lb_mode == VOP3_ESMART_4K_2K_2K_MODE && 2346 win->phys_id == ROCKCHIP_VOP2_ESMART1) 2347 return true; 2348 else 2349 return false; 2350 } 2351 2352 static void vop3_init_esmart_scale_engine(struct vop2 *vop2) 2353 { 2354 struct vop2_win_data *win_data; 2355 int i; 2356 u8 scale_engine_num = 0; 2357 2358 /* store plane mask for vop2_fixup_dts */ 2359 for (i = 0; i < vop2->data->nr_layers; i++) { 2360 win_data = &vop2->data->win_data[i]; 2361 if (win_data->type == CLUSTER_LAYER || vop3_ignore_plane(vop2, win_data)) 2362 continue; 2363 2364 win_data->scale_engine_num = scale_engine_num++; 2365 } 2366 } 2367 2368 static void vop2_global_initial(struct vop2 *vop2, struct display_state *state) 2369 { 2370 struct crtc_state *cstate = &state->crtc_state; 2371 struct vop2_vp_plane_mask *plane_mask; 2372 int layer_phy_id = 0; 2373 int i, j; 2374 int ret; 2375 u32 layer_nr = 0; 2376 2377 if (vop2->global_init) 2378 return; 2379 2380 /* OTP must enable at the first time, otherwise mirror layer register is error */ 2381 if (soc_is_rk3566()) 2382 vop2_mask_write(vop2, RK3568_SYS_OTP_WIN_EN, EN_MASK, 2383 OTP_WIN_EN_SHIFT, 1, false); 2384 2385 if (cstate->crtc->assign_plane) {/* dts assign plane */ 2386 u32 plane_mask; 2387 int primary_plane_id; 2388 2389 for (i = 0; i < vop2->data->nr_vps; i++) { 2390 plane_mask = cstate->crtc->vps[i].plane_mask; 2391 vop2->vp_plane_mask[i].plane_mask = plane_mask; 2392 layer_nr = hweight32(plane_mask); /* use bitmap to store plane mask */ 2393 vop2->vp_plane_mask[i].attached_layers_nr = layer_nr; 2394 primary_plane_id = cstate->crtc->vps[i].primary_plane_id; 2395 if (primary_plane_id >= ROCKCHIP_VOP2_LAYER_MAX) 2396 primary_plane_id = vop2_get_primary_plane(vop2, plane_mask); 2397 vop2->vp_plane_mask[i].primary_plane_id = primary_plane_id; 2398 vop2->vp_plane_mask[i].plane_mask = plane_mask; 2399 2400 /* plane mask[bitmap] convert into layer phy id[enum vop2_layer_phy_id]*/ 2401 for (j = 0; j < layer_nr; j++) { 2402 vop2->vp_plane_mask[i].attached_layers[j] = ffs(plane_mask) - 1; 2403 plane_mask &= ~BIT(vop2->vp_plane_mask[i].attached_layers[j]); 2404 } 2405 } 2406 } else {/* need soft assign plane mask */ 2407 /* find the first unplug devices and set it as main display */ 2408 int main_vp_index = -1; 2409 int active_vp_num = 0; 2410 2411 for (i = 0; i < vop2->data->nr_vps; i++) { 2412 if (cstate->crtc->vps[i].enable) 2413 active_vp_num++; 2414 } 2415 printf("VOP have %d active VP\n", active_vp_num); 2416 2417 if (soc_is_rk3566() && active_vp_num > 2) 2418 printf("ERROR: rk3566 only support 2 display output!!\n"); 2419 plane_mask = vop2->data->plane_mask; 2420 plane_mask += (active_vp_num - 1) * VOP2_VP_MAX; 2421 /* 2422 * For rk3528, one display policy for hdmi store in plane_mask[0], and the other 2423 * for cvbs store in plane_mask[2]. 2424 */ 2425 if (vop2->version == VOP_VERSION_RK3528 && active_vp_num == 1 && 2426 cstate->crtc->vps[1].output_type == DRM_MODE_CONNECTOR_TV) 2427 plane_mask += 2 * VOP2_VP_MAX; 2428 2429 if (vop2->version == VOP_VERSION_RK3528) { 2430 /* 2431 * For rk3528, the plane mask of vp is limited, only esmart2 can be selected 2432 * by both vp0 and vp1. 2433 */ 2434 j = 0; 2435 } else { 2436 for (i = 0; i < vop2->data->nr_vps; i++) { 2437 if (!is_hot_plug_devices(cstate->crtc->vps[i].output_type)) { 2438 vop2->vp_plane_mask[i] = plane_mask[0]; /* the first store main display plane mask*/ 2439 main_vp_index = i; 2440 break; 2441 } 2442 } 2443 2444 /* if no find unplug devices, use vp0 as main display */ 2445 if (main_vp_index < 0) { 2446 main_vp_index = 0; 2447 vop2->vp_plane_mask[0] = plane_mask[0]; 2448 } 2449 2450 j = 1; /* plane_mask[0] store main display, so we from plane_mask[1] */ 2451 } 2452 2453 /* init other display except main display */ 2454 for (i = 0; i < vop2->data->nr_vps; i++) { 2455 if (i == main_vp_index || !cstate->crtc->vps[i].enable) /* main display or no connect devices */ 2456 continue; 2457 vop2->vp_plane_mask[i] = plane_mask[j++]; 2458 } 2459 2460 /* store plane mask for vop2_fixup_dts */ 2461 for (i = 0; i < vop2->data->nr_vps; i++) { 2462 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 2463 for (j = 0; j < layer_nr; j++) { 2464 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 2465 vop2->vp_plane_mask[i].plane_mask |= BIT(layer_phy_id); 2466 } 2467 } 2468 } 2469 2470 if (vop2->version == VOP_VERSION_RK3588) 2471 rk3588_vop2_regsbak(vop2); 2472 else 2473 memcpy(vop2->regsbak, vop2->regs, vop2->reg_len); 2474 2475 vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, 2476 OVL_PORT_MUX_REG_DONE_IMD_SHIFT, 1, false); 2477 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2478 IF_CTRL_REG_DONE_IMD_SHIFT, 1, false); 2479 2480 for (i = 0; i < vop2->data->nr_vps; i++) { 2481 printf("vp%d have layer nr:%d[", i, vop2->vp_plane_mask[i].attached_layers_nr); 2482 for (j = 0; j < vop2->vp_plane_mask[i].attached_layers_nr; j++) 2483 printf("%d ", vop2->vp_plane_mask[i].attached_layers[j]); 2484 printf("], primary plane: %d\n", vop2->vp_plane_mask[i].primary_plane_id); 2485 } 2486 2487 if (is_vop3(vop2)) 2488 vop3_overlay_init(vop2, state); 2489 else 2490 vop2_overlay_init(vop2, state); 2491 2492 if (is_vop3(vop2)) { 2493 /* 2494 * you can rewrite at dts vop node: 2495 * 2496 * VOP3_ESMART_8K_MODE = 0, 2497 * VOP3_ESMART_4K_4K_MODE = 1, 2498 * VOP3_ESMART_4K_2K_2K_MODE = 2, 2499 * VOP3_ESMART_2K_2K_2K_2K_MODE = 3, 2500 * 2501 * &vop { 2502 * esmart_lb_mode = /bits/ 8 <2>; 2503 * }; 2504 */ 2505 ret = ofnode_read_u32(cstate->node, "esmart_lb_mode", &vop2->esmart_lb_mode); 2506 if (ret < 0) 2507 vop2->esmart_lb_mode = vop2->data->esmart_lb_mode; 2508 vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, ESMART_LB_MODE_SEL_MASK, 2509 ESMART_LB_MODE_SEL_SHIFT, vop2->esmart_lb_mode, false); 2510 2511 vop3_init_esmart_scale_engine(vop2); 2512 2513 vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL, EN_MASK, 2514 DSP_VS_T_SEL_SHIFT, 0, false); 2515 } 2516 2517 if (vop2->version == VOP_VERSION_RK3568) 2518 vop2_writel(vop2, RK3568_AUTO_GATING_CTRL, 0); 2519 2520 vop2->global_init = true; 2521 } 2522 2523 static int vop2_initial(struct vop2 *vop2, struct display_state *state) 2524 { 2525 rockchip_vop2_gamma_lut_init(vop2, state); 2526 rockchip_vop2_cubic_lut_init(vop2, state); 2527 2528 return 0; 2529 } 2530 2531 /* 2532 * VOP2 have multi video ports. 2533 * video port ------- crtc 2534 */ 2535 static int rockchip_vop2_preinit(struct display_state *state) 2536 { 2537 struct crtc_state *cstate = &state->crtc_state; 2538 const struct vop2_data *vop2_data = cstate->crtc->data; 2539 2540 if (!rockchip_vop2) { 2541 rockchip_vop2 = calloc(1, sizeof(struct vop2)); 2542 if (!rockchip_vop2) 2543 return -ENOMEM; 2544 memset(rockchip_vop2, 0, sizeof(struct vop2)); 2545 rockchip_vop2->regsbak = malloc(RK3568_MAX_REG); 2546 rockchip_vop2->reg_len = RK3568_MAX_REG; 2547 #ifdef CONFIG_SPL_BUILD 2548 rockchip_vop2->regs = (void *)RK3528_VOP_BASE; 2549 #else 2550 rockchip_vop2->regs = dev_read_addr_ptr(cstate->dev); 2551 rockchip_vop2->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 2552 if (rockchip_vop2->grf <= 0) 2553 printf("%s: Get syscon grf failed (ret=%p)\n", __func__, rockchip_vop2->grf); 2554 #endif 2555 rockchip_vop2->version = vop2_data->version; 2556 rockchip_vop2->data = vop2_data; 2557 if (rockchip_vop2->version == VOP_VERSION_RK3588) { 2558 struct regmap *map; 2559 2560 rockchip_vop2->vop_grf = syscon_get_first_range(ROCKCHIP_SYSCON_VOP_GRF); 2561 if (rockchip_vop2->vop_grf <= 0) 2562 printf("%s: Get syscon vop_grf failed (ret=%p)\n", __func__, rockchip_vop2->vop_grf); 2563 map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,vo1-grf"); 2564 rockchip_vop2->vo1_grf = regmap_get_range(map, 0); 2565 if (rockchip_vop2->vo1_grf <= 0) 2566 printf("%s: Get syscon vo1_grf failed (ret=%p)\n", __func__, rockchip_vop2->vo1_grf); 2567 rockchip_vop2->sys_pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU); 2568 if (rockchip_vop2->sys_pmu <= 0) 2569 printf("%s: Get syscon sys_pmu failed (ret=%p)\n", __func__, rockchip_vop2->sys_pmu); 2570 } 2571 } 2572 2573 cstate->private = rockchip_vop2; 2574 cstate->max_output = vop2_data->vp_data[cstate->crtc_id].max_output; 2575 cstate->feature = vop2_data->vp_data[cstate->crtc_id].feature; 2576 2577 vop2_global_initial(rockchip_vop2, state); 2578 2579 return 0; 2580 } 2581 2582 /* 2583 * calc the dclk on rk3588 2584 * the available div of dclk is 1, 2, 4 2585 * 2586 */ 2587 static unsigned long vop2_calc_dclk(unsigned long child_clk, unsigned long max_dclk) 2588 { 2589 if (child_clk * 4 <= max_dclk) 2590 return child_clk * 4; 2591 else if (child_clk * 2 <= max_dclk) 2592 return child_clk * 2; 2593 else if (child_clk <= max_dclk) 2594 return child_clk; 2595 else 2596 return 0; 2597 } 2598 2599 /* 2600 * 4 pixclk/cycle on rk3588 2601 * RGB/eDP/HDMI: if_pixclk >= dclk_core 2602 * DP: dp_pixclk = dclk_out <= dclk_core 2603 * DSI: mipi_pixclk <= dclk_out <= dclk_core 2604 */ 2605 static unsigned long vop2_calc_cru_cfg(struct display_state *state, 2606 int *dclk_core_div, int *dclk_out_div, 2607 int *if_pixclk_div, int *if_dclk_div) 2608 { 2609 struct crtc_state *cstate = &state->crtc_state; 2610 struct connector_state *conn_state = &state->conn_state; 2611 struct drm_display_mode *mode = &conn_state->mode; 2612 struct vop2 *vop2 = cstate->private; 2613 unsigned long v_pixclk = mode->crtc_clock; 2614 unsigned long dclk_core_rate = v_pixclk >> 2; 2615 unsigned long dclk_rate = v_pixclk; 2616 unsigned long dclk_out_rate; 2617 u64 if_dclk_rate; 2618 u64 if_pixclk_rate; 2619 int output_type = conn_state->type; 2620 int output_mode = conn_state->output_mode; 2621 int K = 1; 2622 2623 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE && 2624 output_mode == ROCKCHIP_OUT_MODE_YUV420) { 2625 printf("Dual channel and YUV420 can't work together\n"); 2626 return -EINVAL; 2627 } 2628 2629 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE || 2630 output_mode == ROCKCHIP_OUT_MODE_YUV420) 2631 K = 2; 2632 2633 if (output_type == DRM_MODE_CONNECTOR_HDMIA) { 2634 /* 2635 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate 2636 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate 2637 */ 2638 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE || 2639 output_mode == ROCKCHIP_OUT_MODE_YUV420) { 2640 dclk_rate = dclk_rate >> 1; 2641 K = 2; 2642 } 2643 if (cstate->dsc_enable) { 2644 if_pixclk_rate = cstate->dsc_cds_clk_rate << 1; 2645 if_dclk_rate = cstate->dsc_cds_clk_rate; 2646 } else { 2647 if_pixclk_rate = (dclk_core_rate << 1) / K; 2648 if_dclk_rate = dclk_core_rate / K; 2649 } 2650 2651 if (v_pixclk > VOP2_MAX_DCLK_RATE) 2652 dclk_rate = vop2_calc_dclk(dclk_core_rate, 2653 vop2->data->vp_data[cstate->crtc_id].max_dclk); 2654 2655 if (!dclk_rate) { 2656 printf("DP if_pixclk_rate out of range(max_dclk: %d KHZ, dclk_core: %lld KHZ)\n", 2657 vop2->data->vp_data[cstate->crtc_id].max_dclk, if_pixclk_rate); 2658 return -EINVAL; 2659 } 2660 *if_pixclk_div = dclk_rate / if_pixclk_rate; 2661 *if_dclk_div = dclk_rate / if_dclk_rate; 2662 *dclk_core_div = dclk_rate / dclk_core_rate; 2663 printf("dclk:%lu,if_pixclk_div;%d,if_dclk_div:%d\n", 2664 dclk_rate, *if_pixclk_div, *if_dclk_div); 2665 } else if (output_type == DRM_MODE_CONNECTOR_eDP) { 2666 /* edp_pixclk = edp_dclk > dclk_core */ 2667 if_pixclk_rate = v_pixclk / K; 2668 if_dclk_rate = v_pixclk / K; 2669 dclk_rate = if_pixclk_rate * K; 2670 *dclk_core_div = dclk_rate / dclk_core_rate; 2671 *if_pixclk_div = dclk_rate / if_pixclk_rate; 2672 *if_dclk_div = *if_pixclk_div; 2673 } else if (output_type == DRM_MODE_CONNECTOR_DisplayPort) { 2674 dclk_out_rate = v_pixclk >> 2; 2675 dclk_out_rate = dclk_out_rate / K; 2676 2677 dclk_rate = vop2_calc_dclk(dclk_out_rate, 2678 vop2->data->vp_data[cstate->crtc_id].max_dclk); 2679 if (!dclk_rate) { 2680 printf("DP dclk_core out of range(max_dclk: %d KHZ, dclk_core: %ld KHZ)\n", 2681 vop2->data->vp_data[cstate->crtc_id].max_dclk, dclk_core_rate); 2682 return -EINVAL; 2683 } 2684 *dclk_out_div = dclk_rate / dclk_out_rate; 2685 *dclk_core_div = dclk_rate / dclk_core_rate; 2686 } else if (output_type == DRM_MODE_CONNECTOR_DSI) { 2687 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 2688 K = 2; 2689 if (cstate->dsc_enable) 2690 /* dsc output is 96bit, dsi input is 192 bit */ 2691 if_pixclk_rate = cstate->dsc_cds_clk_rate >> 1; 2692 else 2693 if_pixclk_rate = dclk_core_rate / K; 2694 /* dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4 */ 2695 dclk_out_rate = dclk_core_rate / K; 2696 /* dclk_rate = N * dclk_core_rate N = (1,2,4 ), we get a little factor here */ 2697 dclk_rate = vop2_calc_dclk(dclk_out_rate, 2698 vop2->data->vp_data[cstate->crtc_id].max_dclk); 2699 if (!dclk_rate) { 2700 printf("MIPI dclk out of range(max_dclk: %d KHZ, dclk_rate: %ld KHZ)\n", 2701 vop2->data->vp_data[cstate->crtc_id].max_dclk, dclk_rate); 2702 return -EINVAL; 2703 } 2704 2705 if (cstate->dsc_enable) 2706 dclk_rate /= cstate->dsc_slice_num; 2707 2708 *dclk_out_div = dclk_rate / dclk_out_rate; 2709 *dclk_core_div = dclk_rate / dclk_core_rate; 2710 *if_pixclk_div = 1; /*mipi pixclk == dclk_out*/ 2711 if (cstate->dsc_enable) 2712 *if_pixclk_div = dclk_out_rate * 1000LL / if_pixclk_rate; 2713 2714 } else if (output_type == DRM_MODE_CONNECTOR_DPI) { 2715 dclk_rate = v_pixclk; 2716 *dclk_core_div = dclk_rate / dclk_core_rate; 2717 } 2718 2719 *if_pixclk_div = ilog2(*if_pixclk_div); 2720 *if_dclk_div = ilog2(*if_dclk_div); 2721 *dclk_core_div = ilog2(*dclk_core_div); 2722 *dclk_out_div = ilog2(*dclk_out_div); 2723 2724 return dclk_rate; 2725 } 2726 2727 static int vop2_calc_dsc_clk(struct display_state *state) 2728 { 2729 struct connector_state *conn_state = &state->conn_state; 2730 struct drm_display_mode *mode = &conn_state->mode; 2731 struct crtc_state *cstate = &state->crtc_state; 2732 u64 v_pixclk = mode->crtc_clock * 1000LL; /* video timing pixclk */ 2733 u8 k = 1; 2734 2735 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 2736 k = 2; 2737 2738 cstate->dsc_txp_clk_rate = v_pixclk; 2739 do_div(cstate->dsc_txp_clk_rate, (cstate->dsc_pixel_num * k)); 2740 2741 cstate->dsc_pxl_clk_rate = v_pixclk; 2742 do_div(cstate->dsc_pxl_clk_rate, (cstate->dsc_slice_num * k)); 2743 2744 /* dsc_cds = crtc_clock / (cds_dat_width / bits_per_pixel) 2745 * cds_dat_width = 96; 2746 * bits_per_pixel = [8-12]; 2747 * As cds clk is div from txp clk and only support 1/2/4 div, 2748 * so when txp_clk is equal to v_pixclk, we set dsc_cds = crtc_clock / 4, 2749 * otherwise dsc_cds = crtc_clock / 8; 2750 */ 2751 cstate->dsc_cds_clk_rate = v_pixclk / (cstate->dsc_txp_clk_rate == v_pixclk ? 4 : 8); 2752 2753 return 0; 2754 } 2755 2756 static unsigned long rk3588_vop2_if_cfg(struct display_state *state) 2757 { 2758 struct crtc_state *cstate = &state->crtc_state; 2759 struct connector_state *conn_state = &state->conn_state; 2760 struct drm_display_mode *mode = &conn_state->mode; 2761 struct rockchip_dsc_sink_cap *dsc_sink_cap = &cstate->dsc_sink_cap; 2762 struct vop2 *vop2 = cstate->private; 2763 u32 vp_offset = (cstate->crtc_id * 0x100); 2764 u16 hdisplay = mode->crtc_hdisplay; 2765 int output_if = conn_state->output_if; 2766 int if_pixclk_div = 0; 2767 int if_dclk_div = 0; 2768 unsigned long dclk_rate; 2769 u32 val; 2770 2771 if (output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) { 2772 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0; 2773 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0; 2774 } else { 2775 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 2776 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 2777 } 2778 2779 if (cstate->dsc_enable) { 2780 int k = 1; 2781 2782 if (!vop2->data->nr_dscs) { 2783 printf("Unsupported DSC\n"); 2784 return 0; 2785 } 2786 2787 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 2788 k = 2; 2789 2790 cstate->dsc_id = output_if & (VOP_OUTPUT_IF_MIPI0 | VOP_OUTPUT_IF_HDMI0) ? 0 : 1; 2791 cstate->dsc_slice_num = hdisplay / dsc_sink_cap->slice_width / k; 2792 cstate->dsc_pixel_num = cstate->dsc_slice_num > 4 ? 4 : cstate->dsc_slice_num; 2793 2794 vop2_calc_dsc_clk(state); 2795 printf("Enable DSC%d slice:%dx%d, slice num:%d\n", 2796 cstate->dsc_id, dsc_sink_cap->slice_width, 2797 dsc_sink_cap->slice_height, cstate->dsc_slice_num); 2798 } 2799 2800 dclk_rate = vop2_calc_cru_cfg(state, &cstate->dclk_core_div, &cstate->dclk_out_div, &if_pixclk_div, &if_dclk_div); 2801 2802 if (output_if & VOP_OUTPUT_IF_RGB) { 2803 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 2804 4, false); 2805 } 2806 2807 if (output_if & VOP_OUTPUT_IF_BT1120) { 2808 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 2809 3, false); 2810 } 2811 2812 if (output_if & VOP_OUTPUT_IF_BT656) { 2813 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 2814 2, false); 2815 } 2816 2817 if (output_if & VOP_OUTPUT_IF_MIPI0) { 2818 if (cstate->crtc_id == 2) 2819 val = 0; 2820 else 2821 val = 1; 2822 2823 if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE) 2824 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2825 RK3588_MIPI_DSI0_MODE_SEL_SHIFT, 1, false); 2826 2827 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI0_EN_SHIFT, 2828 1, false); 2829 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 1, RK3588_MIPI0_MUX_SHIFT, val, false); 2830 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI0_PIXCLK_DIV_SHIFT, 2831 if_pixclk_div, false); 2832 2833 if (conn_state->hold_mode) { 2834 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2835 EN_MASK, EDPI_TE_EN, !cstate->soft_te, false); 2836 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2837 EN_MASK, EDPI_WMS_HOLD_EN, 1, false); 2838 } 2839 } 2840 2841 if (output_if & VOP_OUTPUT_IF_MIPI1) { 2842 if (cstate->crtc_id == 2) 2843 val = 0; 2844 else if (cstate->crtc_id == 3) 2845 val = 1; 2846 else 2847 val = 3; /*VP1*/ 2848 if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE) 2849 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2850 RK3588_MIPI_DSI1_MODE_SEL_SHIFT, 1, false); 2851 2852 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI1_EN_SHIFT, 2853 1, false); 2854 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, MIPI1_MUX_SHIFT, 2855 val, false); 2856 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI1_PIXCLK_DIV_SHIFT, 2857 if_pixclk_div, false); 2858 2859 if (conn_state->hold_mode) { 2860 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2861 EN_MASK, EDPI_TE_EN, !cstate->soft_te, false); 2862 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2863 EN_MASK, EDPI_WMS_HOLD_EN, 1, false); 2864 } 2865 } 2866 2867 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 2868 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 2869 MIPI_DUAL_EN_SHIFT, 1, false); 2870 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 2871 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2872 EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1, 2873 false); 2874 switch (conn_state->type) { 2875 case DRM_MODE_CONNECTOR_DisplayPort: 2876 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2877 RK3588_DP_DUAL_EN_SHIFT, 1, false); 2878 break; 2879 case DRM_MODE_CONNECTOR_eDP: 2880 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2881 RK3588_EDP_DUAL_EN_SHIFT, 1, false); 2882 break; 2883 case DRM_MODE_CONNECTOR_HDMIA: 2884 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2885 RK3588_HDMI_DUAL_EN_SHIFT, 1, false); 2886 break; 2887 case DRM_MODE_CONNECTOR_DSI: 2888 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2889 RK3568_MIPI_DUAL_EN_SHIFT, 1, false); 2890 break; 2891 default: 2892 break; 2893 } 2894 } 2895 2896 if (output_if & VOP_OUTPUT_IF_eDP0) { 2897 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP0_EN_SHIFT, 2898 1, false); 2899 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT, 2900 cstate->crtc_id, false); 2901 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT, 2902 if_dclk_div, false); 2903 2904 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT, 2905 if_pixclk_div, false); 2906 2907 vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 2908 RK3588_GRF_EDP0_ENABLE_SHIFT, 1); 2909 } 2910 2911 if (output_if & VOP_OUTPUT_IF_eDP1) { 2912 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP1_EN_SHIFT, 2913 1, false); 2914 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT, 2915 cstate->crtc_id, false); 2916 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT, 2917 if_dclk_div, false); 2918 2919 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT, 2920 if_pixclk_div, false); 2921 2922 vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 2923 RK3588_GRF_EDP1_ENABLE_SHIFT, 1); 2924 } 2925 2926 if (output_if & VOP_OUTPUT_IF_HDMI0) { 2927 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI0_EN_SHIFT, 2928 1, false); 2929 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT, 2930 cstate->crtc_id, false); 2931 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT, 2932 if_dclk_div, false); 2933 2934 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT, 2935 if_pixclk_div, false); 2936 2937 vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 2938 RK3588_GRF_HDMITX0_ENABLE_SHIFT, 1); 2939 vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0, 2940 HDMI_SYNC_POL_MASK, 2941 HDMI0_SYNC_POL_SHIFT, val); 2942 } 2943 2944 if (output_if & VOP_OUTPUT_IF_HDMI1) { 2945 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI1_EN_SHIFT, 2946 1, false); 2947 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT, 2948 cstate->crtc_id, false); 2949 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT, 2950 if_dclk_div, false); 2951 2952 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT, 2953 if_pixclk_div, false); 2954 2955 vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 2956 RK3588_GRF_HDMITX1_ENABLE_SHIFT, 1); 2957 vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0, 2958 HDMI_SYNC_POL_MASK, 2959 HDMI1_SYNC_POL_SHIFT, val); 2960 } 2961 2962 if (output_if & VOP_OUTPUT_IF_DP0) { 2963 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP0_EN_SHIFT, 2964 1, false); 2965 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP0_MUX_SHIFT, 2966 cstate->crtc_id, false); 2967 vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK, 2968 RK3588_DP0_PIN_POL_SHIFT, val, false); 2969 } 2970 2971 if (output_if & VOP_OUTPUT_IF_DP1) { 2972 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP1_EN_SHIFT, 2973 1, false); 2974 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP1_MUX_SHIFT, 2975 cstate->crtc_id, false); 2976 vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK, 2977 RK3588_DP1_PIN_POL_SHIFT, val, false); 2978 } 2979 2980 vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3, 2981 DCLK_CORE_DIV_SHIFT, cstate->dclk_core_div, false); 2982 vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3, 2983 DCLK_OUT_DIV_SHIFT, cstate->dclk_out_div, false); 2984 2985 return dclk_rate; 2986 } 2987 2988 static unsigned long rk3568_vop2_if_cfg(struct display_state *state) 2989 { 2990 struct crtc_state *cstate = &state->crtc_state; 2991 struct connector_state *conn_state = &state->conn_state; 2992 struct drm_display_mode *mode = &conn_state->mode; 2993 struct vop2 *vop2 = cstate->private; 2994 u32 vp_offset = (cstate->crtc_id * 0x100); 2995 bool dclk_inv; 2996 u32 val; 2997 2998 dclk_inv = (conn_state->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0; 2999 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 3000 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 3001 3002 if (conn_state->output_if & VOP_OUTPUT_IF_RGB) { 3003 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 3004 1, false); 3005 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3006 RGB_MUX_SHIFT, cstate->crtc_id, false); 3007 vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_RGB_LVDS_PIN_POL_MASK, 3008 IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false); 3009 vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 3010 GRF_RGB_DCLK_INV_SHIFT, dclk_inv); 3011 } 3012 3013 if (conn_state->output_if & VOP_OUTPUT_IF_BT1120) { 3014 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 3015 1, false); 3016 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, 3017 BT1120_EN_SHIFT, 1, false); 3018 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3019 RGB_MUX_SHIFT, cstate->crtc_id, false); 3020 vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 3021 GRF_BT1120_CLK_INV_SHIFT, !dclk_inv); 3022 } 3023 3024 if (conn_state->output_if & VOP_OUTPUT_IF_BT656) { 3025 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT, 3026 1, false); 3027 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3028 RGB_MUX_SHIFT, cstate->crtc_id, false); 3029 vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 3030 GRF_BT656_CLK_INV_SHIFT, !dclk_inv); 3031 } 3032 3033 if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) { 3034 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT, 3035 1, false); 3036 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3037 LVDS0_MUX_SHIFT, cstate->crtc_id, false); 3038 vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_RGB_LVDS_PIN_POL_MASK, 3039 IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false); 3040 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 3041 IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT, dclk_inv, false); 3042 } 3043 3044 if (conn_state->output_if & VOP_OUTPUT_IF_LVDS1) { 3045 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS1_EN_SHIFT, 3046 1, false); 3047 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3048 LVDS1_MUX_SHIFT, cstate->crtc_id, false); 3049 vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_RGB_LVDS_PIN_POL_MASK, 3050 IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false); 3051 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 3052 IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT, dclk_inv, false); 3053 } 3054 3055 if (conn_state->output_flags & 3056 (ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE | 3057 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)) { 3058 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 3059 LVDS_DUAL_EN_SHIFT, 1, false); 3060 if (conn_state->output_flags & 3061 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 3062 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 3063 LVDS_DUAL_LEFT_RIGHT_EN_SHIFT, 1, 3064 false); 3065 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 3066 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 3067 LVDS_DUAL_SWAP_EN_SHIFT, 1, false); 3068 } 3069 3070 if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) { 3071 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT, 3072 1, false); 3073 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3074 MIPI0_MUX_SHIFT, cstate->crtc_id, false); 3075 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 3076 IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false); 3077 } 3078 3079 if (conn_state->output_if & VOP_OUTPUT_IF_MIPI1) { 3080 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI1_EN_SHIFT, 3081 1, false); 3082 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3083 MIPI1_MUX_SHIFT, cstate->crtc_id, false); 3084 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 3085 IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false); 3086 } 3087 3088 if (conn_state->output_flags & 3089 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 3090 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 3091 MIPI_DUAL_EN_SHIFT, 1, false); 3092 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 3093 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 3094 EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1, 3095 false); 3096 } 3097 3098 if (conn_state->output_if & VOP_OUTPUT_IF_eDP0) { 3099 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, EDP0_EN_SHIFT, 3100 1, false); 3101 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3102 EDP0_MUX_SHIFT, cstate->crtc_id, false); 3103 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 3104 IF_CRTL_EDP_DCLK_POL_SHIT, dclk_inv, false); 3105 vop2_mask_write(vop2, RK3568_DSP_IF_POL, IF_CTRL_EDP_PIN_POL_MASK, 3106 IF_CTRL_EDP_PIN_POL_SHIFT, val, false); 3107 } 3108 3109 if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) { 3110 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT, 3111 1, false); 3112 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3113 HDMI0_MUX_SHIFT, cstate->crtc_id, false); 3114 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 3115 IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false); 3116 vop2_mask_write(vop2, RK3568_DSP_IF_POL, 3117 IF_CRTL_HDMI_PIN_POL_MASK, 3118 IF_CRTL_HDMI_PIN_POL_SHIT, val, false); 3119 } 3120 3121 return mode->clock; 3122 } 3123 3124 static unsigned long rk3528_vop2_if_cfg(struct display_state *state) 3125 { 3126 struct crtc_state *cstate = &state->crtc_state; 3127 struct connector_state *conn_state = &state->conn_state; 3128 struct drm_display_mode *mode = &conn_state->mode; 3129 struct vop2 *vop2 = cstate->private; 3130 u32 val; 3131 3132 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 3133 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 3134 3135 if (conn_state->output_if & VOP_OUTPUT_IF_BT656) { 3136 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT, 3137 1, false); 3138 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3139 RGB_MUX_SHIFT, cstate->crtc_id, false); 3140 } 3141 3142 if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) { 3143 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT, 3144 1, false); 3145 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3146 HDMI0_MUX_SHIFT, cstate->crtc_id, false); 3147 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 3148 IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false); 3149 vop2_mask_write(vop2, RK3568_DSP_IF_POL, 3150 IF_CRTL_HDMI_PIN_POL_MASK, 3151 IF_CRTL_HDMI_PIN_POL_SHIT, val, false); 3152 } 3153 3154 return mode->crtc_clock; 3155 } 3156 3157 static unsigned long rk3562_vop2_if_cfg(struct display_state *state) 3158 { 3159 struct crtc_state *cstate = &state->crtc_state; 3160 struct connector_state *conn_state = &state->conn_state; 3161 struct drm_display_mode *mode = &conn_state->mode; 3162 struct vop2 *vop2 = cstate->private; 3163 bool dclk_inv; 3164 u32 val; 3165 3166 dclk_inv = (conn_state->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0; 3167 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 3168 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 3169 3170 if (conn_state->output_if & VOP_OUTPUT_IF_RGB) { 3171 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 3172 1, false); 3173 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3174 RGB_MUX_SHIFT, cstate->crtc_id, false); 3175 vop2_grf_writel(vop2, vop2->grf, RK3562_GRF_IOC_VO_IO_CON, EN_MASK, 3176 GRF_RGB_DCLK_INV_SHIFT, dclk_inv); 3177 vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3562_IF_PIN_POL_MASK, 3178 IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false); 3179 } 3180 3181 if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) { 3182 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT, 3183 1, false); 3184 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3185 LVDS0_MUX_SHIFT, cstate->crtc_id, false); 3186 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 3187 IF_CTRL_RGB_LVDS_DCLK_POL_SHIFT, dclk_inv, false); 3188 vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3562_IF_PIN_POL_MASK, 3189 IF_CTRL_RGB_LVDS_PIN_POL_SHIFT, val, false); 3190 } 3191 3192 if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) { 3193 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT, 3194 1, false); 3195 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 3196 MIPI0_MUX_SHIFT, cstate->crtc_id, false); 3197 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 3198 RK3562_MIPI_DCLK_POL_SHIFT, dclk_inv, false); 3199 vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3562_IF_PIN_POL_MASK, 3200 RK3562_MIPI_PIN_POL_SHIFT, val, false); 3201 } 3202 3203 return mode->crtc_clock; 3204 } 3205 3206 static void vop2_post_color_swap(struct display_state *state) 3207 { 3208 struct crtc_state *cstate = &state->crtc_state; 3209 struct connector_state *conn_state = &state->conn_state; 3210 struct vop2 *vop2 = cstate->private; 3211 u32 vp_offset = (cstate->crtc_id * 0x100); 3212 u32 output_type = conn_state->type; 3213 u32 data_swap = 0; 3214 3215 if (is_uv_swap(conn_state->bus_format, conn_state->output_mode) || 3216 is_rb_swap(conn_state->bus_format, conn_state->output_mode)) 3217 data_swap = DSP_RB_SWAP; 3218 3219 if (vop2->version == VOP_VERSION_RK3588 && 3220 (output_type == DRM_MODE_CONNECTOR_HDMIA || 3221 output_type == DRM_MODE_CONNECTOR_eDP) && 3222 (conn_state->bus_format == MEDIA_BUS_FMT_YUV8_1X24 || 3223 conn_state->bus_format == MEDIA_BUS_FMT_YUV10_1X30)) 3224 data_swap |= DSP_RG_SWAP; 3225 3226 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 3227 DATA_SWAP_MASK, DATA_SWAP_SHIFT, data_swap, false); 3228 } 3229 3230 static void vop2_clk_set_parent(struct clk *clk, struct clk *parent) 3231 { 3232 int ret = 0; 3233 3234 if (parent->dev) 3235 ret = clk_set_parent(clk, parent); 3236 if (ret < 0) 3237 debug("failed to set %s as parent for %s\n", 3238 parent->dev->name, clk->dev->name); 3239 } 3240 3241 static ulong vop2_clk_set_rate(struct clk *clk, ulong rate) 3242 { 3243 int ret = 0; 3244 3245 if (clk->dev) 3246 ret = clk_set_rate(clk, rate); 3247 if (ret < 0) 3248 debug("failed to set %s rate %lu \n", clk->dev->name, rate); 3249 3250 return ret; 3251 } 3252 3253 static void vop2_calc_dsc_cru_cfg(struct display_state *state, 3254 int *dsc_txp_clk_div, int *dsc_pxl_clk_div, 3255 int *dsc_cds_clk_div, u64 dclk_rate) 3256 { 3257 struct crtc_state *cstate = &state->crtc_state; 3258 3259 *dsc_txp_clk_div = dclk_rate / cstate->dsc_txp_clk_rate; 3260 *dsc_pxl_clk_div = dclk_rate / cstate->dsc_pxl_clk_rate; 3261 *dsc_cds_clk_div = dclk_rate / cstate->dsc_cds_clk_rate; 3262 3263 *dsc_txp_clk_div = ilog2(*dsc_txp_clk_div); 3264 *dsc_pxl_clk_div = ilog2(*dsc_pxl_clk_div); 3265 *dsc_cds_clk_div = ilog2(*dsc_cds_clk_div); 3266 } 3267 3268 static void vop2_load_pps(struct display_state *state, struct vop2 *vop2, u8 dsc_id) 3269 { 3270 struct crtc_state *cstate = &state->crtc_state; 3271 struct drm_dsc_picture_parameter_set *pps = &cstate->pps; 3272 struct drm_dsc_picture_parameter_set config_pps; 3273 const struct vop2_data *vop2_data = vop2->data; 3274 const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id]; 3275 u32 *pps_val = (u32 *)&config_pps; 3276 u32 decoder_regs_offset = (dsc_id * 0x100); 3277 int i = 0; 3278 3279 memcpy(&config_pps, pps, sizeof(config_pps)); 3280 3281 if ((config_pps.pps_3 & 0xf) > dsc_data->max_linebuf_depth) { 3282 config_pps.pps_3 &= 0xf0; 3283 config_pps.pps_3 |= dsc_data->max_linebuf_depth; 3284 printf("DSC%d max_linebuf_depth is: %d, current set value is: %d\n", 3285 dsc_id, dsc_data->max_linebuf_depth, config_pps.pps_3 & 0xf); 3286 } 3287 3288 for (i = 0; i < DSC_NUM_BUF_RANGES; i++) { 3289 config_pps.rc_range_parameters[i] = 3290 (pps->rc_range_parameters[i] >> 3 & 0x1f) | 3291 ((pps->rc_range_parameters[i] >> 14 & 0x3) << 5) | 3292 ((pps->rc_range_parameters[i] >> 0 & 0x7) << 7) | 3293 ((pps->rc_range_parameters[i] >> 8 & 0x3f) << 10); 3294 } 3295 3296 for (i = 0; i < ROCKCHIP_DSC_PPS_SIZE_BYTE / 4; i++) 3297 vop2_writel(vop2, RK3588_DSC_8K_PPS0_3 + decoder_regs_offset + i * 4, *pps_val++); 3298 } 3299 3300 static void vop2_dsc_enable(struct display_state *state, struct vop2 *vop2, u8 dsc_id, u64 dclk_rate) 3301 { 3302 struct connector_state *conn_state = &state->conn_state; 3303 struct drm_display_mode *mode = &conn_state->mode; 3304 struct crtc_state *cstate = &state->crtc_state; 3305 struct rockchip_dsc_sink_cap *dsc_sink_cap = &cstate->dsc_sink_cap; 3306 const struct vop2_data *vop2_data = vop2->data; 3307 const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id]; 3308 bool mipi_ds_mode = false; 3309 u8 dsc_interface_mode = 0; 3310 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 3311 u16 hdisplay = mode->crtc_hdisplay; 3312 u16 htotal = mode->crtc_htotal; 3313 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 3314 u16 vdisplay = mode->crtc_vdisplay; 3315 u16 vtotal = mode->crtc_vtotal; 3316 u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; 3317 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 3318 u16 vact_end = vact_st + vdisplay; 3319 u32 ctrl_regs_offset = (dsc_id * 0x30); 3320 u32 decoder_regs_offset = (dsc_id * 0x100); 3321 int dsc_txp_clk_div = 0; 3322 int dsc_pxl_clk_div = 0; 3323 int dsc_cds_clk_div = 0; 3324 int val = 0; 3325 3326 if (!vop2->data->nr_dscs) { 3327 printf("Unsupported DSC\n"); 3328 return; 3329 } 3330 3331 if (cstate->dsc_slice_num > dsc_data->max_slice_num) 3332 printf("DSC%d supported max slice is: %d, current is: %d\n", 3333 dsc_data->id, dsc_data->max_slice_num, cstate->dsc_slice_num); 3334 3335 if (dsc_data->pd_id) { 3336 if (vop2_power_domain_on(vop2, dsc_data->pd_id)) 3337 printf("open dsc%d pd fail\n", dsc_id); 3338 } 3339 3340 vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, EN_MASK, 3341 SCAN_TIMING_PARA_IMD_EN_SHIFT, 1, false); 3342 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PORT_SEL_MASK, 3343 DSC_PORT_SEL_SHIFT, cstate->crtc_id, false); 3344 if (conn_state->output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) { 3345 dsc_interface_mode = VOP_DSC_IF_HDMI; 3346 } else { 3347 mipi_ds_mode = !!(conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE); 3348 if (mipi_ds_mode) 3349 dsc_interface_mode = VOP_DSC_IF_MIPI_DS_MODE; 3350 else 3351 dsc_interface_mode = VOP_DSC_IF_MIPI_VIDEO_MODE; 3352 } 3353 3354 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 3355 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK, 3356 DSC_MAN_MODE_SHIFT, 0, false); 3357 else 3358 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK, 3359 DSC_MAN_MODE_SHIFT, 1, false); 3360 3361 vop2_calc_dsc_cru_cfg(state, &dsc_txp_clk_div, &dsc_pxl_clk_div, &dsc_cds_clk_div, dclk_rate); 3362 3363 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_INTERFACE_MODE_MASK, 3364 DSC_INTERFACE_MODE_SHIFT, dsc_interface_mode, false); 3365 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PIXEL_NUM_MASK, 3366 DSC_PIXEL_NUM_SHIFT, cstate->dsc_pixel_num >> 1, false); 3367 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_TXP_CLK_DIV_MASK, 3368 DSC_TXP_CLK_DIV_SHIFT, dsc_txp_clk_div, false); 3369 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PXL_CLK_DIV_MASK, 3370 DSC_PXL_CLK_DIV_SHIFT, dsc_pxl_clk_div, false); 3371 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK, 3372 DSC_CDS_CLK_DIV_SHIFT, dsc_cds_clk_div, false); 3373 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, EN_MASK, 3374 DSC_SCAN_EN_SHIFT, !mipi_ds_mode, false); 3375 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK, 3376 DSC_HALT_EN_SHIFT, mipi_ds_mode, false); 3377 3378 if (!mipi_ds_mode) { 3379 u16 dsc_hsync, dsc_htotal, dsc_hact_st, dsc_hact_end; 3380 u32 target_bpp = dsc_sink_cap->target_bits_per_pixel_x16; 3381 u64 dsc_cds_rate = cstate->dsc_cds_clk_rate; 3382 u32 v_pixclk_mhz = mode->crtc_clock / 1000; /* video timing pixclk */ 3383 u32 dly_num, dsc_cds_rate_mhz, val = 0; 3384 int k = 1; 3385 3386 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 3387 k = 2; 3388 3389 if (target_bpp >> 4 < dsc_data->min_bits_per_pixel) 3390 printf("Unsupported bpp less than: %d\n", dsc_data->min_bits_per_pixel); 3391 3392 /* 3393 * dly_num = delay_line_num * T(one-line) / T (dsc_cds) 3394 * T (one-line) = 1/v_pixclk_mhz * htotal = htotal/v_pixclk_mhz 3395 * T (dsc_cds) = 1 / dsc_cds_rate_mhz 3396 * 3397 * HDMI: 3398 * delay_line_num: according the pps initial_xmit_delay to adjust vop dsc delay 3399 * delay_line_num = 4 - BPP / 8 3400 * = (64 - target_bpp / 8) / 16 3401 * dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16; 3402 * 3403 * MIPI DSI[4320 and 9216 is buffer size for DSC]: 3404 * DSC0:delay_line_num = 4320 * 8 / slince_num / chunk_size; 3405 * delay_line_num = delay_line_num > 5 ? 5 : delay_line_num; 3406 * DSC1:delay_line_num = 9216 * 2 / slince_num / chunk_size; 3407 * delay_line_num = delay_line_num > 5 ? 5 : delay_line_num; 3408 * dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * delay_line_num 3409 */ 3410 do_div(dsc_cds_rate, 1000000); /* hz to Mhz */ 3411 dsc_cds_rate_mhz = dsc_cds_rate; 3412 dsc_hsync = hsync_len / 2; 3413 if (dsc_interface_mode == VOP_DSC_IF_HDMI) { 3414 dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16; 3415 } else { 3416 int dsc_buf_size = dsc_id == 0 ? 4320 * 8 : 9216 * 2; 3417 int delay_line_num = dsc_buf_size / cstate->dsc_slice_num / 3418 be16_to_cpu(cstate->pps.chunk_size); 3419 3420 delay_line_num = delay_line_num > 5 ? 5 : delay_line_num; 3421 dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * delay_line_num; 3422 3423 /* The dsc mipi video mode dsc_hsync minimum size is 8 pixels */ 3424 if (dsc_hsync < 8) 3425 dsc_hsync = 8; 3426 } 3427 vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_MODE_MASK, 3428 DSC_INIT_DLY_MODE_SHIFT, 0, false); 3429 vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_NUM_MASK, 3430 DSC_INIT_DLY_NUM_SHIFT, dly_num, false); 3431 3432 /* 3433 * htotal / dclk_core = dsc_htotal /cds_clk 3434 * 3435 * dclk_core = DCLK / (1 << dclk_core->div_val) 3436 * cds_clk = txp_clk / (1 << dsc_cds_clk->div_val) 3437 * txp_clk = DCLK / (1 << dsc_txp_clk->div_val) 3438 * 3439 * dsc_htotal = htotal * (1 << dclk_core->div_val) / 3440 * ((1 << dsc_txp_clk->div_val) * (1 << dsc_cds_clk->div_val)) 3441 */ 3442 dsc_htotal = htotal * (1 << cstate->dclk_core_div) / 3443 ((1 << dsc_txp_clk_div) * (1 << dsc_cds_clk_div)); 3444 val = dsc_htotal << 16 | dsc_hsync; 3445 vop2_mask_write(vop2, RK3588_DSC_8K_HTOTAL_HS_END + ctrl_regs_offset, DSC_HTOTAL_PW_MASK, 3446 DSC_HTOTAL_PW_SHIFT, val, false); 3447 3448 dsc_hact_st = hact_st / 2; 3449 dsc_hact_end = (hdisplay / k * target_bpp >> 4) / 24 + dsc_hact_st; 3450 val = dsc_hact_end << 16 | dsc_hact_st; 3451 vop2_mask_write(vop2, RK3588_DSC_8K_HACT_ST_END + ctrl_regs_offset, DSC_HACT_ST_END_MASK, 3452 DSC_HACT_ST_END_SHIFT, val, false); 3453 3454 vop2_mask_write(vop2, RK3588_DSC_8K_VTOTAL_VS_END + ctrl_regs_offset, DSC_VTOTAL_PW_MASK, 3455 DSC_VTOTAL_PW_SHIFT, vtotal << 16 | vsync_len, false); 3456 vop2_mask_write(vop2, RK3588_DSC_8K_VACT_ST_END + ctrl_regs_offset, DSC_VACT_ST_END_MASK, 3457 DSC_VACT_ST_END_SHIFT, vact_end << 16 | vact_st, false); 3458 } 3459 3460 vop2_mask_write(vop2, RK3588_DSC_8K_RST + ctrl_regs_offset, RST_DEASSERT_MASK, 3461 RST_DEASSERT_SHIFT, 1, false); 3462 udelay(10); 3463 3464 val |= DSC_CTRL0_DEF_CON | (ilog2(cstate->dsc_slice_num) << DSC_NSLC_SHIFT) | 3465 ((dsc_sink_cap->version_minor == 2 ? 1 : 0) << DSC_IFEP_SHIFT); 3466 vop2_writel(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, val); 3467 3468 vop2_load_pps(state, vop2, dsc_id); 3469 3470 val |= (1 << DSC_PPS_UPD_SHIFT); 3471 vop2_writel(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, val); 3472 3473 printf("DSC%d: txp:%lld div:%d, pxl:%lld div:%d, dsc:%lld div:%d\n", 3474 dsc_id, 3475 cstate->dsc_txp_clk_rate, dsc_txp_clk_div, 3476 cstate->dsc_pxl_clk_rate, dsc_pxl_clk_div, 3477 cstate->dsc_cds_clk_rate, dsc_cds_clk_div); 3478 } 3479 3480 static bool is_extend_pll(struct display_state *state, struct udevice **clk_dev) 3481 { 3482 struct crtc_state *cstate = &state->crtc_state; 3483 struct vop2 *vop2 = cstate->private; 3484 struct udevice *vp_dev, *dev; 3485 struct ofnode_phandle_args args; 3486 char vp_name[10]; 3487 int ret; 3488 3489 if (vop2->version != VOP_VERSION_RK3588) 3490 return false; 3491 3492 sprintf(vp_name, "port@%d", cstate->crtc_id); 3493 if (uclass_find_device_by_name(UCLASS_VIDEO_CRTC, vp_name, &vp_dev)) { 3494 debug("warn: can't get vp device\n"); 3495 return false; 3496 } 3497 3498 ret = dev_read_phandle_with_args(vp_dev, "assigned-clock-parents", "#clock-cells", 0, 3499 0, &args); 3500 if (ret) { 3501 debug("assigned-clock-parents's node not define\n"); 3502 return false; 3503 } 3504 3505 if (uclass_find_device_by_ofnode(UCLASS_CLK, args.node, &dev)) { 3506 debug("warn: can't get clk device\n"); 3507 return false; 3508 } 3509 3510 if (!strcmp(dev->name, "hdmiphypll_clk0") || !strcmp(dev->name, "hdmiphypll_clk1")) { 3511 printf("%s: clk dev :%s: vp port:%s\n", __func__, dev->name, vp_dev->name); 3512 if (clk_dev) 3513 *clk_dev = dev; 3514 return true; 3515 } 3516 3517 return false; 3518 } 3519 3520 static void vop3_mcu_mode_setup(struct display_state *state) 3521 { 3522 struct crtc_state *cstate = &state->crtc_state; 3523 struct vop2 *vop2 = cstate->private; 3524 u32 vp_offset = (cstate->crtc_id * 0x100); 3525 3526 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 3527 MCU_TYPE_SHIFT, 1, false); 3528 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 3529 MCU_HOLD_MODE_SHIFT, 1, false); 3530 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_PIX_TOTAL_MASK, 3531 MCU_PIX_TOTAL_SHIFT, cstate->mcu_timing.mcu_pix_total, false); 3532 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PST_MASK, 3533 MCU_CS_PST_SHIFT, cstate->mcu_timing.mcu_cs_pst, false); 3534 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PEND_MASK, 3535 MCU_CS_PEND_SHIFT, cstate->mcu_timing.mcu_cs_pend, false); 3536 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PST_MASK, 3537 MCU_RW_PST_SHIFT, cstate->mcu_timing.mcu_rw_pst, false); 3538 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PEND_MASK, 3539 MCU_RW_PEND_SHIFT, cstate->mcu_timing.mcu_rw_pend, false); 3540 } 3541 3542 static void vop3_mcu_bypass_mode_setup(struct display_state *state) 3543 { 3544 struct crtc_state *cstate = &state->crtc_state; 3545 struct vop2 *vop2 = cstate->private; 3546 u32 vp_offset = (cstate->crtc_id * 0x100); 3547 3548 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 3549 MCU_TYPE_SHIFT, 1, false); 3550 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 3551 MCU_HOLD_MODE_SHIFT, 1, false); 3552 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_PIX_TOTAL_MASK, 3553 MCU_PIX_TOTAL_SHIFT, 53, false); 3554 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PST_MASK, 3555 MCU_CS_PST_SHIFT, 6, false); 3556 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_CS_PEND_MASK, 3557 MCU_CS_PEND_SHIFT, 48, false); 3558 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PST_MASK, 3559 MCU_RW_PST_SHIFT, 12, false); 3560 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, MCU_RW_PEND_MASK, 3561 MCU_RW_PEND_SHIFT, 30, false); 3562 } 3563 3564 static int rockchip_vop2_send_mcu_cmd(struct display_state *state, u32 type, u32 value) 3565 { 3566 struct crtc_state *cstate = &state->crtc_state; 3567 struct connector_state *conn_state = &state->conn_state; 3568 struct drm_display_mode *mode = &conn_state->mode; 3569 struct vop2 *vop2 = cstate->private; 3570 u32 vp_offset = (cstate->crtc_id * 0x100); 3571 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 3572 3573 /* 3574 * 1.disable port dclk auto gating. 3575 * 2.set mcu bypass mode timing to adapt to the mode of sending cmds. 3576 * 3.make setting of output mode take effect. 3577 * 4.set dclk rate to 150M, in order to sync with hclk in sending cmds. 3578 */ 3579 if (type == MCU_SETBYPASS && value) { 3580 vop2_mask_write(vop2, RK3568_AUTO_GATING_CTRL, EN_MASK, 3581 AUTO_GATING_EN_SHIFT, 0, false); 3582 vop2_mask_write(vop2, RK3568_AUTO_GATING_CTRL, EN_MASK, 3583 PORT_DCLK_AUTO_GATING_EN_SHIFT, 0, false); 3584 vop3_mcu_bypass_mode_setup(state); 3585 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3586 STANDBY_EN_SHIFT, 0, false); 3587 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 3588 vop2_clk_set_rate(&cstate->dclk, 150000000); 3589 } 3590 3591 switch (type) { 3592 case MCU_WRCMD: 3593 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 3594 MCU_RS_SHIFT, 0, false); 3595 vop2_mask_write(vop2, RK3562_VP0_MCU_RW_BYPASS_PORT + vp_offset, 3596 MCU_WRITE_DATA_BYPASS_MASK, MCU_WRITE_DATA_BYPASS_SHIFT, 3597 value, false); 3598 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 3599 MCU_RS_SHIFT, 1, false); 3600 break; 3601 case MCU_WRDATA: 3602 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 3603 MCU_RS_SHIFT, 1, false); 3604 vop2_mask_write(vop2, RK3562_VP0_MCU_RW_BYPASS_PORT + vp_offset, 3605 MCU_WRITE_DATA_BYPASS_MASK, MCU_WRITE_DATA_BYPASS_SHIFT, 3606 value, false); 3607 break; 3608 case MCU_SETBYPASS: 3609 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 3610 MCU_BYPASS_SHIFT, value ? 1 : 0, false); 3611 break; 3612 default: 3613 break; 3614 } 3615 3616 /* 3617 * 1.restore port dclk auto gating. 3618 * 2.restore mcu data mode timing. 3619 * 3.restore dclk rate to crtc_clock. 3620 */ 3621 if (type == MCU_SETBYPASS && !value) { 3622 vop2_mask_write(vop2, RK3568_AUTO_GATING_CTRL, EN_MASK, 3623 AUTO_GATING_EN_SHIFT, 1, false); 3624 vop2_mask_write(vop2, RK3568_AUTO_GATING_CTRL, EN_MASK, 3625 PORT_DCLK_AUTO_GATING_EN_SHIFT, 1, false); 3626 vop3_mcu_mode_setup(state); 3627 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3628 STANDBY_EN_SHIFT, 1, false); 3629 vop2_clk_set_rate(&cstate->dclk, mode->crtc_clock * 1000); 3630 } 3631 3632 return 0; 3633 } 3634 3635 static int vop2_get_vrefresh(struct display_state *state) 3636 { 3637 struct crtc_state *cstate = &state->crtc_state; 3638 struct connector_state *conn_state = &state->conn_state; 3639 struct drm_display_mode *mode = &conn_state->mode; 3640 3641 if (cstate->mcu_timing.mcu_pix_total) 3642 return mode->vrefresh / cstate->mcu_timing.mcu_pix_total; 3643 else 3644 return mode->vrefresh; 3645 } 3646 3647 static int rockchip_vop2_init(struct display_state *state) 3648 { 3649 struct crtc_state *cstate = &state->crtc_state; 3650 struct rockchip_vp *vp = &cstate->crtc->vps[cstate->crtc_id]; 3651 struct connector_state *conn_state = &state->conn_state; 3652 struct drm_display_mode *mode = &conn_state->mode; 3653 struct vop2 *vop2 = cstate->private; 3654 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 3655 u16 hdisplay = mode->crtc_hdisplay; 3656 u16 htotal = mode->crtc_htotal; 3657 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 3658 u16 hact_end = hact_st + hdisplay; 3659 u16 vdisplay = mode->crtc_vdisplay; 3660 u16 vtotal = mode->crtc_vtotal; 3661 u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; 3662 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 3663 u16 vact_end = vact_st + vdisplay; 3664 bool yuv_overlay = false; 3665 u32 vp_offset = (cstate->crtc_id * 0x100); 3666 u32 line_flag_offset = (cstate->crtc_id * 4); 3667 u32 val, act_end; 3668 u8 dither_down_en = 0; 3669 u8 dither_down_mode = 0; 3670 u8 pre_dither_down_en = 0; 3671 u8 dclk_div_factor = 0; 3672 char output_type_name[30] = {0}; 3673 #ifndef CONFIG_SPL_BUILD 3674 char dclk_name[9]; 3675 #endif 3676 struct clk hdmi0_phy_pll; 3677 struct clk hdmi1_phy_pll; 3678 struct clk hdmi_phy_pll; 3679 struct udevice *disp_dev; 3680 unsigned long dclk_rate = 0; 3681 int ret; 3682 3683 printf("VOP update mode to: %dx%d%s%d, type:%s for VP%d\n", 3684 mode->crtc_hdisplay, mode->vdisplay, 3685 mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p", 3686 vop2_get_vrefresh(state), 3687 get_output_if_name(conn_state->output_if, output_type_name), 3688 cstate->crtc_id); 3689 3690 if (mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) { 3691 cstate->splice_mode = true; 3692 cstate->splice_crtc_id = vop2->data->vp_data[cstate->crtc_id].splice_vp_id; 3693 if (!cstate->splice_crtc_id) { 3694 printf("%s: Splice mode is unsupported by vp%d\n", 3695 __func__, cstate->crtc_id); 3696 return -EINVAL; 3697 } 3698 3699 vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, EN_MASK, 3700 PORT_MERGE_EN_SHIFT, 1, false); 3701 } 3702 3703 vop2_mask_write(vop2, RK3588_SYS_VAR_FREQ_CTRL, EN_MASK, 3704 RK3588_VP0_LINE_FLAG_OR_EN_SHIFT + cstate->crtc_id, 1, false); 3705 vop2_mask_write(vop2, RK3588_SYS_VAR_FREQ_CTRL, EN_MASK, 3706 RK3588_VP0_ALMOST_FULL_OR_EN_SHIFT + cstate->crtc_id, 1, false); 3707 3708 vop2_initial(vop2, state); 3709 if (vop2->version == VOP_VERSION_RK3588) 3710 dclk_rate = rk3588_vop2_if_cfg(state); 3711 else if (vop2->version == VOP_VERSION_RK3568) 3712 dclk_rate = rk3568_vop2_if_cfg(state); 3713 else if (vop2->version == VOP_VERSION_RK3528) 3714 dclk_rate = rk3528_vop2_if_cfg(state); 3715 else if (vop2->version == VOP_VERSION_RK3562) 3716 dclk_rate = rk3562_vop2_if_cfg(state); 3717 3718 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA && 3719 !(cstate->feature & VOP_FEATURE_OUTPUT_10BIT)) 3720 conn_state->output_mode = ROCKCHIP_OUT_MODE_P888; 3721 3722 vop2_post_color_swap(state); 3723 3724 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, OUT_MODE_MASK, 3725 OUT_MODE_SHIFT, conn_state->output_mode, false); 3726 3727 switch (conn_state->bus_format) { 3728 case MEDIA_BUS_FMT_RGB565_1X16: 3729 dither_down_en = 1; 3730 dither_down_mode = RGB888_TO_RGB565; 3731 pre_dither_down_en = 1; 3732 break; 3733 case MEDIA_BUS_FMT_RGB666_1X18: 3734 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: 3735 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 3736 case MEDIA_BUS_FMT_RGB666_1X7X3_JEIDA: 3737 dither_down_en = 1; 3738 dither_down_mode = RGB888_TO_RGB666; 3739 pre_dither_down_en = 1; 3740 break; 3741 case MEDIA_BUS_FMT_YUV8_1X24: 3742 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 3743 dither_down_en = 0; 3744 pre_dither_down_en = 1; 3745 break; 3746 case MEDIA_BUS_FMT_YUV10_1X30: 3747 case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 3748 dither_down_en = 0; 3749 pre_dither_down_en = 0; 3750 break; 3751 case MEDIA_BUS_FMT_YUYV10_1X20: 3752 case MEDIA_BUS_FMT_RGB888_1X24: 3753 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: 3754 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: 3755 case MEDIA_BUS_FMT_RGB101010_1X30: 3756 default: 3757 dither_down_en = 0; 3758 pre_dither_down_en = 1; 3759 break; 3760 } 3761 3762 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3763 DITHER_DOWN_EN_SHIFT, dither_down_en, false); 3764 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3765 DITHER_DOWN_MODE_SHIFT, dither_down_mode, false); 3766 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3767 PRE_DITHER_DOWN_EN_SHIFT, pre_dither_down_en, false); 3768 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3769 DITHER_DOWN_MODE_SHIFT, dither_down_mode, false); 3770 3771 yuv_overlay = is_yuv_output(conn_state->bus_format) ? 1 : 0; 3772 vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, cstate->crtc_id, 3773 yuv_overlay, false); 3774 3775 cstate->yuv_overlay = yuv_overlay; 3776 3777 vop2_writel(vop2, RK3568_VP0_DSP_HTOTAL_HS_END + vp_offset, 3778 (htotal << 16) | hsync_len); 3779 val = hact_st << 16; 3780 val |= hact_end; 3781 vop2_writel(vop2, RK3568_VP0_DSP_HACT_ST_END + vp_offset, val); 3782 val = vact_st << 16; 3783 val |= vact_end; 3784 vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END + vp_offset, val); 3785 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 3786 u16 vact_st_f1 = vtotal + vact_st + 1; 3787 u16 vact_end_f1 = vact_st_f1 + vdisplay; 3788 3789 val = vact_st_f1 << 16 | vact_end_f1; 3790 vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END_F1 + vp_offset, 3791 val); 3792 3793 val = vtotal << 16 | (vtotal + vsync_len); 3794 vop2_writel(vop2, RK3568_VP0_DSP_VS_ST_END_F1 + vp_offset, val); 3795 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3796 INTERLACE_EN_SHIFT, 1, false); 3797 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3798 DSP_FILED_POL, 1, false); 3799 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3800 P2I_EN_SHIFT, 1, false); 3801 vtotal += vtotal + 1; 3802 act_end = vact_end_f1; 3803 } else { 3804 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3805 INTERLACE_EN_SHIFT, 0, false); 3806 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3807 P2I_EN_SHIFT, 0, false); 3808 act_end = vact_end; 3809 } 3810 vop2_writel(vop2, RK3568_VP0_DSP_VTOTAL_VS_END + vp_offset, 3811 (vtotal << 16) | vsync_len); 3812 3813 if (mode->flags & DRM_MODE_FLAG_DBLCLK || 3814 conn_state->output_if & VOP_OUTPUT_IF_BT656) 3815 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3816 CORE_DCLK_DIV_EN_SHIFT, 1, false); 3817 else 3818 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3819 CORE_DCLK_DIV_EN_SHIFT, 0, false); 3820 3821 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420) 3822 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 3823 DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0x3, false); 3824 else 3825 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 3826 DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0, false); 3827 3828 vop2_mask_write(vop2, RK3568_OVL_CTRL, OVL_MODE_SEL_MASK, 3829 OVL_MODE_SEL_SHIFT + cstate->crtc_id, yuv_overlay, false); 3830 3831 if (yuv_overlay) 3832 val = 0x20010200; 3833 else 3834 val = 0; 3835 vop2_writel(vop2, RK3568_VP0_DSP_BG + vp_offset, val); 3836 if (cstate->splice_mode) { 3837 vop2_mask_write(vop2, RK3568_OVL_CTRL, OVL_MODE_SEL_MASK, 3838 OVL_MODE_SEL_SHIFT + cstate->splice_crtc_id, 3839 yuv_overlay, false); 3840 vop2_writel(vop2, RK3568_VP0_DSP_BG + (cstate->splice_crtc_id * 0x100), val); 3841 } 3842 3843 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3844 POST_DSP_OUT_R2Y_SHIFT, yuv_overlay, false); 3845 3846 if (vp->xmirror_en) 3847 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3848 DSP_X_MIR_EN_SHIFT, 1, false); 3849 3850 vop2_tv_config_update(state, vop2); 3851 vop2_post_config(state, vop2); 3852 if (cstate->feature & (VOP_FEATURE_POST_ACM | VOP_FEATURE_POST_CSC)) 3853 vop3_post_config(state, vop2); 3854 3855 if (cstate->dsc_enable) { 3856 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 3857 vop2_dsc_enable(state, vop2, 0, dclk_rate * 1000LL); 3858 vop2_dsc_enable(state, vop2, 1, dclk_rate * 1000LL); 3859 } else { 3860 vop2_dsc_enable(state, vop2, cstate->dsc_id, dclk_rate * 1000LL); 3861 } 3862 } 3863 3864 #ifndef CONFIG_SPL_BUILD 3865 snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", cstate->crtc_id); 3866 ret = clk_get_by_name(cstate->dev, dclk_name, &cstate->dclk); 3867 if (ret) { 3868 printf("%s: Failed to get dclk ret=%d\n", __func__, ret); 3869 return ret; 3870 } 3871 #endif 3872 3873 ret = uclass_get_device_by_name(UCLASS_VIDEO, "display-subsystem", &disp_dev); 3874 if (!ret) { 3875 ret = clk_get_by_name(disp_dev, "hdmi0_phy_pll", &hdmi0_phy_pll); 3876 if (ret) 3877 debug("%s: hdmi0_phy_pll may not define\n", __func__); 3878 ret = clk_get_by_name(disp_dev, "hdmi1_phy_pll", &hdmi1_phy_pll); 3879 if (ret) 3880 debug("%s: hdmi1_phy_pll may not define\n", __func__); 3881 } else { 3882 hdmi0_phy_pll.dev = NULL; 3883 hdmi1_phy_pll.dev = NULL; 3884 debug("%s: Faile to find display-subsystem node\n", __func__); 3885 } 3886 3887 if (vop2->version == VOP_VERSION_RK3528) { 3888 struct ofnode_phandle_args args; 3889 3890 ret = dev_read_phandle_with_args(cstate->dev, "assigned-clock-parents", 3891 "#clock-cells", 0, 0, &args); 3892 if (!ret) { 3893 ret = uclass_find_device_by_ofnode(UCLASS_CLK, args.node, &hdmi0_phy_pll.dev); 3894 if (ret) { 3895 debug("warn: can't get clk device\n"); 3896 return ret; 3897 } 3898 } else { 3899 debug("assigned-clock-parents's node not define\n"); 3900 } 3901 } 3902 3903 if (mode->crtc_clock < VOP2_MAX_DCLK_RATE) { 3904 if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) 3905 vop2_clk_set_parent(&cstate->dclk, &hdmi0_phy_pll); 3906 else if (conn_state->output_if & VOP_OUTPUT_IF_HDMI1) 3907 vop2_clk_set_parent(&cstate->dclk, &hdmi1_phy_pll); 3908 3909 /* 3910 * uboot clk driver won't set dclk parent's rate when use 3911 * hdmi phypll as dclk source. 3912 * So set dclk rate is meaningless. Set hdmi phypll rate 3913 * directly. 3914 */ 3915 if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI0) && hdmi0_phy_pll.dev) { 3916 ret = vop2_clk_set_rate(&hdmi0_phy_pll, dclk_rate * 1000); 3917 } else if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI1) && hdmi1_phy_pll.dev) { 3918 ret = vop2_clk_set_rate(&hdmi1_phy_pll, dclk_rate * 1000); 3919 } else { 3920 if (is_extend_pll(state, &hdmi_phy_pll.dev)) { 3921 ret = vop2_clk_set_rate(&hdmi_phy_pll, dclk_rate * 1000); 3922 } else { 3923 #ifndef CONFIG_SPL_BUILD 3924 ret = vop2_clk_set_rate(&cstate->dclk, dclk_rate * 1000); 3925 #else 3926 if (vop2->version == VOP_VERSION_RK3528) { 3927 void *cru_base = (void *)RK3528_CRU_BASE; 3928 3929 /* dclk src switch to hdmiphy pll */ 3930 writel((BIT(0) << 16) | BIT(0), cru_base + 0x450); 3931 rockchip_phy_set_pll(conn_state->connector->phy, dclk_rate * 1000); 3932 ret = dclk_rate * 1000; 3933 } 3934 #endif 3935 } 3936 } 3937 } else { 3938 if (is_extend_pll(state, &hdmi_phy_pll.dev)) 3939 ret = vop2_clk_set_rate(&hdmi_phy_pll, dclk_rate * 1000); 3940 else 3941 ret = vop2_clk_set_rate(&cstate->dclk, dclk_rate * 1000); 3942 } 3943 3944 if (IS_ERR_VALUE(ret)) { 3945 printf("%s: Failed to set vp%d dclk[%ld KHZ] ret=%d\n", 3946 __func__, cstate->crtc_id, dclk_rate, ret); 3947 return ret; 3948 } else { 3949 dclk_div_factor = mode->clock / dclk_rate; 3950 if (vop2->version == VOP_VERSION_RK3528 && 3951 conn_state->output_if & VOP_OUTPUT_IF_BT656) 3952 mode->crtc_clock = ret / 4 / 1000; 3953 else 3954 mode->crtc_clock = ret * dclk_div_factor / 1000; 3955 printf("VP%d set crtc_clock to %dKHz\n", cstate->crtc_id, mode->crtc_clock); 3956 } 3957 3958 vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK, 3959 RK3568_DSP_LINE_FLAG_NUM0_SHIFT, act_end, false); 3960 vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK, 3961 RK3568_DSP_LINE_FLAG_NUM1_SHIFT, act_end, false); 3962 3963 if (cstate->mcu_timing.mcu_pix_total) 3964 vop3_mcu_mode_setup(state); 3965 3966 return 0; 3967 } 3968 3969 static void vop2_setup_scale(struct vop2 *vop2, struct vop2_win_data *win, 3970 uint32_t src_w, uint32_t src_h, uint32_t dst_w, 3971 uint32_t dst_h) 3972 { 3973 uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode; 3974 uint16_t hscl_filter_mode, vscl_filter_mode; 3975 uint8_t xgt2 = 0, xgt4 = 0; 3976 uint8_t ygt2 = 0, ygt4 = 0; 3977 uint32_t xfac = 0, yfac = 0; 3978 u32 win_offset = win->reg_offset; 3979 bool xgt_en = false; 3980 bool xavg_en = false; 3981 3982 if (is_vop3(vop2)) { 3983 if (src_w >= (4 * dst_w)) { 3984 xgt4 = 1; 3985 src_w >>= 2; 3986 } else if (src_w >= (2 * dst_w)) { 3987 xgt2 = 1; 3988 src_w >>= 1; 3989 } 3990 } 3991 3992 if (src_h >= (4 * dst_h)) { 3993 ygt4 = 1; 3994 src_h >>= 2; 3995 } else if (src_h >= (2 * dst_h)) { 3996 ygt2 = 1; 3997 src_h >>= 1; 3998 } 3999 4000 yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w); 4001 yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h); 4002 4003 if (yrgb_hor_scl_mode == SCALE_UP) 4004 hscl_filter_mode = win->hsu_filter_mode; 4005 else 4006 hscl_filter_mode = win->hsd_filter_mode; 4007 4008 if (yrgb_ver_scl_mode == SCALE_UP) 4009 vscl_filter_mode = win->vsu_filter_mode; 4010 else 4011 vscl_filter_mode = win->vsd_filter_mode; 4012 4013 /* 4014 * RK3568 VOP Esmart/Smart dsp_w should be even pixel 4015 * at scale down mode 4016 */ 4017 if ((yrgb_hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1) && !is_vop3(vop2)) { 4018 printf("win dst_w[%d] should align as 2 pixel\n", dst_w); 4019 dst_w += 1; 4020 } 4021 4022 if (is_vop3(vop2)) { 4023 xfac = vop3_scale_factor(yrgb_hor_scl_mode, src_w, dst_w, true); 4024 yfac = vop3_scale_factor(yrgb_ver_scl_mode, src_h, dst_h, false); 4025 4026 if (win->hsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_AVG) 4027 xavg_en = xgt2 || xgt4; 4028 else 4029 xgt_en = xgt2 || xgt4; 4030 } else { 4031 xfac = vop2_scale_factor(yrgb_hor_scl_mode, hscl_filter_mode, src_w, dst_w); 4032 yfac = vop2_scale_factor(yrgb_ver_scl_mode, vscl_filter_mode, src_h, dst_h); 4033 } 4034 4035 if (win->type == CLUSTER_LAYER) { 4036 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB + win_offset, 4037 yfac << 16 | xfac); 4038 4039 if (is_vop3(vop2)) { 4040 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4041 EN_MASK, CLUSTER_XGT_EN_SHIFT, xgt_en, false); 4042 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4043 EN_MASK, CLUSTER_XAVG_EN_SHIFT, xavg_en, false); 4044 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4045 XGT_MODE_MASK, CLUSTER_XGT_MODE_SHIFT, xgt2 ? 0 : 1, false); 4046 4047 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4048 YRGB_XSCL_MODE_MASK, RK3528_CLUSTER_YRGB_XSCL_MODE_SHIFT, 4049 yrgb_hor_scl_mode, false); 4050 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4051 YRGB_YSCL_MODE_MASK, RK3528_CLUSTER_YRGB_YSCL_MODE_SHIFT, 4052 yrgb_ver_scl_mode, false); 4053 } else { 4054 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4055 YRGB_XSCL_MODE_MASK, RK3568_CLUSTER_YRGB_XSCL_MODE_SHIFT, 4056 yrgb_hor_scl_mode, false); 4057 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4058 YRGB_YSCL_MODE_MASK, RK3568_CLUSTER_YRGB_YSCL_MODE_SHIFT, 4059 yrgb_ver_scl_mode, false); 4060 } 4061 4062 if (!is_vop3(vop2) || win->vsd_pre_filter_mode == VOP3_PRE_SCALE_DOWN_GT) { 4063 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4064 YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, ygt2, false); 4065 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4066 YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, ygt4, false); 4067 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4068 AVG2_MASK, CLUSTER_AVG2_SHIFT, 0, false); 4069 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4070 AVG4_MASK, CLUSTER_AVG4_SHIFT, 0, false); 4071 } else { 4072 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4073 YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, 0, false); 4074 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4075 YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, 0, false); 4076 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4077 AVG2_MASK, CLUSTER_AVG2_SHIFT, ygt2, false); 4078 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 4079 AVG4_MASK, CLUSTER_AVG4_SHIFT, ygt4, false); 4080 } 4081 } else { 4082 vop2_writel(vop2, RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB + win_offset, 4083 yfac << 16 | xfac); 4084 4085 if (is_vop3(vop2)) { 4086 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 4087 EN_MASK, ESMART_XGT_EN_SHIFT, xgt_en, false); 4088 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 4089 EN_MASK, ESMART_XAVG_EN_SHIFT, xavg_en, false); 4090 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 4091 XGT_MODE_MASK, ESMART_XGT_MODE_SHIFT, xgt2 ? 0 : 1, false); 4092 } 4093 4094 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 4095 YRGB_GT2_MASK, YRGB_GT2_SHIFT, ygt2, false); 4096 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 4097 YRGB_GT4_MASK, YRGB_GT4_SHIFT, ygt4, false); 4098 4099 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 4100 YRGB_XSCL_MODE_MASK, YRGB_XSCL_MODE_SHIFT, yrgb_hor_scl_mode, false); 4101 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 4102 YRGB_YSCL_MODE_MASK, YRGB_YSCL_MODE_SHIFT, yrgb_ver_scl_mode, false); 4103 4104 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 4105 YRGB_XSCL_FILTER_MODE_MASK, YRGB_XSCL_FILTER_MODE_SHIFT, 4106 hscl_filter_mode, false); 4107 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 4108 YRGB_YSCL_FILTER_MODE_MASK, YRGB_YSCL_FILTER_MODE_SHIFT, 4109 vscl_filter_mode, false); 4110 } 4111 } 4112 4113 static void vop2_axi_config(struct vop2 *vop2, struct vop2_win_data *win) 4114 { 4115 u32 win_offset = win->reg_offset; 4116 4117 if (win->type == CLUSTER_LAYER) { 4118 vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, CLUSTER_AXI_ID_MASK, 4119 CLUSTER_AXI_ID_SHIFT, win->axi_id, false); 4120 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_YRGB_ID_MASK, 4121 CLUSTER_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false); 4122 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_UV_ID_MASK, 4123 CLUSTER_AXI_UV_ID_SHIFT, win->axi_uv_id, false); 4124 } else { 4125 vop2_mask_write(vop2, RK3568_ESMART0_AXI_CTRL + win_offset, ESMART_AXI_ID_MASK, 4126 ESMART_AXI_ID_SHIFT, win->axi_id, false); 4127 vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_YRGB_ID_MASK, 4128 ESMART_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false); 4129 vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_UV_ID_MASK, 4130 ESMART_AXI_UV_ID_SHIFT, win->axi_uv_id, false); 4131 } 4132 } 4133 4134 static void vop2_set_cluster_win(struct display_state *state, struct vop2_win_data *win) 4135 { 4136 struct crtc_state *cstate = &state->crtc_state; 4137 struct connector_state *conn_state = &state->conn_state; 4138 struct drm_display_mode *mode = &conn_state->mode; 4139 struct vop2 *vop2 = cstate->private; 4140 int src_w = cstate->src_rect.w; 4141 int src_h = cstate->src_rect.h; 4142 int crtc_x = cstate->crtc_rect.x; 4143 int crtc_y = cstate->crtc_rect.y; 4144 int crtc_w = cstate->crtc_rect.w; 4145 int crtc_h = cstate->crtc_rect.h; 4146 int xvir = cstate->xvir; 4147 int y_mirror = 0; 4148 int csc_mode; 4149 u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty; 4150 /* offset of the right window in splice mode */ 4151 u32 splice_pixel_offset = 0; 4152 u32 splice_yrgb_offset = 0; 4153 u32 win_offset = win->reg_offset; 4154 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 4155 4156 if (win->splice_mode_right) { 4157 src_w = cstate->right_src_rect.w; 4158 src_h = cstate->right_src_rect.h; 4159 crtc_x = cstate->right_crtc_rect.x; 4160 crtc_y = cstate->right_crtc_rect.y; 4161 crtc_w = cstate->right_crtc_rect.w; 4162 crtc_h = cstate->right_crtc_rect.h; 4163 splice_pixel_offset = cstate->right_src_rect.x - cstate->src_rect.x; 4164 splice_yrgb_offset = splice_pixel_offset * (state->logo.bpp >> 3); 4165 cfg_done = CFG_DONE_EN | BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 4166 } 4167 4168 act_info = (src_h - 1) << 16; 4169 act_info |= (src_w - 1) & 0xffff; 4170 4171 dsp_info = (crtc_h - 1) << 16; 4172 dsp_info |= (crtc_w - 1) & 0xffff; 4173 4174 dsp_stx = crtc_x; 4175 dsp_sty = crtc_y; 4176 dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); 4177 4178 if (mode->flags & DRM_MODE_FLAG_YMIRROR) 4179 y_mirror = 1; 4180 else 4181 y_mirror = 0; 4182 4183 vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h); 4184 4185 if (vop2->version == VOP_VERSION_RK3588 || vop2->version == VOP_VERSION_RK3528 || 4186 vop2->version == VOP_VERSION_RK3562) 4187 vop2_axi_config(vop2, win); 4188 4189 if (y_mirror) 4190 printf("WARN: y mirror is unsupported by cluster window\n"); 4191 4192 /* rk3588 should set half_blocK_en to 1 in line and tile mode */ 4193 if (vop2->version == VOP_VERSION_RK3588) 4194 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_AFBCD_CTRL + win_offset, 4195 EN_MASK, CLUSTER_AFBCD_HALF_BLOCK_SHIFT, 1, false); 4196 4197 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, 4198 WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format, 4199 false); 4200 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_VIR + win_offset, xvir); 4201 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_YRGB_MST + win_offset, 4202 cstate->dma_addr + splice_yrgb_offset); 4203 4204 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_ACT_INFO + win_offset, act_info); 4205 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_INFO + win_offset, dsp_info); 4206 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_ST + win_offset, dsp_st); 4207 4208 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, WIN_EN_SHIFT, 1, false); 4209 4210 csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_10BIT_DEPTH); 4211 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, 4212 CLUSTER_RGB2YUV_EN_SHIFT, 4213 is_yuv_output(conn_state->bus_format), false); 4214 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, CSC_MODE_MASK, 4215 CLUSTER_CSC_MODE_SHIFT, csc_mode, false); 4216 vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, EN_MASK, CLUSTER_EN_SHIFT, 1, false); 4217 4218 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 4219 } 4220 4221 static void vop2_set_smart_win(struct display_state *state, struct vop2_win_data *win) 4222 { 4223 struct crtc_state *cstate = &state->crtc_state; 4224 struct connector_state *conn_state = &state->conn_state; 4225 struct drm_display_mode *mode = &conn_state->mode; 4226 struct vop2 *vop2 = cstate->private; 4227 int src_w = cstate->src_rect.w; 4228 int src_h = cstate->src_rect.h; 4229 int crtc_x = cstate->crtc_rect.x; 4230 int crtc_y = cstate->crtc_rect.y; 4231 int crtc_w = cstate->crtc_rect.w; 4232 int crtc_h = cstate->crtc_rect.h; 4233 int xvir = cstate->xvir; 4234 int y_mirror = 0; 4235 int csc_mode; 4236 u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty; 4237 /* offset of the right window in splice mode */ 4238 u32 splice_pixel_offset = 0; 4239 u32 splice_yrgb_offset = 0; 4240 u32 win_offset = win->reg_offset; 4241 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 4242 4243 if (win->splice_mode_right) { 4244 src_w = cstate->right_src_rect.w; 4245 src_h = cstate->right_src_rect.h; 4246 crtc_x = cstate->right_crtc_rect.x; 4247 crtc_y = cstate->right_crtc_rect.y; 4248 crtc_w = cstate->right_crtc_rect.w; 4249 crtc_h = cstate->right_crtc_rect.h; 4250 splice_pixel_offset = cstate->right_src_rect.x - cstate->src_rect.x; 4251 splice_yrgb_offset = splice_pixel_offset * (state->logo.bpp >> 3); 4252 cfg_done = CFG_DONE_EN | BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 4253 } 4254 4255 /* 4256 * This is workaround solution for IC design: 4257 * esmart can't support scale down when actual_w % 16 == 1. 4258 */ 4259 if (src_w > crtc_w && (src_w & 0xf) == 1) { 4260 printf("WARN: vp%d unsupported act_w[%d] mode 16 = 1 when scale down\n", cstate->crtc_id, src_w); 4261 src_w -= 1; 4262 } 4263 4264 act_info = (src_h - 1) << 16; 4265 act_info |= (src_w - 1) & 0xffff; 4266 4267 dsp_info = (crtc_h - 1) << 16; 4268 dsp_info |= (crtc_w - 1) & 0xffff; 4269 4270 dsp_stx = crtc_x; 4271 dsp_sty = crtc_y; 4272 dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); 4273 4274 if (mode->flags & DRM_MODE_FLAG_YMIRROR) 4275 y_mirror = 1; 4276 else 4277 y_mirror = 0; 4278 4279 if (is_vop3(vop2)) 4280 vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, ESMART_LB_SELECT_MASK, 4281 ESMART_LB_SELECT_SHIFT, win->scale_engine_num, false); 4282 4283 vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h); 4284 4285 if (vop2->version == VOP_VERSION_RK3588 || vop2->version == VOP_VERSION_RK3528 || 4286 vop2->version == VOP_VERSION_RK3562) 4287 vop2_axi_config(vop2, win); 4288 4289 if (y_mirror) 4290 cstate->dma_addr += (src_h - 1) * xvir * 4; 4291 vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, EN_MASK, 4292 YMIRROR_EN_SHIFT, y_mirror, false); 4293 4294 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 4295 WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format, 4296 false); 4297 vop2_writel(vop2, RK3568_ESMART0_REGION0_VIR + win_offset, xvir); 4298 vop2_writel(vop2, RK3568_ESMART0_REGION0_YRGB_MST + win_offset, 4299 cstate->dma_addr + splice_yrgb_offset); 4300 4301 vop2_writel(vop2, RK3568_ESMART0_REGION0_ACT_INFO + win_offset, 4302 act_info); 4303 vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_INFO + win_offset, 4304 dsp_info); 4305 vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_ST + win_offset, dsp_st); 4306 4307 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK, 4308 WIN_EN_SHIFT, 1, false); 4309 4310 csc_mode = vop2_convert_csc_mode(conn_state->color_space, CSC_10BIT_DEPTH); 4311 vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, EN_MASK, 4312 RGB2YUV_EN_SHIFT, 4313 is_yuv_output(conn_state->bus_format), false); 4314 vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, CSC_MODE_MASK, 4315 CSC_MODE_SHIFT, csc_mode, false); 4316 4317 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 4318 } 4319 4320 static void vop2_calc_display_rect_for_splice(struct display_state *state) 4321 { 4322 struct crtc_state *cstate = &state->crtc_state; 4323 struct connector_state *conn_state = &state->conn_state; 4324 struct drm_display_mode *mode = &conn_state->mode; 4325 struct display_rect *src_rect = &cstate->src_rect; 4326 struct display_rect *dst_rect = &cstate->crtc_rect; 4327 struct display_rect left_src, left_dst, right_src, right_dst; 4328 u16 half_hdisplay = mode->crtc_hdisplay >> 1; 4329 int left_src_w, left_dst_w, right_dst_w; 4330 4331 left_dst_w = min_t(u16, half_hdisplay, dst_rect->x + dst_rect->w) - dst_rect->x; 4332 if (left_dst_w < 0) 4333 left_dst_w = 0; 4334 right_dst_w = dst_rect->w - left_dst_w; 4335 4336 if (!right_dst_w) 4337 left_src_w = src_rect->w; 4338 else 4339 left_src_w = src_rect->x + src_rect->w - src_rect->w / 2; 4340 4341 left_src.x = src_rect->x; 4342 left_src.w = left_src_w; 4343 left_dst.x = dst_rect->x; 4344 left_dst.w = left_dst_w; 4345 right_src.x = left_src.x + left_src.w; 4346 right_src.w = src_rect->x + src_rect->w - left_src.x - left_src.w; 4347 right_dst.x = dst_rect->x + left_dst_w - half_hdisplay; 4348 right_dst.w = right_dst_w; 4349 4350 left_src.y = src_rect->y; 4351 left_src.h = src_rect->h; 4352 left_dst.y = dst_rect->y; 4353 left_dst.h = dst_rect->h; 4354 right_src.y = src_rect->y; 4355 right_src.h = src_rect->h; 4356 right_dst.y = dst_rect->y; 4357 right_dst.h = dst_rect->h; 4358 4359 memcpy(&cstate->src_rect, &left_src, sizeof(struct display_rect)); 4360 memcpy(&cstate->crtc_rect, &left_dst, sizeof(struct display_rect)); 4361 memcpy(&cstate->right_src_rect, &right_src, sizeof(struct display_rect)); 4362 memcpy(&cstate->right_crtc_rect, &right_dst, sizeof(struct display_rect)); 4363 } 4364 4365 static int rockchip_vop2_set_plane(struct display_state *state) 4366 { 4367 struct crtc_state *cstate = &state->crtc_state; 4368 struct vop2 *vop2 = cstate->private; 4369 struct vop2_win_data *win_data; 4370 struct vop2_win_data *splice_win_data; 4371 u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id; 4372 char plane_name[10] = {0}; 4373 4374 if (cstate->crtc_rect.w > cstate->max_output.width) { 4375 printf("ERROR: output w[%d] exceeded max width[%d]\n", 4376 cstate->crtc_rect.w, cstate->max_output.width); 4377 return -EINVAL; 4378 } 4379 4380 win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id); 4381 if (!win_data) { 4382 printf("invalid win id %d\n", primary_plane_id); 4383 return -ENODEV; 4384 } 4385 4386 /* ignore some plane register according vop3 esmart lb mode */ 4387 if (vop3_ignore_plane(vop2, win_data)) 4388 return -EACCES; 4389 4390 if (vop2->version == VOP_VERSION_RK3588) { 4391 if (vop2_power_domain_on(vop2, win_data->pd_id)) 4392 printf("open vp%d plane pd fail\n", cstate->crtc_id); 4393 } 4394 4395 if (cstate->splice_mode) { 4396 if (win_data->splice_win_id) { 4397 splice_win_data = vop2_find_win_by_phys_id(vop2, win_data->splice_win_id); 4398 splice_win_data->splice_mode_right = true; 4399 4400 if (vop2_power_domain_on(vop2, splice_win_data->pd_id)) 4401 printf("splice mode: open vp%d plane pd fail\n", cstate->splice_crtc_id); 4402 4403 vop2_calc_display_rect_for_splice(state); 4404 if (win_data->type == CLUSTER_LAYER) 4405 vop2_set_cluster_win(state, splice_win_data); 4406 else 4407 vop2_set_smart_win(state, splice_win_data); 4408 } else { 4409 printf("ERROR: splice mode is unsupported by plane %s\n", 4410 get_plane_name(primary_plane_id, plane_name)); 4411 return -EINVAL; 4412 } 4413 } 4414 4415 if (win_data->type == CLUSTER_LAYER) 4416 vop2_set_cluster_win(state, win_data); 4417 else 4418 vop2_set_smart_win(state, win_data); 4419 4420 printf("VOP VP%d enable %s[%dx%d->%dx%d@%dx%d] fmt[%d] addr[0x%x]\n", 4421 cstate->crtc_id, get_plane_name(primary_plane_id, plane_name), 4422 cstate->src_rect.w, cstate->src_rect.h, cstate->crtc_rect.w, cstate->crtc_rect.h, 4423 cstate->crtc_rect.x, cstate->crtc_rect.y, cstate->format, 4424 cstate->dma_addr); 4425 4426 return 0; 4427 } 4428 4429 static int rockchip_vop2_prepare(struct display_state *state) 4430 { 4431 return 0; 4432 } 4433 4434 static void vop2_dsc_cfg_done(struct display_state *state) 4435 { 4436 struct connector_state *conn_state = &state->conn_state; 4437 struct crtc_state *cstate = &state->crtc_state; 4438 struct vop2 *vop2 = cstate->private; 4439 u8 dsc_id = cstate->dsc_id; 4440 u32 ctrl_regs_offset = (dsc_id * 0x30); 4441 4442 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 4443 vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE, EN_MASK, 4444 DSC_CFG_DONE_SHIFT, 1, false); 4445 vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE + 0x30, EN_MASK, 4446 DSC_CFG_DONE_SHIFT, 1, false); 4447 } else { 4448 vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE + ctrl_regs_offset, EN_MASK, 4449 DSC_CFG_DONE_SHIFT, 1, false); 4450 } 4451 } 4452 4453 static int rockchip_vop2_enable(struct display_state *state) 4454 { 4455 struct crtc_state *cstate = &state->crtc_state; 4456 struct vop2 *vop2 = cstate->private; 4457 u32 vp_offset = (cstate->crtc_id * 0x100); 4458 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 4459 4460 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4461 STANDBY_EN_SHIFT, 0, false); 4462 4463 if (cstate->splice_mode) 4464 cfg_done |= BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 4465 4466 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 4467 4468 if (cstate->dsc_enable) 4469 vop2_dsc_cfg_done(state); 4470 4471 if (cstate->mcu_timing.mcu_pix_total) 4472 vop2_mask_write(vop2, RK3562_VP0_MCU_CTRL + vp_offset, EN_MASK, 4473 MCU_HOLD_MODE_SHIFT, 0, false); 4474 4475 return 0; 4476 } 4477 4478 static int rockchip_vop2_disable(struct display_state *state) 4479 { 4480 struct crtc_state *cstate = &state->crtc_state; 4481 struct vop2 *vop2 = cstate->private; 4482 u32 vp_offset = (cstate->crtc_id * 0x100); 4483 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 4484 4485 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 4486 STANDBY_EN_SHIFT, 1, false); 4487 4488 if (cstate->splice_mode) 4489 cfg_done |= BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 4490 4491 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 4492 4493 return 0; 4494 } 4495 4496 static int rockchip_vop2_get_cursor_plane(struct display_state *state, u32 plane_mask, int cursor_plane) 4497 { 4498 struct crtc_state *cstate = &state->crtc_state; 4499 struct vop2 *vop2 = cstate->private; 4500 int i = 0; 4501 int correct_cursor_plane = -1; 4502 int plane_type = -1; 4503 4504 if (cursor_plane < 0) 4505 return -1; 4506 4507 if (plane_mask & (1 << cursor_plane)) 4508 return cursor_plane; 4509 4510 /* Get current cursor plane type */ 4511 for (i = 0; i < vop2->data->nr_layers; i++) { 4512 if (vop2->data->plane_table[i].plane_id == cursor_plane) { 4513 plane_type = vop2->data->plane_table[i].plane_type; 4514 break; 4515 } 4516 } 4517 4518 /* Get the other same plane type plane id */ 4519 for (i = 0; i < vop2->data->nr_layers; i++) { 4520 if (vop2->data->plane_table[i].plane_type == plane_type && 4521 vop2->data->plane_table[i].plane_id != cursor_plane) { 4522 correct_cursor_plane = vop2->data->plane_table[i].plane_id; 4523 break; 4524 } 4525 } 4526 4527 /* To check whether the new correct_cursor_plane is attach to current vp */ 4528 if (correct_cursor_plane < 0 || !(plane_mask & (1 << correct_cursor_plane))) { 4529 printf("error: faild to find correct plane as cursor plane\n"); 4530 return -1; 4531 } 4532 4533 printf("vp%d adjust cursor plane from %d to %d\n", 4534 cstate->crtc_id, cursor_plane, correct_cursor_plane); 4535 4536 return correct_cursor_plane; 4537 } 4538 4539 static int rockchip_vop2_fixup_dts(struct display_state *state, void *blob) 4540 { 4541 struct crtc_state *cstate = &state->crtc_state; 4542 struct vop2 *vop2 = cstate->private; 4543 ofnode vp_node; 4544 struct device_node *port_parent_node = cstate->ports_node; 4545 static bool vop_fix_dts; 4546 const char *path; 4547 u32 plane_mask = 0; 4548 int vp_id = 0; 4549 int cursor_plane_id = -1; 4550 4551 if (vop_fix_dts || vop2->version == VOP_VERSION_RK3528) 4552 return 0; 4553 4554 ofnode_for_each_subnode(vp_node, np_to_ofnode(port_parent_node)) { 4555 path = vp_node.np->full_name; 4556 plane_mask = vop2->vp_plane_mask[vp_id].plane_mask; 4557 4558 if (cstate->crtc->assign_plane) 4559 continue; 4560 cursor_plane_id = rockchip_vop2_get_cursor_plane(state, plane_mask, 4561 cstate->crtc->vps[vp_id].cursor_plane); 4562 printf("vp%d, plane_mask:0x%x, primary-id:%d, curser-id:%d\n", 4563 vp_id, plane_mask, 4564 vop2->vp_plane_mask[vp_id].primary_plane_id, 4565 cursor_plane_id); 4566 4567 do_fixup_by_path_u32(blob, path, "rockchip,plane-mask", 4568 plane_mask, 1); 4569 do_fixup_by_path_u32(blob, path, "rockchip,primary-plane", 4570 vop2->vp_plane_mask[vp_id].primary_plane_id, 1); 4571 if (cursor_plane_id >= 0) 4572 do_fixup_by_path_u32(blob, path, "cursor-win-id", 4573 cursor_plane_id, 1); 4574 vp_id++; 4575 } 4576 4577 vop_fix_dts = true; 4578 4579 return 0; 4580 } 4581 4582 static int rockchip_vop2_check(struct display_state *state) 4583 { 4584 struct crtc_state *cstate = &state->crtc_state; 4585 struct rockchip_crtc *crtc = cstate->crtc; 4586 4587 if (crtc->splice_mode && cstate->crtc_id == crtc->splice_crtc_id) { 4588 printf("WARN: VP%d is busy in splice mode\n", cstate->crtc_id); 4589 return -ENOTSUPP; 4590 } 4591 4592 if (cstate->splice_mode) { 4593 crtc->splice_mode = true; 4594 crtc->splice_crtc_id = cstate->splice_crtc_id; 4595 } 4596 4597 return 0; 4598 } 4599 4600 static int rockchip_vop2_mode_valid(struct display_state *state) 4601 { 4602 struct connector_state *conn_state = &state->conn_state; 4603 struct crtc_state *cstate = &state->crtc_state; 4604 struct drm_display_mode *mode = &conn_state->mode; 4605 struct videomode vm; 4606 4607 drm_display_mode_to_videomode(mode, &vm); 4608 4609 if (vm.hactive < 32 || vm.vactive < 32 || 4610 (vm.hfront_porch * vm.hsync_len * vm.hback_porch * 4611 vm.vfront_porch * vm.vsync_len * vm.vback_porch == 0)) { 4612 printf("ERROR: VP%d: unsupported display timing\n", cstate->crtc_id); 4613 return -EINVAL; 4614 } 4615 4616 return 0; 4617 } 4618 4619 static int rockchip_vop2_mode_fixup(struct display_state *state) 4620 { 4621 struct connector_state *conn_state = &state->conn_state; 4622 struct drm_display_mode *mode = &conn_state->mode; 4623 struct crtc_state *cstate = &state->crtc_state; 4624 struct vop2 *vop2 = cstate->private; 4625 4626 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); 4627 4628 if (mode->flags & DRM_MODE_FLAG_DBLCLK || conn_state->output_if & VOP_OUTPUT_IF_BT656) 4629 mode->crtc_clock *= 2; 4630 4631 /* 4632 * For RK3528, the path of CVBS output is like: 4633 * VOP BT656 ENCODER -> CVBS BT656 DECODER -> CVBS ENCODER -> CVBS VDAC 4634 * The vop2 dclk should be four times crtc_clock for CVBS sampling 4635 * clock needs. 4636 */ 4637 if (vop2->version == VOP_VERSION_RK3528 && conn_state->output_if & VOP_OUTPUT_IF_BT656) 4638 mode->crtc_clock *= 4; 4639 4640 if (cstate->mcu_timing.mcu_pix_total) { 4641 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_S888) 4642 /* 4643 * For serial output_mode rgb3x8, one pixel need 3 cycles. 4644 * So dclk should be three times mode clock. 4645 */ 4646 mode->crtc_clock *= 3; 4647 else if (conn_state->output_mode == ROCKCHIP_OUT_MODE_S888_DUMMY) 4648 /* 4649 * For serial output_mode argb4x8, one pixel need 4 cycles. 4650 * So dclk should be four times mode clock. 4651 */ 4652 mode->crtc_clock *= 4; 4653 } 4654 4655 if (conn_state->secondary) { 4656 mode->crtc_clock *= 2; 4657 mode->crtc_hdisplay *= 2; 4658 mode->crtc_hsync_start *= 2; 4659 mode->crtc_hsync_end *= 2; 4660 mode->crtc_htotal *= 2; 4661 } 4662 4663 return 0; 4664 } 4665 4666 #define FRAC_16_16(mult, div) (((mult) << 16) / (div)) 4667 4668 static int rockchip_vop2_plane_check(struct display_state *state) 4669 { 4670 struct crtc_state *cstate = &state->crtc_state; 4671 struct vop2 *vop2 = cstate->private; 4672 struct display_rect *src = &cstate->src_rect; 4673 struct display_rect *dst = &cstate->crtc_rect; 4674 struct vop2_win_data *win_data; 4675 int min_scale, max_scale; 4676 int hscale, vscale; 4677 u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id; 4678 4679 win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id); 4680 if (!win_data) { 4681 printf("ERROR: invalid win id %d\n", primary_plane_id); 4682 return -ENODEV; 4683 } 4684 4685 min_scale = FRAC_16_16(1, win_data->max_downscale_factor); 4686 max_scale = FRAC_16_16(win_data->max_upscale_factor, 1); 4687 4688 hscale = display_rect_calc_hscale(src, dst, min_scale, max_scale); 4689 vscale = display_rect_calc_vscale(src, dst, min_scale, max_scale); 4690 if (hscale < 0 || vscale < 0) { 4691 printf("ERROR: VP%d %s: scale factor is out of range\n", cstate->crtc_id, win_data->name); 4692 return -ERANGE; 4693 } 4694 4695 return 0; 4696 } 4697 4698 static int rockchip_vop2_apply_soft_te(struct display_state *state) 4699 { 4700 __maybe_unused struct connector_state *conn_state = &state->conn_state; 4701 struct crtc_state *cstate = &state->crtc_state; 4702 struct vop2 *vop2 = cstate->private; 4703 u32 vp_offset = (cstate->crtc_id * 0x100); 4704 int val = 0; 4705 int ret = 0; 4706 4707 ret = readl_poll_timeout(vop2->regs + RK3568_VP0_MIPI_CTRL + vp_offset, val, 4708 (val >> EDPI_WMS_FS) & 0x1, 50 * 1000); 4709 if (!ret) { 4710 #ifndef CONFIG_SPL_BUILD 4711 ret = readx_poll_timeout(dm_gpio_get_value, conn_state->te_gpio, val, 4712 !val, 50 * 1000); 4713 if (!ret) { 4714 ret = readx_poll_timeout(dm_gpio_get_value, conn_state->te_gpio, val, 4715 val, 50 * 1000); 4716 if (!ret) { 4717 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 4718 EN_MASK, EDPI_WMS_FS, 1, false); 4719 } else { 4720 printf("ERROR: vp%d wait for active TE signal timeout\n", 4721 cstate->crtc_id); 4722 return ret; 4723 } 4724 } else { 4725 printf("ERROR: vp%d TE signal maybe always high\n", cstate->crtc_id); 4726 return ret; 4727 } 4728 #endif 4729 } else { 4730 printf("ERROR: vp%d wait vop2 frame start timeout in hold mode\n", cstate->crtc_id); 4731 return ret; 4732 } 4733 4734 return 0; 4735 } 4736 4737 static int rockchip_vop2_regs_dump(struct display_state *state) 4738 { 4739 struct crtc_state *cstate = &state->crtc_state; 4740 struct vop2 *vop2 = cstate->private; 4741 const struct vop2_data *vop2_data = vop2->data; 4742 const struct vop2_dump_regs *regs = vop2_data->dump_regs; 4743 u32 n, i, j; 4744 u32 base; 4745 4746 if (!cstate->crtc->active) 4747 return -EINVAL; 4748 4749 n = vop2_data->dump_regs_size; 4750 for (i = 0; i < n; i++) { 4751 base = regs[i].offset; 4752 printf("\n%s:\n", regs[i].name); 4753 for (j = 0; j < 68;) { 4754 printf("%08lx: %08x %08x %08x %08x\n", (uintptr_t)vop2->regs + base + j * 4, 4755 vop2_readl(vop2, base + (4 * j)), 4756 vop2_readl(vop2, base + (4 * (j + 1))), 4757 vop2_readl(vop2, base + (4 * (j + 2))), 4758 vop2_readl(vop2, base + (4 * (j + 3)))); 4759 j += 4; 4760 } 4761 } 4762 4763 return 0; 4764 } 4765 4766 static int rockchip_vop2_active_regs_dump(struct display_state *state) 4767 { 4768 struct crtc_state *cstate = &state->crtc_state; 4769 struct vop2 *vop2 = cstate->private; 4770 const struct vop2_data *vop2_data = vop2->data; 4771 const struct vop2_dump_regs *regs = vop2_data->dump_regs; 4772 u32 n, i, j; 4773 u32 base; 4774 bool enable_state; 4775 4776 if (!cstate->crtc->active) 4777 return -EINVAL; 4778 4779 n = vop2_data->dump_regs_size; 4780 for (i = 0; i < n; i++) { 4781 if (regs[i].state_mask) { 4782 enable_state = (vop2_readl(vop2, regs[i].state_base) >> regs[i].state_shift) & 4783 regs[i].state_mask; 4784 if (enable_state != regs[i].enable_state) 4785 continue; 4786 } 4787 4788 base = regs[i].offset; 4789 printf("\n%s:\n", regs[i].name); 4790 for (j = 0; j < 68;) { 4791 printf("%08lx: %08x %08x %08x %08x\n", (uintptr_t)vop2->regs + base + j * 4, 4792 vop2_readl(vop2, base + (4 * j)), 4793 vop2_readl(vop2, base + (4 * (j + 1))), 4794 vop2_readl(vop2, base + (4 * (j + 2))), 4795 vop2_readl(vop2, base + (4 * (j + 3)))); 4796 j += 4; 4797 } 4798 } 4799 4800 return 0; 4801 } 4802 4803 static struct vop2_dump_regs rk3528_dump_regs[] = { 4804 { RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 }, 4805 { RK3528_OVL_SYS, "OVL_SYS", 0, 0, 0, 0 }, 4806 { RK3528_OVL_PORT0_CTRL, "OVL_VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 }, 4807 { RK3528_OVL_PORT1_CTRL, "OVL_VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 }, 4808 { RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 }, 4809 { RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 }, 4810 { RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0, 1 }, 4811 { RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 }, 4812 { RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 }, 4813 { RK3568_SMART0_CTRL0, "Esmart2", RK3568_SMART0_CTRL0, 0x1, 0, 1 }, 4814 { RK3568_SMART1_CTRL0, "Esmart3", RK3568_SMART1_CTRL0, 0x1, 0, 1 }, 4815 { RK3528_HDR_LUT_CTRL, "HDR", 0, 0, 0, 0 }, 4816 { RK3528_ACM_CTRL, "ACM", RK3528_ACM_CTRL, 0x1, 0, 1}, 4817 }; 4818 4819 static u8 rk3528_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = { 4820 ROCKCHIP_VOP2_ESMART0, 4821 ROCKCHIP_VOP2_ESMART1, 4822 ROCKCHIP_VOP2_ESMART2, 4823 ROCKCHIP_VOP2_ESMART3, 4824 }; 4825 4826 static struct vop2_plane_table rk3528_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 4827 {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER}, 4828 {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 4829 {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 4830 {ROCKCHIP_VOP2_ESMART2, ESMART_LAYER}, 4831 {ROCKCHIP_VOP2_ESMART3, ESMART_LAYER}, 4832 }; 4833 4834 static struct vop2_vp_plane_mask rk3528_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 4835 { /* one display policy for hdmi */ 4836 {/* main display */ 4837 .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 4838 .attached_layers_nr = 4, 4839 .attached_layers = { 4840 ROCKCHIP_VOP2_CLUSTER0, 4841 ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_ESMART2 4842 }, 4843 }, 4844 {/* second display */}, 4845 {/* third display */}, 4846 {/* fourth display */}, 4847 }, 4848 4849 { /* two display policy */ 4850 {/* main display */ 4851 .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 4852 .attached_layers_nr = 3, 4853 .attached_layers = { 4854 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1 4855 }, 4856 }, 4857 4858 {/* second display */ 4859 .primary_plane_id = ROCKCHIP_VOP2_ESMART3, 4860 .attached_layers_nr = 2, 4861 .attached_layers = { 4862 ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 4863 }, 4864 }, 4865 {/* third display */}, 4866 {/* fourth display */}, 4867 }, 4868 4869 { /* one display policy for cvbs */ 4870 {/* main display */ 4871 .primary_plane_id = ROCKCHIP_VOP2_ESMART3, 4872 .attached_layers_nr = 2, 4873 .attached_layers = { 4874 ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 4875 }, 4876 }, 4877 {/* second display */}, 4878 {/* third display */}, 4879 {/* fourth display */}, 4880 }, 4881 4882 {/* reserved */}, 4883 }; 4884 4885 static struct vop2_win_data rk3528_win_data[5] = { 4886 { 4887 .name = "Esmart0", 4888 .phys_id = ROCKCHIP_VOP2_ESMART0, 4889 .type = ESMART_LAYER, 4890 .win_sel_port_offset = 8, 4891 .layer_sel_win_id = { 1, 0xff, 0xff, 0xff }, 4892 .reg_offset = 0, 4893 .axi_id = 0, 4894 .axi_yrgb_id = 0x06, 4895 .axi_uv_id = 0x07, 4896 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 4897 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 4898 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 4899 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 4900 .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 4901 .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */ 4902 .max_upscale_factor = 8, 4903 .max_downscale_factor = 8, 4904 }, 4905 4906 { 4907 .name = "Esmart1", 4908 .phys_id = ROCKCHIP_VOP2_ESMART1, 4909 .type = ESMART_LAYER, 4910 .win_sel_port_offset = 10, 4911 .layer_sel_win_id = { 2, 0xff, 0xff, 0xff }, 4912 .reg_offset = 0x200, 4913 .axi_id = 0, 4914 .axi_yrgb_id = 0x08, 4915 .axi_uv_id = 0x09, 4916 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 4917 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 4918 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 4919 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 4920 .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 4921 .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */ 4922 .max_upscale_factor = 8, 4923 .max_downscale_factor = 8, 4924 }, 4925 4926 { 4927 .name = "Esmart2", 4928 .phys_id = ROCKCHIP_VOP2_ESMART2, 4929 .type = ESMART_LAYER, 4930 .win_sel_port_offset = 12, 4931 .layer_sel_win_id = { 3, 0, 0xff, 0xff }, 4932 .reg_offset = 0x400, 4933 .axi_id = 0, 4934 .axi_yrgb_id = 0x0a, 4935 .axi_uv_id = 0x0b, 4936 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 4937 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 4938 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 4939 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 4940 .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 4941 .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */ 4942 .max_upscale_factor = 8, 4943 .max_downscale_factor = 8, 4944 }, 4945 4946 { 4947 .name = "Esmart3", 4948 .phys_id = ROCKCHIP_VOP2_ESMART3, 4949 .type = ESMART_LAYER, 4950 .win_sel_port_offset = 14, 4951 .layer_sel_win_id = { 0xff, 1, 0xff, 0xff }, 4952 .reg_offset = 0x600, 4953 .axi_id = 0, 4954 .axi_yrgb_id = 0x0c, 4955 .axi_uv_id = 0x0d, 4956 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 4957 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 4958 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 4959 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 4960 .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 4961 .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_GT, /* gt only */ 4962 .max_upscale_factor = 8, 4963 .max_downscale_factor = 8, 4964 }, 4965 4966 { 4967 .name = "Cluster0", 4968 .phys_id = ROCKCHIP_VOP2_CLUSTER0, 4969 .type = CLUSTER_LAYER, 4970 .win_sel_port_offset = 0, 4971 .layer_sel_win_id = { 0, 0xff, 0xff, 0xff }, 4972 .reg_offset = 0, 4973 .axi_id = 0, 4974 .axi_yrgb_id = 0x02, 4975 .axi_uv_id = 0x03, 4976 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 4977 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 4978 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 4979 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 4980 .hsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 4981 .vsd_pre_filter_mode = VOP3_PRE_SCALE_DOWN_AVG, /* gt or avg */ 4982 .max_upscale_factor = 8, 4983 .max_downscale_factor = 8, 4984 }, 4985 }; 4986 4987 static struct vop2_vp_data rk3528_vp_data[2] = { 4988 { 4989 .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN | VOP_FEATURE_POST_ACM | 4990 VOP_FEATURE_POST_CSC, 4991 .max_output = {4096, 4096}, 4992 .layer_mix_dly = 6, 4993 .hdr_mix_dly = 2, 4994 .win_dly = 8, 4995 }, 4996 { 4997 .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN, 4998 .max_output = {1920, 1080}, 4999 .layer_mix_dly = 2, 5000 .hdr_mix_dly = 0, 5001 .win_dly = 8, 5002 }, 5003 }; 5004 5005 const struct vop2_data rk3528_vop = { 5006 .version = VOP_VERSION_RK3528, 5007 .nr_vps = 2, 5008 .vp_data = rk3528_vp_data, 5009 .win_data = rk3528_win_data, 5010 .plane_mask = rk3528_vp_plane_mask[0], 5011 .plane_table = rk3528_plane_table, 5012 .vp_primary_plane_order = rk3528_vp_primary_plane_order, 5013 .nr_layers = 5, 5014 .nr_mixers = 3, 5015 .nr_gammas = 2, 5016 .esmart_lb_mode = VOP3_ESMART_4K_2K_2K_MODE, 5017 .dump_regs = rk3528_dump_regs, 5018 .dump_regs_size = ARRAY_SIZE(rk3528_dump_regs), 5019 }; 5020 5021 static struct vop2_dump_regs rk3562_dump_regs[] = { 5022 { RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 }, 5023 { RK3528_OVL_SYS, "OVL_SYS", 0, 0, 0, 0 }, 5024 { RK3528_OVL_PORT0_CTRL, "OVL_VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 }, 5025 { RK3528_OVL_PORT1_CTRL, "OVL_VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 }, 5026 { RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 }, 5027 { RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 }, 5028 { RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 }, 5029 { RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 }, 5030 { RK3568_SMART0_CTRL0, "Esmart2", RK3568_SMART0_CTRL0, 0x1, 0, 1 }, 5031 { RK3568_SMART1_CTRL0, "Esmart3", RK3568_SMART1_CTRL0, 0x1, 0, 1 }, 5032 }; 5033 5034 static u8 rk3562_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = { 5035 ROCKCHIP_VOP2_ESMART0, 5036 ROCKCHIP_VOP2_ESMART1, 5037 ROCKCHIP_VOP2_ESMART2, 5038 ROCKCHIP_VOP2_ESMART3, 5039 }; 5040 5041 static struct vop2_plane_table rk3562_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 5042 {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 5043 {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 5044 {ROCKCHIP_VOP2_ESMART2, ESMART_LAYER}, 5045 {ROCKCHIP_VOP2_ESMART3, ESMART_LAYER}, 5046 }; 5047 5048 static struct vop2_vp_plane_mask rk3562_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 5049 { /* one display policy for hdmi */ 5050 {/* main display */ 5051 .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 5052 .attached_layers_nr = 4, 5053 .attached_layers = { 5054 ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1, 5055 ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 5056 }, 5057 }, 5058 {/* second display */}, 5059 {/* third display */}, 5060 {/* fourth display */}, 5061 }, 5062 5063 { /* two display policy */ 5064 {/* main display */ 5065 .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 5066 .attached_layers_nr = 2, 5067 .attached_layers = { 5068 ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART1 5069 }, 5070 }, 5071 5072 {/* second display */ 5073 .primary_plane_id = ROCKCHIP_VOP2_ESMART2, 5074 .attached_layers_nr = 2, 5075 .attached_layers = { 5076 ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 5077 }, 5078 }, 5079 {/* third display */}, 5080 {/* fourth display */}, 5081 }, 5082 5083 {/* reserved */}, 5084 }; 5085 5086 static struct vop2_win_data rk3562_win_data[4] = { 5087 { 5088 .name = "Esmart0", 5089 .phys_id = ROCKCHIP_VOP2_ESMART0, 5090 .type = ESMART_LAYER, 5091 .win_sel_port_offset = 8, 5092 .layer_sel_win_id = { 0, 0, 0xff, 0xff }, 5093 .reg_offset = 0, 5094 .axi_id = 0, 5095 .axi_yrgb_id = 0x02, 5096 .axi_uv_id = 0x03, 5097 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5098 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5099 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5100 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5101 .max_upscale_factor = 8, 5102 .max_downscale_factor = 8, 5103 }, 5104 5105 { 5106 .name = "Esmart1", 5107 .phys_id = ROCKCHIP_VOP2_ESMART1, 5108 .type = ESMART_LAYER, 5109 .win_sel_port_offset = 10, 5110 .layer_sel_win_id = { 1, 1, 0xff, 0xff }, 5111 .reg_offset = 0x200, 5112 .axi_id = 0, 5113 .axi_yrgb_id = 0x04, 5114 .axi_uv_id = 0x05, 5115 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5116 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5117 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5118 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5119 .max_upscale_factor = 8, 5120 .max_downscale_factor = 8, 5121 }, 5122 5123 { 5124 .name = "Esmart2", 5125 .phys_id = ROCKCHIP_VOP2_ESMART2, 5126 .type = ESMART_LAYER, 5127 .win_sel_port_offset = 12, 5128 .layer_sel_win_id = { 2, 2, 0xff, 0xff }, 5129 .reg_offset = 0x400, 5130 .axi_id = 0, 5131 .axi_yrgb_id = 0x06, 5132 .axi_uv_id = 0x07, 5133 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5134 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5135 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5136 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5137 .max_upscale_factor = 8, 5138 .max_downscale_factor = 8, 5139 }, 5140 5141 { 5142 .name = "Esmart3", 5143 .phys_id = ROCKCHIP_VOP2_ESMART3, 5144 .type = ESMART_LAYER, 5145 .win_sel_port_offset = 14, 5146 .layer_sel_win_id = { 3, 3, 0xff, 0xff }, 5147 .reg_offset = 0x600, 5148 .axi_id = 0, 5149 .axi_yrgb_id = 0x08, 5150 .axi_uv_id = 0x0d, 5151 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5152 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5153 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5154 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5155 .max_upscale_factor = 8, 5156 .max_downscale_factor = 8, 5157 }, 5158 }; 5159 5160 static struct vop2_vp_data rk3562_vp_data[2] = { 5161 { 5162 .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN, 5163 .max_output = {2048, 4096}, 5164 .win_dly = 8, 5165 .layer_mix_dly = 8, 5166 }, 5167 { 5168 .feature = VOP_FEATURE_ALPHA_SCALE | VOP_FEATURE_OVERSCAN, 5169 .max_output = {2048, 1080}, 5170 .win_dly = 8, 5171 .layer_mix_dly = 8, 5172 }, 5173 }; 5174 5175 const struct vop2_data rk3562_vop = { 5176 .version = VOP_VERSION_RK3562, 5177 .nr_vps = 2, 5178 .vp_data = rk3562_vp_data, 5179 .win_data = rk3562_win_data, 5180 .plane_mask = rk3562_vp_plane_mask[0], 5181 .plane_table = rk3562_plane_table, 5182 .vp_primary_plane_order = rk3562_vp_primary_plane_order, 5183 .nr_layers = 4, 5184 .nr_mixers = 3, 5185 .nr_gammas = 2, 5186 .esmart_lb_mode = VOP3_ESMART_2K_2K_2K_2K_MODE, 5187 .dump_regs = rk3562_dump_regs, 5188 .dump_regs_size = ARRAY_SIZE(rk3562_dump_regs), 5189 }; 5190 5191 static struct vop2_dump_regs rk3568_dump_regs[] = { 5192 { RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 }, 5193 { RK3568_OVL_CTRL, "OVL", 0, 0, 0, 0 }, 5194 { RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 }, 5195 { RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 }, 5196 { RK3568_VP2_DSP_CTRL, "VP2", RK3568_VP2_DSP_CTRL, 0x1, 31, 0 }, 5197 { RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0, 1 }, 5198 { RK3568_CLUSTER1_WIN0_CTRL0, "Cluster1", RK3568_CLUSTER1_WIN0_CTRL0, 0x1, 0, 1 }, 5199 { RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 }, 5200 { RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 }, 5201 { RK3568_SMART0_CTRL0, "Smart0", RK3568_SMART0_REGION0_CTRL, 0x1, 0, 1 }, 5202 { RK3568_SMART1_CTRL0, "Smart1", RK3568_SMART1_REGION0_CTRL, 0x1, 0, 1 }, 5203 { RK3568_HDR_LUT_CTRL, "HDR", 0, 0, 0, 0 }, 5204 }; 5205 5206 static u8 rk3568_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = { 5207 ROCKCHIP_VOP2_SMART0, 5208 ROCKCHIP_VOP2_SMART1, 5209 ROCKCHIP_VOP2_ESMART0, 5210 ROCKCHIP_VOP2_ESMART1, 5211 }; 5212 5213 static struct vop2_plane_table rk356x_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 5214 {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER}, 5215 {ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER}, 5216 {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 5217 {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 5218 {ROCKCHIP_VOP2_SMART0, SMART_LAYER}, 5219 {ROCKCHIP_VOP2_SMART0, SMART_LAYER}, 5220 }; 5221 5222 static struct vop2_vp_plane_mask rk356x_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 5223 { /* one display policy */ 5224 {/* main display */ 5225 .primary_plane_id = ROCKCHIP_VOP2_SMART0, 5226 .attached_layers_nr = 6, 5227 .attached_layers = { 5228 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0, 5229 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1 5230 }, 5231 }, 5232 {/* second display */}, 5233 {/* third display */}, 5234 {/* fourth display */}, 5235 }, 5236 5237 { /* two display policy */ 5238 {/* main display */ 5239 .primary_plane_id = ROCKCHIP_VOP2_SMART0, 5240 .attached_layers_nr = 3, 5241 .attached_layers = { 5242 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0 5243 }, 5244 }, 5245 5246 {/* second display */ 5247 .primary_plane_id = ROCKCHIP_VOP2_SMART1, 5248 .attached_layers_nr = 3, 5249 .attached_layers = { 5250 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1 5251 }, 5252 }, 5253 {/* third display */}, 5254 {/* fourth display */}, 5255 }, 5256 5257 { /* three display policy */ 5258 {/* main display */ 5259 .primary_plane_id = ROCKCHIP_VOP2_SMART0, 5260 .attached_layers_nr = 3, 5261 .attached_layers = { 5262 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0 5263 }, 5264 }, 5265 5266 {/* second display */ 5267 .primary_plane_id = ROCKCHIP_VOP2_SMART1, 5268 .attached_layers_nr = 2, 5269 .attached_layers = { 5270 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_SMART1 5271 }, 5272 }, 5273 5274 {/* third display */ 5275 .primary_plane_id = ROCKCHIP_VOP2_ESMART1, 5276 .attached_layers_nr = 1, 5277 .attached_layers = { ROCKCHIP_VOP2_ESMART1 }, 5278 }, 5279 5280 {/* fourth display */}, 5281 }, 5282 5283 {/* reserved for four display policy */}, 5284 }; 5285 5286 static struct vop2_win_data rk3568_win_data[6] = { 5287 { 5288 .name = "Cluster0", 5289 .phys_id = ROCKCHIP_VOP2_CLUSTER0, 5290 .type = CLUSTER_LAYER, 5291 .win_sel_port_offset = 0, 5292 .layer_sel_win_id = { 0, 0, 0, 0xff }, 5293 .reg_offset = 0, 5294 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5295 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5296 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5297 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5298 .max_upscale_factor = 4, 5299 .max_downscale_factor = 4, 5300 }, 5301 5302 { 5303 .name = "Cluster1", 5304 .phys_id = ROCKCHIP_VOP2_CLUSTER1, 5305 .type = CLUSTER_LAYER, 5306 .win_sel_port_offset = 1, 5307 .layer_sel_win_id = { 1, 1, 1, 0xff }, 5308 .reg_offset = 0x200, 5309 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5310 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5311 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5312 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5313 .max_upscale_factor = 4, 5314 .max_downscale_factor = 4, 5315 }, 5316 5317 { 5318 .name = "Esmart0", 5319 .phys_id = ROCKCHIP_VOP2_ESMART0, 5320 .type = ESMART_LAYER, 5321 .win_sel_port_offset = 4, 5322 .layer_sel_win_id = { 2, 2, 2, 0xff }, 5323 .reg_offset = 0, 5324 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5325 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5326 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5327 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5328 .max_upscale_factor = 8, 5329 .max_downscale_factor = 8, 5330 }, 5331 5332 { 5333 .name = "Esmart1", 5334 .phys_id = ROCKCHIP_VOP2_ESMART1, 5335 .type = ESMART_LAYER, 5336 .win_sel_port_offset = 5, 5337 .layer_sel_win_id = { 6, 6, 6, 0xff }, 5338 .reg_offset = 0x200, 5339 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5340 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5341 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5342 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5343 .max_upscale_factor = 8, 5344 .max_downscale_factor = 8, 5345 }, 5346 5347 { 5348 .name = "Smart0", 5349 .phys_id = ROCKCHIP_VOP2_SMART0, 5350 .type = SMART_LAYER, 5351 .win_sel_port_offset = 6, 5352 .layer_sel_win_id = { 3, 3, 3, 0xff }, 5353 .reg_offset = 0x400, 5354 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5355 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5356 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5357 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5358 .max_upscale_factor = 8, 5359 .max_downscale_factor = 8, 5360 }, 5361 5362 { 5363 .name = "Smart1", 5364 .phys_id = ROCKCHIP_VOP2_SMART1, 5365 .type = SMART_LAYER, 5366 .win_sel_port_offset = 7, 5367 .layer_sel_win_id = { 7, 7, 7, 0xff }, 5368 .reg_offset = 0x600, 5369 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5370 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5371 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5372 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5373 .max_upscale_factor = 8, 5374 .max_downscale_factor = 8, 5375 }, 5376 }; 5377 5378 static struct vop2_vp_data rk3568_vp_data[3] = { 5379 { 5380 .feature = VOP_FEATURE_OUTPUT_10BIT, 5381 .pre_scan_max_dly = 42, 5382 .max_output = {4096, 2304}, 5383 }, 5384 { 5385 .feature = 0, 5386 .pre_scan_max_dly = 40, 5387 .max_output = {2048, 1536}, 5388 }, 5389 { 5390 .feature = 0, 5391 .pre_scan_max_dly = 40, 5392 .max_output = {1920, 1080}, 5393 }, 5394 }; 5395 5396 const struct vop2_data rk3568_vop = { 5397 .version = VOP_VERSION_RK3568, 5398 .nr_vps = 3, 5399 .vp_data = rk3568_vp_data, 5400 .win_data = rk3568_win_data, 5401 .plane_mask = rk356x_vp_plane_mask[0], 5402 .plane_table = rk356x_plane_table, 5403 .vp_primary_plane_order = rk3568_vp_primary_plane_order, 5404 .nr_layers = 6, 5405 .nr_mixers = 5, 5406 .nr_gammas = 1, 5407 .dump_regs = rk3568_dump_regs, 5408 .dump_regs_size = ARRAY_SIZE(rk3568_dump_regs), 5409 }; 5410 5411 static u8 rk3588_vp_primary_plane_order[ROCKCHIP_VOP2_LAYER_MAX] = { 5412 ROCKCHIP_VOP2_ESMART0, 5413 ROCKCHIP_VOP2_ESMART1, 5414 ROCKCHIP_VOP2_ESMART2, 5415 ROCKCHIP_VOP2_ESMART3, 5416 ROCKCHIP_VOP2_CLUSTER0, 5417 ROCKCHIP_VOP2_CLUSTER1, 5418 ROCKCHIP_VOP2_CLUSTER2, 5419 ROCKCHIP_VOP2_CLUSTER3, 5420 }; 5421 5422 static struct vop2_plane_table rk3588_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 5423 {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER}, 5424 {ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER}, 5425 {ROCKCHIP_VOP2_CLUSTER2, CLUSTER_LAYER}, 5426 {ROCKCHIP_VOP2_CLUSTER3, CLUSTER_LAYER}, 5427 {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 5428 {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 5429 {ROCKCHIP_VOP2_ESMART2, ESMART_LAYER}, 5430 {ROCKCHIP_VOP2_ESMART3, ESMART_LAYER}, 5431 }; 5432 5433 static struct vop2_dump_regs rk3588_dump_regs[] = { 5434 { RK3568_REG_CFG_DONE, "SYS", 0, 0, 0, 0 }, 5435 { RK3568_OVL_CTRL, "OVL", 0, 0, 0, 0 }, 5436 { RK3568_VP0_DSP_CTRL, "VP0", RK3568_VP0_DSP_CTRL, 0x1, 31, 0 }, 5437 { RK3568_VP1_DSP_CTRL, "VP1", RK3568_VP1_DSP_CTRL, 0x1, 31, 0 }, 5438 { RK3568_VP2_DSP_CTRL, "VP2", RK3568_VP2_DSP_CTRL, 0x1, 31, 0 }, 5439 { RK3588_VP3_DSP_CTRL, "VP3", RK3588_VP3_DSP_CTRL, 0x1, 31, 0 }, 5440 { RK3568_CLUSTER0_WIN0_CTRL0, "Cluster0", RK3568_CLUSTER0_WIN0_CTRL0, 0x1, 0, 1 }, 5441 { RK3568_CLUSTER1_WIN0_CTRL0, "Cluster1", RK3568_CLUSTER1_WIN0_CTRL0, 0x1, 0, 1 }, 5442 { RK3588_CLUSTER2_WIN0_CTRL0, "Cluster2", RK3588_CLUSTER2_WIN0_CTRL0, 0x1, 0, 1 }, 5443 { RK3588_CLUSTER3_WIN0_CTRL0, "Cluster3", RK3588_CLUSTER3_WIN0_CTRL0, 0x1, 0, 1 }, 5444 { RK3568_ESMART0_CTRL0, "Esmart0", RK3568_ESMART0_REGION0_CTRL, 0x1, 0, 1 }, 5445 { RK3568_ESMART1_CTRL0, "Esmart1", RK3568_ESMART1_REGION0_CTRL, 0x1, 0, 1 }, 5446 { RK3568_SMART0_CTRL0, "Esmart2", RK3568_SMART0_REGION0_CTRL, 0x1, 0, 1 }, 5447 { RK3568_SMART1_CTRL0, "Esmart3", RK3568_SMART1_REGION0_CTRL, 0x1, 0, 1 }, 5448 { RK3568_HDR_LUT_CTRL, "HDR", 0, 0, 0, 0 }, 5449 }; 5450 5451 static struct vop2_vp_plane_mask rk3588_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 5452 { /* one display policy */ 5453 {/* main display */ 5454 .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 5455 .attached_layers_nr = 8, 5456 .attached_layers = { 5457 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART2, 5458 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_ESMART3, 5459 ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3 5460 }, 5461 }, 5462 {/* second display */}, 5463 {/* third display */}, 5464 {/* fourth display */}, 5465 }, 5466 5467 { /* two display policy */ 5468 {/* main display */ 5469 .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 5470 .attached_layers_nr = 4, 5471 .attached_layers = { 5472 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, 5473 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1 5474 }, 5475 }, 5476 5477 {/* second display */ 5478 .primary_plane_id = ROCKCHIP_VOP2_ESMART2, 5479 .attached_layers_nr = 4, 5480 .attached_layers = { 5481 ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2, 5482 ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3 5483 }, 5484 }, 5485 {/* third display */}, 5486 {/* fourth display */}, 5487 }, 5488 5489 { /* three display policy */ 5490 {/* main display */ 5491 .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 5492 .attached_layers_nr = 3, 5493 .attached_layers = { 5494 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART0 5495 }, 5496 }, 5497 5498 {/* second display */ 5499 .primary_plane_id = ROCKCHIP_VOP2_ESMART1, 5500 .attached_layers_nr = 3, 5501 .attached_layers = { 5502 ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART1 5503 }, 5504 }, 5505 5506 {/* third display */ 5507 .primary_plane_id = ROCKCHIP_VOP2_ESMART2, 5508 .attached_layers_nr = 2, 5509 .attached_layers = { ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 }, 5510 }, 5511 5512 {/* fourth display */}, 5513 }, 5514 5515 { /* four display policy */ 5516 {/* main display */ 5517 .primary_plane_id = ROCKCHIP_VOP2_ESMART0, 5518 .attached_layers_nr = 2, 5519 .attached_layers = { ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0 }, 5520 }, 5521 5522 {/* second display */ 5523 .primary_plane_id = ROCKCHIP_VOP2_ESMART1, 5524 .attached_layers_nr = 2, 5525 .attached_layers = { ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1 }, 5526 }, 5527 5528 {/* third display */ 5529 .primary_plane_id = ROCKCHIP_VOP2_ESMART2, 5530 .attached_layers_nr = 2, 5531 .attached_layers = { ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2 }, 5532 }, 5533 5534 {/* fourth display */ 5535 .primary_plane_id = ROCKCHIP_VOP2_ESMART3, 5536 .attached_layers_nr = 2, 5537 .attached_layers = { ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3 }, 5538 }, 5539 }, 5540 5541 }; 5542 5543 static struct vop2_win_data rk3588_win_data[8] = { 5544 { 5545 .name = "Cluster0", 5546 .phys_id = ROCKCHIP_VOP2_CLUSTER0, 5547 .splice_win_id = ROCKCHIP_VOP2_CLUSTER1, 5548 .type = CLUSTER_LAYER, 5549 .win_sel_port_offset = 0, 5550 .layer_sel_win_id = { 0, 0, 0, 0 }, 5551 .reg_offset = 0, 5552 .axi_id = 0, 5553 .axi_yrgb_id = 2, 5554 .axi_uv_id = 3, 5555 .pd_id = VOP2_PD_CLUSTER0, 5556 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5557 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5558 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5559 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5560 .max_upscale_factor = 4, 5561 .max_downscale_factor = 4, 5562 }, 5563 5564 { 5565 .name = "Cluster1", 5566 .phys_id = ROCKCHIP_VOP2_CLUSTER1, 5567 .type = CLUSTER_LAYER, 5568 .win_sel_port_offset = 1, 5569 .layer_sel_win_id = { 1, 1, 1, 1 }, 5570 .reg_offset = 0x200, 5571 .axi_id = 0, 5572 .axi_yrgb_id = 6, 5573 .axi_uv_id = 7, 5574 .pd_id = VOP2_PD_CLUSTER1, 5575 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5576 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5577 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5578 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5579 .max_upscale_factor = 4, 5580 .max_downscale_factor = 4, 5581 }, 5582 5583 { 5584 .name = "Cluster2", 5585 .phys_id = ROCKCHIP_VOP2_CLUSTER2, 5586 .splice_win_id = ROCKCHIP_VOP2_CLUSTER3, 5587 .type = CLUSTER_LAYER, 5588 .win_sel_port_offset = 2, 5589 .layer_sel_win_id = { 4, 4, 4, 4 }, 5590 .reg_offset = 0x400, 5591 .axi_id = 1, 5592 .axi_yrgb_id = 2, 5593 .axi_uv_id = 3, 5594 .pd_id = VOP2_PD_CLUSTER2, 5595 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5596 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5597 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5598 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5599 .max_upscale_factor = 4, 5600 .max_downscale_factor = 4, 5601 }, 5602 5603 { 5604 .name = "Cluster3", 5605 .phys_id = ROCKCHIP_VOP2_CLUSTER3, 5606 .type = CLUSTER_LAYER, 5607 .win_sel_port_offset = 3, 5608 .layer_sel_win_id = { 5, 5, 5, 5 }, 5609 .reg_offset = 0x600, 5610 .axi_id = 1, 5611 .axi_yrgb_id = 6, 5612 .axi_uv_id = 7, 5613 .pd_id = VOP2_PD_CLUSTER3, 5614 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5615 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5616 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5617 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5618 .max_upscale_factor = 4, 5619 .max_downscale_factor = 4, 5620 }, 5621 5622 { 5623 .name = "Esmart0", 5624 .phys_id = ROCKCHIP_VOP2_ESMART0, 5625 .splice_win_id = ROCKCHIP_VOP2_ESMART1, 5626 .type = ESMART_LAYER, 5627 .win_sel_port_offset = 4, 5628 .layer_sel_win_id = { 2, 2, 2, 2 }, 5629 .reg_offset = 0, 5630 .axi_id = 0, 5631 .axi_yrgb_id = 0x0a, 5632 .axi_uv_id = 0x0b, 5633 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5634 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5635 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5636 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5637 .max_upscale_factor = 8, 5638 .max_downscale_factor = 8, 5639 }, 5640 5641 { 5642 .name = "Esmart1", 5643 .phys_id = ROCKCHIP_VOP2_ESMART1, 5644 .type = ESMART_LAYER, 5645 .win_sel_port_offset = 5, 5646 .layer_sel_win_id = { 3, 3, 3, 3 }, 5647 .reg_offset = 0x200, 5648 .axi_id = 0, 5649 .axi_yrgb_id = 0x0c, 5650 .axi_uv_id = 0x0d, 5651 .pd_id = VOP2_PD_ESMART, 5652 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5653 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5654 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5655 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5656 .max_upscale_factor = 8, 5657 .max_downscale_factor = 8, 5658 }, 5659 5660 { 5661 .name = "Esmart2", 5662 .phys_id = ROCKCHIP_VOP2_ESMART2, 5663 .splice_win_id = ROCKCHIP_VOP2_ESMART3, 5664 .type = ESMART_LAYER, 5665 .win_sel_port_offset = 6, 5666 .layer_sel_win_id = { 6, 6, 6, 6 }, 5667 .reg_offset = 0x400, 5668 .axi_id = 1, 5669 .axi_yrgb_id = 0x0a, 5670 .axi_uv_id = 0x0b, 5671 .pd_id = VOP2_PD_ESMART, 5672 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5673 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5674 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5675 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5676 .max_upscale_factor = 8, 5677 .max_downscale_factor = 8, 5678 }, 5679 5680 { 5681 .name = "Esmart3", 5682 .phys_id = ROCKCHIP_VOP2_ESMART3, 5683 .type = ESMART_LAYER, 5684 .win_sel_port_offset = 7, 5685 .layer_sel_win_id = { 7, 7, 7, 7 }, 5686 .reg_offset = 0x600, 5687 .axi_id = 1, 5688 .axi_yrgb_id = 0x0c, 5689 .axi_uv_id = 0x0d, 5690 .pd_id = VOP2_PD_ESMART, 5691 .hsu_filter_mode = VOP2_SCALE_UP_BIC, 5692 .hsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5693 .vsu_filter_mode = VOP2_SCALE_UP_BIL, 5694 .vsd_filter_mode = VOP2_SCALE_DOWN_BIL, 5695 .max_upscale_factor = 8, 5696 .max_downscale_factor = 8, 5697 }, 5698 }; 5699 5700 static struct dsc_error_info dsc_ecw[] = { 5701 {0x00000000, "no error detected by DSC encoder"}, 5702 {0x0030ffff, "bits per component error"}, 5703 {0x0040ffff, "multiple mode error"}, 5704 {0x0050ffff, "line buffer depth error"}, 5705 {0x0060ffff, "minor version error"}, 5706 {0x0070ffff, "picture height error"}, 5707 {0x0080ffff, "picture width error"}, 5708 {0x0090ffff, "number of slices error"}, 5709 {0x00c0ffff, "slice height Error "}, 5710 {0x00d0ffff, "slice width error"}, 5711 {0x00e0ffff, "second line BPG offset error"}, 5712 {0x00f0ffff, "non second line BPG offset error"}, 5713 {0x0100ffff, "PPS ID error"}, 5714 {0x0110ffff, "bits per pixel (BPP) Error"}, 5715 {0x0120ffff, "buffer flow error"}, /* dsc_buffer_flow */ 5716 5717 {0x01510001, "slice 0 RC buffer model overflow error"}, 5718 {0x01510002, "slice 1 RC buffer model overflow error"}, 5719 {0x01510004, "slice 2 RC buffer model overflow error"}, 5720 {0x01510008, "slice 3 RC buffer model overflow error"}, 5721 {0x01510010, "slice 4 RC buffer model overflow error"}, 5722 {0x01510020, "slice 5 RC buffer model overflow error"}, 5723 {0x01510040, "slice 6 RC buffer model overflow error"}, 5724 {0x01510080, "slice 7 RC buffer model overflow error"}, 5725 5726 {0x01610001, "slice 0 RC buffer model underflow error"}, 5727 {0x01610002, "slice 1 RC buffer model underflow error"}, 5728 {0x01610004, "slice 2 RC buffer model underflow error"}, 5729 {0x01610008, "slice 3 RC buffer model underflow error"}, 5730 {0x01610010, "slice 4 RC buffer model underflow error"}, 5731 {0x01610020, "slice 5 RC buffer model underflow error"}, 5732 {0x01610040, "slice 6 RC buffer model underflow error"}, 5733 {0x01610080, "slice 7 RC buffer model underflow error"}, 5734 5735 {0xffffffff, "unsuccessful RESET cycle status"}, 5736 {0x00a0ffff, "ICH full error precision settings error"}, 5737 {0x0020ffff, "native mode"}, 5738 }; 5739 5740 static struct dsc_error_info dsc_buffer_flow[] = { 5741 {0x00000000, "rate buffer status"}, 5742 {0x00000001, "line buffer status"}, 5743 {0x00000002, "decoder model status"}, 5744 {0x00000003, "pixel buffer status"}, 5745 {0x00000004, "balance fifo buffer status"}, 5746 {0x00000005, "syntax element fifo status"}, 5747 }; 5748 5749 static struct vop2_dsc_data rk3588_dsc_data[] = { 5750 { 5751 .id = ROCKCHIP_VOP2_DSC_8K, 5752 .pd_id = VOP2_PD_DSC_8K, 5753 .max_slice_num = 8, 5754 .max_linebuf_depth = 11, 5755 .min_bits_per_pixel = 8, 5756 .dsc_txp_clk_src_name = "dsc_8k_txp_clk_src", 5757 .dsc_txp_clk_name = "dsc_8k_txp_clk", 5758 .dsc_pxl_clk_name = "dsc_8k_pxl_clk", 5759 .dsc_cds_clk_name = "dsc_8k_cds_clk", 5760 }, 5761 5762 { 5763 .id = ROCKCHIP_VOP2_DSC_4K, 5764 .pd_id = VOP2_PD_DSC_4K, 5765 .max_slice_num = 2, 5766 .max_linebuf_depth = 11, 5767 .min_bits_per_pixel = 8, 5768 .dsc_txp_clk_src_name = "dsc_4k_txp_clk_src", 5769 .dsc_txp_clk_name = "dsc_4k_txp_clk", 5770 .dsc_pxl_clk_name = "dsc_4k_pxl_clk", 5771 .dsc_cds_clk_name = "dsc_4k_cds_clk", 5772 }, 5773 }; 5774 5775 static struct vop2_vp_data rk3588_vp_data[4] = { 5776 { 5777 .splice_vp_id = 1, 5778 .feature = VOP_FEATURE_OUTPUT_10BIT, 5779 .pre_scan_max_dly = 54, 5780 .max_dclk = 600000, 5781 .max_output = {7680, 4320}, 5782 }, 5783 { 5784 .feature = VOP_FEATURE_OUTPUT_10BIT, 5785 .pre_scan_max_dly = 54, 5786 .max_dclk = 600000, 5787 .max_output = {4096, 2304}, 5788 }, 5789 { 5790 .feature = VOP_FEATURE_OUTPUT_10BIT, 5791 .pre_scan_max_dly = 52, 5792 .max_dclk = 600000, 5793 .max_output = {4096, 2304}, 5794 }, 5795 { 5796 .feature = 0, 5797 .pre_scan_max_dly = 52, 5798 .max_dclk = 200000, 5799 .max_output = {1920, 1080}, 5800 }, 5801 }; 5802 5803 static struct vop2_power_domain_data rk3588_vop_pd_data[] = { 5804 { 5805 .id = VOP2_PD_CLUSTER0, 5806 .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER0), 5807 }, 5808 { 5809 .id = VOP2_PD_CLUSTER1, 5810 .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER1), 5811 .parent_id = VOP2_PD_CLUSTER0, 5812 }, 5813 { 5814 .id = VOP2_PD_CLUSTER2, 5815 .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER2), 5816 .parent_id = VOP2_PD_CLUSTER0, 5817 }, 5818 { 5819 .id = VOP2_PD_CLUSTER3, 5820 .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER3), 5821 .parent_id = VOP2_PD_CLUSTER0, 5822 }, 5823 { 5824 .id = VOP2_PD_ESMART, 5825 .module_id_mask = BIT(ROCKCHIP_VOP2_ESMART1) | 5826 BIT(ROCKCHIP_VOP2_ESMART2) | 5827 BIT(ROCKCHIP_VOP2_ESMART3), 5828 }, 5829 { 5830 .id = VOP2_PD_DSC_8K, 5831 .module_id_mask = BIT(ROCKCHIP_VOP2_DSC_8K), 5832 }, 5833 { 5834 .id = VOP2_PD_DSC_4K, 5835 .module_id_mask = BIT(ROCKCHIP_VOP2_DSC_4K), 5836 }, 5837 }; 5838 5839 const struct vop2_data rk3588_vop = { 5840 .version = VOP_VERSION_RK3588, 5841 .nr_vps = 4, 5842 .vp_data = rk3588_vp_data, 5843 .win_data = rk3588_win_data, 5844 .plane_mask = rk3588_vp_plane_mask[0], 5845 .plane_table = rk3588_plane_table, 5846 .pd = rk3588_vop_pd_data, 5847 .dsc = rk3588_dsc_data, 5848 .dsc_error_ecw = dsc_ecw, 5849 .dsc_error_buffer_flow = dsc_buffer_flow, 5850 .vp_primary_plane_order = rk3588_vp_primary_plane_order, 5851 .nr_layers = 8, 5852 .nr_mixers = 7, 5853 .nr_gammas = 4, 5854 .nr_pd = ARRAY_SIZE(rk3588_vop_pd_data), 5855 .nr_dscs = 2, 5856 .nr_dsc_ecw = ARRAY_SIZE(dsc_ecw), 5857 .nr_dsc_buffer_flow = ARRAY_SIZE(dsc_buffer_flow), 5858 .dump_regs = rk3588_dump_regs, 5859 .dump_regs_size = ARRAY_SIZE(rk3588_dump_regs), 5860 }; 5861 5862 const struct rockchip_crtc_funcs rockchip_vop2_funcs = { 5863 .preinit = rockchip_vop2_preinit, 5864 .prepare = rockchip_vop2_prepare, 5865 .init = rockchip_vop2_init, 5866 .set_plane = rockchip_vop2_set_plane, 5867 .enable = rockchip_vop2_enable, 5868 .disable = rockchip_vop2_disable, 5869 .fixup_dts = rockchip_vop2_fixup_dts, 5870 .send_mcu_cmd = rockchip_vop2_send_mcu_cmd, 5871 .check = rockchip_vop2_check, 5872 .mode_valid = rockchip_vop2_mode_valid, 5873 .mode_fixup = rockchip_vop2_mode_fixup, 5874 .plane_check = rockchip_vop2_plane_check, 5875 .regs_dump = rockchip_vop2_regs_dump, 5876 .active_regs_dump = rockchip_vop2_active_regs_dump, 5877 .apply_soft_te = rockchip_vop2_apply_soft_te, 5878 }; 5879