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 <clk.h> 21 #include <asm/arch/clock.h> 22 #include <linux/err.h> 23 #include <linux/ioport.h> 24 #include <dm/device.h> 25 #include <dm/read.h> 26 #include <fixp-arith.h> 27 #include <syscon.h> 28 #include <linux/iopoll.h> 29 30 #include "rockchip_display.h" 31 #include "rockchip_crtc.h" 32 #include "rockchip_connector.h" 33 34 /* System registers definition */ 35 #define RK3568_REG_CFG_DONE 0x000 36 #define CFG_DONE_EN BIT(15) 37 38 #define RK3568_VERSION_INFO 0x004 39 #define EN_MASK 1 40 41 #define RK3568_AUTO_GATING_CTRL 0x008 42 43 #define RK3568_SYS_AXI_LUT_CTRL 0x024 44 #define LUT_DMA_EN_SHIFT 0 45 46 #define RK3568_DSP_IF_EN 0x028 47 #define RGB_EN_SHIFT 0 48 #define RK3588_DP0_EN_SHIFT 0 49 #define RK3588_DP1_EN_SHIFT 1 50 #define RK3588_RGB_EN_SHIFT 8 51 #define HDMI0_EN_SHIFT 1 52 #define EDP0_EN_SHIFT 3 53 #define RK3588_EDP0_EN_SHIFT 2 54 #define RK3588_HDMI0_EN_SHIFT 3 55 #define MIPI0_EN_SHIFT 4 56 #define RK3588_EDP1_EN_SHIFT 4 57 #define RK3588_HDMI1_EN_SHIFT 5 58 #define RK3588_MIPI0_EN_SHIFT 6 59 #define MIPI1_EN_SHIFT 20 60 #define RK3588_MIPI1_EN_SHIFT 7 61 #define LVDS0_EN_SHIFT 5 62 #define LVDS1_EN_SHIFT 24 63 #define BT1120_EN_SHIFT 6 64 #define BT656_EN_SHIFT 7 65 #define IF_MUX_MASK 3 66 #define RGB_MUX_SHIFT 8 67 #define HDMI0_MUX_SHIFT 10 68 #define RK3588_DP0_MUX_SHIFT 12 69 #define RK3588_DP1_MUX_SHIFT 14 70 #define EDP0_MUX_SHIFT 14 71 #define RK3588_HDMI_EDP0_MUX_SHIFT 16 72 #define RK3588_HDMI_EDP1_MUX_SHIFT 18 73 #define MIPI0_MUX_SHIFT 16 74 #define RK3588_MIPI0_MUX_SHIFT 20 75 #define MIPI1_MUX_SHIFT 21 76 #define LVDS0_MUX_SHIFT 18 77 #define LVDS1_MUX_SHIFT 25 78 79 #define RK3568_DSP_IF_CTRL 0x02c 80 #define LVDS_DUAL_EN_SHIFT 0 81 #define LVDS_DUAL_LEFT_RIGHT_EN_SHIFT 1 82 #define LVDS_DUAL_SWAP_EN_SHIFT 2 83 #define RK3568_MIPI_DUAL_EN_SHIFT 10 84 #define RK3588_MIPI_DSI0_MODE_SEL_SHIFT 11 85 #define RK3588_MIPI_DSI1_MODE_SEL_SHIFT 12 86 87 #define RK3568_DSP_IF_POL 0x030 88 #define IF_CTRL_REG_DONE_IMD_MASK 1 89 #define IF_CTRL_REG_DONE_IMD_SHIFT 28 90 #define IF_CRTL_MIPI_DCLK_POL_SHIT 19 91 #define IF_CRTL_EDP_DCLK_POL_SHIT 15 92 #define IF_CRTL_HDMI_DCLK_POL_SHIT 7 93 #define IF_CRTL_HDMI_PIN_POL_MASK 0x7 94 #define IF_CRTL_HDMI_PIN_POL_SHIT 4 95 96 #define RK3588_DP0_PIN_POL_SHIFT 8 97 #define RK3588_DP1_PIN_POL_SHIFT 12 98 #define RK3588_IF_PIN_POL_MASK 0x7 99 100 #define IF_CRTL_RGB_LVDS_DCLK_POL_SHIT 3 101 102 #define HDMI_EDP0_DCLK_DIV_SHIFT 16 103 #define HDMI_EDP0_PIXCLK_DIV_SHIFT 18 104 #define HDMI_EDP1_DCLK_DIV_SHIFT 20 105 #define HDMI_EDP1_PIXCLK_DIV_SHIFT 22 106 #define MIPI0_PIXCLK_DIV_SHIFT 24 107 #define MIPI1_PIXCLK_DIV_SHIFT 26 108 109 #define RK3568_SYS_OTP_WIN_EN 0x50 110 #define OTP_WIN_EN_SHIFT 0 111 #define RK3568_SYS_LUT_PORT_SEL 0x58 112 #define GAMMA_PORT_SEL_MASK 0x3 113 #define GAMMA_PORT_SEL_SHIFT 0 114 #define PORT_MERGE_EN_SHIFT 16 115 116 #define RK3568_SYS_PD_CTRL 0x034 117 #define RK3568_VP0_LINE_FLAG 0x70 118 #define RK3568_VP1_LINE_FLAG 0x74 119 #define RK3568_VP2_LINE_FLAG 0x78 120 #define RK3568_SYS0_INT_EN 0x80 121 #define RK3568_SYS0_INT_CLR 0x84 122 #define RK3568_SYS0_INT_STATUS 0x88 123 #define RK3568_SYS1_INT_EN 0x90 124 #define RK3568_SYS1_INT_CLR 0x94 125 #define RK3568_SYS1_INT_STATUS 0x98 126 #define RK3568_VP0_INT_EN 0xA0 127 #define RK3568_VP0_INT_CLR 0xA4 128 #define RK3568_VP0_INT_STATUS 0xA8 129 #define RK3568_VP1_INT_EN 0xB0 130 #define RK3568_VP1_INT_CLR 0xB4 131 #define RK3568_VP1_INT_STATUS 0xB8 132 #define RK3568_VP2_INT_EN 0xC0 133 #define RK3568_VP2_INT_CLR 0xC4 134 #define RK3568_VP2_INT_STATUS 0xC8 135 #define RK3588_CLUSTER0_PD_EN_SHIFT 0 136 #define RK3588_CLUSTER1_PD_EN_SHIFT 1 137 #define RK3588_CLUSTER2_PD_EN_SHIFT 2 138 #define RK3588_CLUSTER3_PD_EN_SHIFT 3 139 #define RK3588_DSC_8K_PD_EN_SHIFT 5 140 #define RK3588_DSC_4K_PD_EN_SHIFT 6 141 #define RK3588_ESMART_PD_EN_SHIFT 7 142 143 #define RK3568_SYS_STATUS0 0x60 144 #define RK3588_CLUSTER0_PD_STATUS_SHIFT 8 145 #define RK3588_CLUSTER1_PD_STATUS_SHIFT 9 146 #define RK3588_CLUSTER2_PD_STATUS_SHIFT 10 147 #define RK3588_CLUSTER3_PD_STATUS_SHIFT 11 148 #define RK3588_DSC_8K_PD_STATUS_SHIFT 13 149 #define RK3588_DSC_4K_PD_STATUS_SHIFT 14 150 #define RK3588_ESMART_PD_STATUS_SHIFT 15 151 152 #define RK3568_SYS_CTRL_LINE_FLAG0 0x70 153 #define LINE_FLAG_NUM_MASK 0x1fff 154 #define RK3568_DSP_LINE_FLAG_NUM0_SHIFT 0 155 #define RK3568_DSP_LINE_FLAG_NUM1_SHIFT 16 156 157 /* DSC CTRL registers definition */ 158 #define RK3588_DSC_8K_SYS_CTRL 0x200 159 #define DSC_PORT_SEL_MASK 0x3 160 #define DSC_PORT_SEL_SHIFT 0 161 #define DSC_MAN_MODE_MASK 0x1 162 #define DSC_MAN_MODE_SHIFT 2 163 #define DSC_INTERFACE_MODE_MASK 0x3 164 #define DSC_INTERFACE_MODE_SHIFT 4 165 #define DSC_PIXEL_NUM_MASK 0x3 166 #define DSC_PIXEL_NUM_SHIFT 6 167 #define DSC_PXL_CLK_DIV_MASK 0x1 168 #define DSC_PXL_CLK_DIV_SHIFT 8 169 #define DSC_CDS_CLK_DIV_MASK 0x3 170 #define DSC_CDS_CLK_DIV_SHIFT 12 171 #define DSC_TXP_CLK_DIV_MASK 0x3 172 #define DSC_TXP_CLK_DIV_SHIFT 14 173 #define DSC_INIT_DLY_MODE_MASK 0x1 174 #define DSC_INIT_DLY_MODE_SHIFT 16 175 #define DSC_SCAN_EN_SHIFT 17 176 #define DSC_HALT_EN_SHIFT 18 177 178 #define RK3588_DSC_8K_RST 0x204 179 #define RST_DEASSERT_MASK 0x1 180 #define RST_DEASSERT_SHIFT 0 181 182 #define RK3588_DSC_8K_CFG_DONE 0x208 183 #define DSC_CFG_DONE_SHIFT 0 184 185 #define RK3588_DSC_8K_INIT_DLY 0x20C 186 #define DSC_INIT_DLY_NUM_MASK 0xffff 187 #define DSC_INIT_DLY_NUM_SHIFT 0 188 #define SCAN_TIMING_PARA_IMD_EN_SHIFT 16 189 190 #define RK3588_DSC_8K_HTOTAL_HS_END 0x210 191 #define DSC_HTOTAL_PW_MASK 0xffffffff 192 #define DSC_HTOTAL_PW_SHIFT 0 193 194 #define RK3588_DSC_8K_HACT_ST_END 0x214 195 #define DSC_HACT_ST_END_MASK 0xffffffff 196 #define DSC_HACT_ST_END_SHIFT 0 197 198 #define RK3588_DSC_8K_VTOTAL_VS_END 0x218 199 #define DSC_VTOTAL_PW_MASK 0xffffffff 200 #define DSC_VTOTAL_PW_SHIFT 0 201 202 #define RK3588_DSC_8K_VACT_ST_END 0x21C 203 #define DSC_VACT_ST_END_MASK 0xffffffff 204 #define DSC_VACT_ST_END_SHIFT 0 205 206 #define RK3588_DSC_8K_STATUS 0x220 207 208 /* Overlay registers definition */ 209 #define RK3568_OVL_CTRL 0x600 210 #define OVL_MODE_SEL_MASK 0x1 211 #define OVL_MODE_SEL_SHIFT 0 212 #define OVL_PORT_MUX_REG_DONE_IMD_SHIFT 28 213 #define RK3568_OVL_LAYER_SEL 0x604 214 #define LAYER_SEL_MASK 0xf 215 216 #define RK3568_OVL_PORT_SEL 0x608 217 #define PORT_MUX_MASK 0xf 218 #define PORT_MUX_SHIFT 0 219 #define LAYER_SEL_PORT_MASK 0x3 220 #define LAYER_SEL_PORT_SHIFT 16 221 222 #define RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL 0x610 223 #define RK3568_CLUSTER0_MIX_DST_COLOR_CTRL 0x614 224 #define RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x618 225 #define RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL 0x61C 226 #define RK3568_MIX0_SRC_COLOR_CTRL 0x650 227 #define RK3568_MIX0_DST_COLOR_CTRL 0x654 228 #define RK3568_MIX0_SRC_ALPHA_CTRL 0x658 229 #define RK3568_MIX0_DST_ALPHA_CTRL 0x65C 230 #define RK3568_HDR0_SRC_COLOR_CTRL 0x6C0 231 #define RK3568_HDR0_DST_COLOR_CTRL 0x6C4 232 #define RK3568_HDR0_SRC_ALPHA_CTRL 0x6C8 233 #define RK3568_HDR0_DST_ALPHA_CTRL 0x6CC 234 #define RK3568_VP0_BG_MIX_CTRL 0x6E0 235 #define BG_MIX_CTRL_MASK 0xff 236 #define BG_MIX_CTRL_SHIFT 24 237 #define RK3568_VP1_BG_MIX_CTRL 0x6E4 238 #define RK3568_VP2_BG_MIX_CTRL 0x6E8 239 #define RK3568_CLUSTER_DLY_NUM 0x6F0 240 #define RK3568_SMART_DLY_NUM 0x6F8 241 242 /* Video Port registers definition */ 243 #define RK3568_VP0_DSP_CTRL 0xC00 244 #define OUT_MODE_MASK 0xf 245 #define OUT_MODE_SHIFT 0 246 #define DATA_SWAP_MASK 0x1f 247 #define DATA_SWAP_SHIFT 8 248 #define DSP_BG_SWAP 0x1 249 #define DSP_RB_SWAP 0x2 250 #define DSP_RG_SWAP 0x4 251 #define DSP_DELTA_SWAP 0x8 252 #define CORE_DCLK_DIV_EN_SHIFT 4 253 #define P2I_EN_SHIFT 5 254 #define DSP_FILED_POL 6 255 #define INTERLACE_EN_SHIFT 7 256 #define POST_DSP_OUT_R2Y_SHIFT 15 257 #define PRE_DITHER_DOWN_EN_SHIFT 16 258 #define DITHER_DOWN_EN_SHIFT 17 259 #define DSP_LUT_EN_SHIFT 28 260 261 #define STANDBY_EN_SHIFT 31 262 263 #define RK3568_VP0_MIPI_CTRL 0xC04 264 #define DCLK_DIV2_SHIFT 4 265 #define DCLK_DIV2_MASK 0x3 266 #define MIPI_DUAL_EN_SHIFT 20 267 #define MIPI_DUAL_SWAP_EN_SHIFT 21 268 #define EDPI_TE_EN 28 269 #define EDPI_WMS_HOLD_EN 30 270 #define EDPI_WMS_FS 31 271 272 273 #define RK3568_VP0_COLOR_BAR_CTRL 0xC08 274 #define RK3568_VP0_3D_LUT_CTRL 0xC10 275 #define VP0_3D_LUT_EN_SHIFT 0 276 #define VP0_3D_LUT_UPDATE_SHIFT 2 277 278 #define RK3588_VP0_CLK_CTRL 0xC0C 279 #define DCLK_CORE_DIV_SHIFT 0 280 #define DCLK_OUT_DIV_SHIFT 2 281 282 #define RK3568_VP0_3D_LUT_MST 0xC20 283 284 #define RK3568_VP0_DSP_BG 0xC2C 285 #define RK3568_VP0_PRE_SCAN_HTIMING 0xC30 286 #define RK3568_VP0_POST_DSP_HACT_INFO 0xC34 287 #define RK3568_VP0_POST_DSP_VACT_INFO 0xC38 288 #define RK3568_VP0_POST_SCL_FACTOR_YRGB 0xC3C 289 #define RK3568_VP0_POST_SCL_CTRL 0xC40 290 #define RK3568_VP0_POST_DSP_VACT_INFO_F1 0xC44 291 #define RK3568_VP0_DSP_HTOTAL_HS_END 0xC48 292 #define RK3568_VP0_DSP_HACT_ST_END 0xC4C 293 #define RK3568_VP0_DSP_VTOTAL_VS_END 0xC50 294 #define RK3568_VP0_DSP_VACT_ST_END 0xC54 295 #define RK3568_VP0_DSP_VS_ST_END_F1 0xC58 296 #define RK3568_VP0_DSP_VACT_ST_END_F1 0xC5C 297 298 #define RK3568_VP0_BCSH_CTRL 0xC60 299 #define BCSH_CTRL_Y2R_SHIFT 0 300 #define BCSH_CTRL_Y2R_MASK 0x1 301 #define BCSH_CTRL_Y2R_CSC_MODE_SHIFT 2 302 #define BCSH_CTRL_Y2R_CSC_MODE_MASK 0x3 303 #define BCSH_CTRL_R2Y_SHIFT 4 304 #define BCSH_CTRL_R2Y_MASK 0x1 305 #define BCSH_CTRL_R2Y_CSC_MODE_SHIFT 6 306 #define BCSH_CTRL_R2Y_CSC_MODE_MASK 0x3 307 308 #define RK3568_VP0_BCSH_BCS 0xC64 309 #define BCSH_BRIGHTNESS_SHIFT 0 310 #define BCSH_BRIGHTNESS_MASK 0xFF 311 #define BCSH_CONTRAST_SHIFT 8 312 #define BCSH_CONTRAST_MASK 0x1FF 313 #define BCSH_SATURATION_SHIFT 20 314 #define BCSH_SATURATION_MASK 0x3FF 315 #define BCSH_OUT_MODE_SHIFT 30 316 #define BCSH_OUT_MODE_MASK 0x3 317 318 #define RK3568_VP0_BCSH_H 0xC68 319 #define BCSH_SIN_HUE_SHIFT 0 320 #define BCSH_SIN_HUE_MASK 0x1FF 321 #define BCSH_COS_HUE_SHIFT 16 322 #define BCSH_COS_HUE_MASK 0x1FF 323 324 #define RK3568_VP0_BCSH_COLOR 0xC6C 325 #define BCSH_EN_SHIFT 31 326 #define BCSH_EN_MASK 1 327 328 #define RK3568_VP1_DSP_CTRL 0xD00 329 #define RK3568_VP1_MIPI_CTRL 0xD04 330 #define RK3568_VP1_COLOR_BAR_CTRL 0xD08 331 #define RK3568_VP1_PRE_SCAN_HTIMING 0xD30 332 #define RK3568_VP1_POST_DSP_HACT_INFO 0xD34 333 #define RK3568_VP1_POST_DSP_VACT_INFO 0xD38 334 #define RK3568_VP1_POST_SCL_FACTOR_YRGB 0xD3C 335 #define RK3568_VP1_POST_SCL_CTRL 0xD40 336 #define RK3568_VP1_DSP_HACT_INFO 0xD34 337 #define RK3568_VP1_DSP_VACT_INFO 0xD38 338 #define RK3568_VP1_POST_DSP_VACT_INFO_F1 0xD44 339 #define RK3568_VP1_DSP_HTOTAL_HS_END 0xD48 340 #define RK3568_VP1_DSP_HACT_ST_END 0xD4C 341 #define RK3568_VP1_DSP_VTOTAL_VS_END 0xD50 342 #define RK3568_VP1_DSP_VACT_ST_END 0xD54 343 #define RK3568_VP1_DSP_VS_ST_END_F1 0xD58 344 #define RK3568_VP1_DSP_VACT_ST_END_F1 0xD5C 345 346 #define RK3568_VP2_DSP_CTRL 0xE00 347 #define RK3568_VP2_MIPI_CTRL 0xE04 348 #define RK3568_VP2_COLOR_BAR_CTRL 0xE08 349 #define RK3568_VP2_PRE_SCAN_HTIMING 0xE30 350 #define RK3568_VP2_POST_DSP_HACT_INFO 0xE34 351 #define RK3568_VP2_POST_DSP_VACT_INFO 0xE38 352 #define RK3568_VP2_POST_SCL_FACTOR_YRGB 0xE3C 353 #define RK3568_VP2_POST_SCL_CTRL 0xE40 354 #define RK3568_VP2_DSP_HACT_INFO 0xE34 355 #define RK3568_VP2_DSP_VACT_INFO 0xE38 356 #define RK3568_VP2_POST_DSP_VACT_INFO_F1 0xE44 357 #define RK3568_VP2_DSP_HTOTAL_HS_END 0xE48 358 #define RK3568_VP2_DSP_HACT_ST_END 0xE4C 359 #define RK3568_VP2_DSP_VTOTAL_VS_END 0xE50 360 #define RK3568_VP2_DSP_VACT_ST_END 0xE54 361 #define RK3568_VP2_DSP_VS_ST_END_F1 0xE58 362 #define RK3568_VP2_DSP_VACT_ST_END_F1 0xE5C 363 364 /* Cluster0 register definition */ 365 #define RK3568_CLUSTER0_WIN0_CTRL0 0x1000 366 #define CLUSTER_YUV2RGB_EN_SHIFT 8 367 #define CLUSTER_RGB2YUV_EN_SHIFT 9 368 #define CLUSTER_CSC_MODE_SHIFT 10 369 #define CLUSTER_YRGB_XSCL_MODE_SHIFT 12 370 #define CLUSTER_YRGB_YSCL_MODE_SHIFT 14 371 #define RK3568_CLUSTER0_WIN0_CTRL1 0x1004 372 #define CLUSTER_YRGB_GT2_SHIFT 28 373 #define CLUSTER_YRGB_GT4_SHIFT 29 374 #define RK3568_CLUSTER0_WIN0_CTRL2 0x1008 375 #define CLUSTER_AXI_YRGB_ID_MASK 0x1f 376 #define CLUSTER_AXI_YRGB_ID_SHIFT 0 377 #define CLUSTER_AXI_UV_ID_MASK 0x1f 378 #define CLUSTER_AXI_UV_ID_SHIFT 5 379 380 #define RK3568_CLUSTER0_WIN0_YRGB_MST 0x1010 381 #define RK3568_CLUSTER0_WIN0_CBR_MST 0x1014 382 #define RK3568_CLUSTER0_WIN0_VIR 0x1018 383 #define RK3568_CLUSTER0_WIN0_ACT_INFO 0x1020 384 #define RK3568_CLUSTER0_WIN0_DSP_INFO 0x1024 385 #define RK3568_CLUSTER0_WIN0_DSP_ST 0x1028 386 #define RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB 0x1030 387 #define RK3568_CLUSTER0_WIN0_AFBCD_ROTATE_MODE 0x1054 388 #define RK3568_CLUSTER0_WIN0_AFBCD_HDR_PTR 0x1058 389 #define RK3568_CLUSTER0_WIN0_AFBCD_VIR_WIDTH 0x105C 390 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_SIZE 0x1060 391 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_OFFSET 0x1064 392 #define RK3568_CLUSTER0_WIN0_AFBCD_DSP_OFFSET 0x1068 393 #define RK3568_CLUSTER0_WIN0_AFBCD_CTRL 0x106C 394 395 #define RK3568_CLUSTER0_WIN1_CTRL0 0x1080 396 #define RK3568_CLUSTER0_WIN1_CTRL1 0x1084 397 #define RK3568_CLUSTER0_WIN1_YRGB_MST 0x1090 398 #define RK3568_CLUSTER0_WIN1_CBR_MST 0x1094 399 #define RK3568_CLUSTER0_WIN1_VIR 0x1098 400 #define RK3568_CLUSTER0_WIN1_ACT_INFO 0x10A0 401 #define RK3568_CLUSTER0_WIN1_DSP_INFO 0x10A4 402 #define RK3568_CLUSTER0_WIN1_DSP_ST 0x10A8 403 #define RK3568_CLUSTER0_WIN1_SCL_FACTOR_YRGB 0x10B0 404 #define RK3568_CLUSTER0_WIN1_AFBCD_ROTATE_MODE 0x10D4 405 #define RK3568_CLUSTER0_WIN1_AFBCD_HDR_PTR 0x10D8 406 #define RK3568_CLUSTER0_WIN1_AFBCD_VIR_WIDTH 0x10DC 407 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_SIZE 0x10E0 408 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_OFFSET 0x10E4 409 #define RK3568_CLUSTER0_WIN1_AFBCD_DSP_OFFSET 0x10E8 410 #define RK3568_CLUSTER0_WIN1_AFBCD_CTRL 0x10EC 411 412 #define RK3568_CLUSTER0_CTRL 0x1100 413 #define CLUSTER_EN_SHIFT 0 414 #define CLUSTER_AXI_ID_MASK 0x1 415 #define CLUSTER_AXI_ID_SHIFT 13 416 417 #define RK3568_CLUSTER1_WIN0_CTRL0 0x1200 418 #define RK3568_CLUSTER1_WIN0_CTRL1 0x1204 419 #define RK3568_CLUSTER1_WIN0_YRGB_MST 0x1210 420 #define RK3568_CLUSTER1_WIN0_CBR_MST 0x1214 421 #define RK3568_CLUSTER1_WIN0_VIR 0x1218 422 #define RK3568_CLUSTER1_WIN0_ACT_INFO 0x1220 423 #define RK3568_CLUSTER1_WIN0_DSP_INFO 0x1224 424 #define RK3568_CLUSTER1_WIN0_DSP_ST 0x1228 425 #define RK3568_CLUSTER1_WIN0_SCL_FACTOR_YRGB 0x1230 426 #define RK3568_CLUSTER1_WIN0_AFBCD_ROTATE_MODE 0x1254 427 #define RK3568_CLUSTER1_WIN0_AFBCD_HDR_PTR 0x1258 428 #define RK3568_CLUSTER1_WIN0_AFBCD_VIR_WIDTH 0x125C 429 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_SIZE 0x1260 430 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_OFFSET 0x1264 431 #define RK3568_CLUSTER1_WIN0_AFBCD_DSP_OFFSET 0x1268 432 #define RK3568_CLUSTER1_WIN0_AFBCD_CTRL 0x126C 433 434 #define RK3568_CLUSTER1_WIN1_CTRL0 0x1280 435 #define RK3568_CLUSTER1_WIN1_CTRL1 0x1284 436 #define RK3568_CLUSTER1_WIN1_YRGB_MST 0x1290 437 #define RK3568_CLUSTER1_WIN1_CBR_MST 0x1294 438 #define RK3568_CLUSTER1_WIN1_VIR 0x1298 439 #define RK3568_CLUSTER1_WIN1_ACT_INFO 0x12A0 440 #define RK3568_CLUSTER1_WIN1_DSP_INFO 0x12A4 441 #define RK3568_CLUSTER1_WIN1_DSP_ST 0x12A8 442 #define RK3568_CLUSTER1_WIN1_SCL_FACTOR_YRGB 0x12B0 443 #define RK3568_CLUSTER1_WIN1_AFBCD_ROTATE_MODE 0x12D4 444 #define RK3568_CLUSTER1_WIN1_AFBCD_HDR_PTR 0x12D8 445 #define RK3568_CLUSTER1_WIN1_AFBCD_VIR_WIDTH 0x12DC 446 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_SIZE 0x12E0 447 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_OFFSET 0x12E4 448 #define RK3568_CLUSTER1_WIN1_AFBCD_DSP_OFFSET 0x12E8 449 #define RK3568_CLUSTER1_WIN1_AFBCD_CTRL 0x12EC 450 451 #define RK3568_CLUSTER1_CTRL 0x1300 452 453 /* Esmart register definition */ 454 #define RK3568_ESMART0_CTRL0 0x1800 455 #define RGB2YUV_EN_SHIFT 1 456 #define CSC_MODE_SHIFT 2 457 #define CSC_MODE_MASK 0x3 458 459 #define RK3568_ESMART0_CTRL1 0x1804 460 #define ESMART_AXI_YRGB_ID_MASK 0x1f 461 #define ESMART_AXI_YRGB_ID_SHIFT 4 462 #define ESMART_AXI_UV_ID_MASK 0x1f 463 #define ESMART_AXI_UV_ID_SHIFT 12 464 #define YMIRROR_EN_SHIFT 31 465 466 #define RK3568_ESMART0_AXI_CTRL 0x1808 467 #define ESMART_AXI_ID_MASK 0x1 468 #define ESMART_AXI_ID_SHIFT 1 469 470 #define RK3568_ESMART0_REGION0_CTRL 0x1810 471 #define REGION0_RB_SWAP_SHIFT 14 472 #define WIN_EN_SHIFT 0 473 #define WIN_FORMAT_MASK 0x1f 474 #define WIN_FORMAT_SHIFT 1 475 476 #define RK3568_ESMART0_REGION0_YRGB_MST 0x1814 477 #define RK3568_ESMART0_REGION0_CBR_MST 0x1818 478 #define RK3568_ESMART0_REGION0_VIR 0x181C 479 #define RK3568_ESMART0_REGION0_ACT_INFO 0x1820 480 #define RK3568_ESMART0_REGION0_DSP_INFO 0x1824 481 #define RK3568_ESMART0_REGION0_DSP_ST 0x1828 482 #define RK3568_ESMART0_REGION0_SCL_CTRL 0x1830 483 #define YRGB_XSCL_MODE_MASK 0x3 484 #define YRGB_XSCL_MODE_SHIFT 0 485 #define YRGB_XSCL_FILTER_MODE_MASK 0x3 486 #define YRGB_XSCL_FILTER_MODE_SHIFT 2 487 #define YRGB_YSCL_MODE_MASK 0x3 488 #define YRGB_YSCL_MODE_SHIFT 4 489 #define YRGB_YSCL_FILTER_MODE_MASK 0x3 490 #define YRGB_YSCL_FILTER_MODE_SHIFT 6 491 492 #define RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB 0x1834 493 #define RK3568_ESMART0_REGION0_SCL_FACTOR_CBR 0x1838 494 #define RK3568_ESMART0_REGION0_SCL_OFFSET 0x183C 495 #define RK3568_ESMART0_REGION1_CTRL 0x1840 496 #define YRGB_GT2_MASK 0x1 497 #define YRGB_GT2_SHIFT 8 498 #define YRGB_GT4_MASK 0x1 499 #define YRGB_GT4_SHIFT 9 500 501 #define RK3568_ESMART0_REGION1_YRGB_MST 0x1844 502 #define RK3568_ESMART0_REGION1_CBR_MST 0x1848 503 #define RK3568_ESMART0_REGION1_VIR 0x184C 504 #define RK3568_ESMART0_REGION1_ACT_INFO 0x1850 505 #define RK3568_ESMART0_REGION1_DSP_INFO 0x1854 506 #define RK3568_ESMART0_REGION1_DSP_ST 0x1858 507 #define RK3568_ESMART0_REGION1_SCL_CTRL 0x1860 508 #define RK3568_ESMART0_REGION1_SCL_FACTOR_YRGB 0x1864 509 #define RK3568_ESMART0_REGION1_SCL_FACTOR_CBR 0x1868 510 #define RK3568_ESMART0_REGION1_SCL_OFFSET 0x186C 511 #define RK3568_ESMART0_REGION2_CTRL 0x1870 512 #define RK3568_ESMART0_REGION2_YRGB_MST 0x1874 513 #define RK3568_ESMART0_REGION2_CBR_MST 0x1878 514 #define RK3568_ESMART0_REGION2_VIR 0x187C 515 #define RK3568_ESMART0_REGION2_ACT_INFO 0x1880 516 #define RK3568_ESMART0_REGION2_DSP_INFO 0x1884 517 #define RK3568_ESMART0_REGION2_DSP_ST 0x1888 518 #define RK3568_ESMART0_REGION2_SCL_CTRL 0x1890 519 #define RK3568_ESMART0_REGION2_SCL_FACTOR_YRGB 0x1894 520 #define RK3568_ESMART0_REGION2_SCL_FACTOR_CBR 0x1898 521 #define RK3568_ESMART0_REGION2_SCL_OFFSET 0x189C 522 #define RK3568_ESMART0_REGION3_CTRL 0x18A0 523 #define RK3568_ESMART0_REGION3_YRGB_MST 0x18A4 524 #define RK3568_ESMART0_REGION3_CBR_MST 0x18A8 525 #define RK3568_ESMART0_REGION3_VIR 0x18AC 526 #define RK3568_ESMART0_REGION3_ACT_INFO 0x18B0 527 #define RK3568_ESMART0_REGION3_DSP_INFO 0x18B4 528 #define RK3568_ESMART0_REGION3_DSP_ST 0x18B8 529 #define RK3568_ESMART0_REGION3_SCL_CTRL 0x18C0 530 #define RK3568_ESMART0_REGION3_SCL_FACTOR_YRGB 0x18C4 531 #define RK3568_ESMART0_REGION3_SCL_FACTOR_CBR 0x18C8 532 #define RK3568_ESMART0_REGION3_SCL_OFFSET 0x18CC 533 534 #define RK3568_ESMART1_CTRL0 0x1A00 535 #define RK3568_ESMART1_CTRL1 0x1A04 536 #define RK3568_ESMART1_REGION0_CTRL 0x1A10 537 #define RK3568_ESMART1_REGION0_YRGB_MST 0x1A14 538 #define RK3568_ESMART1_REGION0_CBR_MST 0x1A18 539 #define RK3568_ESMART1_REGION0_VIR 0x1A1C 540 #define RK3568_ESMART1_REGION0_ACT_INFO 0x1A20 541 #define RK3568_ESMART1_REGION0_DSP_INFO 0x1A24 542 #define RK3568_ESMART1_REGION0_DSP_ST 0x1A28 543 #define RK3568_ESMART1_REGION0_SCL_CTRL 0x1A30 544 #define RK3568_ESMART1_REGION0_SCL_FACTOR_YRGB 0x1A34 545 #define RK3568_ESMART1_REGION0_SCL_FACTOR_CBR 0x1A38 546 #define RK3568_ESMART1_REGION0_SCL_OFFSET 0x1A3C 547 #define RK3568_ESMART1_REGION1_CTRL 0x1A40 548 #define RK3568_ESMART1_REGION1_YRGB_MST 0x1A44 549 #define RK3568_ESMART1_REGION1_CBR_MST 0x1A48 550 #define RK3568_ESMART1_REGION1_VIR 0x1A4C 551 #define RK3568_ESMART1_REGION1_ACT_INFO 0x1A50 552 #define RK3568_ESMART1_REGION1_DSP_INFO 0x1A54 553 #define RK3568_ESMART1_REGION1_DSP_ST 0x1A58 554 #define RK3568_ESMART1_REGION1_SCL_CTRL 0x1A60 555 #define RK3568_ESMART1_REGION1_SCL_FACTOR_YRGB 0x1A64 556 #define RK3568_ESMART1_REGION1_SCL_FACTOR_CBR 0x1A68 557 #define RK3568_ESMART1_REGION1_SCL_OFFSET 0x1A6C 558 #define RK3568_ESMART1_REGION2_CTRL 0x1A70 559 #define RK3568_ESMART1_REGION2_YRGB_MST 0x1A74 560 #define RK3568_ESMART1_REGION2_CBR_MST 0x1A78 561 #define RK3568_ESMART1_REGION2_VIR 0x1A7C 562 #define RK3568_ESMART1_REGION2_ACT_INFO 0x1A80 563 #define RK3568_ESMART1_REGION2_DSP_INFO 0x1A84 564 #define RK3568_ESMART1_REGION2_DSP_ST 0x1A88 565 #define RK3568_ESMART1_REGION2_SCL_CTRL 0x1A90 566 #define RK3568_ESMART1_REGION2_SCL_FACTOR_YRGB 0x1A94 567 #define RK3568_ESMART1_REGION2_SCL_FACTOR_CBR 0x1A98 568 #define RK3568_ESMART1_REGION2_SCL_OFFSET 0x1A9C 569 #define RK3568_ESMART1_REGION3_CTRL 0x1AA0 570 #define RK3568_ESMART1_REGION3_YRGB_MST 0x1AA4 571 #define RK3568_ESMART1_REGION3_CBR_MST 0x1AA8 572 #define RK3568_ESMART1_REGION3_VIR 0x1AAC 573 #define RK3568_ESMART1_REGION3_ACT_INFO 0x1AB0 574 #define RK3568_ESMART1_REGION3_DSP_INFO 0x1AB4 575 #define RK3568_ESMART1_REGION3_DSP_ST 0x1AB8 576 #define RK3568_ESMART1_REGION3_SCL_CTRL 0x1AC0 577 #define RK3568_ESMART1_REGION3_SCL_FACTOR_YRGB 0x1AC4 578 #define RK3568_ESMART1_REGION3_SCL_FACTOR_CBR 0x1AC8 579 #define RK3568_ESMART1_REGION3_SCL_OFFSET 0x1ACC 580 581 #define RK3568_SMART0_CTRL0 0x1C00 582 #define RK3568_SMART0_CTRL1 0x1C04 583 #define RK3568_SMART0_REGION0_CTRL 0x1C10 584 #define RK3568_SMART0_REGION0_YRGB_MST 0x1C14 585 #define RK3568_SMART0_REGION0_CBR_MST 0x1C18 586 #define RK3568_SMART0_REGION0_VIR 0x1C1C 587 #define RK3568_SMART0_REGION0_ACT_INFO 0x1C20 588 #define RK3568_SMART0_REGION0_DSP_INFO 0x1C24 589 #define RK3568_SMART0_REGION0_DSP_ST 0x1C28 590 #define RK3568_SMART0_REGION0_SCL_CTRL 0x1C30 591 #define RK3568_SMART0_REGION0_SCL_FACTOR_YRGB 0x1C34 592 #define RK3568_SMART0_REGION0_SCL_FACTOR_CBR 0x1C38 593 #define RK3568_SMART0_REGION0_SCL_OFFSET 0x1C3C 594 #define RK3568_SMART0_REGION1_CTRL 0x1C40 595 #define RK3568_SMART0_REGION1_YRGB_MST 0x1C44 596 #define RK3568_SMART0_REGION1_CBR_MST 0x1C48 597 #define RK3568_SMART0_REGION1_VIR 0x1C4C 598 #define RK3568_SMART0_REGION1_ACT_INFO 0x1C50 599 #define RK3568_SMART0_REGION1_DSP_INFO 0x1C54 600 #define RK3568_SMART0_REGION1_DSP_ST 0x1C58 601 #define RK3568_SMART0_REGION1_SCL_CTRL 0x1C60 602 #define RK3568_SMART0_REGION1_SCL_FACTOR_YRGB 0x1C64 603 #define RK3568_SMART0_REGION1_SCL_FACTOR_CBR 0x1C68 604 #define RK3568_SMART0_REGION1_SCL_OFFSET 0x1C6C 605 #define RK3568_SMART0_REGION2_CTRL 0x1C70 606 #define RK3568_SMART0_REGION2_YRGB_MST 0x1C74 607 #define RK3568_SMART0_REGION2_CBR_MST 0x1C78 608 #define RK3568_SMART0_REGION2_VIR 0x1C7C 609 #define RK3568_SMART0_REGION2_ACT_INFO 0x1C80 610 #define RK3568_SMART0_REGION2_DSP_INFO 0x1C84 611 #define RK3568_SMART0_REGION2_DSP_ST 0x1C88 612 #define RK3568_SMART0_REGION2_SCL_CTRL 0x1C90 613 #define RK3568_SMART0_REGION2_SCL_FACTOR_YRGB 0x1C94 614 #define RK3568_SMART0_REGION2_SCL_FACTOR_CBR 0x1C98 615 #define RK3568_SMART0_REGION2_SCL_OFFSET 0x1C9C 616 #define RK3568_SMART0_REGION3_CTRL 0x1CA0 617 #define RK3568_SMART0_REGION3_YRGB_MST 0x1CA4 618 #define RK3568_SMART0_REGION3_CBR_MST 0x1CA8 619 #define RK3568_SMART0_REGION3_VIR 0x1CAC 620 #define RK3568_SMART0_REGION3_ACT_INFO 0x1CB0 621 #define RK3568_SMART0_REGION3_DSP_INFO 0x1CB4 622 #define RK3568_SMART0_REGION3_DSP_ST 0x1CB8 623 #define RK3568_SMART0_REGION3_SCL_CTRL 0x1CC0 624 #define RK3568_SMART0_REGION3_SCL_FACTOR_YRGB 0x1CC4 625 #define RK3568_SMART0_REGION3_SCL_FACTOR_CBR 0x1CC8 626 #define RK3568_SMART0_REGION3_SCL_OFFSET 0x1CCC 627 628 #define RK3568_SMART1_CTRL0 0x1E00 629 #define RK3568_SMART1_CTRL1 0x1E04 630 #define RK3568_SMART1_REGION0_CTRL 0x1E10 631 #define RK3568_SMART1_REGION0_YRGB_MST 0x1E14 632 #define RK3568_SMART1_REGION0_CBR_MST 0x1E18 633 #define RK3568_SMART1_REGION0_VIR 0x1E1C 634 #define RK3568_SMART1_REGION0_ACT_INFO 0x1E20 635 #define RK3568_SMART1_REGION0_DSP_INFO 0x1E24 636 #define RK3568_SMART1_REGION0_DSP_ST 0x1E28 637 #define RK3568_SMART1_REGION0_SCL_CTRL 0x1E30 638 #define RK3568_SMART1_REGION0_SCL_FACTOR_YRGB 0x1E34 639 #define RK3568_SMART1_REGION0_SCL_FACTOR_CBR 0x1E38 640 #define RK3568_SMART1_REGION0_SCL_OFFSET 0x1E3C 641 #define RK3568_SMART1_REGION1_CTRL 0x1E40 642 #define RK3568_SMART1_REGION1_YRGB_MST 0x1E44 643 #define RK3568_SMART1_REGION1_CBR_MST 0x1E48 644 #define RK3568_SMART1_REGION1_VIR 0x1E4C 645 #define RK3568_SMART1_REGION1_ACT_INFO 0x1E50 646 #define RK3568_SMART1_REGION1_DSP_INFO 0x1E54 647 #define RK3568_SMART1_REGION1_DSP_ST 0x1E58 648 #define RK3568_SMART1_REGION1_SCL_CTRL 0x1E60 649 #define RK3568_SMART1_REGION1_SCL_FACTOR_YRGB 0x1E64 650 #define RK3568_SMART1_REGION1_SCL_FACTOR_CBR 0x1E68 651 #define RK3568_SMART1_REGION1_SCL_OFFSET 0x1E6C 652 #define RK3568_SMART1_REGION2_CTRL 0x1E70 653 #define RK3568_SMART1_REGION2_YRGB_MST 0x1E74 654 #define RK3568_SMART1_REGION2_CBR_MST 0x1E78 655 #define RK3568_SMART1_REGION2_VIR 0x1E7C 656 #define RK3568_SMART1_REGION2_ACT_INFO 0x1E80 657 #define RK3568_SMART1_REGION2_DSP_INFO 0x1E84 658 #define RK3568_SMART1_REGION2_DSP_ST 0x1E88 659 #define RK3568_SMART1_REGION2_SCL_CTRL 0x1E90 660 #define RK3568_SMART1_REGION2_SCL_FACTOR_YRGB 0x1E94 661 #define RK3568_SMART1_REGION2_SCL_FACTOR_CBR 0x1E98 662 #define RK3568_SMART1_REGION2_SCL_OFFSET 0x1E9C 663 #define RK3568_SMART1_REGION3_CTRL 0x1EA0 664 #define RK3568_SMART1_REGION3_YRGB_MST 0x1EA4 665 #define RK3568_SMART1_REGION3_CBR_MST 0x1EA8 666 #define RK3568_SMART1_REGION3_VIR 0x1EAC 667 #define RK3568_SMART1_REGION3_ACT_INFO 0x1EB0 668 #define RK3568_SMART1_REGION3_DSP_INFO 0x1EB4 669 #define RK3568_SMART1_REGION3_DSP_ST 0x1EB8 670 #define RK3568_SMART1_REGION3_SCL_CTRL 0x1EC0 671 #define RK3568_SMART1_REGION3_SCL_FACTOR_YRGB 0x1EC4 672 #define RK3568_SMART1_REGION3_SCL_FACTOR_CBR 0x1EC8 673 #define RK3568_SMART1_REGION3_SCL_OFFSET 0x1ECC 674 675 /* DSC 8K/4K register definition */ 676 #define RK3588_DSC_8K_PPS0_3 0x4000 677 #define RK3588_DSC_8K_CTRL0 0x40A0 678 #define DSC_EN_SHIFT 0 679 #define DSC_RBIT_SHIFT 2 680 #define DSC_RBYT_SHIFT 3 681 #define DSC_FLAL_SHIFT 4 682 #define DSC_MER_SHIFT 5 683 #define DSC_EPB_SHIFT 6 684 #define DSC_EPL_SHIFT 7 685 #define DSC_NSLC_SHIFT 16 686 #define DSC_SBO_SHIFT 28 687 #define DSC_IFEP_SHIFT 29 688 #define DSC_PPS_UPD_SHIFT 31 689 690 #define RK3588_DSC_8K_CTRL1 0x40A4 691 #define RK3588_DSC_8K_STS0 0x40A8 692 #define RK3588_DSC_8K_ERS 0x40C4 693 694 #define RK3588_DSC_4K_PPS0_3 0x4100 695 #define RK3588_DSC_4K_CTRL0 0x41A0 696 #define RK3588_DSC_4K_CTRL1 0x41A4 697 #define RK3588_DSC_4K_STS0 0x41A8 698 #define RK3588_DSC_4K_ERS 0x41C4 699 700 #define RK3568_MAX_REG 0x1ED0 701 702 #define RK3568_GRF_VO_CON1 0x0364 703 #define GRF_BT656_CLK_INV_SHIFT 1 704 #define GRF_BT1120_CLK_INV_SHIFT 2 705 #define GRF_RGB_DCLK_INV_SHIFT 3 706 707 #define RK3588_GRF_VOP_CON2 0x0008 708 #define RK3588_GRF_EDP0_ENABLE_SHIFT 0 709 #define RK3588_GRF_HDMITX0_ENABLE_SHIFT 1 710 #define RK3588_GRF_EDP1_ENABLE_SHIFT 3 711 #define RK3588_GRF_HDMITX1_ENABLE_SHIFT 4 712 713 #define RK3588_GRF_VO1_CON0 0x0000 714 #define HDMI_SYNC_POL_MASK 0x3 715 #define HDMI0_SYNC_POL_SHIFT 5 716 #define HDMI1_SYNC_POL_SHIFT 7 717 718 #define RK3588_PMU_BISR_CON3 0x20C 719 #define RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT 9 720 #define RK3588_PD_CLUSTER1_REPAIR_EN_SHIFT 10 721 #define RK3588_PD_CLUSTER2_REPAIR_EN_SHIFT 11 722 #define RK3588_PD_CLUSTER3_REPAIR_EN_SHIFT 12 723 #define RK3588_PD_DSC_8K_REPAIR_EN_SHIFT 13 724 #define RK3588_PD_DSC_4K_REPAIR_EN_SHIFT 14 725 #define RK3588_PD_ESMART_REPAIR_EN_SHIFT 15 726 727 #define RK3588_PMU_BISR_STATUS5 0x294 728 #define RK3588_PD_CLUSTER0_PWR_STAT_SHIFI 9 729 #define RK3588_PD_CLUSTER1_PWR_STAT_SHIFI 10 730 #define RK3588_PD_CLUSTER2_PWR_STAT_SHIFI 11 731 #define RK3588_PD_CLUSTER3_PWR_STAT_SHIFI 12 732 #define RK3588_PD_DSC_8K_PWR_STAT_SHIFI 13 733 #define RK3588_PD_DSC_4K_PWR_STAT_SHIFI 14 734 #define RK3588_PD_ESMART_PWR_STAT_SHIFI 15 735 736 #define VOP2_LAYER_MAX 8 737 738 #define VOP2_MAX_VP_OUTPUT_WIDTH 4096 739 740 #define VOP_FEATURE_OUTPUT_10BIT BIT(0) 741 742 /* KHz */ 743 #define VOP2_MAX_DCLK_RATE 600000 744 745 /* 746 * vop2 dsc id 747 */ 748 #define ROCKCHIP_VOP2_DSC_8K 0 749 #define ROCKCHIP_VOP2_DSC_4K 1 750 751 /* 752 * vop2 internal power domain id, 753 * should be all none zero, 0 will be 754 * treat as invalid; 755 */ 756 #define VOP2_PD_CLUSTER0 BIT(0) 757 #define VOP2_PD_CLUSTER1 BIT(1) 758 #define VOP2_PD_CLUSTER2 BIT(2) 759 #define VOP2_PD_CLUSTER3 BIT(3) 760 #define VOP2_PD_DSC_8K BIT(5) 761 #define VOP2_PD_DSC_4K BIT(6) 762 #define VOP2_PD_ESMART BIT(7) 763 764 enum vop2_csc_format { 765 CSC_BT601L, 766 CSC_BT709L, 767 CSC_BT601F, 768 CSC_BT2020, 769 }; 770 771 enum vop2_pol { 772 HSYNC_POSITIVE = 0, 773 VSYNC_POSITIVE = 1, 774 DEN_NEGATIVE = 2, 775 DCLK_INVERT = 3 776 }; 777 778 enum vop2_bcsh_out_mode { 779 BCSH_OUT_MODE_BLACK, 780 BCSH_OUT_MODE_BLUE, 781 BCSH_OUT_MODE_COLOR_BAR, 782 BCSH_OUT_MODE_NORMAL_VIDEO, 783 }; 784 785 #define _VOP_REG(off, _mask, _shift, _write_mask) \ 786 { \ 787 .offset = off, \ 788 .mask = _mask, \ 789 .shift = _shift, \ 790 .write_mask = _write_mask, \ 791 } 792 793 #define VOP_REG(off, _mask, _shift) \ 794 _VOP_REG(off, _mask, _shift, false) 795 enum dither_down_mode { 796 RGB888_TO_RGB565 = 0x0, 797 RGB888_TO_RGB666 = 0x1 798 }; 799 800 enum vop2_video_ports_id { 801 VOP2_VP0, 802 VOP2_VP1, 803 VOP2_VP2, 804 VOP2_VP3, 805 VOP2_VP_MAX, 806 }; 807 808 enum vop2_layer_type { 809 CLUSTER_LAYER = 0, 810 ESMART_LAYER = 1, 811 SMART_LAYER = 2, 812 }; 813 814 /* This define must same with kernel win phy id */ 815 enum vop2_layer_phy_id { 816 ROCKCHIP_VOP2_CLUSTER0 = 0, 817 ROCKCHIP_VOP2_CLUSTER1, 818 ROCKCHIP_VOP2_ESMART0, 819 ROCKCHIP_VOP2_ESMART1, 820 ROCKCHIP_VOP2_SMART0, 821 ROCKCHIP_VOP2_SMART1, 822 ROCKCHIP_VOP2_CLUSTER2, 823 ROCKCHIP_VOP2_CLUSTER3, 824 ROCKCHIP_VOP2_ESMART2, 825 ROCKCHIP_VOP2_ESMART3, 826 ROCKCHIP_VOP2_LAYER_MAX, 827 }; 828 829 enum vop2_scale_up_mode { 830 VOP2_SCALE_UP_NRST_NBOR, 831 VOP2_SCALE_UP_BIL, 832 VOP2_SCALE_UP_BIC, 833 }; 834 835 enum vop2_scale_down_mode { 836 VOP2_SCALE_DOWN_NRST_NBOR, 837 VOP2_SCALE_DOWN_BIL, 838 VOP2_SCALE_DOWN_AVG, 839 }; 840 841 enum scale_mode { 842 SCALE_NONE = 0x0, 843 SCALE_UP = 0x1, 844 SCALE_DOWN = 0x2 845 }; 846 847 enum vop_dsc_interface_mode { 848 VOP_DSC_IF_DISABLE = 0, 849 VOP_DSC_IF_HDMI = 1, 850 VOP_DSC_IF_MIPI_DS_MODE = 2, 851 VOP_DSC_IF_MIPI_VIDEO_MODE = 3, 852 }; 853 854 struct vop2_layer { 855 u8 id; 856 /** 857 * @win_phys_id: window id of the layer selected. 858 * Every layer must make sure to select different 859 * windows of others. 860 */ 861 u8 win_phys_id; 862 }; 863 864 struct vop2_power_domain_data { 865 u8 id; 866 u8 parent_id; 867 /* 868 * @module_id_mask: module id of which module this power domain is belongs to. 869 * PD_CLUSTER0,1,2,3 only belongs to CLUSTER0/1/2/3, PD_Esmart0 shared by Esmart1/2/3 870 */ 871 u32 module_id_mask; 872 }; 873 874 struct vop2_win_data { 875 char *name; 876 u8 phys_id; 877 enum vop2_layer_type type; 878 u8 win_sel_port_offset; 879 u8 layer_sel_win_id; 880 u8 axi_id; 881 u8 axi_uv_id; 882 u8 axi_yrgb_id; 883 u8 splice_win_id; 884 u8 pd_id; 885 u32 reg_offset; 886 bool splice_mode_right; 887 }; 888 889 struct vop2_vp_data { 890 u32 feature; 891 u8 pre_scan_max_dly; 892 u8 splice_vp_id; 893 struct vop_rect max_output; 894 u32 max_dclk; 895 }; 896 897 struct vop2_plane_table { 898 enum vop2_layer_phy_id plane_id; 899 enum vop2_layer_type plane_type; 900 }; 901 902 struct vop2_vp_plane_mask { 903 u8 primary_plane_id; /* use this win to show logo */ 904 u8 attached_layers_nr; /* number layers attach to this vp */ 905 u8 attached_layers[VOP2_LAYER_MAX]; /* the layers attached to this vp */ 906 u32 plane_mask; 907 int cursor_plane_id; 908 }; 909 910 struct vop2_dsc_data { 911 u8 id; 912 u8 pd_id; 913 u8 max_slice_num; 914 u8 max_linebuf_depth; /* used to generate the bitstream */ 915 u8 min_bits_per_pixel; /* bit num after encoder compress */ 916 const char *dsc_txp_clk_src_name; 917 const char *dsc_txp_clk_name; 918 const char *dsc_pxl_clk_name; 919 const char *dsc_cds_clk_name; 920 }; 921 922 struct dsc_error_info { 923 u32 dsc_error_val; 924 char dsc_error_info[50]; 925 }; 926 927 struct vop2_data { 928 u32 version; 929 struct vop2_vp_data *vp_data; 930 struct vop2_win_data *win_data; 931 struct vop2_vp_plane_mask *plane_mask; 932 struct vop2_plane_table *plane_table; 933 struct vop2_power_domain_data *pd; 934 struct vop2_dsc_data *dsc; 935 struct dsc_error_info *dsc_error_ecw; 936 struct dsc_error_info *dsc_error_buffer_flow; 937 u8 nr_vps; 938 u8 nr_layers; 939 u8 nr_mixers; 940 u8 nr_gammas; 941 u8 nr_pd; 942 u8 nr_dscs; 943 u8 nr_dsc_ecw; 944 u8 nr_dsc_buffer_flow; 945 u32 reg_len; 946 }; 947 948 struct vop2 { 949 u32 *regsbak; 950 void *regs; 951 void *grf; 952 void *vop_grf; 953 void *vo1_grf; 954 void *sys_pmu; 955 u32 reg_len; 956 u32 version; 957 bool global_init; 958 const struct vop2_data *data; 959 struct vop2_vp_plane_mask vp_plane_mask[VOP2_VP_MAX]; 960 }; 961 962 static struct vop2 *rockchip_vop2; 963 /* 964 * bli_sd_factor = (src - 1) / (dst - 1) << 12; 965 * avg_sd_factor: 966 * bli_su_factor: 967 * bic_su_factor: 968 * = (src - 1) / (dst - 1) << 16; 969 * 970 * gt2 enable: dst get one line from two line of the src 971 * gt4 enable: dst get one line from four line of the src. 972 * 973 */ 974 #define VOP2_BILI_SCL_DN(src, dst) (((src - 1) << 12) / (dst - 1)) 975 #define VOP2_COMMON_SCL(src, dst) (((src - 1) << 16) / (dst - 1)) 976 977 #define VOP2_BILI_SCL_FAC_CHECK(src, dst, fac) \ 978 (fac * (dst - 1) >> 12 < (src - 1)) 979 #define VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac) \ 980 (fac * (dst - 1) >> 16 < (src - 1)) 981 982 static uint16_t vop2_scale_factor(enum scale_mode mode, 983 int32_t filter_mode, 984 uint32_t src, uint32_t dst) 985 { 986 uint32_t fac = 0; 987 int i = 0; 988 989 if (mode == SCALE_NONE) 990 return 0; 991 992 /* 993 * A workaround to avoid zero div. 994 */ 995 if ((dst == 1) || (src == 1)) { 996 dst = dst + 1; 997 src = src + 1; 998 } 999 1000 if ((mode == SCALE_DOWN) && (filter_mode == VOP2_SCALE_DOWN_BIL)) { 1001 fac = VOP2_BILI_SCL_DN(src, dst); 1002 for (i = 0; i < 100; i++) { 1003 if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac)) 1004 break; 1005 fac -= 1; 1006 printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 1007 } 1008 } else { 1009 fac = VOP2_COMMON_SCL(src, dst); 1010 for (i = 0; i < 100; i++) { 1011 if (VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac)) 1012 break; 1013 fac -= 1; 1014 printf("up fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 1015 } 1016 } 1017 1018 return fac; 1019 } 1020 1021 static inline enum scale_mode scl_get_scl_mode(int src, int dst) 1022 { 1023 if (src < dst) 1024 return SCALE_UP; 1025 else if (src > dst) 1026 return SCALE_DOWN; 1027 1028 return SCALE_NONE; 1029 } 1030 1031 static u8 rk3588_vop2_vp_primary_plane_order[VOP2_VP_MAX] = { 1032 ROCKCHIP_VOP2_ESMART0, 1033 ROCKCHIP_VOP2_ESMART1, 1034 ROCKCHIP_VOP2_ESMART2, 1035 ROCKCHIP_VOP2_ESMART3, 1036 }; 1037 1038 static u8 rk3568_vop2_vp_primary_plane_order[VOP2_VP_MAX] = { 1039 ROCKCHIP_VOP2_SMART0, 1040 ROCKCHIP_VOP2_SMART1, 1041 ROCKCHIP_VOP2_ESMART1, 1042 }; 1043 1044 static inline int interpolate(int x1, int y1, int x2, int y2, int x) 1045 { 1046 return y1 + (y2 - y1) * (x - x1) / (x2 - x1); 1047 } 1048 1049 static int vop2_get_primary_plane(struct vop2 *vop2, u32 plane_mask) 1050 { 1051 int i = 0; 1052 u8 *vop2_vp_primary_plane_order; 1053 u8 default_primary_plane; 1054 1055 if (vop2->version == VOP_VERSION_RK3588) { 1056 vop2_vp_primary_plane_order = rk3588_vop2_vp_primary_plane_order; 1057 default_primary_plane = ROCKCHIP_VOP2_ESMART0; 1058 } else { 1059 vop2_vp_primary_plane_order = rk3568_vop2_vp_primary_plane_order; 1060 default_primary_plane = ROCKCHIP_VOP2_SMART0; 1061 } 1062 1063 for (i = 0; i < vop2->data->nr_vps; i++) { 1064 if (plane_mask & BIT(vop2_vp_primary_plane_order[i])) 1065 return vop2_vp_primary_plane_order[i]; 1066 } 1067 1068 return default_primary_plane; 1069 } 1070 1071 static inline u16 scl_cal_scale(int src, int dst, int shift) 1072 { 1073 return ((src * 2 - 3) << (shift - 1)) / (dst - 1); 1074 } 1075 1076 static inline u16 scl_cal_scale2(int src, int dst) 1077 { 1078 return ((src - 1) << 12) / (dst - 1); 1079 } 1080 1081 static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v) 1082 { 1083 writel(v, vop2->regs + offset); 1084 vop2->regsbak[offset >> 2] = v; 1085 } 1086 1087 static inline u32 vop2_readl(struct vop2 *vop2, u32 offset) 1088 { 1089 return readl(vop2->regs + offset); 1090 } 1091 1092 static inline void vop2_mask_write(struct vop2 *vop2, u32 offset, 1093 u32 mask, u32 shift, u32 v, 1094 bool write_mask) 1095 { 1096 if (!mask) 1097 return; 1098 1099 if (write_mask) { 1100 v = ((v & mask) << shift) | (mask << (shift + 16)); 1101 } else { 1102 u32 cached_val = vop2->regsbak[offset >> 2]; 1103 1104 v = (cached_val & ~(mask << shift)) | ((v & mask) << shift); 1105 vop2->regsbak[offset >> 2] = v; 1106 } 1107 1108 writel(v, vop2->regs + offset); 1109 } 1110 1111 static inline void vop2_grf_writel(struct vop2 *vop, void *grf_base, u32 offset, 1112 u32 mask, u32 shift, u32 v) 1113 { 1114 u32 val = 0; 1115 1116 val = (v << shift) | (mask << (shift + 16)); 1117 writel(val, grf_base + offset); 1118 } 1119 1120 static inline u32 vop2_grf_readl(struct vop2 *vop, void *grf_base, u32 offset, 1121 u32 mask, u32 shift) 1122 { 1123 return (readl(grf_base + offset) >> shift) & mask; 1124 } 1125 1126 static char* get_output_if_name(u32 output_if, char *name) 1127 { 1128 if (output_if & VOP_OUTPUT_IF_RGB) 1129 strcat(name, " RGB"); 1130 if (output_if & VOP_OUTPUT_IF_BT1120) 1131 strcat(name, " BT1120"); 1132 if (output_if & VOP_OUTPUT_IF_BT656) 1133 strcat(name, " BT656"); 1134 if (output_if & VOP_OUTPUT_IF_LVDS0) 1135 strcat(name, " LVDS0"); 1136 if (output_if & VOP_OUTPUT_IF_LVDS1) 1137 strcat(name, " LVDS1"); 1138 if (output_if & VOP_OUTPUT_IF_MIPI0) 1139 strcat(name, " MIPI0"); 1140 if (output_if & VOP_OUTPUT_IF_MIPI1) 1141 strcat(name, " MIPI1"); 1142 if (output_if & VOP_OUTPUT_IF_eDP0) 1143 strcat(name, " eDP0"); 1144 if (output_if & VOP_OUTPUT_IF_eDP1) 1145 strcat(name, " eDP1"); 1146 if (output_if & VOP_OUTPUT_IF_DP0) 1147 strcat(name, " DP0"); 1148 if (output_if & VOP_OUTPUT_IF_DP1) 1149 strcat(name, " DP1"); 1150 if (output_if & VOP_OUTPUT_IF_HDMI0) 1151 strcat(name, " HDMI0"); 1152 if (output_if & VOP_OUTPUT_IF_HDMI1) 1153 strcat(name, " HDMI1"); 1154 1155 return name; 1156 } 1157 1158 static char *get_plane_name(int plane_id, char *name) 1159 { 1160 switch (plane_id) { 1161 case ROCKCHIP_VOP2_CLUSTER0: 1162 strcat(name, "Cluster0"); 1163 break; 1164 case ROCKCHIP_VOP2_CLUSTER1: 1165 strcat(name, "Cluster1"); 1166 break; 1167 case ROCKCHIP_VOP2_ESMART0: 1168 strcat(name, "Esmart0"); 1169 break; 1170 case ROCKCHIP_VOP2_ESMART1: 1171 strcat(name, "Esmart1"); 1172 break; 1173 case ROCKCHIP_VOP2_SMART0: 1174 strcat(name, "Smart0"); 1175 break; 1176 case ROCKCHIP_VOP2_SMART1: 1177 strcat(name, "Smart1"); 1178 break; 1179 case ROCKCHIP_VOP2_CLUSTER2: 1180 strcat(name, "Cluster2"); 1181 break; 1182 case ROCKCHIP_VOP2_CLUSTER3: 1183 strcat(name, "Cluster3"); 1184 break; 1185 case ROCKCHIP_VOP2_ESMART2: 1186 strcat(name, "Esmart2"); 1187 break; 1188 case ROCKCHIP_VOP2_ESMART3: 1189 strcat(name, "Esmart3"); 1190 break; 1191 } 1192 1193 return name; 1194 } 1195 1196 static bool is_yuv_output(u32 bus_format) 1197 { 1198 switch (bus_format) { 1199 case MEDIA_BUS_FMT_YUV8_1X24: 1200 case MEDIA_BUS_FMT_YUV10_1X30: 1201 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 1202 case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 1203 case MEDIA_BUS_FMT_YUYV8_2X8: 1204 case MEDIA_BUS_FMT_YVYU8_2X8: 1205 case MEDIA_BUS_FMT_UYVY8_2X8: 1206 case MEDIA_BUS_FMT_VYUY8_2X8: 1207 case MEDIA_BUS_FMT_YUYV8_1X16: 1208 case MEDIA_BUS_FMT_YVYU8_1X16: 1209 case MEDIA_BUS_FMT_UYVY8_1X16: 1210 case MEDIA_BUS_FMT_VYUY8_1X16: 1211 return true; 1212 default: 1213 return false; 1214 } 1215 } 1216 1217 static int vop2_convert_csc_mode(int csc_mode) 1218 { 1219 switch (csc_mode) { 1220 case V4L2_COLORSPACE_SMPTE170M: 1221 case V4L2_COLORSPACE_470_SYSTEM_M: 1222 case V4L2_COLORSPACE_470_SYSTEM_BG: 1223 return CSC_BT601L; 1224 case V4L2_COLORSPACE_REC709: 1225 case V4L2_COLORSPACE_SMPTE240M: 1226 case V4L2_COLORSPACE_DEFAULT: 1227 return CSC_BT709L; 1228 case V4L2_COLORSPACE_JPEG: 1229 return CSC_BT601F; 1230 case V4L2_COLORSPACE_BT2020: 1231 return CSC_BT2020; 1232 default: 1233 return CSC_BT709L; 1234 } 1235 } 1236 1237 static bool is_uv_swap(u32 bus_format, u32 output_mode) 1238 { 1239 /* 1240 * FIXME: 1241 * 1242 * There is no media type for YUV444 output, 1243 * so when out_mode is AAAA or P888, assume output is YUV444 on 1244 * yuv format. 1245 * 1246 * From H/W testing, YUV444 mode need a rb swap. 1247 */ 1248 if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 || 1249 bus_format == MEDIA_BUS_FMT_VYUY8_1X16 || 1250 bus_format == MEDIA_BUS_FMT_YVYU8_2X8 || 1251 bus_format == MEDIA_BUS_FMT_VYUY8_2X8 || 1252 ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 || 1253 bus_format == MEDIA_BUS_FMT_YUV10_1X30) && 1254 (output_mode == ROCKCHIP_OUT_MODE_AAAA || 1255 output_mode == ROCKCHIP_OUT_MODE_P888))) 1256 return true; 1257 else 1258 return false; 1259 } 1260 1261 static inline bool is_hot_plug_devices(int output_type) 1262 { 1263 switch (output_type) { 1264 case DRM_MODE_CONNECTOR_HDMIA: 1265 case DRM_MODE_CONNECTOR_HDMIB: 1266 case DRM_MODE_CONNECTOR_TV: 1267 case DRM_MODE_CONNECTOR_DisplayPort: 1268 case DRM_MODE_CONNECTOR_VGA: 1269 case DRM_MODE_CONNECTOR_Unknown: 1270 return true; 1271 default: 1272 return false; 1273 } 1274 } 1275 1276 static struct vop2_win_data *vop2_find_win_by_phys_id(struct vop2 *vop2, int phys_id) 1277 { 1278 int i = 0; 1279 1280 for (i = 0; i < vop2->data->nr_layers; i++) { 1281 if (vop2->data->win_data[i].phys_id == phys_id) 1282 return &vop2->data->win_data[i]; 1283 } 1284 1285 return NULL; 1286 } 1287 1288 static struct vop2_power_domain_data *vop2_find_pd_data_by_id(struct vop2 *vop2, int pd_id) 1289 { 1290 int i = 0; 1291 1292 for (i = 0; i < vop2->data->nr_pd; i++) { 1293 if (vop2->data->pd[i].id == pd_id) 1294 return &vop2->data->pd[i]; 1295 } 1296 1297 return NULL; 1298 } 1299 1300 static int rockchip_vop2_gamma_lut_init(struct vop2 *vop2, 1301 struct display_state *state) 1302 { 1303 struct connector_state *conn_state = &state->conn_state; 1304 struct crtc_state *cstate = &state->crtc_state; 1305 struct resource gamma_res; 1306 fdt_size_t lut_size; 1307 int i, lut_len, ret = 0; 1308 u32 *lut_regs; 1309 u32 *lut_val; 1310 u32 r, g, b; 1311 u32 vp_offset = cstate->crtc_id * 0x100; 1312 struct base2_disp_info *disp_info = conn_state->disp_info; 1313 static int gamma_lut_en_num = 1; 1314 1315 if (gamma_lut_en_num > vop2->data->nr_gammas) { 1316 printf("warn: only %d vp support gamma\n", vop2->data->nr_gammas); 1317 return 0; 1318 } 1319 1320 if (!disp_info) 1321 return 0; 1322 1323 if (!disp_info->gamma_lut_data.size) 1324 return 0; 1325 1326 ret = ofnode_read_resource_byname(cstate->node, "gamma_lut", &gamma_res); 1327 if (ret) 1328 printf("failed to get gamma lut res\n"); 1329 lut_regs = (u32 *)gamma_res.start; 1330 lut_size = gamma_res.end - gamma_res.start + 1; 1331 if (lut_regs == (u32 *)FDT_ADDR_T_NONE) { 1332 printf("failed to get gamma lut register\n"); 1333 return 0; 1334 } 1335 lut_len = lut_size / 4; 1336 if (lut_len != 256 && lut_len != 1024) { 1337 printf("Warning: unsupport gamma lut table[%d]\n", lut_len); 1338 return 0; 1339 } 1340 lut_val = (u32 *)calloc(1, lut_size); 1341 for (i = 0; i < lut_len; i++) { 1342 r = disp_info->gamma_lut_data.lred[i] * (lut_len - 1) / 0xffff; 1343 g = disp_info->gamma_lut_data.lgreen[i] * (lut_len - 1) / 0xffff; 1344 b = disp_info->gamma_lut_data.lblue[i] * (lut_len - 1) / 0xffff; 1345 1346 lut_val[i] = b * lut_len * lut_len + g * lut_len + r; 1347 } 1348 1349 for (i = 0; i < lut_len; i++) 1350 writel(lut_val[i], lut_regs + i); 1351 1352 vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, 1353 GAMMA_PORT_SEL_MASK, GAMMA_PORT_SEL_SHIFT, 1354 cstate->crtc_id , false); 1355 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 1356 EN_MASK, DSP_LUT_EN_SHIFT, 1, false); 1357 gamma_lut_en_num++; 1358 1359 return 0; 1360 } 1361 1362 static int rockchip_vop2_cubic_lut_init(struct vop2 *vop2, 1363 struct display_state *state) 1364 { 1365 struct connector_state *conn_state = &state->conn_state; 1366 struct crtc_state *cstate = &state->crtc_state; 1367 int i, cubic_lut_len; 1368 u32 vp_offset = cstate->crtc_id * 0x100; 1369 struct base2_disp_info *disp_info = conn_state->disp_info; 1370 struct base2_cubic_lut_data *lut = &conn_state->disp_info->cubic_lut_data; 1371 u32 *cubic_lut_addr; 1372 1373 if (!disp_info || CONFIG_ROCKCHIP_CUBIC_LUT_SIZE == 0) 1374 return 0; 1375 1376 if (!disp_info->cubic_lut_data.size) 1377 return 0; 1378 1379 cubic_lut_addr = (u32 *)get_cubic_lut_buffer(cstate->crtc_id); 1380 cubic_lut_len = disp_info->cubic_lut_data.size; 1381 1382 for (i = 0; i < cubic_lut_len / 2; i++) { 1383 *cubic_lut_addr++ = ((lut->lred[2 * i]) & 0xfff) + 1384 ((lut->lgreen[2 * i] & 0xfff) << 12) + 1385 ((lut->lblue[2 * i] & 0xff) << 24); 1386 *cubic_lut_addr++ = ((lut->lblue[2 * i] & 0xf00) >> 8) + 1387 ((lut->lred[2 * i + 1] & 0xfff) << 4) + 1388 ((lut->lgreen[2 * i + 1] & 0xfff) << 16) + 1389 ((lut->lblue[2 * i + 1] & 0xf) << 28); 1390 *cubic_lut_addr++ = (lut->lblue[2 * i + 1] & 0xff0) >> 4; 1391 *cubic_lut_addr++ = 0; 1392 } 1393 1394 if (cubic_lut_len % 2) { 1395 *cubic_lut_addr++ = (lut->lred[2 * i] & 0xfff) + 1396 ((lut->lgreen[2 * i] & 0xfff) << 12) + 1397 ((lut->lblue[2 * i] & 0xff) << 24); 1398 *cubic_lut_addr++ = (lut->lblue[2 * i] & 0xf00) >> 8; 1399 *cubic_lut_addr++ = 0; 1400 *cubic_lut_addr = 0; 1401 } 1402 1403 vop2_writel(vop2, RK3568_VP0_3D_LUT_MST + vp_offset, 1404 get_cubic_lut_buffer(cstate->crtc_id)); 1405 vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL, 1406 EN_MASK, LUT_DMA_EN_SHIFT, 1, false); 1407 vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset, 1408 EN_MASK, VP0_3D_LUT_EN_SHIFT, 1, false); 1409 vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset, 1410 EN_MASK, VP0_3D_LUT_UPDATE_SHIFT, 1, false); 1411 1412 return 0; 1413 } 1414 1415 static void vop2_bcsh_reg_update(struct display_state *state, struct vop2 *vop2, 1416 struct bcsh_state *bcsh_state, int crtc_id) 1417 { 1418 struct crtc_state *cstate = &state->crtc_state; 1419 u32 vp_offset = crtc_id * 0x100; 1420 1421 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_MASK, 1422 BCSH_CTRL_R2Y_SHIFT, cstate->post_r2y_en, false); 1423 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_MASK, 1424 BCSH_CTRL_Y2R_SHIFT, cstate->post_y2r_en, false); 1425 1426 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_CSC_MODE_MASK, 1427 BCSH_CTRL_R2Y_CSC_MODE_SHIFT, cstate->post_csc_mode, false); 1428 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_CSC_MODE_MASK, 1429 BCSH_CTRL_Y2R_CSC_MODE_SHIFT, cstate->post_csc_mode, false); 1430 1431 if (!cstate->bcsh_en) { 1432 vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset, 1433 BCSH_EN_MASK, BCSH_EN_SHIFT, 0, false); 1434 return; 1435 } 1436 1437 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1438 BCSH_BRIGHTNESS_MASK, BCSH_BRIGHTNESS_SHIFT, 1439 bcsh_state->brightness, false); 1440 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1441 BCSH_CONTRAST_MASK, BCSH_CONTRAST_SHIFT, bcsh_state->contrast, false); 1442 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1443 BCSH_SATURATION_MASK, BCSH_SATURATION_SHIFT, 1444 bcsh_state->saturation * bcsh_state->contrast / 0x100, false); 1445 vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset, 1446 BCSH_SIN_HUE_MASK, BCSH_SIN_HUE_SHIFT, bcsh_state->sin_hue, false); 1447 vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset, 1448 BCSH_COS_HUE_MASK, BCSH_COS_HUE_SHIFT, bcsh_state->cos_hue, false); 1449 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1450 BCSH_OUT_MODE_MASK, BCSH_OUT_MODE_SHIFT, 1451 BCSH_OUT_MODE_NORMAL_VIDEO, false); 1452 vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset, 1453 BCSH_EN_MASK, BCSH_EN_SHIFT, 1, false); 1454 } 1455 1456 static void vop2_tv_config_update(struct display_state *state, struct vop2 *vop2) 1457 { 1458 struct connector_state *conn_state = &state->conn_state; 1459 struct base_bcsh_info *bcsh_info; 1460 struct crtc_state *cstate = &state->crtc_state; 1461 struct bcsh_state bcsh_state; 1462 int brightness, contrast, saturation, hue, sin_hue, cos_hue; 1463 1464 if (!conn_state->disp_info) 1465 return; 1466 bcsh_info = &conn_state->disp_info->bcsh_info; 1467 if (!bcsh_info) 1468 return; 1469 1470 if (bcsh_info->brightness != 50 || 1471 bcsh_info->contrast != 50 || 1472 bcsh_info->saturation != 50 || bcsh_info->hue != 50) 1473 cstate->bcsh_en = true; 1474 1475 if (cstate->bcsh_en) { 1476 if (!cstate->yuv_overlay) 1477 cstate->post_r2y_en = 1; 1478 if (!is_yuv_output(conn_state->bus_format)) 1479 cstate->post_y2r_en = 1; 1480 } else { 1481 if (!cstate->yuv_overlay && is_yuv_output(conn_state->bus_format)) 1482 cstate->post_r2y_en = 1; 1483 if (cstate->yuv_overlay && !is_yuv_output(conn_state->bus_format)) 1484 cstate->post_y2r_en = 1; 1485 } 1486 1487 cstate->post_csc_mode = vop2_convert_csc_mode(conn_state->color_space); 1488 1489 if (cstate->feature & VOP_FEATURE_OUTPUT_10BIT) 1490 brightness = interpolate(0, -128, 100, 127, 1491 bcsh_info->brightness); 1492 else 1493 brightness = interpolate(0, -32, 100, 31, 1494 bcsh_info->brightness); 1495 contrast = interpolate(0, 0, 100, 511, bcsh_info->contrast); 1496 saturation = interpolate(0, 0, 100, 511, bcsh_info->saturation); 1497 hue = interpolate(0, -30, 100, 30, bcsh_info->hue); 1498 1499 1500 /* 1501 * a:[-30~0): 1502 * sin_hue = 0x100 - sin(a)*256; 1503 * cos_hue = cos(a)*256; 1504 * a:[0~30] 1505 * sin_hue = sin(a)*256; 1506 * cos_hue = cos(a)*256; 1507 */ 1508 sin_hue = fixp_sin32(hue) >> 23; 1509 cos_hue = fixp_cos32(hue) >> 23; 1510 1511 bcsh_state.brightness = brightness; 1512 bcsh_state.contrast = contrast; 1513 bcsh_state.saturation = saturation; 1514 bcsh_state.sin_hue = sin_hue; 1515 bcsh_state.cos_hue = cos_hue; 1516 1517 vop2_bcsh_reg_update(state, vop2, &bcsh_state, cstate->crtc_id); 1518 if (cstate->splice_mode) 1519 vop2_bcsh_reg_update(state, vop2, &bcsh_state, cstate->splice_crtc_id); 1520 } 1521 1522 static void vop2_setup_dly_for_vp(struct display_state *state, struct vop2 *vop2, int crtc_id) 1523 { 1524 struct connector_state *conn_state = &state->conn_state; 1525 struct drm_display_mode *mode = &conn_state->mode; 1526 struct crtc_state *cstate = &state->crtc_state; 1527 u32 bg_ovl_dly, bg_dly, pre_scan_dly; 1528 u16 hdisplay = mode->crtc_hdisplay; 1529 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 1530 1531 bg_ovl_dly = cstate->crtc->vps[crtc_id].bg_ovl_dly; 1532 bg_dly = vop2->data->vp_data[crtc_id].pre_scan_max_dly; 1533 bg_dly -= bg_ovl_dly; 1534 1535 if (cstate->splice_mode) 1536 pre_scan_dly = bg_dly + (hdisplay >> 2) - 1; 1537 else 1538 pre_scan_dly = bg_dly + (hdisplay >> 1) - 1; 1539 1540 if (vop2->version == VOP_VERSION_RK3588 && hsync_len < 8) 1541 hsync_len = 8; 1542 pre_scan_dly = (pre_scan_dly << 16) | hsync_len; 1543 vop2_mask_write(vop2, RK3568_VP0_BG_MIX_CTRL + crtc_id * 4, 1544 BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false); 1545 vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + (crtc_id * 0x100), pre_scan_dly); 1546 } 1547 1548 static void vop2_post_config(struct display_state *state, struct vop2 *vop2) 1549 { 1550 struct connector_state *conn_state = &state->conn_state; 1551 struct drm_display_mode *mode = &conn_state->mode; 1552 struct crtc_state *cstate = &state->crtc_state; 1553 u32 vp_offset = (cstate->crtc_id * 0x100); 1554 u16 vtotal = mode->crtc_vtotal; 1555 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 1556 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 1557 u16 hdisplay = mode->crtc_hdisplay; 1558 u16 vdisplay = mode->crtc_vdisplay; 1559 u16 hsize = 1560 hdisplay * (conn_state->overscan.left_margin + 1561 conn_state->overscan.right_margin) / 200; 1562 u16 vsize = 1563 vdisplay * (conn_state->overscan.top_margin + 1564 conn_state->overscan.bottom_margin) / 200; 1565 u16 hact_end, vact_end; 1566 u32 val; 1567 1568 hsize = round_down(hsize, 2); 1569 vsize = round_down(vsize, 2); 1570 1571 hact_st += hdisplay * (100 - conn_state->overscan.left_margin) / 200; 1572 hact_end = hact_st + hsize; 1573 val = hact_st << 16; 1574 val |= hact_end; 1575 1576 vop2_writel(vop2, RK3568_VP0_POST_DSP_HACT_INFO + vp_offset, val); 1577 vact_st += vdisplay * (100 - conn_state->overscan.top_margin) / 200; 1578 vact_end = vact_st + vsize; 1579 val = vact_st << 16; 1580 val |= vact_end; 1581 vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO + vp_offset, val); 1582 val = scl_cal_scale2(vdisplay, vsize) << 16; 1583 val |= scl_cal_scale2(hdisplay, hsize); 1584 vop2_writel(vop2, RK3568_VP0_POST_SCL_FACTOR_YRGB + vp_offset, val); 1585 #define POST_HORIZONTAL_SCALEDOWN_EN(x) ((x) << 0) 1586 #define POST_VERTICAL_SCALEDOWN_EN(x) ((x) << 1) 1587 vop2_writel(vop2, RK3568_VP0_POST_SCL_CTRL + vp_offset, 1588 POST_HORIZONTAL_SCALEDOWN_EN(hdisplay != hsize) | 1589 POST_VERTICAL_SCALEDOWN_EN(vdisplay != vsize)); 1590 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 1591 u16 vact_st_f1 = vtotal + vact_st + 1; 1592 u16 vact_end_f1 = vact_st_f1 + vsize; 1593 1594 val = vact_st_f1 << 16 | vact_end_f1; 1595 vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO_F1 + vp_offset, val); 1596 } 1597 1598 vop2_setup_dly_for_vp(state, vop2, cstate->crtc_id); 1599 if (cstate->splice_mode) 1600 vop2_setup_dly_for_vp(state, vop2, cstate->splice_crtc_id); 1601 } 1602 1603 /* 1604 * Read VOP internal power domain on/off status. 1605 * We should query BISR_STS register in PMU for 1606 * power up/down status when memory repair is enabled. 1607 * Return value: 1 for power on, 0 for power off; 1608 */ 1609 static int vop2_wait_power_domain_on(struct vop2 *vop2, struct vop2_power_domain_data *pd_data) 1610 { 1611 int val = 0; 1612 int shift = 0; 1613 int shift_factor = 0; 1614 bool is_bisr_en = false; 1615 1616 /* 1617 * The order of pd status bits in BISR_STS register 1618 * is different from that in VOP SYS_STS register. 1619 */ 1620 if (pd_data->id == VOP2_PD_DSC_8K || 1621 pd_data->id == VOP2_PD_DSC_4K || 1622 pd_data->id == VOP2_PD_ESMART) 1623 shift_factor = 1; 1624 1625 shift = RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT + generic_ffs(pd_data->id) - 1 - shift_factor; 1626 is_bisr_en = vop2_grf_readl(vop2, vop2->sys_pmu, RK3588_PMU_BISR_CON3, EN_MASK, shift); 1627 if (is_bisr_en) { 1628 shift = RK3588_PD_CLUSTER0_PWR_STAT_SHIFI + generic_ffs(pd_data->id) - 1 - shift_factor; 1629 1630 return readl_poll_timeout(vop2->sys_pmu + RK3588_PMU_BISR_STATUS5, val, 1631 ((val >> shift) & 0x1), 50 * 1000); 1632 } else { 1633 shift = RK3588_CLUSTER0_PD_STATUS_SHIFT + generic_ffs(pd_data->id) - 1; 1634 1635 return readl_poll_timeout(vop2->regs + RK3568_SYS_STATUS0, val, 1636 !((val >> shift) & 0x1), 50 * 1000); 1637 } 1638 } 1639 1640 static int vop2_power_domain_on(struct vop2 *vop2, int pd_id) 1641 { 1642 struct vop2_power_domain_data *pd_data; 1643 int ret = 0; 1644 1645 if (!pd_id) 1646 return 0; 1647 1648 pd_data = vop2_find_pd_data_by_id(vop2, pd_id); 1649 if (!pd_data) { 1650 printf("can't find pd_data by id\n"); 1651 return -EINVAL; 1652 } 1653 1654 if (pd_data->parent_id) { 1655 ret = vop2_power_domain_on(vop2, pd_data->parent_id); 1656 if (ret) { 1657 printf("can't open parent power domain\n"); 1658 return -EINVAL; 1659 } 1660 } 1661 1662 vop2_mask_write(vop2, RK3568_SYS_PD_CTRL, EN_MASK, 1663 RK3588_CLUSTER0_PD_EN_SHIFT + generic_ffs(pd_id) - 1, 0, false); 1664 ret = vop2_wait_power_domain_on(vop2, pd_data); 1665 if (ret) { 1666 printf("wait vop2 power domain timeout\n"); 1667 return ret; 1668 } 1669 1670 return 0; 1671 } 1672 1673 static void rk3588_vop2_regsbak(struct vop2 *vop2) 1674 { 1675 u32 *base = vop2->regs; 1676 int i = 0; 1677 1678 /* 1679 * No need to backup HDR/DSC/GAMMA_LUT/BPP_LUT/MMU 1680 */ 1681 for (i = 0; i < (vop2->reg_len >> 2); i++) 1682 vop2->regsbak[i] = base[i]; 1683 } 1684 1685 static void vop2_global_initial(struct vop2 *vop2, struct display_state *state) 1686 { 1687 struct crtc_state *cstate = &state->crtc_state; 1688 int i, j, port_mux = 0, total_used_layer = 0; 1689 u8 shift = 0; 1690 int layer_phy_id = 0; 1691 u32 layer_nr = 0; 1692 struct vop2_win_data *win_data; 1693 struct vop2_vp_plane_mask *plane_mask; 1694 1695 if (vop2->global_init) 1696 return; 1697 1698 /* OTP must enable at the first time, otherwise mirror layer register is error */ 1699 if (soc_is_rk3566()) 1700 vop2_mask_write(vop2, RK3568_SYS_OTP_WIN_EN, EN_MASK, 1701 OTP_WIN_EN_SHIFT, 1, false); 1702 1703 if (cstate->crtc->assign_plane) {/* dts assign plane */ 1704 u32 plane_mask; 1705 int primary_plane_id; 1706 1707 for (i = 0; i < vop2->data->nr_vps; i++) { 1708 plane_mask = cstate->crtc->vps[i].plane_mask; 1709 vop2->vp_plane_mask[i].plane_mask = plane_mask; 1710 layer_nr = hweight32(plane_mask); /* use bitmap to store plane mask */ 1711 vop2->vp_plane_mask[i].attached_layers_nr = layer_nr; 1712 primary_plane_id = vop2_get_primary_plane(vop2, plane_mask); 1713 vop2->vp_plane_mask[i].primary_plane_id = primary_plane_id; 1714 vop2->vp_plane_mask[i].plane_mask = plane_mask; 1715 1716 /* plane mask[bitmap] convert into layer phy id[enum vop2_layer_phy_id]*/ 1717 for (j = 0; j < layer_nr; j++) { 1718 vop2->vp_plane_mask[i].attached_layers[j] = ffs(plane_mask) - 1; 1719 plane_mask &= ~BIT(vop2->vp_plane_mask[i].attached_layers[j]); 1720 } 1721 } 1722 } else {/* need soft assign plane mask */ 1723 /* find the first unplug devices and set it as main display */ 1724 int main_vp_index = -1; 1725 int active_vp_num = 0; 1726 1727 for (i = 0; i < vop2->data->nr_vps; i++) { 1728 if (cstate->crtc->vps[i].enable) 1729 active_vp_num++; 1730 } 1731 printf("VOP have %d active VP\n", active_vp_num); 1732 1733 if (soc_is_rk3566() && active_vp_num > 2) 1734 printf("ERROR: rk3566 only support 2 display output!!\n"); 1735 plane_mask = vop2->data->plane_mask; 1736 plane_mask += (active_vp_num - 1) * VOP2_VP_MAX; 1737 1738 for (i = 0; i < vop2->data->nr_vps; i++) { 1739 if (!is_hot_plug_devices(cstate->crtc->vps[i].output_type)) { 1740 vop2->vp_plane_mask[i] = plane_mask[0]; /* the first store main display plane mask*/ 1741 main_vp_index = i; 1742 break; 1743 } 1744 } 1745 1746 /* if no find unplug devices, use vp0 as main display */ 1747 if (main_vp_index < 0) { 1748 main_vp_index = 0; 1749 vop2->vp_plane_mask[0] = plane_mask[0]; 1750 } 1751 1752 j = 1; /* plane_mask[0] store main display, so we from plane_mask[1] */ 1753 1754 /* init other display except main display */ 1755 for (i = 0; i < vop2->data->nr_vps; i++) { 1756 if (i == main_vp_index || !cstate->crtc->vps[i].enable) /* main display or no connect devices */ 1757 continue; 1758 vop2->vp_plane_mask[i] = plane_mask[j++]; 1759 } 1760 1761 /* store plane mask for vop2_fixup_dts */ 1762 for (i = 0; i < vop2->data->nr_vps; i++) { 1763 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 1764 /* rk3566 only support 3+3 policy */ 1765 if (soc_is_rk3566() && active_vp_num == 1) { 1766 if (cstate->crtc->vps[i].enable) { 1767 for (j = 0; j < 3; j++) { 1768 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 1769 vop2->vp_plane_mask[i].plane_mask |= BIT(layer_phy_id); 1770 } 1771 } 1772 } else { 1773 for (j = 0; j < layer_nr; j++) { 1774 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 1775 vop2->vp_plane_mask[i].plane_mask |= BIT(layer_phy_id); 1776 } 1777 } 1778 } 1779 } 1780 1781 if (vop2->version == VOP_VERSION_RK3588) 1782 rk3588_vop2_regsbak(vop2); 1783 else 1784 memcpy(vop2->regsbak, vop2->regs, vop2->reg_len); 1785 1786 vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, 1787 OVL_PORT_MUX_REG_DONE_IMD_SHIFT, 1, false); 1788 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 1789 IF_CTRL_REG_DONE_IMD_SHIFT, 1, false); 1790 1791 for (i = 0; i < vop2->data->nr_vps; i++) { 1792 printf("vp%d have layer nr:%d[", i, vop2->vp_plane_mask[i].attached_layers_nr); 1793 for (j = 0; j < vop2->vp_plane_mask[i].attached_layers_nr; j++) 1794 printf("%d ", vop2->vp_plane_mask[i].attached_layers[j]); 1795 printf("], primary plane: %d\n", vop2->vp_plane_mask[i].primary_plane_id); 1796 } 1797 1798 shift = 0; 1799 /* layer sel win id */ 1800 for (i = 0; i < vop2->data->nr_vps; i++) { 1801 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 1802 for (j = 0; j < layer_nr; j++) { 1803 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 1804 win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 1805 vop2_mask_write(vop2, RK3568_OVL_LAYER_SEL, LAYER_SEL_MASK, 1806 shift, win_data->layer_sel_win_id, false); 1807 shift += 4; 1808 } 1809 } 1810 1811 /* win sel port */ 1812 for (i = 0; i < vop2->data->nr_vps; i++) { 1813 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 1814 for (j = 0; j < layer_nr; j++) { 1815 if (!vop2->vp_plane_mask[i].attached_layers[j]) 1816 continue; 1817 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 1818 win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 1819 shift = win_data->win_sel_port_offset * 2; 1820 vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, LAYER_SEL_PORT_MASK, 1821 LAYER_SEL_PORT_SHIFT + shift, i, false); 1822 } 1823 } 1824 1825 /** 1826 * port mux config 1827 */ 1828 for (i = 0; i < vop2->data->nr_vps; i++) { 1829 shift = i * 4; 1830 if (vop2->vp_plane_mask[i].attached_layers_nr) { 1831 total_used_layer += vop2->vp_plane_mask[i].attached_layers_nr; 1832 port_mux = total_used_layer - 1; 1833 } else { 1834 port_mux = 8; 1835 } 1836 1837 if (i == vop2->data->nr_vps - 1) 1838 port_mux = vop2->data->nr_mixers; 1839 1840 cstate->crtc->vps[i].bg_ovl_dly = (vop2->data->nr_mixers - port_mux) << 1; 1841 vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, PORT_MUX_MASK, 1842 PORT_MUX_SHIFT + shift, port_mux, false); 1843 } 1844 1845 if (vop2->version == VOP_VERSION_RK3568) 1846 vop2_writel(vop2, RK3568_AUTO_GATING_CTRL, 0); 1847 1848 vop2->global_init = true; 1849 } 1850 1851 static int vop2_initial(struct vop2 *vop2, struct display_state *state) 1852 { 1853 struct crtc_state *cstate = &state->crtc_state; 1854 int ret; 1855 1856 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 1857 ret = clk_set_defaults(cstate->dev); 1858 if (ret) 1859 debug("%s clk_set_defaults failed %d\n", __func__, ret); 1860 1861 rockchip_vop2_gamma_lut_init(vop2, state); 1862 rockchip_vop2_cubic_lut_init(vop2, state); 1863 1864 return 0; 1865 } 1866 1867 /* 1868 * VOP2 have multi video ports. 1869 * video port ------- crtc 1870 */ 1871 static int rockchip_vop2_preinit(struct display_state *state) 1872 { 1873 struct crtc_state *cstate = &state->crtc_state; 1874 const struct vop2_data *vop2_data = cstate->crtc->data; 1875 1876 if (!rockchip_vop2) { 1877 rockchip_vop2 = calloc(1, sizeof(struct vop2)); 1878 if (!rockchip_vop2) 1879 return -ENOMEM; 1880 rockchip_vop2->regs = dev_read_addr_ptr(cstate->dev); 1881 rockchip_vop2->regsbak = malloc(RK3568_MAX_REG); 1882 rockchip_vop2->reg_len = RK3568_MAX_REG; 1883 rockchip_vop2->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 1884 if (rockchip_vop2->grf <= 0) 1885 printf("%s: Get syscon grf failed (ret=%p)\n", __func__, rockchip_vop2->grf); 1886 rockchip_vop2->version = vop2_data->version; 1887 rockchip_vop2->data = vop2_data; 1888 if (rockchip_vop2->version == VOP_VERSION_RK3588) { 1889 struct regmap *map; 1890 1891 rockchip_vop2->vop_grf = syscon_get_first_range(ROCKCHIP_SYSCON_VOP_GRF); 1892 if (rockchip_vop2->vop_grf <= 0) 1893 printf("%s: Get syscon vop_grf failed (ret=%p)\n", __func__, rockchip_vop2->vop_grf); 1894 map = syscon_regmap_lookup_by_phandle(cstate->dev, "rockchip,vo1-grf"); 1895 rockchip_vop2->vo1_grf = regmap_get_range(map, 0); 1896 if (rockchip_vop2->vo1_grf <= 0) 1897 printf("%s: Get syscon vo1_grf failed (ret=%p)\n", __func__, rockchip_vop2->vo1_grf); 1898 rockchip_vop2->sys_pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU); 1899 if (rockchip_vop2->sys_pmu <= 0) 1900 printf("%s: Get syscon sys_pmu failed (ret=%p)\n", __func__, rockchip_vop2->sys_pmu); 1901 } 1902 } 1903 1904 cstate->private = rockchip_vop2; 1905 cstate->max_output = vop2_data->vp_data[cstate->crtc_id].max_output; 1906 cstate->feature = vop2_data->vp_data[cstate->crtc_id].feature; 1907 1908 vop2_global_initial(rockchip_vop2, state); 1909 1910 return 0; 1911 } 1912 1913 /* 1914 * calc the dclk on rk3588 1915 * the available div of dclk is 1, 2, 4 1916 * 1917 */ 1918 static unsigned long vop2_calc_dclk(unsigned long child_clk, unsigned long max_dclk) 1919 { 1920 if (child_clk * 4 <= max_dclk) 1921 return child_clk * 4; 1922 else if (child_clk * 2 <= max_dclk) 1923 return child_clk * 2; 1924 else if (child_clk <= max_dclk) 1925 return child_clk; 1926 else 1927 return 0; 1928 } 1929 1930 /* 1931 * 4 pixclk/cycle on rk3588 1932 * RGB/eDP/HDMI: if_pixclk >= dclk_core 1933 * DP: dp_pixclk = dclk_out <= dclk_core 1934 * DSI: mipi_pixclk <= dclk_out <= dclk_core 1935 */ 1936 static unsigned long vop2_calc_cru_cfg(struct display_state *state, 1937 int *dclk_core_div, int *dclk_out_div, 1938 int *if_pixclk_div, int *if_dclk_div) 1939 { 1940 struct crtc_state *cstate = &state->crtc_state; 1941 struct connector_state *conn_state = &state->conn_state; 1942 struct drm_display_mode *mode = &conn_state->mode; 1943 struct vop2 *vop2 = cstate->private; 1944 unsigned long v_pixclk = mode->clock; 1945 unsigned long dclk_core_rate = v_pixclk >> 2; 1946 unsigned long dclk_rate = v_pixclk; 1947 unsigned long dclk_out_rate; 1948 u64 if_dclk_rate; 1949 u64 if_pixclk_rate; 1950 int output_type = conn_state->type; 1951 int output_mode = conn_state->output_mode; 1952 int K = 1; 1953 1954 if (output_type == DRM_MODE_CONNECTOR_HDMIA) { 1955 /* 1956 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate 1957 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate 1958 */ 1959 if (output_mode == ROCKCHIP_OUT_MODE_YUV420) { 1960 dclk_rate = dclk_rate >> 1; 1961 K = 2; 1962 } 1963 if (cstate->dsc_enable) { 1964 if_pixclk_rate = cstate->dsc_cds_clk_rate << 1; 1965 if_dclk_rate = cstate->dsc_cds_clk_rate; 1966 } else { 1967 if_pixclk_rate = (dclk_core_rate << 1) / K; 1968 if_dclk_rate = dclk_core_rate / K; 1969 } 1970 1971 if (v_pixclk > VOP2_MAX_DCLK_RATE) 1972 dclk_rate = vop2_calc_dclk(dclk_core_rate, vop2->data->vp_data->max_dclk); 1973 1974 if (!dclk_rate) { 1975 printf("DP if_pixclk_rate out of range(max_dclk: %d KHZ, dclk_core: %lld KHZ)\n", 1976 vop2->data->vp_data->max_dclk, if_pixclk_rate); 1977 return -EINVAL; 1978 } 1979 *if_pixclk_div = dclk_rate / if_pixclk_rate; 1980 *if_dclk_div = dclk_rate / if_dclk_rate; 1981 *dclk_core_div = dclk_rate / dclk_core_rate; 1982 printf("dclk:%lu,if_pixclk_div;%d,if_dclk_div:%d\n", 1983 dclk_rate, *if_pixclk_div, *if_dclk_div); 1984 } else if (output_type == DRM_MODE_CONNECTOR_eDP) { 1985 /* edp_pixclk = edp_dclk > dclk_core */ 1986 if_pixclk_rate = v_pixclk / K; 1987 if_dclk_rate = v_pixclk / K; 1988 dclk_rate = if_pixclk_rate * K; 1989 *dclk_core_div = dclk_rate / dclk_core_rate; 1990 *if_pixclk_div = dclk_rate / if_pixclk_rate; 1991 *if_dclk_div = *if_pixclk_div; 1992 } else if (output_type == DRM_MODE_CONNECTOR_DisplayPort) { 1993 if (output_mode == ROCKCHIP_OUT_MODE_YUV420) 1994 dclk_out_rate = v_pixclk >> 3; 1995 else 1996 dclk_out_rate = v_pixclk >> 2; 1997 1998 dclk_rate = vop2_calc_dclk(dclk_out_rate, vop2->data->vp_data->max_dclk); 1999 if (!dclk_rate) { 2000 printf("DP dclk_core out of range(max_dclk: %d KHZ, dclk_core: %ld KHZ)\n", 2001 vop2->data->vp_data->max_dclk, dclk_core_rate); 2002 return -EINVAL; 2003 } 2004 *dclk_out_div = dclk_rate / dclk_out_rate; 2005 *dclk_core_div = dclk_rate / dclk_core_rate; 2006 2007 } else if (output_type == DRM_MODE_CONNECTOR_DSI) { 2008 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 2009 K = 2; 2010 if (cstate->dsc_enable) 2011 /* dsc output is 96bit, dsi input is 192 bit */ 2012 if_pixclk_rate = cstate->dsc_cds_clk_rate >> 1; 2013 else 2014 if_pixclk_rate = dclk_core_rate / K; 2015 /* dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4 */ 2016 dclk_out_rate = dclk_core_rate / K; 2017 /* dclk_rate = N * dclk_core_rate N = (1,2,4 ), we get a little factor here */ 2018 dclk_rate = vop2_calc_dclk(dclk_out_rate, vop2->data->vp_data->max_dclk); 2019 if (!dclk_rate) { 2020 printf("MIPI dclk out of range(max_dclk: %d KHZ, dclk_rate: %ld KHZ)\n", 2021 vop2->data->vp_data->max_dclk, dclk_rate); 2022 return -EINVAL; 2023 } 2024 2025 if (cstate->dsc_enable) 2026 dclk_rate = dclk_rate >> 1; 2027 2028 *dclk_out_div = dclk_rate / dclk_out_rate; 2029 *dclk_core_div = dclk_rate / dclk_core_rate; 2030 *if_pixclk_div = 1; /*mipi pixclk == dclk_out*/ 2031 if (cstate->dsc_enable) 2032 *if_pixclk_div = dclk_out_rate / if_pixclk_rate; 2033 2034 } else if (output_type == DRM_MODE_CONNECTOR_DPI) { 2035 dclk_rate = v_pixclk; 2036 *dclk_core_div = dclk_rate / dclk_core_rate; 2037 } 2038 2039 *if_pixclk_div = ilog2(*if_pixclk_div); 2040 *if_dclk_div = ilog2(*if_dclk_div); 2041 *dclk_core_div = ilog2(*dclk_core_div); 2042 *dclk_out_div = ilog2(*dclk_out_div); 2043 2044 return dclk_rate; 2045 } 2046 2047 static int vop2_calc_dsc_clk(struct display_state *state) 2048 { 2049 struct connector_state *conn_state = &state->conn_state; 2050 struct drm_display_mode *mode = &conn_state->mode; 2051 struct crtc_state *cstate = &state->crtc_state; 2052 u64 v_pixclk = mode->clock; /* video timing pixclk */ 2053 u8 k = 1; 2054 2055 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 2056 k = 2; 2057 2058 cstate->dsc_txp_clk_rate = v_pixclk; 2059 do_div(cstate->dsc_txp_clk_rate, (cstate->dsc_pixel_num * k)); 2060 2061 cstate->dsc_pxl_clk_rate = v_pixclk; 2062 do_div(cstate->dsc_pxl_clk_rate, (cstate->dsc_slice_num * k)); 2063 2064 /* dsc_cds = crtc_clock / (cds_dat_width / bits_per_pixel) 2065 * cds_dat_width = 96; 2066 * bits_per_pixel = [8-12]; 2067 * As only support 1/2/4 div, so we set dsc_cds = crtc_clock / 8; 2068 */ 2069 cstate->dsc_cds_clk_rate = v_pixclk / 8; 2070 2071 return 0; 2072 } 2073 2074 static unsigned long rk3588_vop2_if_cfg(struct display_state *state) 2075 { 2076 struct crtc_state *cstate = &state->crtc_state; 2077 struct connector_state *conn_state = &state->conn_state; 2078 struct drm_display_mode *mode = &conn_state->mode; 2079 struct rockchip_dsc_sink_cap *dsc_sink_cap = &cstate->dsc_sink_cap; 2080 struct vop2 *vop2 = cstate->private; 2081 u32 vp_offset = (cstate->crtc_id * 0x100); 2082 u16 hdisplay = mode->crtc_hdisplay; 2083 int output_if = conn_state->output_if; 2084 int dclk_core_div = 0; 2085 int dclk_out_div = 0; 2086 int if_pixclk_div = 0; 2087 int if_dclk_div = 0; 2088 unsigned long dclk_rate; 2089 u32 val; 2090 2091 if (output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) { 2092 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0; 2093 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0; 2094 } else { 2095 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 2096 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 2097 } 2098 2099 if (cstate->dsc_enable) { 2100 int k = 1; 2101 2102 if (!vop2->data->nr_dscs) { 2103 printf("Unsupported DSC\n"); 2104 return 0; 2105 } 2106 2107 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 2108 k = 2; 2109 2110 cstate->dsc_id = output_if & (VOP_OUTPUT_IF_MIPI0 | VOP_OUTPUT_IF_HDMI0) ? 0 : 1; 2111 cstate->dsc_slice_num = hdisplay / dsc_sink_cap->slice_width / k; 2112 cstate->dsc_pixel_num = cstate->dsc_slice_num > 4 ? 4 : cstate->dsc_slice_num; 2113 2114 vop2_calc_dsc_clk(state); 2115 printf("Enable DSC%d slice:%dx%d, slice num:%d\n", 2116 cstate->dsc_id, dsc_sink_cap->slice_width, 2117 dsc_sink_cap->slice_height, cstate->dsc_slice_num); 2118 } 2119 2120 dclk_rate = vop2_calc_cru_cfg(state, &dclk_core_div, &dclk_out_div, &if_pixclk_div, &if_dclk_div); 2121 2122 if (output_if & VOP_OUTPUT_IF_RGB) { 2123 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 2124 4, false); 2125 } 2126 2127 if (output_if & VOP_OUTPUT_IF_BT1120) { 2128 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 2129 3, false); 2130 } 2131 2132 if (output_if & VOP_OUTPUT_IF_BT656) { 2133 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 2134 2, false); 2135 } 2136 2137 if (output_if & VOP_OUTPUT_IF_MIPI0) { 2138 if (cstate->crtc_id == 2) 2139 val = 0; 2140 else 2141 val = 1; 2142 2143 if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE) 2144 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2145 RK3588_MIPI_DSI0_MODE_SEL_SHIFT, 1, false); 2146 2147 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI0_EN_SHIFT, 2148 1, false); 2149 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 1, RK3588_MIPI0_MUX_SHIFT, val, false); 2150 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI0_PIXCLK_DIV_SHIFT, 2151 if_pixclk_div, false); 2152 2153 if (conn_state->hold_mode) { 2154 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2155 EN_MASK, EDPI_TE_EN, 1, false); 2156 2157 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2158 EN_MASK, EDPI_WMS_HOLD_EN, 1, false); 2159 } 2160 } 2161 2162 if (output_if & VOP_OUTPUT_IF_MIPI1) { 2163 if (cstate->crtc_id == 2) 2164 val = 0; 2165 else if (cstate->crtc_id == 3) 2166 val = 1; 2167 else 2168 val = 3; /*VP1*/ 2169 if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE) 2170 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2171 RK3588_MIPI_DSI1_MODE_SEL_SHIFT, 1, false); 2172 2173 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI1_EN_SHIFT, 2174 1, false); 2175 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, MIPI1_MUX_SHIFT, 2176 val, false); 2177 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI1_PIXCLK_DIV_SHIFT, 2178 if_pixclk_div, false); 2179 2180 if (conn_state->hold_mode) { 2181 /* UNDO: RK3588 VP1->DSC1->DSI1 only can support soft TE mode */ 2182 if (vop2->version == VOP_VERSION_RK3588 && val == 3) 2183 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2184 EN_MASK, EDPI_TE_EN, 0, false); 2185 else 2186 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2187 EN_MASK, EDPI_TE_EN, 1, false); 2188 2189 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2190 EN_MASK, EDPI_WMS_HOLD_EN, 1, false); 2191 } 2192 } 2193 2194 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 2195 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2196 RK3568_MIPI_DUAL_EN_SHIFT, 1, false); 2197 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 2198 MIPI_DUAL_EN_SHIFT, 1, false); 2199 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 2200 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2201 EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1, 2202 false); 2203 } 2204 2205 if (output_if & VOP_OUTPUT_IF_eDP0) { 2206 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP0_EN_SHIFT, 2207 1, false); 2208 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT, 2209 cstate->crtc_id, false); 2210 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT, 2211 if_dclk_div, false); 2212 2213 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT, 2214 if_pixclk_div, false); 2215 2216 vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 2217 RK3588_GRF_EDP0_ENABLE_SHIFT, 1); 2218 } 2219 2220 if (output_if & VOP_OUTPUT_IF_eDP1) { 2221 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP1_EN_SHIFT, 2222 1, false); 2223 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT, 2224 cstate->crtc_id, false); 2225 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT, 2226 if_dclk_div, false); 2227 2228 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT, 2229 if_pixclk_div, false); 2230 2231 vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 2232 RK3588_GRF_EDP1_ENABLE_SHIFT, 1); 2233 } 2234 2235 if (output_if & VOP_OUTPUT_IF_HDMI0) { 2236 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI0_EN_SHIFT, 2237 1, false); 2238 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT, 2239 cstate->crtc_id, false); 2240 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT, 2241 if_dclk_div, false); 2242 2243 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT, 2244 if_pixclk_div, false); 2245 2246 vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 2247 RK3588_GRF_HDMITX0_ENABLE_SHIFT, 1); 2248 vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0, 2249 HDMI_SYNC_POL_MASK, 2250 HDMI0_SYNC_POL_SHIFT, val); 2251 } 2252 2253 if (output_if & VOP_OUTPUT_IF_HDMI1) { 2254 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI1_EN_SHIFT, 2255 1, false); 2256 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT, 2257 cstate->crtc_id, false); 2258 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT, 2259 if_dclk_div, false); 2260 2261 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT, 2262 if_pixclk_div, false); 2263 2264 vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 2265 RK3588_GRF_HDMITX1_ENABLE_SHIFT, 1); 2266 vop2_grf_writel(vop2, vop2->vo1_grf, RK3588_GRF_VO1_CON0, 2267 HDMI_SYNC_POL_MASK, 2268 HDMI1_SYNC_POL_SHIFT, val); 2269 } 2270 2271 if (output_if & VOP_OUTPUT_IF_DP0) { 2272 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP0_EN_SHIFT, 2273 1, false); 2274 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP0_MUX_SHIFT, 2275 cstate->crtc_id, false); 2276 vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK, 2277 RK3588_DP0_PIN_POL_SHIFT, val, false); 2278 } 2279 2280 if (output_if & VOP_OUTPUT_IF_DP1) { 2281 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP1_EN_SHIFT, 2282 1, false); 2283 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP1_MUX_SHIFT, 2284 cstate->crtc_id, false); 2285 vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK, 2286 RK3588_DP1_PIN_POL_SHIFT, val, false); 2287 } 2288 2289 vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3, 2290 DCLK_CORE_DIV_SHIFT, dclk_core_div, false); 2291 vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3, 2292 DCLK_OUT_DIV_SHIFT, dclk_out_div, false); 2293 2294 return dclk_rate; 2295 } 2296 2297 static unsigned long rk3568_vop2_if_cfg(struct display_state *state) 2298 { 2299 struct crtc_state *cstate = &state->crtc_state; 2300 struct connector_state *conn_state = &state->conn_state; 2301 struct drm_display_mode *mode = &conn_state->mode; 2302 struct vop2 *vop2 = cstate->private; 2303 u32 vp_offset = (cstate->crtc_id * 0x100); 2304 bool dclk_inv; 2305 u32 val; 2306 2307 dclk_inv = (mode->flags & DRM_MODE_FLAG_PPIXDATA) ? 0 : 1; 2308 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 2309 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 2310 2311 if (conn_state->output_if & VOP_OUTPUT_IF_RGB) { 2312 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 2313 1, false); 2314 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2315 RGB_MUX_SHIFT, cstate->crtc_id, false); 2316 vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 2317 GRF_RGB_DCLK_INV_SHIFT, dclk_inv); 2318 } 2319 2320 if (conn_state->output_if & VOP_OUTPUT_IF_BT1120) { 2321 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 2322 1, false); 2323 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, 2324 BT1120_EN_SHIFT, 1, false); 2325 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2326 RGB_MUX_SHIFT, cstate->crtc_id, false); 2327 vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 2328 GRF_BT1120_CLK_INV_SHIFT, !dclk_inv); 2329 } 2330 2331 if (conn_state->output_if & VOP_OUTPUT_IF_BT656) { 2332 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT, 2333 1, false); 2334 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2335 RGB_MUX_SHIFT, cstate->crtc_id, false); 2336 vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 2337 GRF_BT656_CLK_INV_SHIFT, !dclk_inv); 2338 } 2339 2340 if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) { 2341 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT, 2342 1, false); 2343 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2344 LVDS0_MUX_SHIFT, cstate->crtc_id, false); 2345 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2346 IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, dclk_inv, false); 2347 } 2348 2349 if (conn_state->output_if & VOP_OUTPUT_IF_LVDS1) { 2350 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS1_EN_SHIFT, 2351 1, false); 2352 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2353 LVDS1_MUX_SHIFT, cstate->crtc_id, false); 2354 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2355 IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, dclk_inv, false); 2356 } 2357 2358 if (conn_state->output_flags & 2359 (ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE | 2360 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)) { 2361 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2362 LVDS_DUAL_EN_SHIFT, 1, false); 2363 if (conn_state->output_flags & 2364 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 2365 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2366 LVDS_DUAL_LEFT_RIGHT_EN_SHIFT, 1, 2367 false); 2368 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 2369 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2370 LVDS_DUAL_SWAP_EN_SHIFT, 1, false); 2371 } 2372 2373 if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) { 2374 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT, 2375 1, false); 2376 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2377 MIPI0_MUX_SHIFT, cstate->crtc_id, false); 2378 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2379 IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false); 2380 } 2381 2382 if (conn_state->output_if & VOP_OUTPUT_IF_MIPI1) { 2383 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI1_EN_SHIFT, 2384 1, false); 2385 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2386 MIPI1_MUX_SHIFT, cstate->crtc_id, false); 2387 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2388 IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false); 2389 } 2390 2391 if (conn_state->output_flags & 2392 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 2393 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 2394 MIPI_DUAL_EN_SHIFT, 1, false); 2395 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 2396 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2397 EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1, 2398 false); 2399 } 2400 2401 if (conn_state->output_if & VOP_OUTPUT_IF_eDP0) { 2402 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, EDP0_EN_SHIFT, 2403 1, false); 2404 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2405 EDP0_MUX_SHIFT, cstate->crtc_id, false); 2406 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2407 IF_CRTL_EDP_DCLK_POL_SHIT, dclk_inv, false); 2408 } 2409 2410 if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) { 2411 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT, 2412 1, false); 2413 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2414 HDMI0_MUX_SHIFT, cstate->crtc_id, false); 2415 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2416 IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false); 2417 vop2_mask_write(vop2, RK3568_DSP_IF_POL, 2418 IF_CRTL_HDMI_PIN_POL_MASK, 2419 IF_CRTL_HDMI_PIN_POL_SHIT, val, false); 2420 } 2421 2422 return mode->clock; 2423 } 2424 2425 static void vop2_post_color_swap(struct display_state *state) 2426 { 2427 struct crtc_state *cstate = &state->crtc_state; 2428 struct connector_state *conn_state = &state->conn_state; 2429 struct vop2 *vop2 = cstate->private; 2430 u32 vp_offset = (cstate->crtc_id * 0x100); 2431 u32 output_type = conn_state->type; 2432 u32 data_swap = 0; 2433 2434 if (is_uv_swap(conn_state->bus_format, conn_state->output_mode)) 2435 data_swap = DSP_RB_SWAP; 2436 2437 if (vop2->version == VOP_VERSION_RK3588 && 2438 (output_type == DRM_MODE_CONNECTOR_HDMIA || 2439 output_type == DRM_MODE_CONNECTOR_eDP) && 2440 (conn_state->bus_format == MEDIA_BUS_FMT_YUV8_1X24 || 2441 conn_state->bus_format == MEDIA_BUS_FMT_YUV10_1X30)) 2442 data_swap |= DSP_RG_SWAP; 2443 2444 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 2445 DATA_SWAP_MASK, DATA_SWAP_SHIFT, data_swap, false); 2446 } 2447 2448 static void vop2_clk_set_parent(struct clk *clk, struct clk *parent) 2449 { 2450 int ret = 0; 2451 2452 if (parent->dev) 2453 ret = clk_set_parent(clk, parent); 2454 if (ret < 0) 2455 debug("failed to set %s as parent for %s\n", 2456 parent->dev->name, clk->dev->name); 2457 } 2458 2459 static ulong vop2_clk_set_rate(struct clk *clk, ulong rate) 2460 { 2461 int ret = 0; 2462 2463 if (clk->dev) 2464 ret = clk_set_rate(clk, rate); 2465 if (ret < 0) 2466 debug("failed to set %s rate %lu \n", clk->dev->name, rate); 2467 2468 return ret; 2469 } 2470 2471 static void vop2_calc_dsc_cru_cfg(struct display_state *state, 2472 int *dsc_txp_clk_div, int *dsc_pxl_clk_div, 2473 int *dsc_cds_clk_div, u64 dclk_rate) 2474 { 2475 struct crtc_state *cstate = &state->crtc_state; 2476 2477 *dsc_txp_clk_div = dclk_rate / cstate->dsc_txp_clk_rate; 2478 *dsc_pxl_clk_div = dclk_rate / cstate->dsc_pxl_clk_rate; 2479 *dsc_cds_clk_div = dclk_rate / cstate->dsc_cds_clk_rate; 2480 2481 *dsc_txp_clk_div = ilog2(*dsc_txp_clk_div); 2482 *dsc_pxl_clk_div = ilog2(*dsc_pxl_clk_div); 2483 *dsc_cds_clk_div = ilog2(*dsc_cds_clk_div); 2484 } 2485 2486 static void vop2_load_pps(struct display_state *state, struct vop2 *vop2, u8 dsc_id) 2487 { 2488 struct crtc_state *cstate = &state->crtc_state; 2489 struct drm_dsc_picture_parameter_set *pps = &cstate->pps; 2490 struct drm_dsc_picture_parameter_set config_pps; 2491 const struct vop2_data *vop2_data = vop2->data; 2492 const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id]; 2493 u32 *pps_val = (u32 *)&config_pps; 2494 u32 decoder_regs_offset = (dsc_id * 0x100); 2495 int i = 0; 2496 2497 memcpy(&config_pps, pps, sizeof(config_pps)); 2498 2499 if ((config_pps.pps_3 & 0xf) > dsc_data->max_linebuf_depth) { 2500 config_pps.pps_3 &= 0xf0; 2501 config_pps.pps_3 |= dsc_data->max_linebuf_depth; 2502 printf("DSC%d max_linebuf_depth is: %d, current set value is: %d\n", 2503 dsc_id, dsc_data->max_linebuf_depth, config_pps.pps_3 & 0xf); 2504 } 2505 2506 for (i = 0; i < DSC_NUM_BUF_RANGES; i++) { 2507 config_pps.rc_range_parameters[i] = 2508 (pps->rc_range_parameters[i] >> 3 & 0x1f) | 2509 ((pps->rc_range_parameters[i] >> 14 & 0x3) << 5) | 2510 ((pps->rc_range_parameters[i] >> 0 & 0x7) << 7) | 2511 ((pps->rc_range_parameters[i] >> 8 & 0x3f) << 10); 2512 } 2513 2514 for (i = 0; i < ROCKCHIP_DSC_PPS_SIZE_BYTE / 4; i++) 2515 vop2_writel(vop2, RK3588_DSC_8K_PPS0_3 + decoder_regs_offset + i * 4, *pps_val++); 2516 } 2517 2518 static void vop2_dsc_enable(struct display_state *state, struct vop2 *vop2, u8 dsc_id, u64 dclk_rate) 2519 { 2520 struct connector_state *conn_state = &state->conn_state; 2521 struct drm_display_mode *mode = &conn_state->mode; 2522 struct crtc_state *cstate = &state->crtc_state; 2523 struct rockchip_dsc_sink_cap *dsc_sink_cap = &cstate->dsc_sink_cap; 2524 const struct vop2_data *vop2_data = vop2->data; 2525 const struct vop2_dsc_data *dsc_data = &vop2_data->dsc[dsc_id]; 2526 bool mipi_ds_mode = false; 2527 u8 dsc_interface_mode = 0; 2528 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 2529 u16 hdisplay = mode->crtc_hdisplay; 2530 u16 htotal = mode->crtc_htotal; 2531 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 2532 u16 vdisplay = mode->crtc_vdisplay; 2533 u16 vtotal = mode->crtc_vtotal; 2534 u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; 2535 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 2536 u16 vact_end = vact_st + vdisplay; 2537 u32 ctrl_regs_offset = (dsc_id * 0x30); 2538 u32 decoder_regs_offset = (dsc_id * 0x100); 2539 u32 backup_regs_offset = 0; 2540 int dsc_txp_clk_div = 0; 2541 int dsc_pxl_clk_div = 0; 2542 int dsc_cds_clk_div = 0; 2543 2544 if (!vop2->data->nr_dscs) { 2545 printf("Unsupported DSC\n"); 2546 return; 2547 } 2548 2549 if (cstate->dsc_slice_num > dsc_data->max_slice_num) 2550 printf("DSC%d supported max slice is: %d, current is: %d\n", 2551 dsc_data->id, dsc_data->max_slice_num, cstate->dsc_slice_num); 2552 2553 if (dsc_data->pd_id) { 2554 if (vop2_power_domain_on(vop2, dsc_data->pd_id)) 2555 printf("open dsc%d pd fail\n", dsc_id); 2556 } 2557 2558 vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, EN_MASK, 2559 SCAN_TIMING_PARA_IMD_EN_SHIFT, 1, false); 2560 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PORT_SEL_MASK, 2561 DSC_PORT_SEL_SHIFT, cstate->crtc_id, false); 2562 if (conn_state->output_if & (VOP_OUTPUT_IF_HDMI0 | VOP_OUTPUT_IF_HDMI1)) { 2563 dsc_interface_mode = VOP_DSC_IF_HDMI; 2564 } else { 2565 mipi_ds_mode = !!(conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE); 2566 if (mipi_ds_mode) 2567 dsc_interface_mode = VOP_DSC_IF_MIPI_DS_MODE; 2568 else 2569 dsc_interface_mode = VOP_DSC_IF_MIPI_VIDEO_MODE; 2570 } 2571 2572 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 2573 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK, 2574 DSC_MAN_MODE_SHIFT, 0, false); 2575 else 2576 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_MAN_MODE_MASK, 2577 DSC_MAN_MODE_SHIFT, 1, false); 2578 2579 vop2_calc_dsc_cru_cfg(state, &dsc_txp_clk_div, &dsc_pxl_clk_div, &dsc_cds_clk_div, dclk_rate); 2580 2581 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_INTERFACE_MODE_MASK, 2582 DSC_INTERFACE_MODE_SHIFT, dsc_interface_mode, false); 2583 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PIXEL_NUM_MASK, 2584 DSC_PIXEL_NUM_SHIFT, cstate->dsc_pixel_num >> 1, false); 2585 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_TXP_CLK_DIV_MASK, 2586 DSC_TXP_CLK_DIV_SHIFT, dsc_txp_clk_div, false); 2587 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_PXL_CLK_DIV_MASK, 2588 DSC_PXL_CLK_DIV_SHIFT, dsc_pxl_clk_div, false); 2589 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK, 2590 DSC_CDS_CLK_DIV_SHIFT, dsc_cds_clk_div, false); 2591 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, EN_MASK, 2592 DSC_SCAN_EN_SHIFT, !mipi_ds_mode, false); 2593 vop2_mask_write(vop2, RK3588_DSC_8K_SYS_CTRL + ctrl_regs_offset, DSC_CDS_CLK_DIV_MASK, 2594 DSC_HALT_EN_SHIFT, mipi_ds_mode, false); 2595 2596 if (!mipi_ds_mode) { 2597 u16 dsc_hsync, dsc_htotal, dsc_hact_st, dsc_hact_end; 2598 u32 target_bpp = dsc_sink_cap->target_bits_per_pixel_x16; 2599 u64 dsc_cds_rate = cstate->dsc_cds_clk_rate; 2600 u32 v_pixclk_mhz = mode->crtc_clock / 1000; /* video timing pixclk */ 2601 u32 dly_num, dsc_cds_rate_mhz, val = 0; 2602 2603 if (target_bpp >> 4 < dsc_data->min_bits_per_pixel) 2604 printf("Unsupported bpp less than: %d\n", dsc_data->min_bits_per_pixel); 2605 2606 /* 2607 * dly_num = delay_line_num * T(one-line) / T (dsc_cds) 2608 * T (one-line) = 1/v_pixclk_mhz * htotal = htotal/v_pixclk_mhz 2609 * T (dsc_cds) = 1 / dsc_cds_rate_mhz 2610 * delay_line_num: according the pps initial_xmit_delay to adjust vop dsc delay 2611 * delay_line_num = 4 - BPP / 8 2612 * = (64 - target_bpp / 8) / 16 2613 * 2614 * dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16; 2615 */ 2616 do_div(dsc_cds_rate, 1000000); /* hz to Mhz */ 2617 dsc_cds_rate_mhz = dsc_cds_rate; 2618 dly_num = htotal * dsc_cds_rate_mhz / v_pixclk_mhz * (64 - target_bpp / 8) / 16; 2619 vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_MODE_MASK, 2620 DSC_INIT_DLY_MODE_SHIFT, 0, false); 2621 vop2_mask_write(vop2, RK3588_DSC_8K_INIT_DLY + ctrl_regs_offset, DSC_INIT_DLY_NUM_MASK, 2622 DSC_INIT_DLY_NUM_SHIFT, dly_num, false); 2623 2624 dsc_hsync = hsync_len / 2; 2625 dsc_htotal = htotal / (1 << dsc_cds_clk_div); 2626 val = dsc_htotal << 16 | dsc_hsync; 2627 vop2_mask_write(vop2, RK3588_DSC_8K_HTOTAL_HS_END + ctrl_regs_offset, DSC_HTOTAL_PW_MASK, 2628 DSC_HTOTAL_PW_SHIFT, val, false); 2629 2630 dsc_hact_st = hact_st / 2; 2631 dsc_hact_end = (hdisplay * target_bpp >> 4) / 24 + dsc_hact_st; 2632 val = dsc_hact_end << 16 | dsc_hact_st; 2633 vop2_mask_write(vop2, RK3588_DSC_8K_HACT_ST_END + ctrl_regs_offset, DSC_HACT_ST_END_MASK, 2634 DSC_HACT_ST_END_SHIFT, val, false); 2635 2636 vop2_mask_write(vop2, RK3588_DSC_8K_VTOTAL_VS_END + ctrl_regs_offset, DSC_VTOTAL_PW_MASK, 2637 DSC_VTOTAL_PW_SHIFT, vtotal << 16 | vsync_len, false); 2638 vop2_mask_write(vop2, RK3588_DSC_8K_VACT_ST_END + ctrl_regs_offset, DSC_VACT_ST_END_MASK, 2639 DSC_VACT_ST_END_SHIFT, vact_end << 16 | vact_st, false); 2640 } 2641 2642 vop2_mask_write(vop2, RK3588_DSC_8K_RST + ctrl_regs_offset, RST_DEASSERT_MASK, 2643 RST_DEASSERT_SHIFT, 1, false); 2644 udelay(10); 2645 /* read current dsc core register and backup to regsbak */ 2646 backup_regs_offset = RK3588_DSC_8K_CTRL0; 2647 vop2->regsbak[backup_regs_offset >> 2] = vop2_readl(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset); 2648 2649 vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 2650 DSC_EN_SHIFT, 1, false); 2651 vop2_load_pps(state, vop2, dsc_id); 2652 2653 vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 2654 DSC_RBIT_SHIFT, 1, false); 2655 vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 2656 DSC_RBYT_SHIFT, 0, false); 2657 vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 2658 DSC_FLAL_SHIFT, 1, false); 2659 vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 2660 DSC_MER_SHIFT, 1, false); 2661 vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 2662 DSC_EPB_SHIFT, 0, false); 2663 vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 2664 DSC_EPL_SHIFT, 1, false); 2665 vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 2666 DSC_NSLC_SHIFT, ilog2(cstate->dsc_slice_num), false); 2667 vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 2668 DSC_SBO_SHIFT, 1, false); 2669 vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 2670 DSC_IFEP_SHIFT, dsc_sink_cap->version_minor == 2 ? 1 : 0, false); 2671 vop2_mask_write(vop2, RK3588_DSC_8K_CTRL0 + decoder_regs_offset, EN_MASK, 2672 DSC_PPS_UPD_SHIFT, 1, false); 2673 2674 printf("DSC%d: txp:%lld div:%d, pxl:%lld div:%d, dsc:%lld div:%d\n", 2675 dsc_id, 2676 cstate->dsc_txp_clk_rate, dsc_txp_clk_div, 2677 cstate->dsc_pxl_clk_rate, dsc_pxl_clk_div, 2678 cstate->dsc_cds_clk_rate, dsc_cds_clk_div); 2679 } 2680 2681 static int rockchip_vop2_init(struct display_state *state) 2682 { 2683 struct crtc_state *cstate = &state->crtc_state; 2684 struct connector_state *conn_state = &state->conn_state; 2685 struct drm_display_mode *mode = &conn_state->mode; 2686 struct vop2 *vop2 = cstate->private; 2687 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 2688 u16 hdisplay = mode->crtc_hdisplay; 2689 u16 htotal = mode->crtc_htotal; 2690 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 2691 u16 hact_end = hact_st + hdisplay; 2692 u16 vdisplay = mode->crtc_vdisplay; 2693 u16 vtotal = mode->crtc_vtotal; 2694 u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; 2695 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 2696 u16 vact_end = vact_st + vdisplay; 2697 bool yuv_overlay = false; 2698 bool splice_en = false; 2699 u32 vp_offset = (cstate->crtc_id * 0x100); 2700 u32 line_flag_offset = (cstate->crtc_id * 4); 2701 u32 val, act_end; 2702 u8 dither_down_en = 0; 2703 u8 pre_dither_down_en = 0; 2704 char output_type_name[30] = {0}; 2705 char dclk_name[9]; 2706 struct clk dclk; 2707 struct clk hdmi0_phy_pll; 2708 struct clk hdmi1_phy_pll; 2709 unsigned long dclk_rate; 2710 int ret; 2711 2712 printf("VOP update mode to: %dx%d%s%d, type:%s for VP%d\n", 2713 mode->hdisplay, mode->vdisplay, 2714 mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p", 2715 mode->vscan, 2716 get_output_if_name(conn_state->output_if, output_type_name), 2717 cstate->crtc_id); 2718 2719 if (mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) { 2720 cstate->splice_mode = true; 2721 splice_en = true; 2722 cstate->splice_crtc_id = vop2->data->vp_data[cstate->crtc_id].splice_vp_id; 2723 if (!cstate->splice_crtc_id) { 2724 printf("%s: Splice mode is unsupported by vp%d\n", 2725 __func__, cstate->crtc_id); 2726 return -EINVAL; 2727 } 2728 } 2729 2730 vop2_initial(vop2, state); 2731 if (vop2->version == VOP_VERSION_RK3588) 2732 dclk_rate = rk3588_vop2_if_cfg(state); 2733 else 2734 dclk_rate = rk3568_vop2_if_cfg(state); 2735 2736 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA && 2737 !(cstate->feature & VOP_FEATURE_OUTPUT_10BIT)) 2738 conn_state->output_mode = ROCKCHIP_OUT_MODE_P888; 2739 2740 vop2_post_color_swap(state); 2741 2742 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, OUT_MODE_MASK, 2743 OUT_MODE_SHIFT, conn_state->output_mode, false); 2744 2745 switch (conn_state->bus_format) { 2746 case MEDIA_BUS_FMT_RGB565_1X16: 2747 dither_down_en = 1; 2748 break; 2749 case MEDIA_BUS_FMT_RGB666_1X18: 2750 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: 2751 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 2752 case MEDIA_BUS_FMT_RGB666_1X7X3_JEIDA: 2753 dither_down_en = 1; 2754 break; 2755 case MEDIA_BUS_FMT_YUV8_1X24: 2756 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 2757 dither_down_en = 0; 2758 pre_dither_down_en = 1; 2759 break; 2760 case MEDIA_BUS_FMT_YUV10_1X30: 2761 case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 2762 case MEDIA_BUS_FMT_RGB888_1X24: 2763 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: 2764 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: 2765 default: 2766 dither_down_en = 0; 2767 pre_dither_down_en = 0; 2768 break; 2769 } 2770 2771 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA) 2772 pre_dither_down_en = 0; 2773 else 2774 pre_dither_down_en = 1; 2775 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2776 DITHER_DOWN_EN_SHIFT, dither_down_en, false); 2777 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2778 PRE_DITHER_DOWN_EN_SHIFT, pre_dither_down_en, false); 2779 2780 yuv_overlay = is_yuv_output(conn_state->bus_format) ? 1 : 0; 2781 vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, cstate->crtc_id, 2782 yuv_overlay, false); 2783 2784 cstate->yuv_overlay = yuv_overlay; 2785 2786 vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, EN_MASK, 2787 PORT_MERGE_EN_SHIFT, splice_en, false); 2788 2789 vop2_writel(vop2, RK3568_VP0_DSP_HTOTAL_HS_END + vp_offset, 2790 (htotal << 16) | hsync_len); 2791 val = hact_st << 16; 2792 val |= hact_end; 2793 vop2_writel(vop2, RK3568_VP0_DSP_HACT_ST_END + vp_offset, val); 2794 val = vact_st << 16; 2795 val |= vact_end; 2796 vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END + vp_offset, val); 2797 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 2798 u16 vact_st_f1 = vtotal + vact_st + 1; 2799 u16 vact_end_f1 = vact_st_f1 + vdisplay; 2800 2801 val = vact_st_f1 << 16 | vact_end_f1; 2802 vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END_F1 + vp_offset, 2803 val); 2804 2805 val = vtotal << 16 | (vtotal + vsync_len); 2806 vop2_writel(vop2, RK3568_VP0_DSP_VS_ST_END_F1 + vp_offset, val); 2807 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2808 INTERLACE_EN_SHIFT, 1, false); 2809 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2810 DSP_FILED_POL, 1, false); 2811 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2812 P2I_EN_SHIFT, 1, false); 2813 vtotal += vtotal + 1; 2814 act_end = vact_end_f1; 2815 } else { 2816 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2817 INTERLACE_EN_SHIFT, 0, false); 2818 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2819 P2I_EN_SHIFT, 0, false); 2820 act_end = vact_end; 2821 } 2822 vop2_writel(vop2, RK3568_VP0_DSP_VTOTAL_VS_END + vp_offset, 2823 (vtotal << 16) | vsync_len); 2824 2825 if (vop2->version == VOP_VERSION_RK3568) { 2826 if (mode->flags & DRM_MODE_FLAG_DBLCLK || 2827 conn_state->output_if & VOP_OUTPUT_IF_BT656) 2828 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2829 CORE_DCLK_DIV_EN_SHIFT, 1, false); 2830 else 2831 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2832 CORE_DCLK_DIV_EN_SHIFT, 0, false); 2833 } 2834 2835 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420) 2836 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2837 DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0x3, false); 2838 else 2839 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2840 DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0, false); 2841 2842 vop2_mask_write(vop2, RK3568_OVL_CTRL, OVL_MODE_SEL_MASK, 2843 OVL_MODE_SEL_SHIFT + cstate->crtc_id, yuv_overlay, false); 2844 2845 if (yuv_overlay) 2846 val = 0x20010200; 2847 else 2848 val = 0; 2849 vop2_writel(vop2, RK3568_VP0_DSP_BG + vp_offset, val); 2850 if (splice_en) { 2851 vop2_mask_write(vop2, RK3568_OVL_CTRL, OVL_MODE_SEL_MASK, 2852 OVL_MODE_SEL_SHIFT + cstate->splice_crtc_id, 2853 yuv_overlay, false); 2854 vop2_writel(vop2, RK3568_VP0_DSP_BG + (cstate->splice_crtc_id * 0x100), val); 2855 } 2856 2857 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2858 POST_DSP_OUT_R2Y_SHIFT, yuv_overlay, false); 2859 2860 vop2_tv_config_update(state, vop2); 2861 vop2_post_config(state, vop2); 2862 2863 if (cstate->dsc_enable) { 2864 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 2865 vop2_dsc_enable(state, vop2, 0, dclk_rate); 2866 vop2_dsc_enable(state, vop2, 1, dclk_rate); 2867 } else { 2868 vop2_dsc_enable(state, vop2, cstate->dsc_id, dclk_rate); 2869 } 2870 } 2871 2872 snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", cstate->crtc_id); 2873 ret = clk_get_by_name(cstate->dev, dclk_name, &dclk); 2874 if (ret) { 2875 printf("%s: Failed to get dclk ret=%d\n", __func__, ret); 2876 return ret; 2877 } 2878 2879 ret = uclass_get_device_by_name(UCLASS_CLK, "hdmiphypll_clk0", 2880 &hdmi0_phy_pll.dev); 2881 if (ret) { 2882 hdmi0_phy_pll.dev = NULL; 2883 printf("%s:No hdmiphypll clk0 found, use system clk\n", 2884 __func__); 2885 } 2886 2887 ret = uclass_get_device_by_name(UCLASS_CLK, "hdmiphypll_clk1", 2888 &hdmi1_phy_pll.dev); 2889 if (ret) { 2890 hdmi1_phy_pll.dev = NULL; 2891 printf("%s:No hdmiphypll clk1 found, use system clk\n", 2892 __func__); 2893 } 2894 2895 if (mode->clock < VOP2_MAX_DCLK_RATE) { 2896 if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) 2897 vop2_clk_set_parent(&dclk, &hdmi0_phy_pll); 2898 else if (conn_state->output_if & VOP_OUTPUT_IF_HDMI1) 2899 vop2_clk_set_parent(&dclk, &hdmi1_phy_pll); 2900 2901 /* 2902 * uboot clk driver won't set dclk parent's rate when use 2903 * hdmi phypll as dclk source. 2904 * So set dclk rate is meaningless. Set hdmi phypll rate 2905 * directly. 2906 */ 2907 if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI0) && hdmi0_phy_pll.dev) 2908 ret = vop2_clk_set_rate(&hdmi0_phy_pll, dclk_rate * 1000); 2909 else if ((conn_state->output_if & VOP_OUTPUT_IF_HDMI1) && hdmi1_phy_pll.dev) 2910 ret = vop2_clk_set_rate(&hdmi1_phy_pll, dclk_rate * 1000); 2911 else 2912 ret = vop2_clk_set_rate(&dclk, dclk_rate * 1000); 2913 2914 if (IS_ERR_VALUE(ret)) { 2915 printf("%s: Failed to set vp%d dclk[%ld KHZ] ret=%d\n", 2916 __func__, cstate->crtc_id, dclk_rate, ret); 2917 return ret; 2918 } 2919 } else { 2920 ret = vop2_clk_set_rate(&dclk, dclk_rate * 1000); 2921 } 2922 2923 vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK, 2924 RK3568_DSP_LINE_FLAG_NUM0_SHIFT, act_end, false); 2925 vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK, 2926 RK3568_DSP_LINE_FLAG_NUM1_SHIFT, act_end, false); 2927 2928 return 0; 2929 } 2930 2931 static void vop2_setup_scale(struct vop2 *vop2, struct vop2_win_data *win, 2932 uint32_t src_w, uint32_t src_h, uint32_t dst_w, 2933 uint32_t dst_h) 2934 { 2935 uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode; 2936 uint16_t hscl_filter_mode, vscl_filter_mode; 2937 uint8_t gt2 = 0, gt4 = 0; 2938 uint32_t xfac = 0, yfac = 0; 2939 uint16_t hsu_filter_mode = VOP2_SCALE_UP_BIC; 2940 uint16_t hsd_filter_mode = VOP2_SCALE_DOWN_BIL; 2941 uint16_t vsu_filter_mode = VOP2_SCALE_UP_BIL; 2942 uint16_t vsd_filter_mode = VOP2_SCALE_DOWN_BIL; 2943 u32 win_offset = win->reg_offset; 2944 2945 if (src_h >= (4 * dst_h)) 2946 gt4 = 1; 2947 else if (src_h >= (2 * dst_h)) 2948 gt2 = 1; 2949 2950 if (gt4) 2951 src_h >>= 2; 2952 else if (gt2) 2953 src_h >>= 1; 2954 2955 yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w); 2956 yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h); 2957 2958 if (yrgb_hor_scl_mode == SCALE_UP) 2959 hscl_filter_mode = hsu_filter_mode; 2960 else 2961 hscl_filter_mode = hsd_filter_mode; 2962 2963 if (yrgb_ver_scl_mode == SCALE_UP) 2964 vscl_filter_mode = vsu_filter_mode; 2965 else 2966 vscl_filter_mode = vsd_filter_mode; 2967 2968 /* 2969 * RK3568 VOP Esmart/Smart dsp_w should be even pixel 2970 * at scale down mode 2971 */ 2972 if ((yrgb_hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1)) { 2973 printf("win dst_w[%d] should align as 2 pixel\n", dst_w); 2974 dst_w += 1; 2975 } 2976 2977 xfac = vop2_scale_factor(yrgb_hor_scl_mode, hscl_filter_mode, src_w, dst_w); 2978 yfac = vop2_scale_factor(yrgb_ver_scl_mode, vscl_filter_mode, src_h, dst_h); 2979 2980 if (win->type == CLUSTER_LAYER) { 2981 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB + win_offset, 2982 yfac << 16 | xfac); 2983 2984 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 2985 YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, gt2, false); 2986 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 2987 YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, gt4, false); 2988 2989 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 2990 YRGB_XSCL_MODE_MASK, CLUSTER_YRGB_XSCL_MODE_SHIFT, yrgb_hor_scl_mode, false); 2991 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 2992 YRGB_YSCL_MODE_MASK, CLUSTER_YRGB_YSCL_MODE_SHIFT, yrgb_ver_scl_mode, false); 2993 2994 } else { 2995 vop2_writel(vop2, RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB + win_offset, 2996 yfac << 16 | xfac); 2997 2998 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 2999 YRGB_GT2_MASK, YRGB_GT2_SHIFT, gt2, false); 3000 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 3001 YRGB_GT4_MASK, YRGB_GT4_SHIFT, gt4, false); 3002 3003 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 3004 YRGB_XSCL_MODE_MASK, YRGB_XSCL_MODE_SHIFT, yrgb_hor_scl_mode, false); 3005 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 3006 YRGB_YSCL_MODE_MASK, YRGB_YSCL_MODE_SHIFT, yrgb_ver_scl_mode, false); 3007 3008 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 3009 YRGB_XSCL_FILTER_MODE_MASK, YRGB_XSCL_FILTER_MODE_SHIFT, 3010 hscl_filter_mode, false); 3011 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 3012 YRGB_YSCL_FILTER_MODE_MASK, YRGB_YSCL_FILTER_MODE_SHIFT, 3013 vscl_filter_mode, false); 3014 } 3015 } 3016 3017 static void vop2_axi_config(struct vop2 *vop2, struct vop2_win_data *win) 3018 { 3019 u32 win_offset = win->reg_offset; 3020 3021 if (win->type == CLUSTER_LAYER) { 3022 vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, CLUSTER_AXI_ID_MASK, 3023 CLUSTER_AXI_ID_SHIFT, win->axi_id, false); 3024 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_YRGB_ID_MASK, 3025 CLUSTER_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false); 3026 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL2 + win_offset, CLUSTER_AXI_UV_ID_MASK, 3027 CLUSTER_AXI_UV_ID_SHIFT, win->axi_uv_id, false); 3028 } else { 3029 vop2_mask_write(vop2, RK3568_ESMART0_AXI_CTRL + win_offset, ESMART_AXI_ID_MASK, 3030 ESMART_AXI_ID_SHIFT, win->axi_id, false); 3031 vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_YRGB_ID_MASK, 3032 ESMART_AXI_YRGB_ID_SHIFT, win->axi_yrgb_id, false); 3033 vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, ESMART_AXI_UV_ID_MASK, 3034 ESMART_AXI_UV_ID_SHIFT, win->axi_uv_id, false); 3035 } 3036 } 3037 3038 static void vop2_set_cluster_win(struct display_state *state, struct vop2_win_data *win) 3039 { 3040 struct crtc_state *cstate = &state->crtc_state; 3041 struct connector_state *conn_state = &state->conn_state; 3042 struct drm_display_mode *mode = &conn_state->mode; 3043 struct vop2 *vop2 = cstate->private; 3044 int src_w = cstate->src_rect.w; 3045 int src_h = cstate->src_rect.h; 3046 int crtc_x = cstate->crtc_rect.x; 3047 int crtc_y = cstate->crtc_rect.y; 3048 int crtc_w = cstate->crtc_rect.w; 3049 int crtc_h = cstate->crtc_rect.h; 3050 int xvir = cstate->xvir; 3051 int y_mirror = 0; 3052 int csc_mode; 3053 u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty; 3054 /* offset of the right window in splice mode */ 3055 u32 splice_pixel_offset = 0; 3056 u32 splice_yrgb_offset = 0; 3057 u32 win_offset = win->reg_offset; 3058 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 3059 3060 if (win->splice_mode_right) { 3061 src_w = cstate->right_src_rect.w; 3062 src_h = cstate->right_src_rect.h; 3063 crtc_x = cstate->right_crtc_rect.x; 3064 crtc_y = cstate->right_crtc_rect.y; 3065 crtc_w = cstate->right_crtc_rect.w; 3066 crtc_h = cstate->right_crtc_rect.h; 3067 splice_pixel_offset = cstate->right_src_rect.x - cstate->src_rect.x; 3068 splice_yrgb_offset = splice_pixel_offset * (state->logo.bpp >> 3); 3069 cfg_done = CFG_DONE_EN | BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 3070 } 3071 3072 act_info = (src_h - 1) << 16; 3073 act_info |= (src_w - 1) & 0xffff; 3074 3075 dsp_info = (crtc_h - 1) << 16; 3076 dsp_info |= (crtc_w - 1) & 0xffff; 3077 3078 dsp_stx = crtc_x; 3079 dsp_sty = crtc_y; 3080 dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); 3081 3082 if (mode->flags & DRM_MODE_FLAG_YMIRROR) 3083 y_mirror = 1; 3084 else 3085 y_mirror = 0; 3086 3087 vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h); 3088 3089 if (vop2->version == VOP_VERSION_RK3588) 3090 vop2_axi_config(vop2, win); 3091 3092 if (y_mirror) 3093 printf("WARN: y mirror is unsupported by cluster window\n"); 3094 3095 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, 3096 WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format, 3097 false); 3098 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_VIR + win_offset, xvir); 3099 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_YRGB_MST + win_offset, 3100 cstate->dma_addr + splice_yrgb_offset); 3101 3102 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_ACT_INFO + win_offset, act_info); 3103 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_INFO + win_offset, dsp_info); 3104 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_ST + win_offset, dsp_st); 3105 3106 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, WIN_EN_SHIFT, 1, false); 3107 3108 csc_mode = vop2_convert_csc_mode(conn_state->color_space); 3109 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, 3110 CLUSTER_RGB2YUV_EN_SHIFT, 3111 is_yuv_output(conn_state->bus_format), false); 3112 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, CSC_MODE_MASK, 3113 CLUSTER_CSC_MODE_SHIFT, csc_mode, false); 3114 vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, EN_MASK, CLUSTER_EN_SHIFT, 1, false); 3115 3116 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 3117 } 3118 3119 static void vop2_set_smart_win(struct display_state *state, struct vop2_win_data *win) 3120 { 3121 struct crtc_state *cstate = &state->crtc_state; 3122 struct connector_state *conn_state = &state->conn_state; 3123 struct drm_display_mode *mode = &conn_state->mode; 3124 struct vop2 *vop2 = cstate->private; 3125 int src_w = cstate->src_rect.w; 3126 int src_h = cstate->src_rect.h; 3127 int crtc_x = cstate->crtc_rect.x; 3128 int crtc_y = cstate->crtc_rect.y; 3129 int crtc_w = cstate->crtc_rect.w; 3130 int crtc_h = cstate->crtc_rect.h; 3131 int xvir = cstate->xvir; 3132 int y_mirror = 0; 3133 int csc_mode; 3134 u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty; 3135 /* offset of the right window in splice mode */ 3136 u32 splice_pixel_offset = 0; 3137 u32 splice_yrgb_offset = 0; 3138 u32 win_offset = win->reg_offset; 3139 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 3140 3141 if (win->splice_mode_right) { 3142 src_w = cstate->right_src_rect.w; 3143 src_h = cstate->right_src_rect.h; 3144 crtc_x = cstate->right_crtc_rect.x; 3145 crtc_y = cstate->right_crtc_rect.y; 3146 crtc_w = cstate->right_crtc_rect.w; 3147 crtc_h = cstate->right_crtc_rect.h; 3148 splice_pixel_offset = cstate->right_src_rect.x - cstate->src_rect.x; 3149 splice_yrgb_offset = splice_pixel_offset * (state->logo.bpp >> 3); 3150 cfg_done = CFG_DONE_EN | BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 3151 } 3152 3153 /* 3154 * This is workaround solution for IC design: 3155 * esmart can't support scale down when actual_w % 16 == 1. 3156 */ 3157 if (src_w > crtc_w && (src_w & 0xf) == 1) { 3158 printf("WARN: vp%d unsupported act_w[%d] mode 16 = 1 when scale down\n", cstate->crtc_id, src_w); 3159 src_w -= 1; 3160 } 3161 3162 act_info = (src_h - 1) << 16; 3163 act_info |= (src_w - 1) & 0xffff; 3164 3165 dsp_info = (crtc_h - 1) << 16; 3166 dsp_info |= (crtc_w - 1) & 0xffff; 3167 3168 dsp_stx = crtc_x; 3169 dsp_sty = crtc_y; 3170 dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); 3171 3172 if (mode->flags & DRM_MODE_FLAG_YMIRROR) 3173 y_mirror = 1; 3174 else 3175 y_mirror = 0; 3176 3177 vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h); 3178 3179 if (vop2->version == VOP_VERSION_RK3588) 3180 vop2_axi_config(vop2, win); 3181 3182 if (y_mirror) 3183 cstate->dma_addr += (src_h - 1) * xvir * 4; 3184 vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, EN_MASK, 3185 YMIRROR_EN_SHIFT, y_mirror, false); 3186 3187 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 3188 WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format, 3189 false); 3190 vop2_writel(vop2, RK3568_ESMART0_REGION0_VIR + win_offset, xvir); 3191 vop2_writel(vop2, RK3568_ESMART0_REGION0_YRGB_MST + win_offset, 3192 cstate->dma_addr + splice_yrgb_offset); 3193 3194 vop2_writel(vop2, RK3568_ESMART0_REGION0_ACT_INFO + win_offset, 3195 act_info); 3196 vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_INFO + win_offset, 3197 dsp_info); 3198 vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_ST + win_offset, dsp_st); 3199 3200 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK, 3201 WIN_EN_SHIFT, 1, false); 3202 3203 csc_mode = vop2_convert_csc_mode(conn_state->color_space); 3204 vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, EN_MASK, 3205 RGB2YUV_EN_SHIFT, 3206 is_yuv_output(conn_state->bus_format), false); 3207 vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, CSC_MODE_MASK, 3208 CSC_MODE_SHIFT, csc_mode, false); 3209 3210 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 3211 } 3212 3213 static int display_rect_calc_scale(int src, int dst) 3214 { 3215 int scale = 0; 3216 3217 if (WARN_ON(src < 0 || dst < 0)) 3218 return -EINVAL; 3219 3220 if (dst == 0) 3221 return 0; 3222 3223 if (src > (dst << 16)) 3224 return DIV_ROUND_UP(src, dst); 3225 3226 scale = src / dst; 3227 3228 return scale; 3229 } 3230 3231 static int display_rect_calc_hscale(const struct display_rect *src, 3232 const struct display_rect *dst, 3233 int min_hscale, int max_hscale) 3234 { 3235 int src_w = src->w; 3236 int dst_w = dst->w; 3237 int hscale = display_rect_calc_scale(src_w, dst_w); 3238 3239 if (hscale < 0 || dst_w == 0) 3240 return hscale; 3241 3242 if (hscale < min_hscale || hscale > max_hscale) 3243 return -ERANGE; 3244 3245 return hscale; 3246 } 3247 3248 static void vop2_calc_display_rect_for_splice(struct display_state *state) 3249 { 3250 struct crtc_state *cstate = &state->crtc_state; 3251 struct connector_state *conn_state = &state->conn_state; 3252 struct drm_display_mode *mode = &conn_state->mode; 3253 struct display_rect *src_rect = &cstate->src_rect; 3254 struct display_rect *dst_rect = &cstate->crtc_rect; 3255 struct display_rect left_src, left_dst, right_src, right_dst; 3256 u16 half_hdisplay = mode->crtc_hdisplay >> 1; 3257 int hscale = display_rect_calc_hscale(src_rect, dst_rect, 0, INT_MAX); 3258 int left_src_w, left_dst_w, right_dst_w; 3259 3260 left_dst_w = min_t(u16, half_hdisplay, dst_rect->x + dst_rect->w) - dst_rect->x; 3261 if (left_dst_w < 0) 3262 left_dst_w = 0; 3263 right_dst_w = dst_rect->w - left_dst_w; 3264 3265 if (!right_dst_w) 3266 left_src_w = src_rect->w; 3267 else 3268 left_src_w = left_dst_w * hscale; 3269 3270 left_src.x = src_rect->x; 3271 left_src.w = left_src_w; 3272 left_dst.x = dst_rect->x; 3273 left_dst.w = left_dst_w; 3274 right_src.x = left_src.x + left_src.w; 3275 right_src.w = src_rect->x + src_rect->w - left_src.x - left_src.w; 3276 right_dst.x = dst_rect->x + left_dst_w - half_hdisplay; 3277 right_dst.w = right_dst_w; 3278 3279 left_src.y = src_rect->y; 3280 left_src.h = src_rect->h; 3281 left_dst.y = dst_rect->y; 3282 left_dst.h = dst_rect->h; 3283 right_src.y = src_rect->y; 3284 right_src.h = src_rect->h; 3285 right_dst.y = dst_rect->y; 3286 right_dst.h = dst_rect->h; 3287 3288 memcpy(&cstate->src_rect, &left_src, sizeof(struct display_rect)); 3289 memcpy(&cstate->crtc_rect, &left_dst, sizeof(struct display_rect)); 3290 memcpy(&cstate->right_src_rect, &right_src, sizeof(struct display_rect)); 3291 memcpy(&cstate->right_crtc_rect, &right_dst, sizeof(struct display_rect)); 3292 } 3293 3294 static int rockchip_vop2_set_plane(struct display_state *state) 3295 { 3296 struct crtc_state *cstate = &state->crtc_state; 3297 struct vop2 *vop2 = cstate->private; 3298 struct vop2_win_data *win_data; 3299 struct vop2_win_data *splice_win_data; 3300 u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id; 3301 char plane_name[10] = {0}; 3302 3303 if (cstate->crtc_rect.w > cstate->max_output.width) { 3304 printf("ERROR: output w[%d] exceeded max width[%d]\n", 3305 cstate->crtc_rect.w, cstate->max_output.width); 3306 return -EINVAL; 3307 } 3308 3309 win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id); 3310 if (!win_data) { 3311 printf("invalid win id %d\n", primary_plane_id); 3312 return -ENODEV; 3313 } 3314 3315 if (vop2->version == VOP_VERSION_RK3588) { 3316 if (vop2_power_domain_on(vop2, win_data->pd_id)) 3317 printf("open vp%d plane pd fail\n", cstate->crtc_id); 3318 } 3319 3320 if (cstate->splice_mode) { 3321 if (win_data->splice_win_id) { 3322 splice_win_data = vop2_find_win_by_phys_id(vop2, win_data->splice_win_id); 3323 splice_win_data->splice_mode_right = true; 3324 3325 if (vop2_power_domain_on(vop2, splice_win_data->pd_id)) 3326 printf("splice mode: open vp%d plane pd fail\n", cstate->splice_crtc_id); 3327 3328 vop2_calc_display_rect_for_splice(state); 3329 if (win_data->type == CLUSTER_LAYER) 3330 vop2_set_cluster_win(state, splice_win_data); 3331 else 3332 vop2_set_smart_win(state, splice_win_data); 3333 } else { 3334 printf("ERROR: splice mode is unsupported by plane %s\n", 3335 get_plane_name(primary_plane_id, plane_name)); 3336 return -EINVAL; 3337 } 3338 } 3339 3340 if (win_data->type == CLUSTER_LAYER) 3341 vop2_set_cluster_win(state, win_data); 3342 else 3343 vop2_set_smart_win(state, win_data); 3344 3345 printf("VOP VP%d enable %s[%dx%d->%dx%d@%dx%d] fmt[%d] addr[0x%x]\n", 3346 cstate->crtc_id, get_plane_name(primary_plane_id, plane_name), 3347 cstate->src_rect.w, cstate->src_rect.h, cstate->crtc_rect.w, cstate->crtc_rect.h, 3348 cstate->crtc_rect.x, cstate->crtc_rect.y, cstate->format, 3349 cstate->dma_addr); 3350 3351 return 0; 3352 } 3353 3354 static int rockchip_vop2_prepare(struct display_state *state) 3355 { 3356 return 0; 3357 } 3358 3359 static void vop2_dsc_cfg_done(struct display_state *state) 3360 { 3361 struct connector_state *conn_state = &state->conn_state; 3362 struct crtc_state *cstate = &state->crtc_state; 3363 struct vop2 *vop2 = cstate->private; 3364 u8 dsc_id = cstate->dsc_id; 3365 u32 ctrl_regs_offset = (dsc_id * 0x30); 3366 3367 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 3368 vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE, EN_MASK, 3369 DSC_CFG_DONE_SHIFT, 1, false); 3370 vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE + 0x30, EN_MASK, 3371 DSC_CFG_DONE_SHIFT, 1, false); 3372 } else { 3373 vop2_mask_write(vop2, RK3588_DSC_8K_CFG_DONE + ctrl_regs_offset, EN_MASK, 3374 DSC_CFG_DONE_SHIFT, 1, false); 3375 } 3376 } 3377 3378 static int rockchip_vop2_enable(struct display_state *state) 3379 { 3380 struct crtc_state *cstate = &state->crtc_state; 3381 struct vop2 *vop2 = cstate->private; 3382 u32 vp_offset = (cstate->crtc_id * 0x100); 3383 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 3384 3385 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3386 STANDBY_EN_SHIFT, 0, false); 3387 3388 if (cstate->splice_mode) 3389 cfg_done |= BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 3390 3391 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 3392 3393 if (cstate->dsc_enable) 3394 vop2_dsc_cfg_done(state); 3395 3396 return 0; 3397 } 3398 3399 static int rockchip_vop2_disable(struct display_state *state) 3400 { 3401 struct crtc_state *cstate = &state->crtc_state; 3402 struct vop2 *vop2 = cstate->private; 3403 u32 vp_offset = (cstate->crtc_id * 0x100); 3404 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 3405 3406 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 3407 STANDBY_EN_SHIFT, 1, false); 3408 3409 if (cstate->splice_mode) 3410 cfg_done |= BIT(cstate->splice_crtc_id) | (BIT(cstate->splice_crtc_id) << 16); 3411 3412 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 3413 3414 return 0; 3415 } 3416 3417 static int rockchip_vop2_get_cursor_plane(struct display_state *state, u32 plane_mask, int cursor_plane) 3418 { 3419 struct crtc_state *cstate = &state->crtc_state; 3420 struct vop2 *vop2 = cstate->private; 3421 int i = 0; 3422 int correct_cursor_plane = -1; 3423 int plane_type = -1; 3424 3425 if (cursor_plane < 0) 3426 return -1; 3427 3428 if (plane_mask & (1 << cursor_plane)) 3429 return cursor_plane; 3430 3431 /* Get current cursor plane type */ 3432 for (i = 0; i < vop2->data->nr_layers; i++) { 3433 if (vop2->data->plane_table[i].plane_id == cursor_plane) { 3434 plane_type = vop2->data->plane_table[i].plane_type; 3435 break; 3436 } 3437 } 3438 3439 /* Get the other same plane type plane id */ 3440 for (i = 0; i < vop2->data->nr_layers; i++) { 3441 if (vop2->data->plane_table[i].plane_type == plane_type && 3442 vop2->data->plane_table[i].plane_id != cursor_plane) { 3443 correct_cursor_plane = vop2->data->plane_table[i].plane_id; 3444 break; 3445 } 3446 } 3447 3448 /* To check whether the new correct_cursor_plane is attach to current vp */ 3449 if (correct_cursor_plane < 0 || !(plane_mask & (1 << correct_cursor_plane))) { 3450 printf("error: faild to find correct plane as cursor plane\n"); 3451 return -1; 3452 } 3453 3454 printf("vp%d adjust cursor plane from %d to %d\n", 3455 cstate->crtc_id, cursor_plane, correct_cursor_plane); 3456 3457 return correct_cursor_plane; 3458 } 3459 3460 static int rockchip_vop2_fixup_dts(struct display_state *state, void *blob) 3461 { 3462 struct crtc_state *cstate = &state->crtc_state; 3463 struct vop2 *vop2 = cstate->private; 3464 ofnode vp_node; 3465 struct device_node *port_parent_node = cstate->ports_node; 3466 static bool vop_fix_dts; 3467 const char *path; 3468 u32 plane_mask = 0; 3469 int vp_id = 0; 3470 int cursor_plane_id = -1; 3471 3472 if (vop_fix_dts) 3473 return 0; 3474 3475 ofnode_for_each_subnode(vp_node, np_to_ofnode(port_parent_node)) { 3476 path = vp_node.np->full_name; 3477 plane_mask = vop2->vp_plane_mask[vp_id].plane_mask; 3478 3479 if (cstate->crtc->assign_plane) 3480 continue; 3481 cursor_plane_id = rockchip_vop2_get_cursor_plane(state, plane_mask, 3482 cstate->crtc->vps[vp_id].cursor_plane); 3483 printf("vp%d, plane_mask:0x%x, primary-id:%d, curser-id:%d\n", 3484 vp_id, plane_mask, 3485 vop2->vp_plane_mask[vp_id].primary_plane_id, 3486 cursor_plane_id); 3487 3488 do_fixup_by_path_u32(blob, path, "rockchip,plane-mask", 3489 plane_mask, 1); 3490 do_fixup_by_path_u32(blob, path, "rockchip,primary-plane", 3491 vop2->vp_plane_mask[vp_id].primary_plane_id, 1); 3492 if (cursor_plane_id >= 0) 3493 do_fixup_by_path_u32(blob, path, "cursor-win-id", 3494 cursor_plane_id, 1); 3495 vp_id++; 3496 } 3497 3498 vop_fix_dts = true; 3499 3500 return 0; 3501 } 3502 3503 static struct vop2_plane_table rk356x_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 3504 {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER}, 3505 {ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER}, 3506 {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 3507 {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 3508 {ROCKCHIP_VOP2_SMART0, SMART_LAYER}, 3509 {ROCKCHIP_VOP2_SMART0, SMART_LAYER}, 3510 }; 3511 3512 static struct vop2_vp_plane_mask rk356x_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 3513 { /* one display policy */ 3514 {/* main display */ 3515 .primary_plane_id = ROCKCHIP_VOP2_SMART0, 3516 .attached_layers_nr = 6, 3517 .attached_layers = { 3518 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0, 3519 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1 3520 }, 3521 }, 3522 {/* second display */}, 3523 {/* third display */}, 3524 {/* fourth display */}, 3525 }, 3526 3527 { /* two display policy */ 3528 {/* main display */ 3529 .primary_plane_id = ROCKCHIP_VOP2_SMART0, 3530 .attached_layers_nr = 3, 3531 .attached_layers = { 3532 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0 3533 }, 3534 }, 3535 3536 {/* second display */ 3537 .primary_plane_id = ROCKCHIP_VOP2_SMART1, 3538 .attached_layers_nr = 3, 3539 .attached_layers = { 3540 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1 3541 }, 3542 }, 3543 {/* third display */}, 3544 {/* fourth display */}, 3545 }, 3546 3547 { /* three display policy */ 3548 {/* main display */ 3549 .primary_plane_id = ROCKCHIP_VOP2_SMART0, 3550 .attached_layers_nr = 3, 3551 .attached_layers = { 3552 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0 3553 }, 3554 }, 3555 3556 {/* second display */ 3557 .primary_plane_id = ROCKCHIP_VOP2_SMART1, 3558 .attached_layers_nr = 2, 3559 .attached_layers = { 3560 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_SMART1 3561 }, 3562 }, 3563 3564 {/* third display */ 3565 .primary_plane_id = ROCKCHIP_VOP2_ESMART1, 3566 .attached_layers_nr = 1, 3567 .attached_layers = { ROCKCHIP_VOP2_ESMART1 }, 3568 }, 3569 3570 {/* fourth display */}, 3571 }, 3572 3573 {/* reserved for four display policy */}, 3574 }; 3575 3576 static struct vop2_win_data rk3568_win_data[6] = { 3577 { 3578 .name = "Cluster0", 3579 .phys_id = ROCKCHIP_VOP2_CLUSTER0, 3580 .type = CLUSTER_LAYER, 3581 .win_sel_port_offset = 0, 3582 .layer_sel_win_id = 0, 3583 .reg_offset = 0, 3584 }, 3585 3586 { 3587 .name = "Cluster1", 3588 .phys_id = ROCKCHIP_VOP2_CLUSTER1, 3589 .type = CLUSTER_LAYER, 3590 .win_sel_port_offset = 1, 3591 .layer_sel_win_id = 1, 3592 .reg_offset = 0x200, 3593 }, 3594 3595 { 3596 .name = "Esmart0", 3597 .phys_id = ROCKCHIP_VOP2_ESMART0, 3598 .type = ESMART_LAYER, 3599 .win_sel_port_offset = 4, 3600 .layer_sel_win_id = 2, 3601 .reg_offset = 0, 3602 }, 3603 3604 { 3605 .name = "Esmart1", 3606 .phys_id = ROCKCHIP_VOP2_ESMART1, 3607 .type = ESMART_LAYER, 3608 .win_sel_port_offset = 5, 3609 .layer_sel_win_id = 6, 3610 .reg_offset = 0x200, 3611 }, 3612 3613 { 3614 .name = "Smart0", 3615 .phys_id = ROCKCHIP_VOP2_SMART0, 3616 .type = SMART_LAYER, 3617 .win_sel_port_offset = 6, 3618 .layer_sel_win_id = 3, 3619 .reg_offset = 0x400, 3620 }, 3621 3622 { 3623 .name = "Smart1", 3624 .phys_id = ROCKCHIP_VOP2_SMART1, 3625 .type = SMART_LAYER, 3626 .win_sel_port_offset = 7, 3627 .layer_sel_win_id = 7, 3628 .reg_offset = 0x600, 3629 }, 3630 }; 3631 3632 static struct vop2_vp_data rk3568_vp_data[3] = { 3633 { 3634 .feature = VOP_FEATURE_OUTPUT_10BIT, 3635 .pre_scan_max_dly = 42, 3636 .max_output = {4096, 2304}, 3637 }, 3638 { 3639 .feature = 0, 3640 .pre_scan_max_dly = 40, 3641 .max_output = {2048, 1536}, 3642 }, 3643 { 3644 .feature = 0, 3645 .pre_scan_max_dly = 40, 3646 .max_output = {1920, 1080}, 3647 }, 3648 }; 3649 3650 const struct vop2_data rk3568_vop = { 3651 .version = VOP_VERSION_RK3568, 3652 .nr_vps = 3, 3653 .vp_data = rk3568_vp_data, 3654 .win_data = rk3568_win_data, 3655 .plane_mask = rk356x_vp_plane_mask[0], 3656 .plane_table = rk356x_plane_table, 3657 .nr_layers = 6, 3658 .nr_mixers = 5, 3659 .nr_gammas = 1, 3660 }; 3661 3662 static struct vop2_plane_table rk3588_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 3663 {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER}, 3664 {ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER}, 3665 {ROCKCHIP_VOP2_CLUSTER2, CLUSTER_LAYER}, 3666 {ROCKCHIP_VOP2_CLUSTER3, CLUSTER_LAYER}, 3667 {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 3668 {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 3669 {ROCKCHIP_VOP2_ESMART2, ESMART_LAYER}, 3670 {ROCKCHIP_VOP2_ESMART3, ESMART_LAYER}, 3671 }; 3672 3673 static struct vop2_vp_plane_mask rk3588_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 3674 { /* one display policy */ 3675 {/* main display */ 3676 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER0, 3677 .attached_layers_nr = 8, 3678 .attached_layers = { 3679 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART2, 3680 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_ESMART3, 3681 ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3 3682 }, 3683 }, 3684 {/* second display */}, 3685 {/* third display */}, 3686 {/* fourth display */}, 3687 }, 3688 3689 { /* two display policy */ 3690 {/* main display */ 3691 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER0, 3692 .attached_layers_nr = 4, 3693 .attached_layers = { 3694 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, 3695 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1 3696 }, 3697 }, 3698 3699 {/* second display */ 3700 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER2, 3701 .attached_layers_nr = 4, 3702 .attached_layers = { 3703 ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2, 3704 ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3 3705 }, 3706 }, 3707 {/* third display */}, 3708 {/* fourth display */}, 3709 }, 3710 3711 { /* three display policy */ 3712 {/* main display */ 3713 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER0, 3714 .attached_layers_nr = 3, 3715 .attached_layers = { 3716 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART0 3717 }, 3718 }, 3719 3720 {/* second display */ 3721 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER2, 3722 .attached_layers_nr = 3, 3723 .attached_layers = { 3724 ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART1 3725 }, 3726 }, 3727 3728 {/* third display */ 3729 .primary_plane_id = ROCKCHIP_VOP2_ESMART2, 3730 .attached_layers_nr = 2, 3731 .attached_layers = { ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 }, 3732 }, 3733 3734 {/* fourth display */}, 3735 }, 3736 3737 { /* four display policy */ 3738 {/* main display */ 3739 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER0, 3740 .attached_layers_nr = 2, 3741 .attached_layers = { ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0 }, 3742 }, 3743 3744 {/* second display */ 3745 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER1, 3746 .attached_layers_nr = 2, 3747 .attached_layers = { ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1 }, 3748 }, 3749 3750 {/* third display */ 3751 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER2, 3752 .attached_layers_nr = 2, 3753 .attached_layers = { ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2 }, 3754 }, 3755 3756 {/* fourth display */ 3757 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER3, 3758 .attached_layers_nr = 2, 3759 .attached_layers = { ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3 }, 3760 }, 3761 }, 3762 3763 }; 3764 3765 static struct vop2_win_data rk3588_win_data[8] = { 3766 { 3767 .name = "Cluster0", 3768 .phys_id = ROCKCHIP_VOP2_CLUSTER0, 3769 .splice_win_id = ROCKCHIP_VOP2_CLUSTER1, 3770 .type = CLUSTER_LAYER, 3771 .win_sel_port_offset = 0, 3772 .layer_sel_win_id = 0, 3773 .reg_offset = 0, 3774 .axi_id = 0, 3775 .axi_yrgb_id = 2, 3776 .axi_uv_id = 3, 3777 .pd_id = VOP2_PD_CLUSTER0, 3778 }, 3779 3780 { 3781 .name = "Cluster1", 3782 .phys_id = ROCKCHIP_VOP2_CLUSTER1, 3783 .type = CLUSTER_LAYER, 3784 .win_sel_port_offset = 1, 3785 .layer_sel_win_id = 1, 3786 .reg_offset = 0x200, 3787 .axi_id = 0, 3788 .axi_yrgb_id = 6, 3789 .axi_uv_id = 7, 3790 .pd_id = VOP2_PD_CLUSTER1, 3791 }, 3792 3793 { 3794 .name = "Cluster2", 3795 .phys_id = ROCKCHIP_VOP2_CLUSTER2, 3796 .splice_win_id = ROCKCHIP_VOP2_CLUSTER3, 3797 .type = CLUSTER_LAYER, 3798 .win_sel_port_offset = 2, 3799 .layer_sel_win_id = 4, 3800 .reg_offset = 0x400, 3801 .axi_id = 1, 3802 .axi_yrgb_id = 2, 3803 .axi_uv_id = 3, 3804 .pd_id = VOP2_PD_CLUSTER2, 3805 }, 3806 3807 { 3808 .name = "Cluster3", 3809 .phys_id = ROCKCHIP_VOP2_CLUSTER3, 3810 .type = CLUSTER_LAYER, 3811 .win_sel_port_offset = 3, 3812 .layer_sel_win_id = 5, 3813 .reg_offset = 0x600, 3814 .axi_id = 1, 3815 .axi_yrgb_id = 6, 3816 .axi_uv_id = 7, 3817 .pd_id = VOP2_PD_CLUSTER3, 3818 }, 3819 3820 { 3821 .name = "Esmart0", 3822 .phys_id = ROCKCHIP_VOP2_ESMART0, 3823 .splice_win_id = ROCKCHIP_VOP2_ESMART1, 3824 .type = ESMART_LAYER, 3825 .win_sel_port_offset = 4, 3826 .layer_sel_win_id = 2, 3827 .reg_offset = 0, 3828 .axi_id = 0, 3829 .axi_yrgb_id = 0x0a, 3830 .axi_uv_id = 0x0b, 3831 }, 3832 3833 { 3834 .name = "Esmart1", 3835 .phys_id = ROCKCHIP_VOP2_ESMART1, 3836 .type = ESMART_LAYER, 3837 .win_sel_port_offset = 5, 3838 .layer_sel_win_id = 3, 3839 .reg_offset = 0x200, 3840 .axi_id = 0, 3841 .axi_yrgb_id = 0x0c, 3842 .axi_uv_id = 0x0d, 3843 .pd_id = VOP2_PD_ESMART, 3844 }, 3845 3846 { 3847 .name = "Esmart2", 3848 .phys_id = ROCKCHIP_VOP2_ESMART2, 3849 .splice_win_id = ROCKCHIP_VOP2_ESMART3, 3850 .type = ESMART_LAYER, 3851 .win_sel_port_offset = 6, 3852 .layer_sel_win_id = 6, 3853 .reg_offset = 0x400, 3854 .axi_id = 1, 3855 .axi_yrgb_id = 0x0a, 3856 .axi_uv_id = 0x0b, 3857 .pd_id = VOP2_PD_ESMART, 3858 }, 3859 3860 { 3861 .name = "Esmart3", 3862 .phys_id = ROCKCHIP_VOP2_ESMART3, 3863 .type = ESMART_LAYER, 3864 .win_sel_port_offset = 7, 3865 .layer_sel_win_id = 7, 3866 .reg_offset = 0x600, 3867 .axi_id = 1, 3868 .axi_yrgb_id = 0x0c, 3869 .axi_uv_id = 0x0d, 3870 .pd_id = VOP2_PD_ESMART, 3871 }, 3872 }; 3873 3874 static struct dsc_error_info dsc_ecw[] = { 3875 {0x00000000, "no error detected by DSC encoder"}, 3876 {0x0030ffff, "bits per component error"}, 3877 {0x0040ffff, "multiple mode error"}, 3878 {0x0050ffff, "line buffer depth error"}, 3879 {0x0060ffff, "minor version error"}, 3880 {0x0070ffff, "picture height error"}, 3881 {0x0080ffff, "picture width error"}, 3882 {0x0090ffff, "number of slices error"}, 3883 {0x00c0ffff, "slice height Error "}, 3884 {0x00d0ffff, "slice width error"}, 3885 {0x00e0ffff, "second line BPG offset error"}, 3886 {0x00f0ffff, "non second line BPG offset error"}, 3887 {0x0100ffff, "PPS ID error"}, 3888 {0x0110ffff, "bits per pixel (BPP) Error"}, 3889 {0x0120ffff, "buffer flow error"}, /* dsc_buffer_flow */ 3890 3891 {0x01510001, "slice 0 RC buffer model overflow error"}, 3892 {0x01510002, "slice 1 RC buffer model overflow error"}, 3893 {0x01510004, "slice 2 RC buffer model overflow error"}, 3894 {0x01510008, "slice 3 RC buffer model overflow error"}, 3895 {0x01510010, "slice 4 RC buffer model overflow error"}, 3896 {0x01510020, "slice 5 RC buffer model overflow error"}, 3897 {0x01510040, "slice 6 RC buffer model overflow error"}, 3898 {0x01510080, "slice 7 RC buffer model overflow error"}, 3899 3900 {0x01610001, "slice 0 RC buffer model underflow error"}, 3901 {0x01610002, "slice 1 RC buffer model underflow error"}, 3902 {0x01610004, "slice 2 RC buffer model underflow error"}, 3903 {0x01610008, "slice 3 RC buffer model underflow error"}, 3904 {0x01610010, "slice 4 RC buffer model underflow error"}, 3905 {0x01610020, "slice 5 RC buffer model underflow error"}, 3906 {0x01610040, "slice 6 RC buffer model underflow error"}, 3907 {0x01610080, "slice 7 RC buffer model underflow error"}, 3908 3909 {0xffffffff, "unsuccessful RESET cycle status"}, 3910 {0x00a0ffff, "ICH full error precision settings error"}, 3911 {0x0020ffff, "native mode"}, 3912 }; 3913 3914 static struct dsc_error_info dsc_buffer_flow[] = { 3915 {0x00000000, "rate buffer status"}, 3916 {0x00000001, "line buffer status"}, 3917 {0x00000002, "decoder model status"}, 3918 {0x00000003, "pixel buffer status"}, 3919 {0x00000004, "balance fifo buffer status"}, 3920 {0x00000005, "syntax element fifo status"}, 3921 }; 3922 3923 static struct vop2_dsc_data rk3588_dsc_data[] = { 3924 { 3925 .id = ROCKCHIP_VOP2_DSC_8K, 3926 .pd_id = VOP2_PD_DSC_8K, 3927 .max_slice_num = 8, 3928 .max_linebuf_depth = 11, 3929 .min_bits_per_pixel = 9, 3930 .dsc_txp_clk_src_name = "dsc_8k_txp_clk_src", 3931 .dsc_txp_clk_name = "dsc_8k_txp_clk", 3932 .dsc_pxl_clk_name = "dsc_8k_pxl_clk", 3933 .dsc_cds_clk_name = "dsc_8k_cds_clk", 3934 }, 3935 3936 { 3937 .id = ROCKCHIP_VOP2_DSC_4K, 3938 .pd_id = VOP2_PD_DSC_4K, 3939 .max_slice_num = 2, 3940 .max_linebuf_depth = 11, 3941 .min_bits_per_pixel = 9, 3942 .dsc_txp_clk_src_name = "dsc_4k_txp_clk_src", 3943 .dsc_txp_clk_name = "dsc_4k_txp_clk", 3944 .dsc_pxl_clk_name = "dsc_4k_pxl_clk", 3945 .dsc_cds_clk_name = "dsc_4k_cds_clk", 3946 }, 3947 }; 3948 3949 static struct vop2_vp_data rk3588_vp_data[4] = { 3950 { 3951 .splice_vp_id = 1, 3952 .feature = VOP_FEATURE_OUTPUT_10BIT, 3953 .pre_scan_max_dly = 54, 3954 .max_dclk = 600000, 3955 .max_output = {7680, 4320}, 3956 }, 3957 { 3958 .feature = VOP_FEATURE_OUTPUT_10BIT, 3959 .pre_scan_max_dly = 54, 3960 .max_dclk = 600000, 3961 .max_output = {4096, 2304}, 3962 }, 3963 { 3964 .feature = VOP_FEATURE_OUTPUT_10BIT, 3965 .pre_scan_max_dly = 52, 3966 .max_dclk = 600000, 3967 .max_output = {4096, 2304}, 3968 }, 3969 { 3970 .feature = 0, 3971 .pre_scan_max_dly = 52, 3972 .max_dclk = 200000, 3973 .max_output = {1920, 1080}, 3974 }, 3975 }; 3976 3977 static struct vop2_power_domain_data rk3588_vop_pd_data[] = { 3978 { 3979 .id = VOP2_PD_CLUSTER0, 3980 .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER0), 3981 }, 3982 { 3983 .id = VOP2_PD_CLUSTER1, 3984 .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER1), 3985 .parent_id = VOP2_PD_CLUSTER0, 3986 }, 3987 { 3988 .id = VOP2_PD_CLUSTER2, 3989 .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER2), 3990 .parent_id = VOP2_PD_CLUSTER0, 3991 }, 3992 { 3993 .id = VOP2_PD_CLUSTER3, 3994 .module_id_mask = BIT(ROCKCHIP_VOP2_CLUSTER3), 3995 .parent_id = VOP2_PD_CLUSTER0, 3996 }, 3997 { 3998 .id = VOP2_PD_ESMART, 3999 .module_id_mask = BIT(ROCKCHIP_VOP2_ESMART1) | 4000 BIT(ROCKCHIP_VOP2_ESMART2) | 4001 BIT(ROCKCHIP_VOP2_ESMART3), 4002 }, 4003 { 4004 .id = VOP2_PD_DSC_8K, 4005 .module_id_mask = BIT(ROCKCHIP_VOP2_DSC_8K), 4006 }, 4007 { 4008 .id = VOP2_PD_DSC_4K, 4009 .module_id_mask = BIT(ROCKCHIP_VOP2_DSC_4K), 4010 }, 4011 }; 4012 4013 const struct vop2_data rk3588_vop = { 4014 .version = VOP_VERSION_RK3588, 4015 .nr_vps = 4, 4016 .vp_data = rk3588_vp_data, 4017 .win_data = rk3588_win_data, 4018 .plane_mask = rk3588_vp_plane_mask[0], 4019 .plane_table = rk3588_plane_table, 4020 .pd = rk3588_vop_pd_data, 4021 .dsc = rk3588_dsc_data, 4022 .dsc_error_ecw = dsc_ecw, 4023 .dsc_error_buffer_flow = dsc_buffer_flow, 4024 .nr_layers = 8, 4025 .nr_mixers = 7, 4026 .nr_gammas = 4, 4027 .nr_pd = ARRAY_SIZE(rk3588_vop_pd_data), 4028 .nr_dscs = 2, 4029 .nr_dsc_ecw = ARRAY_SIZE(dsc_ecw), 4030 .nr_dsc_buffer_flow = ARRAY_SIZE(dsc_buffer_flow), 4031 }; 4032 4033 const struct rockchip_crtc_funcs rockchip_vop2_funcs = { 4034 .preinit = rockchip_vop2_preinit, 4035 .prepare = rockchip_vop2_prepare, 4036 .init = rockchip_vop2_init, 4037 .set_plane = rockchip_vop2_set_plane, 4038 .enable = rockchip_vop2_enable, 4039 .disable = rockchip_vop2_disable, 4040 .fixup_dts = rockchip_vop2_fixup_dts, 4041 }; 4042