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