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