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 <asm/arch/cpu.h> 14 #include <asm/unaligned.h> 15 #include <asm/io.h> 16 #include <linux/list.h> 17 #include <linux/log2.h> 18 #include <linux/media-bus-format.h> 19 #include <clk.h> 20 #include <asm/arch/clock.h> 21 #include <linux/err.h> 22 #include <linux/ioport.h> 23 #include <dm/device.h> 24 #include <dm/read.h> 25 #include <fixp-arith.h> 26 #include <syscon.h> 27 #include <linux/iopoll.h> 28 29 #include "rockchip_display.h" 30 #include "rockchip_crtc.h" 31 #include "rockchip_connector.h" 32 33 /* System registers definition */ 34 #define RK3568_REG_CFG_DONE 0x000 35 #define CFG_DONE_EN BIT(15) 36 37 #define RK3568_VERSION_INFO 0x004 38 #define EN_MASK 1 39 40 #define RK3568_AUTO_GATING_CTRL 0x008 41 42 #define RK3568_SYS_AXI_LUT_CTRL 0x024 43 #define LUT_DMA_EN_SHIFT 0 44 45 #define RK3568_DSP_IF_EN 0x028 46 #define RGB_EN_SHIFT 0 47 #define RK3588_DP0_EN_SHIFT 0 48 #define RK3588_DP1_EN_SHIFT 1 49 #define RK3588_RGB_EN_SHIFT 8 50 #define HDMI0_EN_SHIFT 1 51 #define EDP0_EN_SHIFT 3 52 #define RK3588_EDP0_EN_SHIFT 2 53 #define RK3588_HDMI0_EN_SHIFT 3 54 #define MIPI0_EN_SHIFT 4 55 #define RK3588_EDP1_EN_SHIFT 4 56 #define RK3588_HDMI1_EN_SHIFT 5 57 #define RK3588_MIPI0_EN_SHIFT 6 58 #define MIPI1_EN_SHIFT 20 59 #define RK3588_MIPI1_EN_SHIFT 7 60 #define LVDS0_EN_SHIFT 5 61 #define LVDS1_EN_SHIFT 24 62 #define BT1120_EN_SHIFT 6 63 #define BT656_EN_SHIFT 7 64 #define IF_MUX_MASK 3 65 #define RGB_MUX_SHIFT 8 66 #define HDMI0_MUX_SHIFT 10 67 #define RK3588_DP0_MUX_SHIFT 12 68 #define RK3588_DP1_MUX_SHIFT 14 69 #define EDP0_MUX_SHIFT 14 70 #define RK3588_HDMI_EDP0_MUX_SHIFT 16 71 #define RK3588_HDMI_EDP1_MUX_SHIFT 18 72 #define MIPI0_MUX_SHIFT 16 73 #define RK3588_MIPI0_MUX_SHIFT 20 74 #define MIPI1_MUX_SHIFT 21 75 #define LVDS0_MUX_SHIFT 18 76 #define LVDS1_MUX_SHIFT 25 77 78 #define RK3568_DSP_IF_CTRL 0x02c 79 #define LVDS_DUAL_EN_SHIFT 0 80 #define LVDS_DUAL_LEFT_RIGHT_EN_SHIFT 1 81 #define LVDS_DUAL_SWAP_EN_SHIFT 2 82 #define RK3568_MIPI_DUAL_EN_SHIFT 10 83 #define RK3588_MIPI_DSI0_MODE_SEL_SHIFT 11 84 #define RK3588_MIPI_DSI1_MODE_SEL_SHIFT 12 85 86 #define RK3568_DSP_IF_POL 0x030 87 #define IF_CTRL_REG_DONE_IMD_MASK 1 88 #define IF_CTRL_REG_DONE_IMD_SHIFT 28 89 #define IF_CRTL_MIPI_DCLK_POL_SHIT 19 90 #define IF_CRTL_EDP_DCLK_POL_SHIT 15 91 #define IF_CRTL_HDMI_DCLK_POL_SHIT 7 92 #define IF_CRTL_HDMI_PIN_POL_MASK 0x7 93 #define IF_CRTL_HDMI_PIN_POL_SHIT 4 94 95 #define RK3588_DP0_PIN_POL_SHIFT 8 96 #define RK3588_DP1_PIN_POL_SHIFT 12 97 #define RK3588_IF_PIN_POL_MASK 0x7 98 99 #define IF_CRTL_RGB_LVDS_DCLK_POL_SHIT 3 100 101 #define HDMI_EDP0_DCLK_DIV_SHIFT 16 102 #define HDMI_EDP0_PIXCLK_DIV_SHIFT 18 103 #define HDMI_EDP1_DCLK_DIV_SHIFT 20 104 #define HDMI_EDP1_PIXCLK_DIV_SHIFT 22 105 #define MIPI0_PIXCLK_DIV_SHIFT 24 106 #define MIPI1_PIXCLK_DIV_SHIFT 26 107 108 #define RK3568_SYS_OTP_WIN_EN 0x50 109 #define OTP_WIN_EN_SHIFT 0 110 #define RK3568_SYS_LUT_PORT_SEL 0x58 111 #define GAMMA_PORT_SEL_MASK 0x3 112 #define GAMMA_PORT_SEL_SHIFT 0 113 114 #define RK3568_SYS_PD_CTRL 0x034 115 #define RK3568_VP0_LINE_FLAG 0x70 116 #define RK3568_VP1_LINE_FLAG 0x74 117 #define RK3568_VP2_LINE_FLAG 0x78 118 #define RK3568_SYS0_INT_EN 0x80 119 #define RK3568_SYS0_INT_CLR 0x84 120 #define RK3568_SYS0_INT_STATUS 0x88 121 #define RK3568_SYS1_INT_EN 0x90 122 #define RK3568_SYS1_INT_CLR 0x94 123 #define RK3568_SYS1_INT_STATUS 0x98 124 #define RK3568_VP0_INT_EN 0xA0 125 #define RK3568_VP0_INT_CLR 0xA4 126 #define RK3568_VP0_INT_STATUS 0xA8 127 #define RK3568_VP1_INT_EN 0xB0 128 #define RK3568_VP1_INT_CLR 0xB4 129 #define RK3568_VP1_INT_STATUS 0xB8 130 #define RK3568_VP2_INT_EN 0xC0 131 #define RK3568_VP2_INT_CLR 0xC4 132 #define RK3568_VP2_INT_STATUS 0xC8 133 #define RK3588_CLUSTER0_PD_EN_SHIFT 0 134 #define RK3588_CLUSTER1_PD_EN_SHIFT 1 135 #define RK3588_CLUSTER2_PD_EN_SHIFT 2 136 #define RK3588_CLUSTER3_PD_EN_SHIFT 3 137 #define RK3588_ESMART_PD_EN_SHIFT 7 138 139 #define RK3568_SYS_STATUS0 0x60 140 #define RK3588_CLUSTER0_PD_STATUS_SHIFT 8 141 #define RK3588_CLUSTER1_PD_STATUS_SHIFT 9 142 #define RK3588_CLUSTER2_PD_STATUS_SHIFT 10 143 #define RK3588_CLUSTER3_PD_STATUS_SHIFT 11 144 #define RK3588_ESMART_PD_STATUS_SHIFT 15 145 146 #define RK3568_SYS_CTRL_LINE_FLAG0 0x70 147 #define LINE_FLAG_NUM_MASK 0x1fff 148 #define RK3568_DSP_LINE_FLAG_NUM0_SHIFT 0 149 #define RK3568_DSP_LINE_FLAG_NUM1_SHIFT 16 150 151 /* Overlay registers definition */ 152 #define RK3568_OVL_CTRL 0x600 153 #define OVL_PORT_MUX_REG_DONE_IMD_SHIFT 28 154 #define RK3568_OVL_LAYER_SEL 0x604 155 #define LAYER_SEL_MASK 0xf 156 157 #define RK3568_OVL_PORT_SEL 0x608 158 #define PORT_MUX_MASK 0xf 159 #define PORT_MUX_SHIFT 0 160 #define LAYER_SEL_PORT_MASK 0x3 161 #define LAYER_SEL_PORT_SHIFT 16 162 163 #define RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL 0x610 164 #define RK3568_CLUSTER0_MIX_DST_COLOR_CTRL 0x614 165 #define RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x618 166 #define RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL 0x61C 167 #define RK3568_MIX0_SRC_COLOR_CTRL 0x650 168 #define RK3568_MIX0_DST_COLOR_CTRL 0x654 169 #define RK3568_MIX0_SRC_ALPHA_CTRL 0x658 170 #define RK3568_MIX0_DST_ALPHA_CTRL 0x65C 171 #define RK3568_HDR0_SRC_COLOR_CTRL 0x6C0 172 #define RK3568_HDR0_DST_COLOR_CTRL 0x6C4 173 #define RK3568_HDR0_SRC_ALPHA_CTRL 0x6C8 174 #define RK3568_HDR0_DST_ALPHA_CTRL 0x6CC 175 #define RK3568_VP0_BG_MIX_CTRL 0x6E0 176 #define BG_MIX_CTRL_MASK 0xff 177 #define BG_MIX_CTRL_SHIFT 24 178 #define RK3568_VP1_BG_MIX_CTRL 0x6E4 179 #define RK3568_VP2_BG_MIX_CTRL 0x6E8 180 #define RK3568_CLUSTER_DLY_NUM 0x6F0 181 #define RK3568_SMART_DLY_NUM 0x6F8 182 183 /* Video Port registers definition */ 184 #define RK3568_VP0_DSP_CTRL 0xC00 185 #define OUT_MODE_MASK 0xf 186 #define OUT_MODE_SHIFT 0 187 #define DATA_SWAP_MASK 0x1f 188 #define DATA_SWAP_SHIFT 8 189 #define DSP_RB_SWAP 2 190 #define CORE_DCLK_DIV_EN_SHIFT 4 191 #define P2I_EN_SHIFT 5 192 #define DSP_FILED_POL 6 193 #define INTERLACE_EN_SHIFT 7 194 #define POST_DSP_OUT_R2Y_SHIFT 15 195 #define PRE_DITHER_DOWN_EN_SHIFT 16 196 #define DITHER_DOWN_EN_SHIFT 17 197 #define DSP_LUT_EN_SHIFT 28 198 199 #define STANDBY_EN_SHIFT 31 200 201 #define RK3568_VP0_MIPI_CTRL 0xC04 202 #define DCLK_DIV2_SHIFT 4 203 #define DCLK_DIV2_MASK 0x3 204 #define MIPI_DUAL_EN_SHIFT 20 205 #define MIPI_DUAL_SWAP_EN_SHIFT 21 206 #define EDPI_TE_EN 28 207 #define EDPI_WMS_HOLD_EN 30 208 #define EDPI_WMS_FS 31 209 210 211 #define RK3568_VP0_COLOR_BAR_CTRL 0xC08 212 #define RK3568_VP0_3D_LUT_CTRL 0xC10 213 #define VP0_3D_LUT_EN_SHIFT 0 214 #define VP0_3D_LUT_UPDATE_SHIFT 2 215 216 #define RK3588_VP0_CLK_CTRL 0xC0C 217 #define DCLK_CORE_DIV_SHIFT 0 218 #define DCLK_OUT_DIV_SHIFT 2 219 220 #define RK3568_VP0_3D_LUT_MST 0xC20 221 222 #define RK3568_VP0_DSP_BG 0xC2C 223 #define RK3568_VP0_PRE_SCAN_HTIMING 0xC30 224 #define RK3568_VP0_POST_DSP_HACT_INFO 0xC34 225 #define RK3568_VP0_POST_DSP_VACT_INFO 0xC38 226 #define RK3568_VP0_POST_SCL_FACTOR_YRGB 0xC3C 227 #define RK3568_VP0_POST_SCL_CTRL 0xC40 228 #define RK3568_VP0_POST_DSP_VACT_INFO_F1 0xC44 229 #define RK3568_VP0_DSP_HTOTAL_HS_END 0xC48 230 #define RK3568_VP0_DSP_HACT_ST_END 0xC4C 231 #define RK3568_VP0_DSP_VTOTAL_VS_END 0xC50 232 #define RK3568_VP0_DSP_VACT_ST_END 0xC54 233 #define RK3568_VP0_DSP_VS_ST_END_F1 0xC58 234 #define RK3568_VP0_DSP_VACT_ST_END_F1 0xC5C 235 236 #define RK3568_VP0_BCSH_CTRL 0xC60 237 #define BCSH_CTRL_Y2R_SHIFT 0 238 #define BCSH_CTRL_Y2R_MASK 0x1 239 #define BCSH_CTRL_Y2R_CSC_MODE_SHIFT 2 240 #define BCSH_CTRL_Y2R_CSC_MODE_MASK 0x3 241 #define BCSH_CTRL_R2Y_SHIFT 4 242 #define BCSH_CTRL_R2Y_MASK 0x1 243 #define BCSH_CTRL_R2Y_CSC_MODE_SHIFT 6 244 #define BCSH_CTRL_R2Y_CSC_MODE_MASK 0x3 245 246 #define RK3568_VP0_BCSH_BCS 0xC64 247 #define BCSH_BRIGHTNESS_SHIFT 0 248 #define BCSH_BRIGHTNESS_MASK 0xFF 249 #define BCSH_CONTRAST_SHIFT 8 250 #define BCSH_CONTRAST_MASK 0x1FF 251 #define BCSH_SATURATION_SHIFT 20 252 #define BCSH_SATURATION_MASK 0x3FF 253 #define BCSH_OUT_MODE_SHIFT 30 254 #define BCSH_OUT_MODE_MASK 0x3 255 256 #define RK3568_VP0_BCSH_H 0xC68 257 #define BCSH_SIN_HUE_SHIFT 0 258 #define BCSH_SIN_HUE_MASK 0x1FF 259 #define BCSH_COS_HUE_SHIFT 16 260 #define BCSH_COS_HUE_MASK 0x1FF 261 262 #define RK3568_VP0_BCSH_COLOR 0xC6C 263 #define BCSH_EN_SHIFT 31 264 #define BCSH_EN_MASK 1 265 266 #define RK3568_VP1_DSP_CTRL 0xD00 267 #define RK3568_VP1_MIPI_CTRL 0xD04 268 #define RK3568_VP1_COLOR_BAR_CTRL 0xD08 269 #define RK3568_VP1_PRE_SCAN_HTIMING 0xD30 270 #define RK3568_VP1_POST_DSP_HACT_INFO 0xD34 271 #define RK3568_VP1_POST_DSP_VACT_INFO 0xD38 272 #define RK3568_VP1_POST_SCL_FACTOR_YRGB 0xD3C 273 #define RK3568_VP1_POST_SCL_CTRL 0xD40 274 #define RK3568_VP1_DSP_HACT_INFO 0xD34 275 #define RK3568_VP1_DSP_VACT_INFO 0xD38 276 #define RK3568_VP1_POST_DSP_VACT_INFO_F1 0xD44 277 #define RK3568_VP1_DSP_HTOTAL_HS_END 0xD48 278 #define RK3568_VP1_DSP_HACT_ST_END 0xD4C 279 #define RK3568_VP1_DSP_VTOTAL_VS_END 0xD50 280 #define RK3568_VP1_DSP_VACT_ST_END 0xD54 281 #define RK3568_VP1_DSP_VS_ST_END_F1 0xD58 282 #define RK3568_VP1_DSP_VACT_ST_END_F1 0xD5C 283 284 #define RK3568_VP2_DSP_CTRL 0xE00 285 #define RK3568_VP2_MIPI_CTRL 0xE04 286 #define RK3568_VP2_COLOR_BAR_CTRL 0xE08 287 #define RK3568_VP2_PRE_SCAN_HTIMING 0xE30 288 #define RK3568_VP2_POST_DSP_HACT_INFO 0xE34 289 #define RK3568_VP2_POST_DSP_VACT_INFO 0xE38 290 #define RK3568_VP2_POST_SCL_FACTOR_YRGB 0xE3C 291 #define RK3568_VP2_POST_SCL_CTRL 0xE40 292 #define RK3568_VP2_DSP_HACT_INFO 0xE34 293 #define RK3568_VP2_DSP_VACT_INFO 0xE38 294 #define RK3568_VP2_POST_DSP_VACT_INFO_F1 0xE44 295 #define RK3568_VP2_DSP_HTOTAL_HS_END 0xE48 296 #define RK3568_VP2_DSP_HACT_ST_END 0xE4C 297 #define RK3568_VP2_DSP_VTOTAL_VS_END 0xE50 298 #define RK3568_VP2_DSP_VACT_ST_END 0xE54 299 #define RK3568_VP2_DSP_VS_ST_END_F1 0xE58 300 #define RK3568_VP2_DSP_VACT_ST_END_F1 0xE5C 301 302 /* Cluster0 register definition */ 303 #define RK3568_CLUSTER0_WIN0_CTRL0 0x1000 304 #define CLUSTER_YUV2RGB_EN_SHIFT 8 305 #define CLUSTER_RGB2YUV_EN_SHIFT 9 306 #define CLUSTER_CSC_MODE_SHIFT 10 307 #define CLUSTER_YRGB_XSCL_MODE_SHIFT 12 308 #define CLUSTER_YRGB_YSCL_MODE_SHIFT 14 309 #define RK3568_CLUSTER0_WIN0_CTRL1 0x1004 310 #define CLUSTER_YRGB_GT2_SHIFT 28 311 #define CLUSTER_YRGB_GT4_SHIFT 29 312 #define RK3568_CLUSTER0_WIN0_YRGB_MST 0x1010 313 #define RK3568_CLUSTER0_WIN0_CBR_MST 0x1014 314 #define RK3568_CLUSTER0_WIN0_VIR 0x1018 315 #define RK3568_CLUSTER0_WIN0_ACT_INFO 0x1020 316 #define RK3568_CLUSTER0_WIN0_DSP_INFO 0x1024 317 #define RK3568_CLUSTER0_WIN0_DSP_ST 0x1028 318 #define RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB 0x1030 319 #define RK3568_CLUSTER0_WIN0_AFBCD_ROTATE_MODE 0x1054 320 #define RK3568_CLUSTER0_WIN0_AFBCD_HDR_PTR 0x1058 321 #define RK3568_CLUSTER0_WIN0_AFBCD_VIR_WIDTH 0x105C 322 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_SIZE 0x1060 323 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_OFFSET 0x1064 324 #define RK3568_CLUSTER0_WIN0_AFBCD_DSP_OFFSET 0x1068 325 #define RK3568_CLUSTER0_WIN0_AFBCD_CTRL 0x106C 326 327 #define RK3568_CLUSTER0_WIN1_CTRL0 0x1080 328 #define RK3568_CLUSTER0_WIN1_CTRL1 0x1084 329 #define RK3568_CLUSTER0_WIN1_YRGB_MST 0x1090 330 #define RK3568_CLUSTER0_WIN1_CBR_MST 0x1094 331 #define RK3568_CLUSTER0_WIN1_VIR 0x1098 332 #define RK3568_CLUSTER0_WIN1_ACT_INFO 0x10A0 333 #define RK3568_CLUSTER0_WIN1_DSP_INFO 0x10A4 334 #define RK3568_CLUSTER0_WIN1_DSP_ST 0x10A8 335 #define RK3568_CLUSTER0_WIN1_SCL_FACTOR_YRGB 0x10B0 336 #define RK3568_CLUSTER0_WIN1_AFBCD_ROTATE_MODE 0x10D4 337 #define RK3568_CLUSTER0_WIN1_AFBCD_HDR_PTR 0x10D8 338 #define RK3568_CLUSTER0_WIN1_AFBCD_VIR_WIDTH 0x10DC 339 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_SIZE 0x10E0 340 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_OFFSET 0x10E4 341 #define RK3568_CLUSTER0_WIN1_AFBCD_DSP_OFFSET 0x10E8 342 #define RK3568_CLUSTER0_WIN1_AFBCD_CTRL 0x10EC 343 344 #define RK3568_CLUSTER0_CTRL 0x1100 345 #define CLUSTER_EN_SHIFT 0 346 347 #define RK3568_CLUSTER1_WIN0_CTRL0 0x1200 348 #define RK3568_CLUSTER1_WIN0_CTRL1 0x1204 349 #define RK3568_CLUSTER1_WIN0_YRGB_MST 0x1210 350 #define RK3568_CLUSTER1_WIN0_CBR_MST 0x1214 351 #define RK3568_CLUSTER1_WIN0_VIR 0x1218 352 #define RK3568_CLUSTER1_WIN0_ACT_INFO 0x1220 353 #define RK3568_CLUSTER1_WIN0_DSP_INFO 0x1224 354 #define RK3568_CLUSTER1_WIN0_DSP_ST 0x1228 355 #define RK3568_CLUSTER1_WIN0_SCL_FACTOR_YRGB 0x1230 356 #define RK3568_CLUSTER1_WIN0_AFBCD_ROTATE_MODE 0x1254 357 #define RK3568_CLUSTER1_WIN0_AFBCD_HDR_PTR 0x1258 358 #define RK3568_CLUSTER1_WIN0_AFBCD_VIR_WIDTH 0x125C 359 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_SIZE 0x1260 360 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_OFFSET 0x1264 361 #define RK3568_CLUSTER1_WIN0_AFBCD_DSP_OFFSET 0x1268 362 #define RK3568_CLUSTER1_WIN0_AFBCD_CTRL 0x126C 363 364 #define RK3568_CLUSTER1_WIN1_CTRL0 0x1280 365 #define RK3568_CLUSTER1_WIN1_CTRL1 0x1284 366 #define RK3568_CLUSTER1_WIN1_YRGB_MST 0x1290 367 #define RK3568_CLUSTER1_WIN1_CBR_MST 0x1294 368 #define RK3568_CLUSTER1_WIN1_VIR 0x1298 369 #define RK3568_CLUSTER1_WIN1_ACT_INFO 0x12A0 370 #define RK3568_CLUSTER1_WIN1_DSP_INFO 0x12A4 371 #define RK3568_CLUSTER1_WIN1_DSP_ST 0x12A8 372 #define RK3568_CLUSTER1_WIN1_SCL_FACTOR_YRGB 0x12B0 373 #define RK3568_CLUSTER1_WIN1_AFBCD_ROTATE_MODE 0x12D4 374 #define RK3568_CLUSTER1_WIN1_AFBCD_HDR_PTR 0x12D8 375 #define RK3568_CLUSTER1_WIN1_AFBCD_VIR_WIDTH 0x12DC 376 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_SIZE 0x12E0 377 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_OFFSET 0x12E4 378 #define RK3568_CLUSTER1_WIN1_AFBCD_DSP_OFFSET 0x12E8 379 #define RK3568_CLUSTER1_WIN1_AFBCD_CTRL 0x12EC 380 381 #define RK3568_CLUSTER1_CTRL 0x1300 382 383 /* Esmart register definition */ 384 #define RK3568_ESMART0_CTRL0 0x1800 385 #define RGB2YUV_EN_SHIFT 1 386 #define CSC_MODE_SHIFT 2 387 #define CSC_MODE_MASK 0x3 388 389 #define RK3568_ESMART0_CTRL1 0x1804 390 #define YMIRROR_EN_SHIFT 31 391 #define RK3568_ESMART0_REGION0_CTRL 0x1810 392 #define REGION0_RB_SWAP_SHIFT 14 393 #define WIN_EN_SHIFT 0 394 #define WIN_FORMAT_MASK 0x1f 395 #define WIN_FORMAT_SHIFT 1 396 397 #define RK3568_ESMART0_REGION0_YRGB_MST 0x1814 398 #define RK3568_ESMART0_REGION0_CBR_MST 0x1818 399 #define RK3568_ESMART0_REGION0_VIR 0x181C 400 #define RK3568_ESMART0_REGION0_ACT_INFO 0x1820 401 #define RK3568_ESMART0_REGION0_DSP_INFO 0x1824 402 #define RK3568_ESMART0_REGION0_DSP_ST 0x1828 403 #define RK3568_ESMART0_REGION0_SCL_CTRL 0x1830 404 #define YRGB_XSCL_MODE_MASK 0x3 405 #define YRGB_XSCL_MODE_SHIFT 0 406 #define YRGB_XSCL_FILTER_MODE_MASK 0x3 407 #define YRGB_XSCL_FILTER_MODE_SHIFT 2 408 #define YRGB_YSCL_MODE_MASK 0x3 409 #define YRGB_YSCL_MODE_SHIFT 4 410 #define YRGB_YSCL_FILTER_MODE_MASK 0x3 411 #define YRGB_YSCL_FILTER_MODE_SHIFT 6 412 413 #define RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB 0x1834 414 #define RK3568_ESMART0_REGION0_SCL_FACTOR_CBR 0x1838 415 #define RK3568_ESMART0_REGION0_SCL_OFFSET 0x183C 416 #define RK3568_ESMART0_REGION1_CTRL 0x1840 417 #define YRGB_GT2_MASK 0x1 418 #define YRGB_GT2_SHIFT 8 419 #define YRGB_GT4_MASK 0x1 420 #define YRGB_GT4_SHIFT 9 421 422 #define RK3568_ESMART0_REGION1_YRGB_MST 0x1844 423 #define RK3568_ESMART0_REGION1_CBR_MST 0x1848 424 #define RK3568_ESMART0_REGION1_VIR 0x184C 425 #define RK3568_ESMART0_REGION1_ACT_INFO 0x1850 426 #define RK3568_ESMART0_REGION1_DSP_INFO 0x1854 427 #define RK3568_ESMART0_REGION1_DSP_ST 0x1858 428 #define RK3568_ESMART0_REGION1_SCL_CTRL 0x1860 429 #define RK3568_ESMART0_REGION1_SCL_FACTOR_YRGB 0x1864 430 #define RK3568_ESMART0_REGION1_SCL_FACTOR_CBR 0x1868 431 #define RK3568_ESMART0_REGION1_SCL_OFFSET 0x186C 432 #define RK3568_ESMART0_REGION2_CTRL 0x1870 433 #define RK3568_ESMART0_REGION2_YRGB_MST 0x1874 434 #define RK3568_ESMART0_REGION2_CBR_MST 0x1878 435 #define RK3568_ESMART0_REGION2_VIR 0x187C 436 #define RK3568_ESMART0_REGION2_ACT_INFO 0x1880 437 #define RK3568_ESMART0_REGION2_DSP_INFO 0x1884 438 #define RK3568_ESMART0_REGION2_DSP_ST 0x1888 439 #define RK3568_ESMART0_REGION2_SCL_CTRL 0x1890 440 #define RK3568_ESMART0_REGION2_SCL_FACTOR_YRGB 0x1894 441 #define RK3568_ESMART0_REGION2_SCL_FACTOR_CBR 0x1898 442 #define RK3568_ESMART0_REGION2_SCL_OFFSET 0x189C 443 #define RK3568_ESMART0_REGION3_CTRL 0x18A0 444 #define RK3568_ESMART0_REGION3_YRGB_MST 0x18A4 445 #define RK3568_ESMART0_REGION3_CBR_MST 0x18A8 446 #define RK3568_ESMART0_REGION3_VIR 0x18AC 447 #define RK3568_ESMART0_REGION3_ACT_INFO 0x18B0 448 #define RK3568_ESMART0_REGION3_DSP_INFO 0x18B4 449 #define RK3568_ESMART0_REGION3_DSP_ST 0x18B8 450 #define RK3568_ESMART0_REGION3_SCL_CTRL 0x18C0 451 #define RK3568_ESMART0_REGION3_SCL_FACTOR_YRGB 0x18C4 452 #define RK3568_ESMART0_REGION3_SCL_FACTOR_CBR 0x18C8 453 #define RK3568_ESMART0_REGION3_SCL_OFFSET 0x18CC 454 455 #define RK3568_ESMART1_CTRL0 0x1A00 456 #define RK3568_ESMART1_CTRL1 0x1A04 457 #define RK3568_ESMART1_REGION0_CTRL 0x1A10 458 #define RK3568_ESMART1_REGION0_YRGB_MST 0x1A14 459 #define RK3568_ESMART1_REGION0_CBR_MST 0x1A18 460 #define RK3568_ESMART1_REGION0_VIR 0x1A1C 461 #define RK3568_ESMART1_REGION0_ACT_INFO 0x1A20 462 #define RK3568_ESMART1_REGION0_DSP_INFO 0x1A24 463 #define RK3568_ESMART1_REGION0_DSP_ST 0x1A28 464 #define RK3568_ESMART1_REGION0_SCL_CTRL 0x1A30 465 #define RK3568_ESMART1_REGION0_SCL_FACTOR_YRGB 0x1A34 466 #define RK3568_ESMART1_REGION0_SCL_FACTOR_CBR 0x1A38 467 #define RK3568_ESMART1_REGION0_SCL_OFFSET 0x1A3C 468 #define RK3568_ESMART1_REGION1_CTRL 0x1A40 469 #define RK3568_ESMART1_REGION1_YRGB_MST 0x1A44 470 #define RK3568_ESMART1_REGION1_CBR_MST 0x1A48 471 #define RK3568_ESMART1_REGION1_VIR 0x1A4C 472 #define RK3568_ESMART1_REGION1_ACT_INFO 0x1A50 473 #define RK3568_ESMART1_REGION1_DSP_INFO 0x1A54 474 #define RK3568_ESMART1_REGION1_DSP_ST 0x1A58 475 #define RK3568_ESMART1_REGION1_SCL_CTRL 0x1A60 476 #define RK3568_ESMART1_REGION1_SCL_FACTOR_YRGB 0x1A64 477 #define RK3568_ESMART1_REGION1_SCL_FACTOR_CBR 0x1A68 478 #define RK3568_ESMART1_REGION1_SCL_OFFSET 0x1A6C 479 #define RK3568_ESMART1_REGION2_CTRL 0x1A70 480 #define RK3568_ESMART1_REGION2_YRGB_MST 0x1A74 481 #define RK3568_ESMART1_REGION2_CBR_MST 0x1A78 482 #define RK3568_ESMART1_REGION2_VIR 0x1A7C 483 #define RK3568_ESMART1_REGION2_ACT_INFO 0x1A80 484 #define RK3568_ESMART1_REGION2_DSP_INFO 0x1A84 485 #define RK3568_ESMART1_REGION2_DSP_ST 0x1A88 486 #define RK3568_ESMART1_REGION2_SCL_CTRL 0x1A90 487 #define RK3568_ESMART1_REGION2_SCL_FACTOR_YRGB 0x1A94 488 #define RK3568_ESMART1_REGION2_SCL_FACTOR_CBR 0x1A98 489 #define RK3568_ESMART1_REGION2_SCL_OFFSET 0x1A9C 490 #define RK3568_ESMART1_REGION3_CTRL 0x1AA0 491 #define RK3568_ESMART1_REGION3_YRGB_MST 0x1AA4 492 #define RK3568_ESMART1_REGION3_CBR_MST 0x1AA8 493 #define RK3568_ESMART1_REGION3_VIR 0x1AAC 494 #define RK3568_ESMART1_REGION3_ACT_INFO 0x1AB0 495 #define RK3568_ESMART1_REGION3_DSP_INFO 0x1AB4 496 #define RK3568_ESMART1_REGION3_DSP_ST 0x1AB8 497 #define RK3568_ESMART1_REGION3_SCL_CTRL 0x1AC0 498 #define RK3568_ESMART1_REGION3_SCL_FACTOR_YRGB 0x1AC4 499 #define RK3568_ESMART1_REGION3_SCL_FACTOR_CBR 0x1AC8 500 #define RK3568_ESMART1_REGION3_SCL_OFFSET 0x1ACC 501 502 #define RK3568_SMART0_CTRL0 0x1C00 503 #define RK3568_SMART0_CTRL1 0x1C04 504 #define RK3568_SMART0_REGION0_CTRL 0x1C10 505 #define RK3568_SMART0_REGION0_YRGB_MST 0x1C14 506 #define RK3568_SMART0_REGION0_CBR_MST 0x1C18 507 #define RK3568_SMART0_REGION0_VIR 0x1C1C 508 #define RK3568_SMART0_REGION0_ACT_INFO 0x1C20 509 #define RK3568_SMART0_REGION0_DSP_INFO 0x1C24 510 #define RK3568_SMART0_REGION0_DSP_ST 0x1C28 511 #define RK3568_SMART0_REGION0_SCL_CTRL 0x1C30 512 #define RK3568_SMART0_REGION0_SCL_FACTOR_YRGB 0x1C34 513 #define RK3568_SMART0_REGION0_SCL_FACTOR_CBR 0x1C38 514 #define RK3568_SMART0_REGION0_SCL_OFFSET 0x1C3C 515 #define RK3568_SMART0_REGION1_CTRL 0x1C40 516 #define RK3568_SMART0_REGION1_YRGB_MST 0x1C44 517 #define RK3568_SMART0_REGION1_CBR_MST 0x1C48 518 #define RK3568_SMART0_REGION1_VIR 0x1C4C 519 #define RK3568_SMART0_REGION1_ACT_INFO 0x1C50 520 #define RK3568_SMART0_REGION1_DSP_INFO 0x1C54 521 #define RK3568_SMART0_REGION1_DSP_ST 0x1C58 522 #define RK3568_SMART0_REGION1_SCL_CTRL 0x1C60 523 #define RK3568_SMART0_REGION1_SCL_FACTOR_YRGB 0x1C64 524 #define RK3568_SMART0_REGION1_SCL_FACTOR_CBR 0x1C68 525 #define RK3568_SMART0_REGION1_SCL_OFFSET 0x1C6C 526 #define RK3568_SMART0_REGION2_CTRL 0x1C70 527 #define RK3568_SMART0_REGION2_YRGB_MST 0x1C74 528 #define RK3568_SMART0_REGION2_CBR_MST 0x1C78 529 #define RK3568_SMART0_REGION2_VIR 0x1C7C 530 #define RK3568_SMART0_REGION2_ACT_INFO 0x1C80 531 #define RK3568_SMART0_REGION2_DSP_INFO 0x1C84 532 #define RK3568_SMART0_REGION2_DSP_ST 0x1C88 533 #define RK3568_SMART0_REGION2_SCL_CTRL 0x1C90 534 #define RK3568_SMART0_REGION2_SCL_FACTOR_YRGB 0x1C94 535 #define RK3568_SMART0_REGION2_SCL_FACTOR_CBR 0x1C98 536 #define RK3568_SMART0_REGION2_SCL_OFFSET 0x1C9C 537 #define RK3568_SMART0_REGION3_CTRL 0x1CA0 538 #define RK3568_SMART0_REGION3_YRGB_MST 0x1CA4 539 #define RK3568_SMART0_REGION3_CBR_MST 0x1CA8 540 #define RK3568_SMART0_REGION3_VIR 0x1CAC 541 #define RK3568_SMART0_REGION3_ACT_INFO 0x1CB0 542 #define RK3568_SMART0_REGION3_DSP_INFO 0x1CB4 543 #define RK3568_SMART0_REGION3_DSP_ST 0x1CB8 544 #define RK3568_SMART0_REGION3_SCL_CTRL 0x1CC0 545 #define RK3568_SMART0_REGION3_SCL_FACTOR_YRGB 0x1CC4 546 #define RK3568_SMART0_REGION3_SCL_FACTOR_CBR 0x1CC8 547 #define RK3568_SMART0_REGION3_SCL_OFFSET 0x1CCC 548 549 #define RK3568_SMART1_CTRL0 0x1E00 550 #define RK3568_SMART1_CTRL1 0x1E04 551 #define RK3568_SMART1_REGION0_CTRL 0x1E10 552 #define RK3568_SMART1_REGION0_YRGB_MST 0x1E14 553 #define RK3568_SMART1_REGION0_CBR_MST 0x1E18 554 #define RK3568_SMART1_REGION0_VIR 0x1E1C 555 #define RK3568_SMART1_REGION0_ACT_INFO 0x1E20 556 #define RK3568_SMART1_REGION0_DSP_INFO 0x1E24 557 #define RK3568_SMART1_REGION0_DSP_ST 0x1E28 558 #define RK3568_SMART1_REGION0_SCL_CTRL 0x1E30 559 #define RK3568_SMART1_REGION0_SCL_FACTOR_YRGB 0x1E34 560 #define RK3568_SMART1_REGION0_SCL_FACTOR_CBR 0x1E38 561 #define RK3568_SMART1_REGION0_SCL_OFFSET 0x1E3C 562 #define RK3568_SMART1_REGION1_CTRL 0x1E40 563 #define RK3568_SMART1_REGION1_YRGB_MST 0x1E44 564 #define RK3568_SMART1_REGION1_CBR_MST 0x1E48 565 #define RK3568_SMART1_REGION1_VIR 0x1E4C 566 #define RK3568_SMART1_REGION1_ACT_INFO 0x1E50 567 #define RK3568_SMART1_REGION1_DSP_INFO 0x1E54 568 #define RK3568_SMART1_REGION1_DSP_ST 0x1E58 569 #define RK3568_SMART1_REGION1_SCL_CTRL 0x1E60 570 #define RK3568_SMART1_REGION1_SCL_FACTOR_YRGB 0x1E64 571 #define RK3568_SMART1_REGION1_SCL_FACTOR_CBR 0x1E68 572 #define RK3568_SMART1_REGION1_SCL_OFFSET 0x1E6C 573 #define RK3568_SMART1_REGION2_CTRL 0x1E70 574 #define RK3568_SMART1_REGION2_YRGB_MST 0x1E74 575 #define RK3568_SMART1_REGION2_CBR_MST 0x1E78 576 #define RK3568_SMART1_REGION2_VIR 0x1E7C 577 #define RK3568_SMART1_REGION2_ACT_INFO 0x1E80 578 #define RK3568_SMART1_REGION2_DSP_INFO 0x1E84 579 #define RK3568_SMART1_REGION2_DSP_ST 0x1E88 580 #define RK3568_SMART1_REGION2_SCL_CTRL 0x1E90 581 #define RK3568_SMART1_REGION2_SCL_FACTOR_YRGB 0x1E94 582 #define RK3568_SMART1_REGION2_SCL_FACTOR_CBR 0x1E98 583 #define RK3568_SMART1_REGION2_SCL_OFFSET 0x1E9C 584 #define RK3568_SMART1_REGION3_CTRL 0x1EA0 585 #define RK3568_SMART1_REGION3_YRGB_MST 0x1EA4 586 #define RK3568_SMART1_REGION3_CBR_MST 0x1EA8 587 #define RK3568_SMART1_REGION3_VIR 0x1EAC 588 #define RK3568_SMART1_REGION3_ACT_INFO 0x1EB0 589 #define RK3568_SMART1_REGION3_DSP_INFO 0x1EB4 590 #define RK3568_SMART1_REGION3_DSP_ST 0x1EB8 591 #define RK3568_SMART1_REGION3_SCL_CTRL 0x1EC0 592 #define RK3568_SMART1_REGION3_SCL_FACTOR_YRGB 0x1EC4 593 #define RK3568_SMART1_REGION3_SCL_FACTOR_CBR 0x1EC8 594 #define RK3568_SMART1_REGION3_SCL_OFFSET 0x1ECC 595 596 #define RK3568_MAX_REG 0x1ED0 597 598 #define RK3568_GRF_VO_CON1 0x0364 599 #define GRF_BT656_CLK_INV_SHIFT 1 600 #define GRF_BT1120_CLK_INV_SHIFT 2 601 #define GRF_RGB_DCLK_INV_SHIFT 3 602 603 #define RK3588_GRF_VOP_CON2 0x0008 604 #define RK3588_GRF_EDP0_ENABLE_SHIFT 0 605 #define RK3588_GRF_HDMITX0_ENABLE_SHIFT 1 606 #define RK3588_GRF_EDP1_ENABLE_SHIFT 3 607 #define RK3588_GRF_HDMITX1_ENABLE_SHIFT 4 608 609 #define RK3588_PMU_BISR_CON3 0x20C 610 #define RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT 9 611 #define RK3588_PD_CLUSTER1_REPAIR_EN_SHIFT 10 612 #define RK3588_PD_CLUSTER2_REPAIR_EN_SHIFT 11 613 #define RK3588_PD_CLUSTER3_REPAIR_EN_SHIFT 12 614 #define RK3588_PD_ESMART_REPAIR_EN_SHIFT 15 615 616 #define RK3588_PMU_BISR_STATUS5 0x294 617 #define RK3588_PD_CLUSTER0_PWR_STAT_SHIFI 9 618 #define RK3588_PD_CLUSTER1_PWR_STAT_SHIFI 10 619 #define RK3588_PD_CLUSTER2_PWR_STAT_SHIFI 11 620 #define RK3588_PD_CLUSTER3_PWR_STAT_SHIFI 12 621 #define RK3588_PD_ESMART_PWR_STAT_SHIFI 15 622 623 #define VOP2_LAYER_MAX 8 624 625 #define VOP_FEATURE_OUTPUT_10BIT BIT(0) 626 627 enum vop2_csc_format { 628 CSC_BT601L, 629 CSC_BT709L, 630 CSC_BT601F, 631 CSC_BT2020, 632 }; 633 634 enum vop2_pol { 635 HSYNC_POSITIVE = 0, 636 VSYNC_POSITIVE = 1, 637 DEN_NEGATIVE = 2, 638 DCLK_INVERT = 3 639 }; 640 641 enum vop2_bcsh_out_mode { 642 BCSH_OUT_MODE_BLACK, 643 BCSH_OUT_MODE_BLUE, 644 BCSH_OUT_MODE_COLOR_BAR, 645 BCSH_OUT_MODE_NORMAL_VIDEO, 646 }; 647 648 #define _VOP_REG(off, _mask, _shift, _write_mask) \ 649 { \ 650 .offset = off, \ 651 .mask = _mask, \ 652 .shift = _shift, \ 653 .write_mask = _write_mask, \ 654 } 655 656 #define VOP_REG(off, _mask, _shift) \ 657 _VOP_REG(off, _mask, _shift, false) 658 enum dither_down_mode { 659 RGB888_TO_RGB565 = 0x0, 660 RGB888_TO_RGB666 = 0x1 661 }; 662 663 enum vop2_video_ports_id { 664 VOP2_VP0, 665 VOP2_VP1, 666 VOP2_VP2, 667 VOP2_VP3, 668 VOP2_VP_MAX, 669 }; 670 671 enum vop2_layer_type { 672 CLUSTER_LAYER = 0, 673 ESMART_LAYER = 1, 674 SMART_LAYER = 2, 675 }; 676 677 /* This define must same with kernel win phy id */ 678 enum vop2_layer_phy_id { 679 ROCKCHIP_VOP2_CLUSTER0 = 0, 680 ROCKCHIP_VOP2_CLUSTER1, 681 ROCKCHIP_VOP2_ESMART0, 682 ROCKCHIP_VOP2_ESMART1, 683 ROCKCHIP_VOP2_SMART0, 684 ROCKCHIP_VOP2_SMART1, 685 ROCKCHIP_VOP2_CLUSTER2, 686 ROCKCHIP_VOP2_CLUSTER3, 687 ROCKCHIP_VOP2_ESMART2, 688 ROCKCHIP_VOP2_ESMART3, 689 ROCKCHIP_VOP2_LAYER_MAX, 690 }; 691 692 enum vop2_scale_up_mode { 693 VOP2_SCALE_UP_NRST_NBOR, 694 VOP2_SCALE_UP_BIL, 695 VOP2_SCALE_UP_BIC, 696 }; 697 698 enum vop2_scale_down_mode { 699 VOP2_SCALE_DOWN_NRST_NBOR, 700 VOP2_SCALE_DOWN_BIL, 701 VOP2_SCALE_DOWN_AVG, 702 }; 703 704 enum scale_mode { 705 SCALE_NONE = 0x0, 706 SCALE_UP = 0x1, 707 SCALE_DOWN = 0x2 708 }; 709 710 struct vop2_layer { 711 u8 id; 712 /** 713 * @win_phys_id: window id of the layer selected. 714 * Every layer must make sure to select different 715 * windows of others. 716 */ 717 u8 win_phys_id; 718 }; 719 720 struct vop2_power_domain_data { 721 bool is_parent_needed; 722 u8 pd_en_shift; 723 u8 pd_status_shift; 724 u8 pmu_status_shift; 725 u8 bisr_en_status_shift; 726 u8 parent_phy_id; 727 }; 728 729 struct vop2_win_data { 730 char *name; 731 u8 phys_id; 732 enum vop2_layer_type type; 733 u8 win_sel_port_offset; 734 u8 layer_sel_win_id; 735 u32 reg_offset; 736 struct vop2_power_domain_data *pd_data; 737 }; 738 739 struct vop2_vp_data { 740 u32 feature; 741 u8 pre_scan_max_dly; 742 struct vop_rect max_output; 743 u32 max_dclk; 744 }; 745 746 struct vop2_plane_table { 747 enum vop2_layer_phy_id plane_id; 748 enum vop2_layer_type plane_type; 749 }; 750 751 struct vop2_vp_plane_mask { 752 u8 primary_plane_id; /* use this win to show logo */ 753 u8 attached_layers_nr; /* number layers attach to this vp */ 754 u8 attached_layers[VOP2_LAYER_MAX]; /* the layers attached to this vp */ 755 u32 plane_mask; 756 int cursor_plane_id; 757 }; 758 759 struct vop2_data { 760 u32 version; 761 struct vop2_vp_data *vp_data; 762 struct vop2_win_data *win_data; 763 struct vop2_vp_plane_mask *plane_mask; 764 struct vop2_plane_table *plane_table; 765 u8 nr_vps; 766 u8 nr_layers; 767 u8 nr_mixers; 768 u8 nr_gammas; 769 u8 nr_dscs; 770 u32 reg_len; 771 }; 772 773 struct vop2 { 774 u32 *regsbak; 775 void *regs; 776 void *grf; 777 void *vop_grf; 778 void *vo1_grf; 779 void *sys_pmu; 780 u32 reg_len; 781 u32 version; 782 bool global_init; 783 const struct vop2_data *data; 784 struct vop2_vp_plane_mask vp_plane_mask[VOP2_VP_MAX]; 785 }; 786 787 static struct vop2 *rockchip_vop2; 788 /* 789 * bli_sd_factor = (src - 1) / (dst - 1) << 12; 790 * avg_sd_factor: 791 * bli_su_factor: 792 * bic_su_factor: 793 * = (src - 1) / (dst - 1) << 16; 794 * 795 * gt2 enable: dst get one line from two line of the src 796 * gt4 enable: dst get one line from four line of the src. 797 * 798 */ 799 #define VOP2_BILI_SCL_DN(src, dst) (((src - 1) << 12) / (dst - 1)) 800 #define VOP2_COMMON_SCL(src, dst) (((src - 1) << 16) / (dst - 1)) 801 802 #define VOP2_BILI_SCL_FAC_CHECK(src, dst, fac) \ 803 (fac * (dst - 1) >> 12 < (src - 1)) 804 #define VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac) \ 805 (fac * (dst - 1) >> 16 < (src - 1)) 806 807 static uint16_t vop2_scale_factor(enum scale_mode mode, 808 int32_t filter_mode, 809 uint32_t src, uint32_t dst) 810 { 811 uint32_t fac = 0; 812 int i = 0; 813 814 if (mode == SCALE_NONE) 815 return 0; 816 817 /* 818 * A workaround to avoid zero div. 819 */ 820 if ((dst == 1) || (src == 1)) { 821 dst = dst + 1; 822 src = src + 1; 823 } 824 825 if ((mode == SCALE_DOWN) && (filter_mode == VOP2_SCALE_DOWN_BIL)) { 826 fac = VOP2_BILI_SCL_DN(src, dst); 827 for (i = 0; i < 100; i++) { 828 if (VOP2_BILI_SCL_FAC_CHECK(src, dst, fac)) 829 break; 830 fac -= 1; 831 printf("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 832 } 833 } else { 834 fac = VOP2_COMMON_SCL(src, dst); 835 for (i = 0; i < 100; i++) { 836 if (VOP2_COMMON_SCL_FAC_CHECK(src, dst, fac)) 837 break; 838 fac -= 1; 839 printf("up fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac); 840 } 841 } 842 843 return fac; 844 } 845 846 static inline enum scale_mode scl_get_scl_mode(int src, int dst) 847 { 848 if (src < dst) 849 return SCALE_UP; 850 else if (src > dst) 851 return SCALE_DOWN; 852 853 return SCALE_NONE; 854 } 855 856 static u8 rk3588_vop2_vp_primary_plane_order[VOP2_VP_MAX] = { 857 ROCKCHIP_VOP2_ESMART0, 858 ROCKCHIP_VOP2_ESMART1, 859 ROCKCHIP_VOP2_ESMART2, 860 ROCKCHIP_VOP2_ESMART3, 861 }; 862 863 static u8 rk3568_vop2_vp_primary_plane_order[VOP2_VP_MAX] = { 864 ROCKCHIP_VOP2_SMART0, 865 ROCKCHIP_VOP2_SMART1, 866 ROCKCHIP_VOP2_ESMART1, 867 }; 868 869 static inline int interpolate(int x1, int y1, int x2, int y2, int x) 870 { 871 return y1 + (y2 - y1) * (x - x1) / (x2 - x1); 872 } 873 874 static int vop2_get_primary_plane(struct vop2 *vop2, u32 plane_mask) 875 { 876 int i = 0; 877 u8 *vop2_vp_primary_plane_order; 878 u8 default_primary_plane; 879 880 if (vop2->version == VOP_VERSION_RK3588) { 881 vop2_vp_primary_plane_order = rk3588_vop2_vp_primary_plane_order; 882 default_primary_plane = ROCKCHIP_VOP2_ESMART0; 883 } else { 884 vop2_vp_primary_plane_order = rk3568_vop2_vp_primary_plane_order; 885 default_primary_plane = ROCKCHIP_VOP2_SMART0; 886 } 887 888 for (i = 0; i < vop2->data->nr_vps; i++) { 889 if (plane_mask & BIT(vop2_vp_primary_plane_order[i])) 890 return vop2_vp_primary_plane_order[i]; 891 } 892 893 return default_primary_plane; 894 } 895 896 static inline u16 scl_cal_scale(int src, int dst, int shift) 897 { 898 return ((src * 2 - 3) << (shift - 1)) / (dst - 1); 899 } 900 901 static inline u16 scl_cal_scale2(int src, int dst) 902 { 903 return ((src - 1) << 12) / (dst - 1); 904 } 905 906 static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v) 907 { 908 writel(v, vop2->regs + offset); 909 vop2->regsbak[offset >> 2] = v; 910 } 911 912 static inline u32 vop2_readl(struct vop2 *vop2, u32 offset) 913 { 914 return readl(vop2->regs + offset); 915 } 916 917 static inline void vop2_mask_write(struct vop2 *vop2, u32 offset, 918 u32 mask, u32 shift, u32 v, 919 bool write_mask) 920 { 921 if (!mask) 922 return; 923 924 if (write_mask) { 925 v = ((v & mask) << shift) | (mask << (shift + 16)); 926 } else { 927 u32 cached_val = vop2->regsbak[offset >> 2]; 928 929 v = (cached_val & ~(mask << shift)) | ((v & mask) << shift); 930 vop2->regsbak[offset >> 2] = v; 931 } 932 933 writel(v, vop2->regs + offset); 934 } 935 936 static inline void vop2_grf_writel(struct vop2 *vop, void *grf_base, u32 offset, 937 u32 mask, u32 shift, u32 v) 938 { 939 u32 val = 0; 940 941 val = (v << shift) | (mask << (shift + 16)); 942 writel(val, grf_base + offset); 943 } 944 945 static inline u32 vop2_grf_readl(struct vop2 *vop, void *grf_base, u32 offset, 946 u32 mask, u32 shift) 947 { 948 return (readl(grf_base + offset) >> shift) & mask; 949 } 950 951 static inline int us_to_vertical_line(struct drm_display_mode *mode, int us) 952 { 953 return us * mode->clock / mode->htotal / 1000; 954 } 955 956 static char* get_output_if_name(u32 output_if, char *name) 957 { 958 if (output_if & VOP_OUTPUT_IF_RGB) 959 strcat(name, " RGB"); 960 if (output_if & VOP_OUTPUT_IF_BT1120) 961 strcat(name, " BT1120"); 962 if (output_if & VOP_OUTPUT_IF_BT656) 963 strcat(name, " BT656"); 964 if (output_if & VOP_OUTPUT_IF_LVDS0) 965 strcat(name, " LVDS0"); 966 if (output_if & VOP_OUTPUT_IF_LVDS1) 967 strcat(name, " LVDS1"); 968 if (output_if & VOP_OUTPUT_IF_MIPI0) 969 strcat(name, " MIPI0"); 970 if (output_if & VOP_OUTPUT_IF_MIPI1) 971 strcat(name, " MIPI1"); 972 if (output_if & VOP_OUTPUT_IF_eDP0) 973 strcat(name, " eDP0"); 974 if (output_if & VOP_OUTPUT_IF_eDP1) 975 strcat(name, " eDP1"); 976 if (output_if & VOP_OUTPUT_IF_DP0) 977 strcat(name, " DP0"); 978 if (output_if & VOP_OUTPUT_IF_DP1) 979 strcat(name, " DP1"); 980 if (output_if & VOP_OUTPUT_IF_HDMI0) 981 strcat(name, " HDMI0"); 982 if (output_if & VOP_OUTPUT_IF_HDMI1) 983 strcat(name, " HDMI1"); 984 985 return name; 986 } 987 988 static char *get_plane_name(int plane_id, char *name) 989 { 990 switch (plane_id) { 991 case ROCKCHIP_VOP2_CLUSTER0: 992 strcat(name, "Cluster0"); 993 break; 994 case ROCKCHIP_VOP2_CLUSTER1: 995 strcat(name, "Cluster1"); 996 break; 997 case ROCKCHIP_VOP2_ESMART0: 998 strcat(name, "Esmart0"); 999 break; 1000 case ROCKCHIP_VOP2_ESMART1: 1001 strcat(name, "Esmart1"); 1002 break; 1003 case ROCKCHIP_VOP2_SMART0: 1004 strcat(name, "Smart0"); 1005 break; 1006 case ROCKCHIP_VOP2_SMART1: 1007 strcat(name, "Smart1"); 1008 break; 1009 case ROCKCHIP_VOP2_CLUSTER2: 1010 strcat(name, "Cluster2"); 1011 break; 1012 case ROCKCHIP_VOP2_CLUSTER3: 1013 strcat(name, "Cluster3"); 1014 break; 1015 case ROCKCHIP_VOP2_ESMART2: 1016 strcat(name, "Esmart2"); 1017 break; 1018 case ROCKCHIP_VOP2_ESMART3: 1019 strcat(name, "Esmart3"); 1020 break; 1021 } 1022 1023 return name; 1024 } 1025 1026 static bool is_yuv_output(u32 bus_format) 1027 { 1028 switch (bus_format) { 1029 case MEDIA_BUS_FMT_YUV8_1X24: 1030 case MEDIA_BUS_FMT_YUV10_1X30: 1031 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 1032 case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 1033 case MEDIA_BUS_FMT_YUYV8_2X8: 1034 case MEDIA_BUS_FMT_YVYU8_2X8: 1035 case MEDIA_BUS_FMT_UYVY8_2X8: 1036 case MEDIA_BUS_FMT_VYUY8_2X8: 1037 case MEDIA_BUS_FMT_YUYV8_1X16: 1038 case MEDIA_BUS_FMT_YVYU8_1X16: 1039 case MEDIA_BUS_FMT_UYVY8_1X16: 1040 case MEDIA_BUS_FMT_VYUY8_1X16: 1041 return true; 1042 default: 1043 return false; 1044 } 1045 } 1046 1047 static int vop2_convert_csc_mode(int csc_mode) 1048 { 1049 switch (csc_mode) { 1050 case V4L2_COLORSPACE_SMPTE170M: 1051 case V4L2_COLORSPACE_470_SYSTEM_M: 1052 case V4L2_COLORSPACE_470_SYSTEM_BG: 1053 return CSC_BT601L; 1054 case V4L2_COLORSPACE_REC709: 1055 case V4L2_COLORSPACE_SMPTE240M: 1056 case V4L2_COLORSPACE_DEFAULT: 1057 return CSC_BT709L; 1058 case V4L2_COLORSPACE_JPEG: 1059 return CSC_BT601F; 1060 case V4L2_COLORSPACE_BT2020: 1061 return CSC_BT2020; 1062 default: 1063 return CSC_BT709L; 1064 } 1065 } 1066 1067 static bool is_uv_swap(u32 bus_format, u32 output_mode) 1068 { 1069 /* 1070 * FIXME: 1071 * 1072 * There is no media type for YUV444 output, 1073 * so when out_mode is AAAA or P888, assume output is YUV444 on 1074 * yuv format. 1075 * 1076 * From H/W testing, YUV444 mode need a rb swap. 1077 */ 1078 if ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 || 1079 bus_format == MEDIA_BUS_FMT_YUV10_1X30) && 1080 (output_mode == ROCKCHIP_OUT_MODE_AAAA || 1081 output_mode == ROCKCHIP_OUT_MODE_P888)) 1082 return true; 1083 else 1084 return false; 1085 } 1086 1087 static inline bool is_hot_plug_devices(int output_type) 1088 { 1089 switch (output_type) { 1090 case DRM_MODE_CONNECTOR_HDMIA: 1091 case DRM_MODE_CONNECTOR_HDMIB: 1092 case DRM_MODE_CONNECTOR_TV: 1093 case DRM_MODE_CONNECTOR_DisplayPort: 1094 case DRM_MODE_CONNECTOR_VGA: 1095 case DRM_MODE_CONNECTOR_Unknown: 1096 return true; 1097 default: 1098 return false; 1099 } 1100 } 1101 1102 static struct vop2_win_data *vop2_find_win_by_phys_id(struct vop2 *vop2, int phys_id) 1103 { 1104 int i = 0; 1105 1106 for (i = 0; i < vop2->data->nr_layers; i++) { 1107 if (vop2->data->win_data[i].phys_id == phys_id) 1108 return &vop2->data->win_data[i]; 1109 } 1110 1111 return NULL; 1112 } 1113 1114 static int rockchip_vop2_gamma_lut_init(struct vop2 *vop2, 1115 struct display_state *state) 1116 { 1117 struct connector_state *conn_state = &state->conn_state; 1118 struct crtc_state *cstate = &state->crtc_state; 1119 struct resource gamma_res; 1120 fdt_size_t lut_size; 1121 int i, lut_len, ret = 0; 1122 u32 *lut_regs; 1123 u32 *lut_val; 1124 u32 r, g, b; 1125 u32 vp_offset = cstate->crtc_id * 0x100; 1126 struct base2_disp_info *disp_info = conn_state->disp_info; 1127 static int gamma_lut_en_num = 1; 1128 1129 if (gamma_lut_en_num > vop2->data->nr_gammas) { 1130 printf("warn: only %d vp support gamma\n", vop2->data->nr_gammas); 1131 return 0; 1132 } 1133 1134 if (!disp_info) 1135 return 0; 1136 1137 if (!disp_info->gamma_lut_data.size) 1138 return 0; 1139 1140 ret = ofnode_read_resource_byname(cstate->node, "gamma_lut", &gamma_res); 1141 if (ret) 1142 printf("failed to get gamma lut res\n"); 1143 lut_regs = (u32 *)gamma_res.start; 1144 lut_size = gamma_res.end - gamma_res.start + 1; 1145 if (lut_regs == (u32 *)FDT_ADDR_T_NONE) { 1146 printf("failed to get gamma lut register\n"); 1147 return 0; 1148 } 1149 lut_len = lut_size / 4; 1150 if (lut_len != 256 && lut_len != 1024) { 1151 printf("Warning: unsupport gamma lut table[%d]\n", lut_len); 1152 return 0; 1153 } 1154 lut_val = (u32 *)calloc(1, lut_size); 1155 for (i = 0; i < lut_len; i++) { 1156 r = disp_info->gamma_lut_data.lred[i] * (lut_len - 1) / 0xffff; 1157 g = disp_info->gamma_lut_data.lgreen[i] * (lut_len - 1) / 0xffff; 1158 b = disp_info->gamma_lut_data.lblue[i] * (lut_len - 1) / 0xffff; 1159 1160 lut_val[i] = b * lut_len * lut_len + g * lut_len + r; 1161 } 1162 1163 for (i = 0; i < lut_len; i++) 1164 writel(lut_val[i], lut_regs + i); 1165 1166 vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, 1167 GAMMA_PORT_SEL_MASK, GAMMA_PORT_SEL_SHIFT, 1168 cstate->crtc_id , false); 1169 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 1170 EN_MASK, DSP_LUT_EN_SHIFT, 1, false); 1171 gamma_lut_en_num++; 1172 1173 return 0; 1174 } 1175 1176 static int rockchip_vop2_cubic_lut_init(struct vop2 *vop2, 1177 struct display_state *state) 1178 { 1179 struct connector_state *conn_state = &state->conn_state; 1180 struct crtc_state *cstate = &state->crtc_state; 1181 int i, cubic_lut_len; 1182 u32 vp_offset = cstate->crtc_id * 0x100; 1183 struct base2_disp_info *disp_info = conn_state->disp_info; 1184 struct base2_cubic_lut_data *lut = &conn_state->disp_info->cubic_lut_data; 1185 u32 *cubic_lut_addr; 1186 1187 if (!disp_info || CONFIG_ROCKCHIP_CUBIC_LUT_SIZE == 0) 1188 return 0; 1189 1190 if (!disp_info->cubic_lut_data.size) 1191 return 0; 1192 1193 cubic_lut_addr = (u32 *)get_cubic_lut_buffer(cstate->crtc_id); 1194 cubic_lut_len = disp_info->cubic_lut_data.size; 1195 1196 for (i = 0; i < cubic_lut_len / 2; i++) { 1197 *cubic_lut_addr++ = ((lut->lred[2 * i]) & 0xfff) + 1198 ((lut->lgreen[2 * i] & 0xfff) << 12) + 1199 ((lut->lblue[2 * i] & 0xff) << 24); 1200 *cubic_lut_addr++ = ((lut->lblue[2 * i] & 0xf00) >> 8) + 1201 ((lut->lred[2 * i + 1] & 0xfff) << 4) + 1202 ((lut->lgreen[2 * i + 1] & 0xfff) << 16) + 1203 ((lut->lblue[2 * i + 1] & 0xf) << 28); 1204 *cubic_lut_addr++ = (lut->lblue[2 * i + 1] & 0xff0) >> 4; 1205 *cubic_lut_addr++ = 0; 1206 } 1207 1208 if (cubic_lut_len % 2) { 1209 *cubic_lut_addr++ = (lut->lred[2 * i] & 0xfff) + 1210 ((lut->lgreen[2 * i] & 0xfff) << 12) + 1211 ((lut->lblue[2 * i] & 0xff) << 24); 1212 *cubic_lut_addr++ = (lut->lblue[2 * i] & 0xf00) >> 8; 1213 *cubic_lut_addr++ = 0; 1214 *cubic_lut_addr = 0; 1215 } 1216 1217 vop2_writel(vop2, RK3568_VP0_3D_LUT_MST + vp_offset, 1218 get_cubic_lut_buffer(cstate->crtc_id)); 1219 vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL, 1220 EN_MASK, LUT_DMA_EN_SHIFT, 1, false); 1221 vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset, 1222 EN_MASK, VP0_3D_LUT_EN_SHIFT, 1, false); 1223 vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset, 1224 EN_MASK, VP0_3D_LUT_UPDATE_SHIFT, 1, false); 1225 1226 return 0; 1227 } 1228 1229 static void vop2_tv_config_update(struct display_state *state, struct vop2 *vop2) 1230 { 1231 struct connector_state *conn_state = &state->conn_state; 1232 struct base_bcsh_info *bcsh_info; 1233 struct crtc_state *cstate = &state->crtc_state; 1234 int brightness, contrast, saturation, hue, sin_hue, cos_hue; 1235 bool bcsh_en = false, post_r2y_en = false, post_y2r_en = false; 1236 u32 vp_offset = (cstate->crtc_id * 0x100); 1237 int post_csc_mode; 1238 1239 if (!conn_state->disp_info) 1240 return; 1241 bcsh_info = &conn_state->disp_info->bcsh_info; 1242 if (!bcsh_info) 1243 return; 1244 1245 if (bcsh_info->brightness != 50 || 1246 bcsh_info->contrast != 50 || 1247 bcsh_info->saturation != 50 || bcsh_info->hue != 50) 1248 bcsh_en = true; 1249 1250 if (bcsh_en) { 1251 if (!cstate->yuv_overlay) 1252 post_r2y_en = 1; 1253 if (!is_yuv_output(conn_state->bus_format)) 1254 post_y2r_en = 1; 1255 } else { 1256 if (!cstate->yuv_overlay && is_yuv_output(conn_state->bus_format)) 1257 post_r2y_en = 1; 1258 if (cstate->yuv_overlay && !is_yuv_output(conn_state->bus_format)) 1259 post_y2r_en = 1; 1260 } 1261 1262 post_csc_mode = vop2_convert_csc_mode(conn_state->color_space); 1263 1264 1265 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_MASK, 1266 BCSH_CTRL_R2Y_SHIFT, post_r2y_en, false); 1267 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_MASK, 1268 BCSH_CTRL_Y2R_SHIFT, post_y2r_en, false); 1269 1270 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_R2Y_CSC_MODE_MASK, 1271 BCSH_CTRL_R2Y_CSC_MODE_SHIFT, post_csc_mode, false); 1272 vop2_mask_write(vop2, RK3568_VP0_BCSH_CTRL + vp_offset, BCSH_CTRL_Y2R_CSC_MODE_MASK, 1273 BCSH_CTRL_Y2R_CSC_MODE_SHIFT, post_csc_mode, false); 1274 if (!bcsh_en) { 1275 vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset, 1276 BCSH_EN_MASK, BCSH_EN_SHIFT, 0, false); 1277 return; 1278 } 1279 1280 if (cstate->feature & VOP_FEATURE_OUTPUT_10BIT) 1281 brightness = interpolate(0, -128, 100, 127, 1282 bcsh_info->brightness); 1283 else 1284 brightness = interpolate(0, -32, 100, 31, 1285 bcsh_info->brightness); 1286 contrast = interpolate(0, 0, 100, 511, bcsh_info->contrast); 1287 saturation = interpolate(0, 0, 100, 511, bcsh_info->saturation); 1288 hue = interpolate(0, -30, 100, 30, bcsh_info->hue); 1289 1290 1291 /* 1292 * a:[-30~0): 1293 * sin_hue = 0x100 - sin(a)*256; 1294 * cos_hue = cos(a)*256; 1295 * a:[0~30] 1296 * sin_hue = sin(a)*256; 1297 * cos_hue = cos(a)*256; 1298 */ 1299 sin_hue = fixp_sin32(hue) >> 23; 1300 cos_hue = fixp_cos32(hue) >> 23; 1301 1302 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1303 BCSH_BRIGHTNESS_MASK, BCSH_BRIGHTNESS_SHIFT, 1304 brightness, false); 1305 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1306 BCSH_CONTRAST_MASK, BCSH_CONTRAST_SHIFT, contrast, false); 1307 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1308 BCSH_SATURATION_MASK, BCSH_SATURATION_SHIFT, 1309 saturation * contrast / 0x100, false); 1310 vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset, 1311 BCSH_SIN_HUE_MASK, BCSH_SIN_HUE_SHIFT, sin_hue, false); 1312 vop2_mask_write(vop2, RK3568_VP0_BCSH_H + vp_offset, 1313 BCSH_COS_HUE_MASK, BCSH_COS_HUE_SHIFT, cos_hue, false); 1314 vop2_mask_write(vop2, RK3568_VP0_BCSH_BCS + vp_offset, 1315 BCSH_OUT_MODE_MASK, BCSH_OUT_MODE_SHIFT, 1316 BCSH_OUT_MODE_NORMAL_VIDEO, false); 1317 vop2_mask_write(vop2, RK3568_VP0_BCSH_COLOR + vp_offset, 1318 BCSH_EN_MASK, BCSH_EN_SHIFT, 1, false); 1319 } 1320 1321 static void vop2_post_config(struct display_state *state, struct vop2 *vop2) 1322 { 1323 struct connector_state *conn_state = &state->conn_state; 1324 struct drm_display_mode *mode = &conn_state->mode; 1325 struct crtc_state *cstate = &state->crtc_state; 1326 u32 vp_offset = (cstate->crtc_id * 0x100); 1327 u16 vtotal = mode->crtc_vtotal; 1328 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 1329 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 1330 u16 hdisplay = mode->crtc_hdisplay; 1331 u16 vdisplay = mode->crtc_vdisplay; 1332 u16 hsize = 1333 hdisplay * (conn_state->overscan.left_margin + 1334 conn_state->overscan.right_margin) / 200; 1335 u16 vsize = 1336 vdisplay * (conn_state->overscan.top_margin + 1337 conn_state->overscan.bottom_margin) / 200; 1338 u16 hact_end, vact_end; 1339 u32 val; 1340 u32 bg_ovl_dly, bg_dly, pre_scan_dly; 1341 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 1342 1343 hsize = round_down(hsize, 2); 1344 vsize = round_down(vsize, 2); 1345 1346 hact_st += hdisplay * (100 - conn_state->overscan.left_margin) / 200; 1347 hact_end = hact_st + hsize; 1348 val = hact_st << 16; 1349 val |= hact_end; 1350 1351 vop2_writel(vop2, RK3568_VP0_POST_DSP_HACT_INFO + vp_offset, val); 1352 vact_st += vdisplay * (100 - conn_state->overscan.top_margin) / 200; 1353 vact_end = vact_st + vsize; 1354 val = vact_st << 16; 1355 val |= vact_end; 1356 vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO + vp_offset, val); 1357 val = scl_cal_scale2(vdisplay, vsize) << 16; 1358 val |= scl_cal_scale2(hdisplay, hsize); 1359 vop2_writel(vop2, RK3568_VP0_POST_SCL_FACTOR_YRGB + vp_offset, val); 1360 #define POST_HORIZONTAL_SCALEDOWN_EN(x) ((x) << 0) 1361 #define POST_VERTICAL_SCALEDOWN_EN(x) ((x) << 1) 1362 vop2_writel(vop2, RK3568_VP0_POST_SCL_CTRL + vp_offset, 1363 POST_HORIZONTAL_SCALEDOWN_EN(hdisplay != hsize) | 1364 POST_VERTICAL_SCALEDOWN_EN(vdisplay != vsize)); 1365 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 1366 u16 vact_st_f1 = vtotal + vact_st + 1; 1367 u16 vact_end_f1 = vact_st_f1 + vsize; 1368 1369 val = vact_st_f1 << 16 | vact_end_f1; 1370 vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO_F1 + vp_offset, val); 1371 } 1372 1373 bg_ovl_dly = cstate->crtc->vps[cstate->crtc_id].bg_ovl_dly; 1374 bg_dly = vop2->data->vp_data[cstate->crtc_id].pre_scan_max_dly; 1375 bg_dly -= bg_ovl_dly; 1376 pre_scan_dly = bg_dly + (hdisplay >> 1) - 1; 1377 if (vop2->version == VOP_VERSION_RK3588 && hsync_len < 8) 1378 hsync_len = 8; 1379 pre_scan_dly = (pre_scan_dly << 16) | hsync_len; 1380 vop2_mask_write(vop2, RK3568_VP0_BG_MIX_CTRL + cstate->crtc_id * 4, 1381 BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false); 1382 vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + vp_offset, pre_scan_dly); 1383 } 1384 1385 static int vop2_wait_power_domain_on(struct vop2 *vop2, struct vop2_power_domain_data *pd_data) 1386 { 1387 int val = 0; 1388 int shift = 0; 1389 bool is_bisr_en = false; 1390 1391 is_bisr_en = vop2_grf_readl(vop2, vop2->sys_pmu, RK3588_PMU_BISR_CON3, EN_MASK, 1392 pd_data->bisr_en_status_shift); 1393 if (is_bisr_en) { 1394 shift = pd_data->pmu_status_shift; 1395 return readl_poll_timeout(vop2->sys_pmu + RK3588_PMU_BISR_STATUS5, val, 1396 !((val >> shift) & 0x1), 50 * 1000); 1397 } else { 1398 shift = pd_data->pd_status_shift; 1399 return readl_poll_timeout(vop2->regs + RK3568_SYS_STATUS0, val, 1400 !((val >> shift) & 0x1), 50 * 1000); 1401 } 1402 } 1403 1404 static int vop2_power_domain_on(struct vop2 *vop2, int plane_id) 1405 { 1406 struct vop2_win_data *win_data; 1407 struct vop2_power_domain_data *pd_data; 1408 int ret = 0; 1409 1410 win_data = vop2_find_win_by_phys_id(vop2, plane_id); 1411 if (!win_data) { 1412 printf("can't find win_data by phys_id\n"); 1413 return -EINVAL; 1414 } 1415 pd_data = win_data->pd_data; 1416 if (pd_data->is_parent_needed) { 1417 ret = vop2_power_domain_on(vop2, pd_data->parent_phy_id); 1418 if (ret) { 1419 printf("can't open parent power domain\n"); 1420 return -EINVAL; 1421 } 1422 } 1423 1424 vop2_mask_write(vop2, RK3568_SYS_PD_CTRL, EN_MASK, pd_data->pd_en_shift, 0, false); 1425 ret = vop2_wait_power_domain_on(vop2, pd_data); 1426 if (ret) { 1427 printf("wait vop2 power domain timeout\n"); 1428 return ret; 1429 } 1430 1431 return 0; 1432 } 1433 1434 static void rk3588_vop2_regsbak(struct vop2 *vop2) 1435 { 1436 u32 *base = vop2->regs; 1437 int i = 0; 1438 1439 /* 1440 * No need to backup HDR/DSC/GAMMA_LUT/BPP_LUT/MMU 1441 */ 1442 for (i = 0; i < (vop2->reg_len >> 2); i++) 1443 vop2->regsbak[i] = base[i]; 1444 } 1445 1446 static void vop2_global_initial(struct vop2 *vop2, struct display_state *state) 1447 { 1448 struct crtc_state *cstate = &state->crtc_state; 1449 int i, j, port_mux = 0, total_used_layer = 0; 1450 u8 shift = 0; 1451 int layer_phy_id = 0; 1452 u32 layer_nr = 0; 1453 struct vop2_win_data *win_data; 1454 struct vop2_vp_plane_mask *plane_mask; 1455 1456 if (vop2->global_init) 1457 return; 1458 1459 /* OTP must enable at the first time, otherwise mirror layer register is error */ 1460 if (soc_is_rk3566()) 1461 vop2_mask_write(vop2, RK3568_SYS_OTP_WIN_EN, EN_MASK, 1462 OTP_WIN_EN_SHIFT, 1, false); 1463 1464 if (cstate->crtc->assign_plane) {/* dts assign plane */ 1465 u32 plane_mask; 1466 int primary_plane_id; 1467 1468 for (i = 0; i < vop2->data->nr_vps; i++) { 1469 plane_mask = cstate->crtc->vps[i].plane_mask; 1470 vop2->vp_plane_mask[i].plane_mask = plane_mask; 1471 layer_nr = hweight32(plane_mask); /* use bitmap to store plane mask */ 1472 vop2->vp_plane_mask[i].attached_layers_nr = layer_nr; 1473 primary_plane_id = vop2_get_primary_plane(vop2, plane_mask); 1474 vop2->vp_plane_mask[i].primary_plane_id = primary_plane_id; 1475 vop2->vp_plane_mask[i].plane_mask = plane_mask; 1476 1477 /* plane mask[bitmap] convert into layer phy id[enum vop2_layer_phy_id]*/ 1478 for (j = 0; j < layer_nr; j++) { 1479 vop2->vp_plane_mask[i].attached_layers[j] = ffs(plane_mask) - 1; 1480 plane_mask &= ~BIT(vop2->vp_plane_mask[i].attached_layers[j]); 1481 } 1482 } 1483 } else {/* need soft assign plane mask */ 1484 /* find the first unplug devices and set it as main display */ 1485 int main_vp_index = -1; 1486 int active_vp_num = 0; 1487 1488 for (i = 0; i < vop2->data->nr_vps; i++) { 1489 if (cstate->crtc->vps[i].enable) 1490 active_vp_num++; 1491 } 1492 printf("VOP have %d active VP\n", active_vp_num); 1493 1494 if (soc_is_rk3566() && active_vp_num > 2) 1495 printf("ERROR: rk3566 only support 2 display output!!\n"); 1496 plane_mask = vop2->data->plane_mask; 1497 plane_mask += (active_vp_num - 1) * VOP2_VP_MAX; 1498 1499 for (i = 0; i < vop2->data->nr_vps; i++) { 1500 if (!is_hot_plug_devices(cstate->crtc->vps[i].output_type)) { 1501 vop2->vp_plane_mask[i] = plane_mask[0]; /* the first store main display plane mask*/ 1502 main_vp_index = i; 1503 break; 1504 } 1505 } 1506 1507 /* if no find unplug devices, use vp0 as main display */ 1508 if (main_vp_index < 0) { 1509 main_vp_index = 0; 1510 vop2->vp_plane_mask[0] = plane_mask[0]; 1511 } 1512 1513 j = 1; /* plane_mask[0] store main display, so we from plane_mask[1] */ 1514 1515 /* init other display except main display */ 1516 for (i = 0; i < vop2->data->nr_vps; i++) { 1517 if (i == main_vp_index || !cstate->crtc->vps[i].enable) /* main display or no connect devices */ 1518 continue; 1519 vop2->vp_plane_mask[i] = plane_mask[j++]; 1520 } 1521 1522 /* store plane mask for vop2_fixup_dts */ 1523 for (i = 0; i < vop2->data->nr_vps; i++) { 1524 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 1525 /* rk3566 only support 3+3 policy */ 1526 if (soc_is_rk3566() && active_vp_num == 1) { 1527 if (cstate->crtc->vps[i].enable) { 1528 for (j = 0; j < 3; j++) { 1529 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 1530 vop2->vp_plane_mask[i].plane_mask |= BIT(layer_phy_id); 1531 } 1532 } 1533 } else { 1534 for (j = 0; j < layer_nr; j++) { 1535 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 1536 vop2->vp_plane_mask[i].plane_mask |= BIT(layer_phy_id); 1537 } 1538 } 1539 } 1540 } 1541 1542 if (vop2->version == VOP_VERSION_RK3588) { 1543 for (i = 0; i < vop2->data->nr_vps; i++) { 1544 if (cstate->crtc->vps[i].enable) { 1545 if (vop2_power_domain_on(vop2, vop2->vp_plane_mask[i].primary_plane_id)) 1546 printf("open vp[%d] plane pd fail\n", i); 1547 } 1548 } 1549 } 1550 1551 if (vop2->version == VOP_VERSION_RK3588) 1552 rk3588_vop2_regsbak(vop2); 1553 else 1554 memcpy(vop2->regsbak, vop2->regs, vop2->reg_len); 1555 1556 vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, 1557 OVL_PORT_MUX_REG_DONE_IMD_SHIFT, 1, false); 1558 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 1559 IF_CTRL_REG_DONE_IMD_SHIFT, 1, false); 1560 1561 for (i = 0; i < vop2->data->nr_vps; i++) { 1562 printf("vp%d have layer nr:%d[", i, vop2->vp_plane_mask[i].attached_layers_nr); 1563 for (j = 0; j < vop2->vp_plane_mask[i].attached_layers_nr; j++) 1564 printf("%d ", vop2->vp_plane_mask[i].attached_layers[j]); 1565 printf("], primary plane: %d\n", vop2->vp_plane_mask[i].primary_plane_id); 1566 } 1567 1568 shift = 0; 1569 /* layer sel win id */ 1570 for (i = 0; i < vop2->data->nr_vps; i++) { 1571 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 1572 for (j = 0; j < layer_nr; j++) { 1573 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 1574 win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 1575 vop2_mask_write(vop2, RK3568_OVL_LAYER_SEL, LAYER_SEL_MASK, 1576 shift, win_data->layer_sel_win_id, false); 1577 shift += 4; 1578 } 1579 } 1580 1581 /* win sel port */ 1582 for (i = 0; i < vop2->data->nr_vps; i++) { 1583 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 1584 for (j = 0; j < layer_nr; j++) { 1585 if (!vop2->vp_plane_mask[i].attached_layers[j]) 1586 continue; 1587 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 1588 win_data = vop2_find_win_by_phys_id(vop2, layer_phy_id); 1589 shift = win_data->win_sel_port_offset * 2; 1590 vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, LAYER_SEL_PORT_MASK, 1591 LAYER_SEL_PORT_SHIFT + shift, i, false); 1592 } 1593 } 1594 1595 /** 1596 * port mux config 1597 */ 1598 for (i = 0; i < vop2->data->nr_vps; i++) { 1599 shift = i * 4; 1600 if (vop2->vp_plane_mask[i].attached_layers_nr) { 1601 total_used_layer += vop2->vp_plane_mask[i].attached_layers_nr; 1602 port_mux = total_used_layer - 1; 1603 } else { 1604 port_mux = 8; 1605 } 1606 1607 if (i == vop2->data->nr_vps - 1) 1608 port_mux = vop2->data->nr_mixers; 1609 1610 cstate->crtc->vps[i].bg_ovl_dly = (vop2->data->nr_mixers - port_mux) << 1; 1611 vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, PORT_MUX_MASK, 1612 PORT_MUX_SHIFT + shift, port_mux, false); 1613 } 1614 1615 if (vop2->version == VOP_VERSION_RK3568) 1616 vop2_writel(vop2, RK3568_AUTO_GATING_CTRL, 0); 1617 1618 vop2->global_init = true; 1619 } 1620 1621 static int vop2_initial(struct vop2 *vop2, struct display_state *state) 1622 { 1623 struct crtc_state *cstate = &state->crtc_state; 1624 int ret; 1625 1626 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 1627 ret = clk_set_defaults(cstate->dev); 1628 if (ret) 1629 debug("%s clk_set_defaults failed %d\n", __func__, ret); 1630 1631 rockchip_vop2_gamma_lut_init(vop2, state); 1632 rockchip_vop2_cubic_lut_init(vop2, state); 1633 1634 return 0; 1635 } 1636 1637 /* 1638 * VOP2 have multi video ports. 1639 * video port ------- crtc 1640 */ 1641 static int rockchip_vop2_preinit(struct display_state *state) 1642 { 1643 struct crtc_state *cstate = &state->crtc_state; 1644 const struct vop2_data *vop2_data = cstate->crtc->data; 1645 1646 if (!rockchip_vop2) { 1647 rockchip_vop2 = calloc(1, sizeof(struct vop2)); 1648 if (!rockchip_vop2) 1649 return -ENOMEM; 1650 rockchip_vop2->regs = dev_read_addr_ptr(cstate->dev); 1651 rockchip_vop2->regsbak = malloc(RK3568_MAX_REG); 1652 rockchip_vop2->reg_len = RK3568_MAX_REG; 1653 rockchip_vop2->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 1654 if (rockchip_vop2->grf <= 0) 1655 printf("%s: Get syscon grf failed (ret=%p)\n", __func__, rockchip_vop2->grf); 1656 rockchip_vop2->version = vop2_data->version; 1657 rockchip_vop2->data = vop2_data; 1658 if (rockchip_vop2->version == VOP_VERSION_RK3588) { 1659 rockchip_vop2->vop_grf = syscon_get_first_range(ROCKCHIP_SYSCON_VOP_GRF); 1660 if (rockchip_vop2->vop_grf <= 0) 1661 printf("%s: Get syscon vop_grf failed (ret=%p)\n", __func__, rockchip_vop2->vop_grf); 1662 rockchip_vop2->vo1_grf = syscon_get_first_range(ROCKCHIP_SYSCON_VO_GRF); 1663 if (rockchip_vop2->vo1_grf <= 0) 1664 printf("%s: Get syscon vo1_grf failed (ret=%p)\n", __func__, rockchip_vop2->vo1_grf); 1665 rockchip_vop2->sys_pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU); 1666 if (rockchip_vop2->vo1_grf <= 0) 1667 printf("%s: Get syscon sys_pmu failed (ret=%p)\n", __func__, rockchip_vop2->sys_pmu); 1668 } 1669 } 1670 1671 cstate->private = rockchip_vop2; 1672 cstate->max_output = vop2_data->vp_data[cstate->crtc_id].max_output; 1673 cstate->feature = vop2_data->vp_data[cstate->crtc_id].feature; 1674 1675 vop2_global_initial(rockchip_vop2, state); 1676 1677 return 0; 1678 } 1679 1680 /* 1681 * calc the dclk on rk3588 1682 * the available div of dclk is 1, 2, 4 1683 * 1684 */ 1685 static unsigned long vop2_calc_dclk(unsigned long child_clk, unsigned long max_dclk) 1686 { 1687 if (child_clk * 4 <= max_dclk) 1688 return child_clk * 4; 1689 else if (child_clk * 2 <= max_dclk) 1690 return child_clk * 2; 1691 else if (child_clk <= max_dclk) 1692 return child_clk; 1693 else 1694 return 0; 1695 } 1696 1697 /* 1698 * 4 pixclk/cycle on rk3588 1699 * RGB/eDP/HDMI: if_pixclk >= dclk_core 1700 * DP: dp_pixclk = dclk_out <= dclk_core 1701 * DSI: mipi_pixclk <= dclk_out <= dclk_core 1702 */ 1703 static unsigned long vop2_calc_cru_cfg(struct display_state *state, 1704 int *dclk_core_div, int *dclk_out_div, 1705 int *if_pixclk_div, int *if_dclk_div) 1706 { 1707 struct crtc_state *cstate = &state->crtc_state; 1708 struct connector_state *conn_state = &state->conn_state; 1709 struct drm_display_mode *mode = &conn_state->mode; 1710 struct vop2 *vop2 = cstate->private; 1711 unsigned long v_pixclk = mode->clock; 1712 unsigned long dclk_core_rate = v_pixclk >> 2; 1713 unsigned long dclk_rate = v_pixclk; 1714 unsigned long dclk_out_rate; 1715 u64 if_dclk_rate; 1716 u64 if_pixclk_rate; 1717 int output_type = conn_state->type; 1718 int output_mode = conn_state->output_mode; 1719 int K = 1; 1720 1721 if (output_type == DRM_MODE_CONNECTOR_HDMIA) { 1722 /* 1723 * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate 1724 * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate 1725 */ 1726 if (output_mode == ROCKCHIP_OUT_MODE_YUV420) 1727 K = 2; 1728 if (conn_state->dsc_enable) { 1729 if_pixclk_rate = conn_state->dsc_cds_clk << 1; 1730 if_dclk_rate = conn_state->dsc_cds_clk; 1731 } else { 1732 if_pixclk_rate = (dclk_core_rate << 1) / K; 1733 if_dclk_rate = dclk_core_rate / K; 1734 } 1735 1736 dclk_rate = vop2_calc_dclk(if_pixclk_rate, vop2->data->vp_data->max_dclk); 1737 if (!dclk_rate) { 1738 printf("DP if_pixclk_rate out of range(max_dclk: %d KHZ, dclk_core: %lld KHZ)\n", 1739 vop2->data->vp_data->max_dclk, if_pixclk_rate); 1740 return -EINVAL; 1741 } 1742 *if_pixclk_div = dclk_rate / if_pixclk_rate; 1743 *if_dclk_div = dclk_rate / if_dclk_rate; 1744 1745 } else if (output_type == DRM_MODE_CONNECTOR_eDP) { 1746 /* edp_pixclk = edp_dclk > dclk_core */ 1747 if_pixclk_rate = v_pixclk / K; 1748 if_dclk_rate = v_pixclk / K; 1749 dclk_rate = if_pixclk_rate * K; 1750 *dclk_core_div = dclk_rate / dclk_core_rate; 1751 *if_pixclk_div = dclk_rate / if_pixclk_rate; 1752 *if_dclk_div = *if_pixclk_div; 1753 } else if (output_type == DRM_MODE_CONNECTOR_DisplayPort) { 1754 if (output_mode == ROCKCHIP_OUT_MODE_YUV420) 1755 dclk_out_rate = v_pixclk >> 3; 1756 else 1757 dclk_out_rate = v_pixclk >> 2; 1758 1759 dclk_rate = vop2_calc_dclk(dclk_core_rate, vop2->data->vp_data->max_dclk); 1760 if (!dclk_rate) { 1761 printf("DP dclk_core out of range(max_dclk: %d KHZ, dclk_core: %ld KHZ)\n", 1762 vop2->data->vp_data->max_dclk, dclk_core_rate); 1763 return -EINVAL; 1764 } 1765 *dclk_out_div = dclk_rate / dclk_out_rate; 1766 *dclk_core_div = dclk_rate / dclk_core_rate; 1767 1768 } else if (output_type == DRM_MODE_CONNECTOR_DSI) { 1769 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 1770 K = 2; 1771 if (conn_state->dsc_enable) 1772 if_pixclk_rate = conn_state->dsc_cds_clk >> 1; 1773 else 1774 if_pixclk_rate = dclk_core_rate / K; 1775 /* dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4 */ 1776 dclk_out_rate = if_pixclk_rate; 1777 /* dclk_rate = N * dclk_core_rate N = (1,2,4 ), we get a little factor here */ 1778 dclk_rate = dclk_core_rate; 1779 *dclk_out_div = dclk_rate / dclk_out_rate; 1780 *dclk_core_div = dclk_rate / dclk_core_rate; 1781 *if_pixclk_div = 1; /*mipi pixclk == dclk_out*/ 1782 1783 } else if (output_type == DRM_MODE_CONNECTOR_DPI) { 1784 dclk_rate = v_pixclk; 1785 *dclk_core_div = dclk_rate / dclk_core_rate; 1786 } 1787 1788 *if_pixclk_div = ilog2(*if_pixclk_div); 1789 *if_dclk_div = ilog2(*if_dclk_div); 1790 *dclk_core_div = ilog2(*dclk_core_div); 1791 *dclk_out_div = ilog2(*dclk_out_div); 1792 1793 return dclk_rate; 1794 } 1795 1796 static int vop2_calc_dsc_clk(struct connector_state *conn_state) 1797 { 1798 struct drm_display_mode *mode = &conn_state->mode; 1799 u64 v_pixclk = mode->clock * 1000LL; /* video timing pixclk */ 1800 u8 k = 1; 1801 1802 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 1803 k = 2; 1804 1805 conn_state->dsc_pxl_clk = v_pixclk; 1806 do_div(conn_state->dsc_pxl_clk, (conn_state->dsc_slice_num * k)); 1807 1808 conn_state->dsc_txp_clk = v_pixclk; 1809 do_div(conn_state->dsc_txp_clk, (conn_state->dsc_pixel_num * k)); 1810 1811 /* dsc_cds = crtc_clock / (cds_dat_width / bits_per_pixel) 1812 * cds_dat_width = 96; 1813 * bits_per_pixel = [8-12]; 1814 * As only support 1/2/4 div, so we set dsc_cds = crtc_clock / 8; 1815 */ 1816 conn_state->dsc_cds_clk = mode->crtc_clock / 8 * 1000; 1817 1818 return 0; 1819 } 1820 1821 static unsigned long rk3588_vop2_if_cfg(struct display_state *state) 1822 { 1823 struct crtc_state *cstate = &state->crtc_state; 1824 struct connector_state *conn_state = &state->conn_state; 1825 struct drm_display_mode *mode = &conn_state->mode; 1826 struct rockchip_dsc_sink_cap *dsc_sink_cap = &conn_state->dsc_sink_cap; 1827 struct vop2 *vop2 = cstate->private; 1828 u32 vp_offset = (cstate->crtc_id * 0x100); 1829 u16 hdisplay = mode->crtc_hdisplay; 1830 int output_if = conn_state->output_if; 1831 int dclk_core_div = 0; 1832 int dclk_out_div = 0; 1833 int if_pixclk_div = 0; 1834 int if_dclk_div = 0; 1835 unsigned long dclk_rate; 1836 u32 val; 1837 1838 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 1839 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 1840 1841 if (conn_state->dsc_enable) { 1842 if (!vop2->data->nr_dscs) { 1843 printf("No DSC\n"); 1844 return 0; 1845 } 1846 conn_state->dsc_id = output_if & (VOP_OUTPUT_IF_MIPI0 | VOP_OUTPUT_IF_HDMI0) ? 0 : 1; 1847 conn_state->dsc_slice_num = hdisplay / dsc_sink_cap->slice_width; 1848 conn_state->dsc_pixel_num = conn_state->dsc_slice_num >= 4 ? 1849 4 : conn_state->dsc_slice_num >= 2 ? 2 : 1; 1850 vop2_calc_dsc_clk(conn_state); 1851 } 1852 1853 dclk_rate = vop2_calc_cru_cfg(state, &dclk_core_div, &dclk_out_div, &if_pixclk_div, &if_dclk_div); 1854 1855 if (output_if & VOP_OUTPUT_IF_RGB) { 1856 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 1857 4, false); 1858 } 1859 1860 if (output_if & VOP_OUTPUT_IF_BT1120) { 1861 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 1862 3, false); 1863 } 1864 1865 if (output_if & VOP_OUTPUT_IF_BT656) { 1866 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 0x7, RK3588_RGB_EN_SHIFT, 1867 2, false); 1868 } 1869 1870 if (output_if & VOP_OUTPUT_IF_MIPI0) { 1871 if (cstate->crtc_id == 2) 1872 val = 0; 1873 else 1874 val = 1; 1875 1876 if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE) 1877 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 1878 RK3588_MIPI_DSI0_MODE_SEL_SHIFT, 1, false); 1879 1880 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI0_EN_SHIFT, 1881 1, false); 1882 vop2_mask_write(vop2, RK3568_DSP_IF_EN, 1, RK3588_MIPI0_MUX_SHIFT, val, false); 1883 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI0_PIXCLK_DIV_SHIFT, 1884 if_pixclk_div, false); 1885 1886 if (conn_state->hold_mode) { 1887 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 1888 EN_MASK, EDPI_TE_EN, 1, false); 1889 1890 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 1891 EN_MASK, EDPI_WMS_HOLD_EN, 1, false); 1892 } 1893 } 1894 1895 if (output_if & VOP_OUTPUT_IF_MIPI1) { 1896 if (cstate->crtc_id == 2) 1897 val = 0; 1898 else if (cstate->crtc_id == 3) 1899 val = 1; 1900 else 1901 val = 3; /*VP1*/ 1902 if (conn_state->output_flags & ROCKCHIP_OUTPUT_MIPI_DS_MODE) 1903 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 1904 RK3588_MIPI_DSI1_MODE_SEL_SHIFT, 1, false); 1905 1906 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_MIPI1_EN_SHIFT, 1907 1, false); 1908 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, MIPI1_MUX_SHIFT, 1909 val, false); 1910 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, MIPI1_PIXCLK_DIV_SHIFT, 1911 if_pixclk_div, false); 1912 1913 if (conn_state->hold_mode) { 1914 /* UNDO: RK3588 VP1->DSC1->DSI1 only can support soft TE mode */ 1915 if (vop2->version == VOP_VERSION_RK3588 && val == 3) 1916 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 1917 EN_MASK, EDPI_TE_EN, 0, false); 1918 else 1919 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 1920 EN_MASK, EDPI_TE_EN, 1, false); 1921 1922 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 1923 EN_MASK, EDPI_WMS_HOLD_EN, 1, false); 1924 } 1925 } 1926 1927 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 1928 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 1929 RK3568_MIPI_DUAL_EN_SHIFT, 1, false); 1930 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 1931 MIPI_DUAL_EN_SHIFT, 1, false); 1932 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 1933 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 1934 EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1, 1935 false); 1936 } 1937 1938 if (output_if & VOP_OUTPUT_IF_eDP0) { 1939 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP0_EN_SHIFT, 1940 1, false); 1941 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT, 1942 cstate->crtc_id, false); 1943 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT, 1944 if_dclk_div, false); 1945 1946 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT, 1947 if_pixclk_div, false); 1948 1949 vop2_grf_writel(vop2, vop2->vop_grf, RK3588_GRF_VOP_CON2, EN_MASK, 1950 RK3588_GRF_EDP0_ENABLE_SHIFT, 1); 1951 } 1952 1953 if (output_if & VOP_OUTPUT_IF_eDP1) { 1954 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_EDP1_EN_SHIFT, 1955 1, false); 1956 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT, 1957 cstate->crtc_id, false); 1958 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT, 1959 if_dclk_div, false); 1960 1961 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT, 1962 if_pixclk_div, false); 1963 } 1964 1965 if (output_if & VOP_OUTPUT_IF_HDMI0) { 1966 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI0_EN_SHIFT, 1967 1, false); 1968 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP0_MUX_SHIFT, 1969 cstate->crtc_id, false); 1970 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_DCLK_DIV_SHIFT, 1971 if_dclk_div, false); 1972 1973 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP0_PIXCLK_DIV_SHIFT, 1974 if_pixclk_div, false); 1975 } 1976 1977 if (output_if & VOP_OUTPUT_IF_HDMI1) { 1978 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI1_EN_SHIFT, 1979 1, false); 1980 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_HDMI_EDP1_MUX_SHIFT, 1981 cstate->crtc_id, false); 1982 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_DCLK_DIV_SHIFT, 1983 if_dclk_div, false); 1984 1985 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, 3, HDMI_EDP1_PIXCLK_DIV_SHIFT, 1986 if_pixclk_div, false); 1987 } 1988 1989 if (output_if & VOP_OUTPUT_IF_DP0) { 1990 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_DP0_EN_SHIFT, 1991 1, false); 1992 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP0_MUX_SHIFT, 1993 cstate->crtc_id, false); 1994 vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK, 1995 RK3588_DP0_PIN_POL_SHIFT, val, false); 1996 } 1997 1998 if (output_if & VOP_OUTPUT_IF_DP1) { 1999 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RK3588_HDMI1_EN_SHIFT, 2000 1, false); 2001 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, RK3588_DP1_MUX_SHIFT, 2002 cstate->crtc_id, false); 2003 vop2_mask_write(vop2, RK3568_DSP_IF_POL, RK3588_IF_PIN_POL_MASK, 2004 RK3588_DP1_PIN_POL_SHIFT, val, false); 2005 } 2006 2007 vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3, 2008 DCLK_CORE_DIV_SHIFT, dclk_core_div, false); 2009 vop2_mask_write(vop2, RK3588_VP0_CLK_CTRL + vp_offset, 0x3, 2010 DCLK_OUT_DIV_SHIFT, dclk_out_div, false); 2011 2012 return dclk_rate; 2013 } 2014 2015 static unsigned long rk3568_vop2_if_cfg(struct display_state *state) 2016 { 2017 struct crtc_state *cstate = &state->crtc_state; 2018 struct connector_state *conn_state = &state->conn_state; 2019 struct drm_display_mode *mode = &conn_state->mode; 2020 struct vop2 *vop2 = cstate->private; 2021 u32 vp_offset = (cstate->crtc_id * 0x100); 2022 bool dclk_inv; 2023 u32 val; 2024 2025 dclk_inv = (mode->flags & DRM_MODE_FLAG_PPIXDATA) ? 0 : 1; 2026 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 2027 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 2028 2029 if (conn_state->output_if & VOP_OUTPUT_IF_RGB) { 2030 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 2031 1, false); 2032 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2033 RGB_MUX_SHIFT, cstate->crtc_id, false); 2034 vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 2035 GRF_RGB_DCLK_INV_SHIFT, dclk_inv); 2036 } 2037 2038 if (conn_state->output_if & VOP_OUTPUT_IF_BT1120) { 2039 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 2040 1, false); 2041 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, 2042 BT1120_EN_SHIFT, 1, false); 2043 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2044 RGB_MUX_SHIFT, cstate->crtc_id, false); 2045 vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 2046 GRF_BT1120_CLK_INV_SHIFT, !dclk_inv); 2047 } 2048 2049 if (conn_state->output_if & VOP_OUTPUT_IF_BT656) { 2050 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT, 2051 1, false); 2052 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2053 RGB_MUX_SHIFT, cstate->crtc_id, false); 2054 vop2_grf_writel(vop2, vop2->grf, RK3568_GRF_VO_CON1, EN_MASK, 2055 GRF_BT656_CLK_INV_SHIFT, !dclk_inv); 2056 } 2057 2058 if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) { 2059 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT, 2060 1, false); 2061 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2062 LVDS0_MUX_SHIFT, cstate->crtc_id, false); 2063 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2064 IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, dclk_inv, false); 2065 } 2066 2067 if (conn_state->output_if & VOP_OUTPUT_IF_LVDS1) { 2068 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS1_EN_SHIFT, 2069 1, false); 2070 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2071 LVDS1_MUX_SHIFT, cstate->crtc_id, false); 2072 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2073 IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, dclk_inv, false); 2074 } 2075 2076 if (conn_state->output_flags & 2077 (ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE | 2078 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)) { 2079 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2080 LVDS_DUAL_EN_SHIFT, 1, false); 2081 if (conn_state->output_flags & 2082 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 2083 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2084 LVDS_DUAL_LEFT_RIGHT_EN_SHIFT, 1, 2085 false); 2086 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 2087 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 2088 LVDS_DUAL_SWAP_EN_SHIFT, 1, false); 2089 } 2090 2091 if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) { 2092 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT, 2093 1, false); 2094 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2095 MIPI0_MUX_SHIFT, cstate->crtc_id, false); 2096 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2097 IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false); 2098 } 2099 2100 if (conn_state->output_if & VOP_OUTPUT_IF_MIPI1) { 2101 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI1_EN_SHIFT, 2102 1, false); 2103 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2104 MIPI1_MUX_SHIFT, cstate->crtc_id, false); 2105 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2106 IF_CRTL_MIPI_DCLK_POL_SHIT, dclk_inv, false); 2107 } 2108 2109 if (conn_state->output_flags & 2110 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 2111 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 2112 MIPI_DUAL_EN_SHIFT, 1, false); 2113 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 2114 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2115 EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1, 2116 false); 2117 } 2118 2119 if (conn_state->output_if & VOP_OUTPUT_IF_eDP0) { 2120 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, EDP0_EN_SHIFT, 2121 1, false); 2122 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2123 EDP0_MUX_SHIFT, cstate->crtc_id, false); 2124 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2125 IF_CRTL_EDP_DCLK_POL_SHIT, dclk_inv, false); 2126 } 2127 2128 if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) { 2129 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT, 2130 1, false); 2131 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 2132 HDMI0_MUX_SHIFT, cstate->crtc_id, false); 2133 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 2134 IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false); 2135 vop2_mask_write(vop2, RK3568_DSP_IF_POL, 2136 IF_CRTL_HDMI_PIN_POL_MASK, 2137 IF_CRTL_HDMI_PIN_POL_SHIT, val, false); 2138 } 2139 2140 return mode->clock; 2141 } 2142 2143 static int rockchip_vop2_init(struct display_state *state) 2144 { 2145 struct crtc_state *cstate = &state->crtc_state; 2146 struct connector_state *conn_state = &state->conn_state; 2147 struct drm_display_mode *mode = &conn_state->mode; 2148 struct vop2 *vop2 = cstate->private; 2149 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 2150 u16 hdisplay = mode->crtc_hdisplay; 2151 u16 htotal = mode->crtc_htotal; 2152 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 2153 u16 hact_end = hact_st + hdisplay; 2154 u16 vdisplay = mode->crtc_vdisplay; 2155 u16 vtotal = mode->crtc_vtotal; 2156 u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; 2157 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 2158 u16 vact_end = vact_st + vdisplay; 2159 bool yuv_overlay = false; 2160 u32 vp_offset = (cstate->crtc_id * 0x100); 2161 u32 line_flag_offset = (cstate->crtc_id * 4); 2162 u32 val, act_end; 2163 u8 dither_down_en = 0; 2164 u8 pre_dither_down_en = 0; 2165 char output_type_name[30] = {0}; 2166 char dclk_name[9]; 2167 struct clk dclk; 2168 unsigned long dclk_rate; 2169 int ret; 2170 2171 printf("VOP update mode to: %dx%d%s%d, type:%s for VP%d\n", 2172 mode->hdisplay, mode->vdisplay, 2173 mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p", 2174 mode->vscan, 2175 get_output_if_name(conn_state->output_if, output_type_name), 2176 cstate->crtc_id); 2177 2178 vop2_initial(vop2, state); 2179 if (vop2->version == VOP_VERSION_RK3588) 2180 dclk_rate = rk3588_vop2_if_cfg(state); 2181 else 2182 dclk_rate = rk3568_vop2_if_cfg(state); 2183 2184 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA && 2185 !(cstate->feature & VOP_FEATURE_OUTPUT_10BIT)) 2186 conn_state->output_mode = ROCKCHIP_OUT_MODE_P888; 2187 2188 if (is_uv_swap(conn_state->bus_format, conn_state->output_mode)) 2189 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 2190 DATA_SWAP_MASK, DATA_SWAP_SHIFT, DSP_RB_SWAP, 2191 false); 2192 else 2193 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 2194 DATA_SWAP_MASK, DATA_SWAP_SHIFT, 0, 2195 false); 2196 2197 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, OUT_MODE_MASK, 2198 OUT_MODE_SHIFT, conn_state->output_mode, false); 2199 2200 switch (conn_state->bus_format) { 2201 case MEDIA_BUS_FMT_RGB565_1X16: 2202 dither_down_en = 1; 2203 break; 2204 case MEDIA_BUS_FMT_RGB666_1X18: 2205 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: 2206 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 2207 case MEDIA_BUS_FMT_RGB666_1X7X3_JEIDA: 2208 dither_down_en = 1; 2209 break; 2210 case MEDIA_BUS_FMT_YUV8_1X24: 2211 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 2212 dither_down_en = 0; 2213 pre_dither_down_en = 1; 2214 break; 2215 case MEDIA_BUS_FMT_YUV10_1X30: 2216 case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 2217 case MEDIA_BUS_FMT_RGB888_1X24: 2218 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: 2219 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: 2220 default: 2221 dither_down_en = 0; 2222 pre_dither_down_en = 0; 2223 break; 2224 } 2225 2226 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA) 2227 pre_dither_down_en = 0; 2228 else 2229 pre_dither_down_en = 1; 2230 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2231 DITHER_DOWN_EN_SHIFT, dither_down_en, false); 2232 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2233 PRE_DITHER_DOWN_EN_SHIFT, pre_dither_down_en, false); 2234 2235 yuv_overlay = is_yuv_output(conn_state->bus_format) ? 1 : 0; 2236 vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, cstate->crtc_id, 2237 yuv_overlay, false); 2238 2239 cstate->yuv_overlay = yuv_overlay; 2240 2241 vop2_writel(vop2, RK3568_VP0_DSP_HTOTAL_HS_END + vp_offset, 2242 (htotal << 16) | hsync_len); 2243 val = hact_st << 16; 2244 val |= hact_end; 2245 vop2_writel(vop2, RK3568_VP0_DSP_HACT_ST_END + vp_offset, val); 2246 val = vact_st << 16; 2247 val |= vact_end; 2248 vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END + vp_offset, val); 2249 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 2250 u16 vact_st_f1 = vtotal + vact_st + 1; 2251 u16 vact_end_f1 = vact_st_f1 + vdisplay; 2252 2253 val = vact_st_f1 << 16 | vact_end_f1; 2254 vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END_F1 + vp_offset, 2255 val); 2256 2257 val = vtotal << 16 | (vtotal + vsync_len); 2258 vop2_writel(vop2, RK3568_VP0_DSP_VS_ST_END_F1 + vp_offset, val); 2259 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2260 INTERLACE_EN_SHIFT, 1, false); 2261 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2262 DSP_FILED_POL, 1, false); 2263 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2264 P2I_EN_SHIFT, 1, false); 2265 vtotal += vtotal + 1; 2266 act_end = vact_end_f1; 2267 } else { 2268 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2269 INTERLACE_EN_SHIFT, 0, false); 2270 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2271 P2I_EN_SHIFT, 0, false); 2272 act_end = vact_end; 2273 } 2274 vop2_writel(vop2, RK3568_VP0_DSP_VTOTAL_VS_END + vp_offset, 2275 (vtotal << 16) | vsync_len); 2276 val = !!(mode->flags & DRM_MODE_FLAG_DBLCLK); 2277 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2278 CORE_DCLK_DIV_EN_SHIFT, val, false); 2279 2280 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420) 2281 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2282 DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0x3, false); 2283 else 2284 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 2285 DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0, false); 2286 2287 if (yuv_overlay) 2288 val = 0x20010200; 2289 else 2290 val = 0; 2291 vop2_writel(vop2, RK3568_VP0_DSP_BG + vp_offset, val); 2292 2293 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2294 POST_DSP_OUT_R2Y_SHIFT, yuv_overlay, false); 2295 2296 vop2_tv_config_update(state, vop2); 2297 vop2_post_config(state, vop2); 2298 2299 snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", cstate->crtc_id); 2300 ret = clk_get_by_name(cstate->dev, dclk_name, &dclk); 2301 if (!ret) 2302 ret = clk_set_rate(&dclk, dclk_rate * 1000); 2303 if (IS_ERR_VALUE(ret)) { 2304 printf("%s: Failed to set vp%d dclk[%ld KHZ] ret=%d\n", 2305 __func__, cstate->crtc_id, dclk_rate, ret); 2306 return ret; 2307 } 2308 2309 vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK, 2310 RK3568_DSP_LINE_FLAG_NUM0_SHIFT, act_end - 3, false); 2311 vop2_mask_write(vop2, RK3568_SYS_CTRL_LINE_FLAG0 + line_flag_offset, LINE_FLAG_NUM_MASK, 2312 RK3568_DSP_LINE_FLAG_NUM1_SHIFT, act_end - us_to_vertical_line(mode, 1000), false); 2313 2314 return 0; 2315 } 2316 2317 static void vop2_setup_scale(struct vop2 *vop2, struct vop2_win_data *win, 2318 uint32_t src_w, uint32_t src_h, uint32_t dst_w, 2319 uint32_t dst_h) 2320 { 2321 uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode; 2322 uint16_t hscl_filter_mode, vscl_filter_mode; 2323 uint8_t gt2 = 0, gt4 = 0; 2324 uint32_t xfac = 0, yfac = 0; 2325 uint16_t hsu_filter_mode = VOP2_SCALE_UP_BIC; 2326 uint16_t hsd_filter_mode = VOP2_SCALE_DOWN_BIL; 2327 uint16_t vsu_filter_mode = VOP2_SCALE_UP_BIL; 2328 uint16_t vsd_filter_mode = VOP2_SCALE_DOWN_BIL; 2329 u32 win_offset = win->reg_offset; 2330 2331 if (src_h >= (4 * dst_h)) 2332 gt4 = 1; 2333 else if (src_h >= (2 * dst_h)) 2334 gt2 = 1; 2335 2336 if (gt4) 2337 src_h >>= 2; 2338 else if (gt2) 2339 src_h >>= 1; 2340 2341 yrgb_hor_scl_mode = scl_get_scl_mode(src_w, dst_w); 2342 yrgb_ver_scl_mode = scl_get_scl_mode(src_h, dst_h); 2343 2344 if (yrgb_hor_scl_mode == SCALE_UP) 2345 hscl_filter_mode = hsu_filter_mode; 2346 else 2347 hscl_filter_mode = hsd_filter_mode; 2348 2349 if (yrgb_ver_scl_mode == SCALE_UP) 2350 vscl_filter_mode = vsu_filter_mode; 2351 else 2352 vscl_filter_mode = vsd_filter_mode; 2353 2354 /* 2355 * RK3568 VOP Esmart/Smart dsp_w should be even pixel 2356 * at scale down mode 2357 */ 2358 if ((yrgb_hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1)) { 2359 printf("win dst_w[%d] should align as 2 pixel\n", dst_w); 2360 dst_w += 1; 2361 } 2362 2363 xfac = vop2_scale_factor(yrgb_hor_scl_mode, hscl_filter_mode, src_w, dst_w); 2364 yfac = vop2_scale_factor(yrgb_ver_scl_mode, vscl_filter_mode, src_h, dst_h); 2365 2366 if (win->type == CLUSTER_LAYER) { 2367 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB + win_offset, 2368 yfac << 16 | xfac); 2369 2370 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 2371 YRGB_GT2_MASK, CLUSTER_YRGB_GT2_SHIFT, gt2, false); 2372 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 2373 YRGB_GT4_MASK, CLUSTER_YRGB_GT4_SHIFT, gt4, false); 2374 2375 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 2376 YRGB_XSCL_MODE_MASK, CLUSTER_YRGB_XSCL_MODE_SHIFT, yrgb_hor_scl_mode, false); 2377 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL1 + win_offset, 2378 YRGB_YSCL_MODE_MASK, CLUSTER_YRGB_YSCL_MODE_SHIFT, yrgb_ver_scl_mode, false); 2379 2380 } else { 2381 vop2_writel(vop2, RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB + win_offset, 2382 yfac << 16 | xfac); 2383 2384 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 2385 YRGB_GT2_MASK, YRGB_GT2_SHIFT, gt2, false); 2386 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 2387 YRGB_GT4_MASK, YRGB_GT4_SHIFT, gt4, false); 2388 2389 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 2390 YRGB_XSCL_MODE_MASK, YRGB_XSCL_MODE_SHIFT, yrgb_hor_scl_mode, false); 2391 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 2392 YRGB_YSCL_MODE_MASK, YRGB_YSCL_MODE_SHIFT, yrgb_ver_scl_mode, false); 2393 2394 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 2395 YRGB_XSCL_FILTER_MODE_MASK, YRGB_XSCL_FILTER_MODE_SHIFT, 2396 hscl_filter_mode, false); 2397 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_SCL_CTRL + win_offset, 2398 YRGB_YSCL_FILTER_MODE_MASK, YRGB_YSCL_FILTER_MODE_SHIFT, 2399 vscl_filter_mode, false); 2400 } 2401 } 2402 2403 static void vop2_set_cluster_win(struct display_state *state, struct vop2_win_data *win) 2404 { 2405 struct crtc_state *cstate = &state->crtc_state; 2406 struct connector_state *conn_state = &state->conn_state; 2407 struct drm_display_mode *mode = &conn_state->mode; 2408 struct vop2 *vop2 = cstate->private; 2409 int src_w = cstate->src_w; 2410 int src_h = cstate->src_h; 2411 int crtc_x = cstate->crtc_x; 2412 int crtc_y = cstate->crtc_y; 2413 int crtc_w = cstate->crtc_w; 2414 int crtc_h = cstate->crtc_h; 2415 int xvir = cstate->xvir; 2416 int y_mirror = 0; 2417 int csc_mode; 2418 u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty; 2419 u32 win_offset = win->reg_offset; 2420 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 2421 2422 act_info = (src_h - 1) << 16; 2423 act_info |= (src_w - 1) & 0xffff; 2424 2425 dsp_info = (crtc_h - 1) << 16; 2426 dsp_info |= (crtc_w - 1) & 0xffff; 2427 2428 dsp_stx = crtc_x; 2429 dsp_sty = crtc_y; 2430 dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); 2431 2432 if (mode->flags & DRM_MODE_FLAG_YMIRROR) 2433 y_mirror = 1; 2434 else 2435 y_mirror = 0; 2436 2437 vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h); 2438 2439 if (y_mirror) 2440 printf("WARN: y mirror is unsupported by cluster window\n"); 2441 2442 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, 2443 WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format, 2444 false); 2445 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_VIR + win_offset, xvir); 2446 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_YRGB_MST + win_offset, cstate->dma_addr); 2447 2448 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_ACT_INFO + win_offset, act_info); 2449 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_INFO + win_offset, dsp_info); 2450 vop2_writel(vop2, RK3568_CLUSTER0_WIN0_DSP_ST + win_offset, dsp_st); 2451 2452 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, WIN_EN_SHIFT, 1, false); 2453 2454 csc_mode = vop2_convert_csc_mode(conn_state->color_space); 2455 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, EN_MASK, 2456 CLUSTER_RGB2YUV_EN_SHIFT, 2457 is_yuv_output(conn_state->bus_format), false); 2458 vop2_mask_write(vop2, RK3568_CLUSTER0_WIN0_CTRL0 + win_offset, CSC_MODE_MASK, 2459 CLUSTER_CSC_MODE_SHIFT, csc_mode, false); 2460 vop2_mask_write(vop2, RK3568_CLUSTER0_CTRL + win_offset, EN_MASK, CLUSTER_EN_SHIFT, 1, false); 2461 2462 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 2463 } 2464 2465 static void vop2_set_smart_win(struct display_state *state, struct vop2_win_data *win) 2466 { 2467 struct crtc_state *cstate = &state->crtc_state; 2468 struct connector_state *conn_state = &state->conn_state; 2469 struct drm_display_mode *mode = &conn_state->mode; 2470 struct vop2 *vop2 = cstate->private; 2471 int src_w = cstate->src_w; 2472 int src_h = cstate->src_h; 2473 int crtc_x = cstate->crtc_x; 2474 int crtc_y = cstate->crtc_y; 2475 int crtc_w = cstate->crtc_w; 2476 int crtc_h = cstate->crtc_h; 2477 int xvir = cstate->xvir; 2478 int y_mirror = 0; 2479 int csc_mode; 2480 u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty; 2481 u32 win_offset = win->reg_offset; 2482 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 2483 2484 /* 2485 * This is workaround solution for IC design: 2486 * esmart can't support scale down when actual_w % 16 == 1. 2487 */ 2488 if (src_w > crtc_w && (src_w & 0xf) == 1) { 2489 printf("WARN: vp%d unsupported act_w[%d] mode 16 = 1 when scale down\n", cstate->crtc_id, src_w); 2490 src_w -= 1; 2491 } 2492 2493 act_info = (src_h - 1) << 16; 2494 act_info |= (src_w - 1) & 0xffff; 2495 2496 dsp_info = (crtc_h - 1) << 16; 2497 dsp_info |= (crtc_w - 1) & 0xffff; 2498 2499 dsp_stx = crtc_x; 2500 dsp_sty = crtc_y; 2501 dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); 2502 2503 if (mode->flags & DRM_MODE_FLAG_YMIRROR) 2504 y_mirror = 1; 2505 else 2506 y_mirror = 0; 2507 2508 vop2_setup_scale(vop2, win, src_w, src_h, crtc_w, crtc_h); 2509 2510 if (y_mirror) 2511 cstate->dma_addr += (src_h - 1) * xvir * 4; 2512 vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, EN_MASK, 2513 YMIRROR_EN_SHIFT, y_mirror, false); 2514 2515 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 2516 WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format, 2517 false); 2518 vop2_writel(vop2, RK3568_ESMART0_REGION0_VIR + win_offset, xvir); 2519 vop2_writel(vop2, RK3568_ESMART0_REGION0_YRGB_MST + win_offset, 2520 cstate->dma_addr); 2521 2522 vop2_writel(vop2, RK3568_ESMART0_REGION0_ACT_INFO + win_offset, 2523 act_info); 2524 vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_INFO + win_offset, 2525 dsp_info); 2526 vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_ST + win_offset, dsp_st); 2527 2528 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK, 2529 WIN_EN_SHIFT, 1, false); 2530 2531 csc_mode = vop2_convert_csc_mode(conn_state->color_space); 2532 vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, EN_MASK, 2533 RGB2YUV_EN_SHIFT, 2534 is_yuv_output(conn_state->bus_format), false); 2535 vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, CSC_MODE_MASK, 2536 CSC_MODE_SHIFT, csc_mode, false); 2537 2538 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 2539 } 2540 2541 static int rockchip_vop2_set_plane(struct display_state *state) 2542 { 2543 struct crtc_state *cstate = &state->crtc_state; 2544 struct vop2 *vop2 = cstate->private; 2545 struct vop2_win_data *win_data; 2546 u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id; 2547 char plane_name[10] = {0}; 2548 2549 if (cstate->crtc_w > cstate->max_output.width) { 2550 printf("ERROR: output w[%d] exceeded max width[%d]\n", 2551 cstate->crtc_w, cstate->max_output.width); 2552 return -EINVAL; 2553 } 2554 2555 win_data = vop2_find_win_by_phys_id(vop2, primary_plane_id); 2556 if (!win_data) { 2557 printf("invalid win id %d\n", primary_plane_id); 2558 return -ENODEV; 2559 } 2560 2561 if (win_data->type == CLUSTER_LAYER) 2562 vop2_set_cluster_win(state, win_data); 2563 else 2564 vop2_set_smart_win(state, win_data); 2565 2566 printf("VOP VP%d enable %s[%dx%d->%dx%d@%dx%d] fmt[%d] addr[0x%x]\n", 2567 cstate->crtc_id, get_plane_name(primary_plane_id, plane_name), 2568 cstate->src_w, cstate->src_h, cstate->crtc_w, cstate->crtc_h, 2569 cstate->crtc_x, cstate->crtc_y, cstate->format, 2570 cstate->dma_addr); 2571 2572 return 0; 2573 } 2574 2575 static int rockchip_vop2_prepare(struct display_state *state) 2576 { 2577 return 0; 2578 } 2579 2580 static int rockchip_vop2_enable(struct display_state *state) 2581 { 2582 struct crtc_state *cstate = &state->crtc_state; 2583 struct vop2 *vop2 = cstate->private; 2584 u32 vp_offset = (cstate->crtc_id * 0x100); 2585 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 2586 2587 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2588 STANDBY_EN_SHIFT, 0, false); 2589 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 2590 2591 return 0; 2592 } 2593 2594 static int rockchip_vop2_disable(struct display_state *state) 2595 { 2596 struct crtc_state *cstate = &state->crtc_state; 2597 struct vop2 *vop2 = cstate->private; 2598 u32 vp_offset = (cstate->crtc_id * 0x100); 2599 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id) | (BIT(cstate->crtc_id) << 16); 2600 2601 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 2602 STANDBY_EN_SHIFT, 1, false); 2603 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 2604 2605 return 0; 2606 } 2607 2608 static int rockchip_vop2_get_cursor_plane(struct display_state *state, u32 plane_mask, int cursor_plane) 2609 { 2610 struct crtc_state *cstate = &state->crtc_state; 2611 struct vop2 *vop2 = cstate->private; 2612 int i = 0; 2613 int correct_cursor_plane = -1; 2614 int plane_type = -1; 2615 2616 if (cursor_plane < 0) 2617 return -1; 2618 2619 if (plane_mask & (1 << cursor_plane)) 2620 return cursor_plane; 2621 2622 /* Get current cursor plane type */ 2623 for (i = 0; i < vop2->data->nr_layers; i++) { 2624 if (vop2->data->plane_table[i].plane_id == cursor_plane) { 2625 plane_type = vop2->data->plane_table[i].plane_type; 2626 break; 2627 } 2628 } 2629 2630 /* Get the other same plane type plane id */ 2631 for (i = 0; i < vop2->data->nr_layers; i++) { 2632 if (vop2->data->plane_table[i].plane_type == plane_type && 2633 vop2->data->plane_table[i].plane_id != cursor_plane) { 2634 correct_cursor_plane = vop2->data->plane_table[i].plane_id; 2635 break; 2636 } 2637 } 2638 2639 /* To check whether the new correct_cursor_plane is attach to current vp */ 2640 if (correct_cursor_plane < 0 || !(plane_mask & (1 << correct_cursor_plane))) { 2641 printf("error: faild to find correct plane as cursor plane\n"); 2642 return -1; 2643 } 2644 2645 printf("vp%d adjust cursor plane from %d to %d\n", 2646 cstate->crtc_id, cursor_plane, correct_cursor_plane); 2647 2648 return correct_cursor_plane; 2649 } 2650 2651 static int rockchip_vop2_fixup_dts(struct display_state *state, void *blob) 2652 { 2653 struct crtc_state *cstate = &state->crtc_state; 2654 struct vop2 *vop2 = cstate->private; 2655 ofnode vp_node; 2656 struct device_node *port_parent_node = cstate->ports_node; 2657 static bool vop_fix_dts; 2658 const char *path; 2659 u32 plane_mask = 0; 2660 int vp_id = 0; 2661 int cursor_plane_id = -1; 2662 2663 if (vop_fix_dts) 2664 return 0; 2665 2666 ofnode_for_each_subnode(vp_node, np_to_ofnode(port_parent_node)) { 2667 path = vp_node.np->full_name; 2668 plane_mask = vop2->vp_plane_mask[vp_id].plane_mask; 2669 2670 if (cstate->crtc->assign_plane) 2671 continue; 2672 cursor_plane_id = rockchip_vop2_get_cursor_plane(state, plane_mask, 2673 cstate->crtc->vps[vp_id].cursor_plane); 2674 printf("vp%d, plane_mask:0x%x, primary-id:%d, curser-id:%d\n", 2675 vp_id, plane_mask, 2676 vop2->vp_plane_mask[vp_id].primary_plane_id, 2677 cursor_plane_id); 2678 2679 do_fixup_by_path_u32(blob, path, "rockchip,plane-mask", 2680 plane_mask, 1); 2681 do_fixup_by_path_u32(blob, path, "rockchip,primary-plane", 2682 vop2->vp_plane_mask[vp_id].primary_plane_id, 1); 2683 if (cursor_plane_id >= 0) 2684 do_fixup_by_path_u32(blob, path, "cursor-win-id", 2685 cursor_plane_id, 1); 2686 vp_id++; 2687 } 2688 2689 vop_fix_dts = true; 2690 2691 return 0; 2692 } 2693 2694 static struct vop2_plane_table rk356x_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 2695 {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER}, 2696 {ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER}, 2697 {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 2698 {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 2699 {ROCKCHIP_VOP2_SMART0, SMART_LAYER}, 2700 {ROCKCHIP_VOP2_SMART0, SMART_LAYER}, 2701 }; 2702 2703 static struct vop2_vp_plane_mask rk356x_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 2704 { /* one display policy */ 2705 {/* main display */ 2706 .primary_plane_id = ROCKCHIP_VOP2_SMART0, 2707 .attached_layers_nr = 6, 2708 .attached_layers = { 2709 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0, 2710 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1 2711 }, 2712 }, 2713 {/* second display */}, 2714 {/* third display */}, 2715 {/* fourth display */}, 2716 }, 2717 2718 { /* two display policy */ 2719 {/* main display */ 2720 .primary_plane_id = ROCKCHIP_VOP2_SMART0, 2721 .attached_layers_nr = 3, 2722 .attached_layers = { 2723 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0 2724 }, 2725 }, 2726 2727 {/* second display */ 2728 .primary_plane_id = ROCKCHIP_VOP2_SMART1, 2729 .attached_layers_nr = 3, 2730 .attached_layers = { 2731 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1 2732 }, 2733 }, 2734 {/* third display */}, 2735 {/* fourth display */}, 2736 }, 2737 2738 { /* three display policy */ 2739 {/* main display */ 2740 .primary_plane_id = ROCKCHIP_VOP2_SMART0, 2741 .attached_layers_nr = 3, 2742 .attached_layers = { 2743 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0 2744 }, 2745 }, 2746 2747 {/* second display */ 2748 .primary_plane_id = ROCKCHIP_VOP2_SMART1, 2749 .attached_layers_nr = 2, 2750 .attached_layers = { 2751 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_SMART1 2752 }, 2753 }, 2754 2755 {/* third display */ 2756 .primary_plane_id = ROCKCHIP_VOP2_ESMART1, 2757 .attached_layers_nr = 1, 2758 .attached_layers = { ROCKCHIP_VOP2_ESMART1 }, 2759 }, 2760 2761 {/* fourth display */}, 2762 }, 2763 2764 {/* reserved for four display policy */}, 2765 }; 2766 2767 static struct vop2_win_data rk3568_win_data[6] = { 2768 { 2769 .name = "Cluster0", 2770 .phys_id = ROCKCHIP_VOP2_CLUSTER0, 2771 .type = CLUSTER_LAYER, 2772 .win_sel_port_offset = 0, 2773 .layer_sel_win_id = 0, 2774 .reg_offset = 0, 2775 }, 2776 2777 { 2778 .name = "Cluster1", 2779 .phys_id = ROCKCHIP_VOP2_CLUSTER1, 2780 .type = CLUSTER_LAYER, 2781 .win_sel_port_offset = 1, 2782 .layer_sel_win_id = 1, 2783 .reg_offset = 0x200, 2784 }, 2785 2786 { 2787 .name = "Esmart0", 2788 .phys_id = ROCKCHIP_VOP2_ESMART0, 2789 .type = ESMART_LAYER, 2790 .win_sel_port_offset = 4, 2791 .layer_sel_win_id = 2, 2792 .reg_offset = 0, 2793 }, 2794 2795 { 2796 .name = "Esmart1", 2797 .phys_id = ROCKCHIP_VOP2_ESMART1, 2798 .type = ESMART_LAYER, 2799 .win_sel_port_offset = 5, 2800 .layer_sel_win_id = 6, 2801 .reg_offset = 0x200, 2802 }, 2803 2804 { 2805 .name = "Smart0", 2806 .phys_id = ROCKCHIP_VOP2_SMART0, 2807 .type = SMART_LAYER, 2808 .win_sel_port_offset = 6, 2809 .layer_sel_win_id = 3, 2810 .reg_offset = 0x400, 2811 }, 2812 2813 { 2814 .name = "Smart1", 2815 .phys_id = ROCKCHIP_VOP2_SMART1, 2816 .type = SMART_LAYER, 2817 .win_sel_port_offset = 7, 2818 .layer_sel_win_id = 7, 2819 .reg_offset = 0x600, 2820 }, 2821 }; 2822 2823 static struct vop2_vp_data rk3568_vp_data[3] = { 2824 { 2825 .feature = VOP_FEATURE_OUTPUT_10BIT, 2826 .pre_scan_max_dly = 42, 2827 .max_output = {4096, 2304}, 2828 }, 2829 { 2830 .feature = 0, 2831 .pre_scan_max_dly = 40, 2832 .max_output = {2048, 1536}, 2833 }, 2834 { 2835 .feature = 0, 2836 .pre_scan_max_dly = 40, 2837 .max_output = {1920, 1080}, 2838 }, 2839 }; 2840 2841 const struct vop2_data rk3568_vop = { 2842 .version = VOP_VERSION_RK3568, 2843 .nr_vps = 3, 2844 .vp_data = rk3568_vp_data, 2845 .win_data = rk3568_win_data, 2846 .plane_mask = rk356x_vp_plane_mask[0], 2847 .plane_table = rk356x_plane_table, 2848 .nr_layers = 6, 2849 .nr_mixers = 5, 2850 .nr_gammas = 1, 2851 }; 2852 2853 static struct vop2_plane_table rk3588_plane_table[ROCKCHIP_VOP2_LAYER_MAX] = { 2854 {ROCKCHIP_VOP2_CLUSTER0, CLUSTER_LAYER}, 2855 {ROCKCHIP_VOP2_CLUSTER1, CLUSTER_LAYER}, 2856 {ROCKCHIP_VOP2_CLUSTER2, CLUSTER_LAYER}, 2857 {ROCKCHIP_VOP2_CLUSTER3, CLUSTER_LAYER}, 2858 {ROCKCHIP_VOP2_ESMART0, ESMART_LAYER}, 2859 {ROCKCHIP_VOP2_ESMART1, ESMART_LAYER}, 2860 {ROCKCHIP_VOP2_ESMART2, ESMART_LAYER}, 2861 {ROCKCHIP_VOP2_ESMART3, ESMART_LAYER}, 2862 }; 2863 2864 static struct vop2_vp_plane_mask rk3588_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 2865 { /* one display policy */ 2866 {/* main display */ 2867 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER0, 2868 .attached_layers_nr = 8, 2869 .attached_layers = { 2870 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_ESMART2, 2871 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_ESMART3, 2872 ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3 2873 }, 2874 }, 2875 {/* second display */}, 2876 {/* third display */}, 2877 {/* fourth display */}, 2878 }, 2879 2880 { /* two display policy */ 2881 {/* main display */ 2882 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER0, 2883 .attached_layers_nr = 4, 2884 .attached_layers = { 2885 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, 2886 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1 2887 }, 2888 }, 2889 2890 {/* second display */ 2891 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER2, 2892 .attached_layers_nr = 4, 2893 .attached_layers = { 2894 ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2, 2895 ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3 2896 }, 2897 }, 2898 {/* third display */}, 2899 {/* fourth display */}, 2900 }, 2901 2902 { /* three display policy */ 2903 {/* main display */ 2904 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER0, 2905 .attached_layers_nr = 3, 2906 .attached_layers = { 2907 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART0 2908 }, 2909 }, 2910 2911 {/* second display */ 2912 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER2, 2913 .attached_layers_nr = 3, 2914 .attached_layers = { 2915 ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART1 2916 }, 2917 }, 2918 2919 {/* third display */ 2920 .primary_plane_id = ROCKCHIP_VOP2_ESMART2, 2921 .attached_layers_nr = 2, 2922 .attached_layers = { ROCKCHIP_VOP2_ESMART2, ROCKCHIP_VOP2_ESMART3 }, 2923 }, 2924 2925 {/* fourth display */}, 2926 }, 2927 2928 { /* four display policy */ 2929 {/* main display */ 2930 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER0, 2931 .attached_layers_nr = 2, 2932 .attached_layers = { ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0 }, 2933 }, 2934 2935 {/* second display */ 2936 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER1, 2937 .attached_layers_nr = 2, 2938 .attached_layers = { ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1 }, 2939 }, 2940 2941 {/* third display */ 2942 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER2, 2943 .attached_layers_nr = 2, 2944 .attached_layers = { ROCKCHIP_VOP2_CLUSTER2, ROCKCHIP_VOP2_ESMART2 }, 2945 }, 2946 2947 {/* fourth display */ 2948 .primary_plane_id = ROCKCHIP_VOP2_CLUSTER3, 2949 .attached_layers_nr = 2, 2950 .attached_layers = { ROCKCHIP_VOP2_CLUSTER3, ROCKCHIP_VOP2_ESMART3 }, 2951 }, 2952 }, 2953 2954 }; 2955 2956 static struct vop2_power_domain_data rk3588_cluster0_pd_data = { 2957 .pd_en_shift = RK3588_CLUSTER0_PD_EN_SHIFT, 2958 .pd_status_shift = RK3588_CLUSTER0_PD_STATUS_SHIFT, 2959 .pmu_status_shift = RK3588_PD_CLUSTER0_PWR_STAT_SHIFI, 2960 .bisr_en_status_shift = RK3588_PD_CLUSTER0_REPAIR_EN_SHIFT, 2961 }; 2962 2963 static struct vop2_power_domain_data rk3588_cluster1_pd_data = { 2964 .is_parent_needed = true, 2965 .pd_en_shift = RK3588_CLUSTER1_PD_EN_SHIFT, 2966 .pd_status_shift = RK3588_CLUSTER1_PD_STATUS_SHIFT, 2967 .pmu_status_shift = RK3588_PD_CLUSTER1_PWR_STAT_SHIFI, 2968 .bisr_en_status_shift = RK3588_PD_CLUSTER1_REPAIR_EN_SHIFT, 2969 .parent_phy_id = ROCKCHIP_VOP2_CLUSTER0, 2970 }; 2971 2972 static struct vop2_power_domain_data rk3588_cluster2_pd_data = { 2973 .is_parent_needed = true, 2974 .pd_en_shift = RK3588_CLUSTER2_PD_EN_SHIFT, 2975 .pd_status_shift = RK3588_CLUSTER2_PD_STATUS_SHIFT, 2976 .pmu_status_shift = RK3588_PD_CLUSTER2_PWR_STAT_SHIFI, 2977 .bisr_en_status_shift = RK3588_PD_CLUSTER2_REPAIR_EN_SHIFT, 2978 .parent_phy_id = ROCKCHIP_VOP2_CLUSTER0, 2979 }; 2980 2981 static struct vop2_power_domain_data rk3588_cluster3_pd_data = { 2982 .is_parent_needed = true, 2983 .pd_en_shift = RK3588_CLUSTER3_PD_EN_SHIFT, 2984 .pd_status_shift = RK3588_CLUSTER3_PD_STATUS_SHIFT, 2985 .pmu_status_shift = RK3588_PD_CLUSTER3_PWR_STAT_SHIFI, 2986 .bisr_en_status_shift = RK3588_PD_CLUSTER3_REPAIR_EN_SHIFT, 2987 .parent_phy_id = ROCKCHIP_VOP2_CLUSTER0, 2988 }; 2989 2990 static struct vop2_power_domain_data rk3588_esmart_pd_data = { 2991 .pd_en_shift = RK3588_ESMART_PD_EN_SHIFT, 2992 .pd_status_shift = RK3588_ESMART_PD_STATUS_SHIFT, 2993 .pmu_status_shift = RK3588_PD_ESMART_PWR_STAT_SHIFI, 2994 .bisr_en_status_shift = RK3588_PD_ESMART_REPAIR_EN_SHIFT, 2995 }; 2996 2997 static struct vop2_win_data rk3588_win_data[8] = { 2998 { 2999 .name = "Cluster0", 3000 .phys_id = ROCKCHIP_VOP2_CLUSTER0, 3001 .type = CLUSTER_LAYER, 3002 .win_sel_port_offset = 0, 3003 .layer_sel_win_id = 0, 3004 .reg_offset = 0, 3005 .pd_data = &rk3588_cluster0_pd_data, 3006 }, 3007 3008 { 3009 .name = "Cluster1", 3010 .phys_id = ROCKCHIP_VOP2_CLUSTER1, 3011 .type = CLUSTER_LAYER, 3012 .win_sel_port_offset = 1, 3013 .layer_sel_win_id = 1, 3014 .reg_offset = 0x200, 3015 .pd_data = &rk3588_cluster1_pd_data, 3016 }, 3017 3018 { 3019 .name = "Cluster2", 3020 .phys_id = ROCKCHIP_VOP2_CLUSTER2, 3021 .type = CLUSTER_LAYER, 3022 .win_sel_port_offset = 2, 3023 .layer_sel_win_id = 4, 3024 .reg_offset = 0x400, 3025 .pd_data = &rk3588_cluster2_pd_data, 3026 }, 3027 3028 { 3029 .name = "Cluster3", 3030 .phys_id = ROCKCHIP_VOP2_CLUSTER3, 3031 .type = CLUSTER_LAYER, 3032 .win_sel_port_offset = 3, 3033 .layer_sel_win_id = 5, 3034 .reg_offset = 0x600, 3035 .pd_data = &rk3588_cluster3_pd_data, 3036 }, 3037 3038 { 3039 .name = "Esmart0", 3040 .phys_id = ROCKCHIP_VOP2_ESMART0, 3041 .type = ESMART_LAYER, 3042 .win_sel_port_offset = 4, 3043 .layer_sel_win_id = 2, 3044 .reg_offset = 0, 3045 .pd_data = &rk3588_esmart_pd_data, 3046 }, 3047 3048 { 3049 .name = "Esmart1", 3050 .phys_id = ROCKCHIP_VOP2_ESMART1, 3051 .type = ESMART_LAYER, 3052 .win_sel_port_offset = 5, 3053 .layer_sel_win_id = 3, 3054 .reg_offset = 0x200, 3055 .pd_data = &rk3588_esmart_pd_data, 3056 }, 3057 3058 { 3059 .name = "Esmart2", 3060 .phys_id = ROCKCHIP_VOP2_ESMART2, 3061 .type = ESMART_LAYER, 3062 .win_sel_port_offset = 6, 3063 .layer_sel_win_id = 6, 3064 .reg_offset = 0x400, 3065 .pd_data = &rk3588_esmart_pd_data, 3066 }, 3067 3068 { 3069 .name = "Esmart3", 3070 .phys_id = ROCKCHIP_VOP2_ESMART3, 3071 .type = ESMART_LAYER, 3072 .win_sel_port_offset = 7, 3073 .layer_sel_win_id = 7, 3074 .reg_offset = 0x600, 3075 .pd_data = &rk3588_esmart_pd_data, 3076 }, 3077 }; 3078 3079 static struct vop2_vp_data rk3588_vp_data[4] = { 3080 { 3081 .feature = VOP_FEATURE_OUTPUT_10BIT, 3082 .pre_scan_max_dly = 42, 3083 .max_dclk = 600000, 3084 .max_output = {7680, 4320}, 3085 }, 3086 { 3087 .feature = VOP_FEATURE_OUTPUT_10BIT, 3088 .pre_scan_max_dly = 40, 3089 .max_dclk = 600000, 3090 .max_output = {4096, 2304}, 3091 }, 3092 { 3093 .feature = VOP_FEATURE_OUTPUT_10BIT, 3094 .pre_scan_max_dly = 52, 3095 .max_dclk = 600000, 3096 .max_output = {4096, 2304}, 3097 }, 3098 { 3099 .feature = 0, 3100 .pre_scan_max_dly = 52, 3101 .max_dclk = 200000, 3102 .max_output = {1920, 1080}, 3103 }, 3104 }; 3105 3106 const struct vop2_data rk3588_vop = { 3107 .version = VOP_VERSION_RK3588, 3108 .nr_vps = 4, 3109 .vp_data = rk3588_vp_data, 3110 .win_data = rk3588_win_data, 3111 .plane_mask = rk3588_vp_plane_mask[0], 3112 .plane_table = rk3588_plane_table, 3113 .nr_layers = 8, 3114 .nr_mixers = 7, 3115 .nr_gammas = 4, 3116 .nr_dscs = 2, 3117 }; 3118 3119 const struct rockchip_crtc_funcs rockchip_vop2_funcs = { 3120 .preinit = rockchip_vop2_preinit, 3121 .prepare = rockchip_vop2_prepare, 3122 .init = rockchip_vop2_init, 3123 .set_plane = rockchip_vop2_set_plane, 3124 .enable = rockchip_vop2_enable, 3125 .disable = rockchip_vop2_disable, 3126 .fixup_dts = rockchip_vop2_fixup_dts, 3127 }; 3128