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