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