1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd 4 * 5 */ 6 7 #include <config.h> 8 #include <common.h> 9 #include <errno.h> 10 #include <malloc.h> 11 #include <fdtdec.h> 12 #include <fdt_support.h> 13 #include <asm/arch/cpu.h> 14 #include <asm/unaligned.h> 15 #include <asm/io.h> 16 #include <linux/list.h> 17 #include <linux/media-bus-format.h> 18 #include <clk.h> 19 #include <asm/arch/clock.h> 20 #include <linux/err.h> 21 #include <linux/ioport.h> 22 #include <dm/device.h> 23 #include <dm/read.h> 24 #include <syscon.h> 25 26 #include "rockchip_display.h" 27 #include "rockchip_crtc.h" 28 #include "rockchip_connector.h" 29 30 /* System registers definition */ 31 #define RK3568_REG_CFG_DONE 0x000 32 #define CFG_DONE_EN BIT(15) 33 34 #define RK3568_VERSION_INFO 0x004 35 #define EN_MASK 1 36 37 #define RK3568_AUTO_GATING_CTRL 0x008 38 39 #define RK3568_SYS_AXI_LUT_CTRL 0x024 40 #define LUT_DMA_EN_SHIFT 0 41 42 #define RK3568_DSP_IF_EN 0x028 43 #define RGB_EN_SHIFT 0 44 #define HDMI0_EN_SHIFT 1 45 #define EDP0_EN_SHIFT 3 46 #define MIPI0_EN_SHIFT 4 47 #define MIPI1_EN_SHIFT 20 48 #define LVDS0_EN_SHIFT 5 49 #define LVDS1_EN_SHIFT 24 50 #define BT1120_EN_SHIFT 6 51 #define BT656_EN_SHIFT 7 52 #define IF_MUX_MASK 3 53 #define RGB_MUX_SHIFT 8 54 #define HDMI0_MUX_SHIFT 10 55 #define EDP0_MUX_SHIFT 14 56 #define MIPI0_MUX_SHIFT 16 57 #define MIPI1_MUX_SHIFT 21 58 #define LVDS0_MUX_SHIFT 18 59 #define LVDS1_MUX_SHIFT 25 60 61 #define RK3568_DSP_IF_CTRL 0x02c 62 #define LVDS_DUAL_EN_SHIFT 0 63 #define LVDS_DUAL_LEFT_RIGHT_EN_SHIFT 1 64 #define LVDS_DUAL_SWAP_EN_SHIFT 2 65 #define RK3568_DSP_IF_POL 0x030 66 #define IF_CTRL_REG_DONE_IMD_MASK 1 67 #define IF_CTRL_REG_DONE_IMD_SHIFT 28 68 #define IF_CRTL_MIPI_DCLK_POL_SHIT 19 69 #define IF_CRTL_EDP_DCLK_POL_SHIT 15 70 #define IF_CRTL_HDMI_DCLK_POL_SHIT 7 71 #define IF_CRTL_HDMI_PIN_POL_MASK 0x7 72 #define IF_CRTL_HDMI_PIN_POL_SHIT 4 73 #define IF_CRTL_RGB_LVDS_DCLK_POL_SHIT 3 74 #define RK3568_SYS_OTP_WIN_EN 0x50 75 #define OTP_WIN_EN_SHIFT 0 76 #define RK3568_SYS_LUT_PORT_SEL 0x58 77 #define GAMMA_PORT_SEL_MASK 0x3 78 #define GAMMA_PORT_SEL_SHIFT 0 79 80 #define RK3568_VP0_LINE_FLAG 0x70 81 #define RK3568_VP1_LINE_FLAG 0x74 82 #define RK3568_VP2_LINE_FLAG 0x78 83 #define RK3568_SYS0_INT_EN 0x80 84 #define RK3568_SYS0_INT_CLR 0x84 85 #define RK3568_SYS0_INT_STATUS 0x88 86 #define RK3568_SYS1_INT_EN 0x90 87 #define RK3568_SYS1_INT_CLR 0x94 88 #define RK3568_SYS1_INT_STATUS 0x98 89 #define RK3568_VP0_INT_EN 0xA0 90 #define RK3568_VP0_INT_CLR 0xA4 91 #define RK3568_VP0_INT_STATUS 0xA8 92 #define RK3568_VP1_INT_EN 0xB0 93 #define RK3568_VP1_INT_CLR 0xB4 94 #define RK3568_VP1_INT_STATUS 0xB8 95 #define RK3568_VP2_INT_EN 0xC0 96 #define RK3568_VP2_INT_CLR 0xC4 97 #define RK3568_VP2_INT_STATUS 0xC8 98 99 /* Overlay registers definition */ 100 #define RK3568_OVL_CTRL 0x600 101 #define OVL_PORT_MUX_REG_DONE_IMD_SHIFT 28 102 #define RK3568_OVL_LAYER_SEL 0x604 103 #define LAYER_SEL_MASK 0xf 104 105 #define RK3568_OVL_PORT_SEL 0x608 106 #define PORT_MUX_MASK 0xf 107 #define PORT_MUX_SHIFT 0 108 #define LAYER_SEL_PORT_MASK 0x3 109 #define LAYER_SEL_PORT_SHIFT 16 110 111 #define RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL 0x610 112 #define RK3568_CLUSTER0_MIX_DST_COLOR_CTRL 0x614 113 #define RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x618 114 #define RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL 0x61C 115 #define RK3568_MIX0_SRC_COLOR_CTRL 0x650 116 #define RK3568_MIX0_DST_COLOR_CTRL 0x654 117 #define RK3568_MIX0_SRC_ALPHA_CTRL 0x658 118 #define RK3568_MIX0_DST_ALPHA_CTRL 0x65C 119 #define RK3568_HDR0_SRC_COLOR_CTRL 0x6C0 120 #define RK3568_HDR0_DST_COLOR_CTRL 0x6C4 121 #define RK3568_HDR0_SRC_ALPHA_CTRL 0x6C8 122 #define RK3568_HDR0_DST_ALPHA_CTRL 0x6CC 123 #define RK3568_VP0_BG_MIX_CTRL 0x6E0 124 #define BG_MIX_CTRL_MASK 0xff 125 #define BG_MIX_CTRL_SHIFT 24 126 #define RK3568_VP1_BG_MIX_CTRL 0x6E4 127 #define RK3568_VP2_BG_MIX_CTRL 0x6E8 128 #define RK3568_CLUSTER_DLY_NUM 0x6F0 129 #define RK3568_SMART_DLY_NUM 0x6F8 130 131 /* Video Port registers definition */ 132 #define RK3568_VP0_DSP_CTRL 0xC00 133 #define OUT_MODE_MASK 0xf 134 #define OUT_MODE_SHIFT 0 135 #define DATA_SWAP_MASK 0x1f 136 #define DATA_SWAP_SHIFT 8 137 #define DSP_RB_SWAP 2 138 #define CORE_DCLK_DIV_EN_SHIFT 4 139 #define P2I_EN_SHIFT 5 140 #define INTERLACE_EN_SHIFT 7 141 #define POST_DSP_OUT_R2Y_SHIFT 15 142 #define PRE_DITHER_DOWN_EN_SHIFT 16 143 #define DITHER_DOWN_EN_SHIFT 17 144 #define DSP_LUT_EN_SHIFT 28 145 146 #define STANDBY_EN_SHIFT 31 147 148 #define RK3568_VP0_MIPI_CTRL 0xC04 149 #define DCLK_DIV2_SHIFT 4 150 #define DCLK_DIV2_MASK 0x3 151 #define MIPI_DUAL_EN_SHIFT 20 152 #define MIPI_DUAL_SWAP_EN_SHIFT 21 153 154 #define RK3568_VP0_COLOR_BAR_CTRL 0xC08 155 #define RK3568_VP0_3D_LUT_CTRL 0xC10 156 #define VP0_3D_LUT_EN_SHIFT 0 157 #define VP0_3D_LUT_UPDATE_SHIFT 2 158 159 #define RK3568_VP0_3D_LUT_MST 0xC20 160 161 #define RK3568_VP0_DSP_BG 0xC2C 162 #define RK3568_VP0_PRE_SCAN_HTIMING 0xC30 163 #define RK3568_VP0_POST_DSP_HACT_INFO 0xC34 164 #define RK3568_VP0_POST_DSP_VACT_INFO 0xC38 165 #define RK3568_VP0_POST_SCL_FACTOR_YRGB 0xC3C 166 #define RK3568_VP0_POST_SCL_CTRL 0xC40 167 #define RK3568_VP0_POST_DSP_VACT_INFO_F1 0xC44 168 #define RK3568_VP0_DSP_HTOTAL_HS_END 0xC48 169 #define RK3568_VP0_DSP_HACT_ST_END 0xC4C 170 #define RK3568_VP0_DSP_VTOTAL_VS_END 0xC50 171 #define RK3568_VP0_DSP_VACT_ST_END 0xC54 172 #define RK3568_VP0_DSP_VS_ST_END_F1 0xC58 173 #define RK3568_VP0_DSP_VACT_ST_END_F1 0xC5C 174 175 #define RK3568_VP1_DSP_CTRL 0xD00 176 #define RK3568_VP1_MIPI_CTRL 0xD04 177 #define RK3568_VP1_COLOR_BAR_CTRL 0xD08 178 #define RK3568_VP1_PRE_SCAN_HTIMING 0xD30 179 #define RK3568_VP1_POST_DSP_HACT_INFO 0xD34 180 #define RK3568_VP1_POST_DSP_VACT_INFO 0xD38 181 #define RK3568_VP1_POST_SCL_FACTOR_YRGB 0xD3C 182 #define RK3568_VP1_POST_SCL_CTRL 0xD40 183 #define RK3568_VP1_DSP_HACT_INFO 0xD34 184 #define RK3568_VP1_DSP_VACT_INFO 0xD38 185 #define RK3568_VP1_POST_DSP_VACT_INFO_F1 0xD44 186 #define RK3568_VP1_DSP_HTOTAL_HS_END 0xD48 187 #define RK3568_VP1_DSP_HACT_ST_END 0xD4C 188 #define RK3568_VP1_DSP_VTOTAL_VS_END 0xD50 189 #define RK3568_VP1_DSP_VACT_ST_END 0xD54 190 #define RK3568_VP1_DSP_VS_ST_END_F1 0xD58 191 #define RK3568_VP1_DSP_VACT_ST_END_F1 0xD5C 192 193 #define RK3568_VP2_DSP_CTRL 0xE00 194 #define RK3568_VP2_MIPI_CTRL 0xE04 195 #define RK3568_VP2_COLOR_BAR_CTRL 0xE08 196 #define RK3568_VP2_PRE_SCAN_HTIMING 0xE30 197 #define RK3568_VP2_POST_DSP_HACT_INFO 0xE34 198 #define RK3568_VP2_POST_DSP_VACT_INFO 0xE38 199 #define RK3568_VP2_POST_SCL_FACTOR_YRGB 0xE3C 200 #define RK3568_VP2_POST_SCL_CTRL 0xE40 201 #define RK3568_VP2_DSP_HACT_INFO 0xE34 202 #define RK3568_VP2_DSP_VACT_INFO 0xE38 203 #define RK3568_VP2_POST_DSP_VACT_INFO_F1 0xE44 204 #define RK3568_VP2_DSP_HTOTAL_HS_END 0xE48 205 #define RK3568_VP2_DSP_HACT_ST_END 0xE4C 206 #define RK3568_VP2_DSP_VTOTAL_VS_END 0xE50 207 #define RK3568_VP2_DSP_VACT_ST_END 0xE54 208 #define RK3568_VP2_DSP_VS_ST_END_F1 0xE58 209 #define RK3568_VP2_DSP_VACT_ST_END_F1 0xE5C 210 211 /* Cluster0 register definition */ 212 #define RK3568_CLUSTER0_WIN0_CTRL0 0x1000 213 #define RK3568_CLUSTER0_WIN0_CTRL1 0x1004 214 #define RK3568_CLUSTER0_WIN0_YRGB_MST 0x1010 215 #define RK3568_CLUSTER0_WIN0_CBR_MST 0x1014 216 #define RK3568_CLUSTER0_WIN0_VIR 0x1018 217 #define RK3568_CLUSTER0_WIN0_ACT_INFO 0x1020 218 #define RK3568_CLUSTER0_WIN0_DSP_INFO 0x1024 219 #define RK3568_CLUSTER0_WIN0_DSP_ST 0x1028 220 #define RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB 0x1030 221 #define RK3568_CLUSTER0_WIN0_AFBCD_ROTATE_MODE 0x1054 222 #define RK3568_CLUSTER0_WIN0_AFBCD_HDR_PTR 0x1058 223 #define RK3568_CLUSTER0_WIN0_AFBCD_VIR_WIDTH 0x105C 224 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_SIZE 0x1060 225 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_OFFSET 0x1064 226 #define RK3568_CLUSTER0_WIN0_AFBCD_DSP_OFFSET 0x1068 227 #define RK3568_CLUSTER0_WIN0_AFBCD_CTRL 0x106C 228 229 #define RK3568_CLUSTER0_WIN1_CTRL0 0x1080 230 #define RK3568_CLUSTER0_WIN1_CTRL1 0x1084 231 #define RK3568_CLUSTER0_WIN1_YRGB_MST 0x1090 232 #define RK3568_CLUSTER0_WIN1_CBR_MST 0x1094 233 #define RK3568_CLUSTER0_WIN1_VIR 0x1098 234 #define RK3568_CLUSTER0_WIN1_ACT_INFO 0x10A0 235 #define RK3568_CLUSTER0_WIN1_DSP_INFO 0x10A4 236 #define RK3568_CLUSTER0_WIN1_DSP_ST 0x10A8 237 #define RK3568_CLUSTER0_WIN1_SCL_FACTOR_YRGB 0x10B0 238 #define RK3568_CLUSTER0_WIN1_AFBCD_ROTATE_MODE 0x10D4 239 #define RK3568_CLUSTER0_WIN1_AFBCD_HDR_PTR 0x10D8 240 #define RK3568_CLUSTER0_WIN1_AFBCD_VIR_WIDTH 0x10DC 241 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_SIZE 0x10E0 242 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_OFFSET 0x10E4 243 #define RK3568_CLUSTER0_WIN1_AFBCD_DSP_OFFSET 0x10E8 244 #define RK3568_CLUSTER0_WIN1_AFBCD_CTRL 0x10EC 245 246 #define RK3568_CLUSTER0_CTRL 0x1100 247 248 #define RK3568_CLUSTER1_WIN0_CTRL0 0x1200 249 #define RK3568_CLUSTER1_WIN0_CTRL1 0x1204 250 #define RK3568_CLUSTER1_WIN0_YRGB_MST 0x1210 251 #define RK3568_CLUSTER1_WIN0_CBR_MST 0x1214 252 #define RK3568_CLUSTER1_WIN0_VIR 0x1218 253 #define RK3568_CLUSTER1_WIN0_ACT_INFO 0x1220 254 #define RK3568_CLUSTER1_WIN0_DSP_INFO 0x1224 255 #define RK3568_CLUSTER1_WIN0_DSP_ST 0x1228 256 #define RK3568_CLUSTER1_WIN0_SCL_FACTOR_YRGB 0x1230 257 #define RK3568_CLUSTER1_WIN0_AFBCD_ROTATE_MODE 0x1254 258 #define RK3568_CLUSTER1_WIN0_AFBCD_HDR_PTR 0x1258 259 #define RK3568_CLUSTER1_WIN0_AFBCD_VIR_WIDTH 0x125C 260 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_SIZE 0x1260 261 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_OFFSET 0x1264 262 #define RK3568_CLUSTER1_WIN0_AFBCD_DSP_OFFSET 0x1268 263 #define RK3568_CLUSTER1_WIN0_AFBCD_CTRL 0x126C 264 265 #define RK3568_CLUSTER1_WIN1_CTRL0 0x1280 266 #define RK3568_CLUSTER1_WIN1_CTRL1 0x1284 267 #define RK3568_CLUSTER1_WIN1_YRGB_MST 0x1290 268 #define RK3568_CLUSTER1_WIN1_CBR_MST 0x1294 269 #define RK3568_CLUSTER1_WIN1_VIR 0x1298 270 #define RK3568_CLUSTER1_WIN1_ACT_INFO 0x12A0 271 #define RK3568_CLUSTER1_WIN1_DSP_INFO 0x12A4 272 #define RK3568_CLUSTER1_WIN1_DSP_ST 0x12A8 273 #define RK3568_CLUSTER1_WIN1_SCL_FACTOR_YRGB 0x12B0 274 #define RK3568_CLUSTER1_WIN1_AFBCD_ROTATE_MODE 0x12D4 275 #define RK3568_CLUSTER1_WIN1_AFBCD_HDR_PTR 0x12D8 276 #define RK3568_CLUSTER1_WIN1_AFBCD_VIR_WIDTH 0x12DC 277 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_SIZE 0x12E0 278 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_OFFSET 0x12E4 279 #define RK3568_CLUSTER1_WIN1_AFBCD_DSP_OFFSET 0x12E8 280 #define RK3568_CLUSTER1_WIN1_AFBCD_CTRL 0x12EC 281 282 #define RK3568_CLUSTER1_CTRL 0x1300 283 284 /* Esmart register definition */ 285 #define RK3568_ESMART0_CTRL0 0x1800 286 #define RGB2YUV_EN_SHIFT 1 287 #define CSC_MODE_SHIFT 2 288 #define CSC_MODE_MASK 0x3 289 290 #define RK3568_ESMART0_CTRL1 0x1804 291 #define YMIRROR_EN_SHIFT 31 292 #define RK3568_ESMART0_REGION0_CTRL 0x1810 293 #define REGION0_RB_SWAP_SHIFT 14 294 #define WIN_EN_SHIFT 0 295 #define WIN_FORMAT_MASK 0x1f 296 #define WIN_FORMAT_SHIFT 1 297 298 #define RK3568_ESMART0_REGION0_YRGB_MST 0x1814 299 #define RK3568_ESMART0_REGION0_CBR_MST 0x1818 300 #define RK3568_ESMART0_REGION0_VIR 0x181C 301 #define RK3568_ESMART0_REGION0_ACT_INFO 0x1820 302 #define RK3568_ESMART0_REGION0_DSP_INFO 0x1824 303 #define RK3568_ESMART0_REGION0_DSP_ST 0x1828 304 #define RK3568_ESMART0_REGION0_SCL_CTRL 0x1830 305 #define RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB 0x1834 306 #define RK3568_ESMART0_REGION0_SCL_FACTOR_CBR 0x1838 307 #define RK3568_ESMART0_REGION0_SCL_OFFSET 0x183C 308 #define RK3568_ESMART0_REGION1_CTRL 0x1840 309 #define RK3568_ESMART0_REGION1_YRGB_MST 0x1844 310 #define RK3568_ESMART0_REGION1_CBR_MST 0x1848 311 #define RK3568_ESMART0_REGION1_VIR 0x184C 312 #define RK3568_ESMART0_REGION1_ACT_INFO 0x1850 313 #define RK3568_ESMART0_REGION1_DSP_INFO 0x1854 314 #define RK3568_ESMART0_REGION1_DSP_ST 0x1858 315 #define RK3568_ESMART0_REGION1_SCL_CTRL 0x1860 316 #define RK3568_ESMART0_REGION1_SCL_FACTOR_YRGB 0x1864 317 #define RK3568_ESMART0_REGION1_SCL_FACTOR_CBR 0x1868 318 #define RK3568_ESMART0_REGION1_SCL_OFFSET 0x186C 319 #define RK3568_ESMART0_REGION2_CTRL 0x1870 320 #define RK3568_ESMART0_REGION2_YRGB_MST 0x1874 321 #define RK3568_ESMART0_REGION2_CBR_MST 0x1878 322 #define RK3568_ESMART0_REGION2_VIR 0x187C 323 #define RK3568_ESMART0_REGION2_ACT_INFO 0x1880 324 #define RK3568_ESMART0_REGION2_DSP_INFO 0x1884 325 #define RK3568_ESMART0_REGION2_DSP_ST 0x1888 326 #define RK3568_ESMART0_REGION2_SCL_CTRL 0x1890 327 #define RK3568_ESMART0_REGION2_SCL_FACTOR_YRGB 0x1894 328 #define RK3568_ESMART0_REGION2_SCL_FACTOR_CBR 0x1898 329 #define RK3568_ESMART0_REGION2_SCL_OFFSET 0x189C 330 #define RK3568_ESMART0_REGION3_CTRL 0x18A0 331 #define RK3568_ESMART0_REGION3_YRGB_MST 0x18A4 332 #define RK3568_ESMART0_REGION3_CBR_MST 0x18A8 333 #define RK3568_ESMART0_REGION3_VIR 0x18AC 334 #define RK3568_ESMART0_REGION3_ACT_INFO 0x18B0 335 #define RK3568_ESMART0_REGION3_DSP_INFO 0x18B4 336 #define RK3568_ESMART0_REGION3_DSP_ST 0x18B8 337 #define RK3568_ESMART0_REGION3_SCL_CTRL 0x18C0 338 #define RK3568_ESMART0_REGION3_SCL_FACTOR_YRGB 0x18C4 339 #define RK3568_ESMART0_REGION3_SCL_FACTOR_CBR 0x18C8 340 #define RK3568_ESMART0_REGION3_SCL_OFFSET 0x18CC 341 342 #define RK3568_ESMART1_CTRL0 0x1A00 343 #define RK3568_ESMART1_CTRL1 0x1A04 344 #define RK3568_ESMART1_REGION0_CTRL 0x1A10 345 #define RK3568_ESMART1_REGION0_YRGB_MST 0x1A14 346 #define RK3568_ESMART1_REGION0_CBR_MST 0x1A18 347 #define RK3568_ESMART1_REGION0_VIR 0x1A1C 348 #define RK3568_ESMART1_REGION0_ACT_INFO 0x1A20 349 #define RK3568_ESMART1_REGION0_DSP_INFO 0x1A24 350 #define RK3568_ESMART1_REGION0_DSP_ST 0x1A28 351 #define RK3568_ESMART1_REGION0_SCL_CTRL 0x1A30 352 #define RK3568_ESMART1_REGION0_SCL_FACTOR_YRGB 0x1A34 353 #define RK3568_ESMART1_REGION0_SCL_FACTOR_CBR 0x1A38 354 #define RK3568_ESMART1_REGION0_SCL_OFFSET 0x1A3C 355 #define RK3568_ESMART1_REGION1_CTRL 0x1A40 356 #define RK3568_ESMART1_REGION1_YRGB_MST 0x1A44 357 #define RK3568_ESMART1_REGION1_CBR_MST 0x1A48 358 #define RK3568_ESMART1_REGION1_VIR 0x1A4C 359 #define RK3568_ESMART1_REGION1_ACT_INFO 0x1A50 360 #define RK3568_ESMART1_REGION1_DSP_INFO 0x1A54 361 #define RK3568_ESMART1_REGION1_DSP_ST 0x1A58 362 #define RK3568_ESMART1_REGION1_SCL_CTRL 0x1A60 363 #define RK3568_ESMART1_REGION1_SCL_FACTOR_YRGB 0x1A64 364 #define RK3568_ESMART1_REGION1_SCL_FACTOR_CBR 0x1A68 365 #define RK3568_ESMART1_REGION1_SCL_OFFSET 0x1A6C 366 #define RK3568_ESMART1_REGION2_CTRL 0x1A70 367 #define RK3568_ESMART1_REGION2_YRGB_MST 0x1A74 368 #define RK3568_ESMART1_REGION2_CBR_MST 0x1A78 369 #define RK3568_ESMART1_REGION2_VIR 0x1A7C 370 #define RK3568_ESMART1_REGION2_ACT_INFO 0x1A80 371 #define RK3568_ESMART1_REGION2_DSP_INFO 0x1A84 372 #define RK3568_ESMART1_REGION2_DSP_ST 0x1A88 373 #define RK3568_ESMART1_REGION2_SCL_CTRL 0x1A90 374 #define RK3568_ESMART1_REGION2_SCL_FACTOR_YRGB 0x1A94 375 #define RK3568_ESMART1_REGION2_SCL_FACTOR_CBR 0x1A98 376 #define RK3568_ESMART1_REGION2_SCL_OFFSET 0x1A9C 377 #define RK3568_ESMART1_REGION3_CTRL 0x1AA0 378 #define RK3568_ESMART1_REGION3_YRGB_MST 0x1AA4 379 #define RK3568_ESMART1_REGION3_CBR_MST 0x1AA8 380 #define RK3568_ESMART1_REGION3_VIR 0x1AAC 381 #define RK3568_ESMART1_REGION3_ACT_INFO 0x1AB0 382 #define RK3568_ESMART1_REGION3_DSP_INFO 0x1AB4 383 #define RK3568_ESMART1_REGION3_DSP_ST 0x1AB8 384 #define RK3568_ESMART1_REGION3_SCL_CTRL 0x1AC0 385 #define RK3568_ESMART1_REGION3_SCL_FACTOR_YRGB 0x1AC4 386 #define RK3568_ESMART1_REGION3_SCL_FACTOR_CBR 0x1AC8 387 #define RK3568_ESMART1_REGION3_SCL_OFFSET 0x1ACC 388 389 #define RK3568_SMART0_CTRL0 0x1C00 390 #define RK3568_SMART0_CTRL1 0x1C04 391 #define RK3568_SMART0_REGION0_CTRL 0x1C10 392 #define RK3568_SMART0_REGION0_YRGB_MST 0x1C14 393 #define RK3568_SMART0_REGION0_CBR_MST 0x1C18 394 #define RK3568_SMART0_REGION0_VIR 0x1C1C 395 #define RK3568_SMART0_REGION0_ACT_INFO 0x1C20 396 #define RK3568_SMART0_REGION0_DSP_INFO 0x1C24 397 #define RK3568_SMART0_REGION0_DSP_ST 0x1C28 398 #define RK3568_SMART0_REGION0_SCL_CTRL 0x1C30 399 #define RK3568_SMART0_REGION0_SCL_FACTOR_YRGB 0x1C34 400 #define RK3568_SMART0_REGION0_SCL_FACTOR_CBR 0x1C38 401 #define RK3568_SMART0_REGION0_SCL_OFFSET 0x1C3C 402 #define RK3568_SMART0_REGION1_CTRL 0x1C40 403 #define RK3568_SMART0_REGION1_YRGB_MST 0x1C44 404 #define RK3568_SMART0_REGION1_CBR_MST 0x1C48 405 #define RK3568_SMART0_REGION1_VIR 0x1C4C 406 #define RK3568_SMART0_REGION1_ACT_INFO 0x1C50 407 #define RK3568_SMART0_REGION1_DSP_INFO 0x1C54 408 #define RK3568_SMART0_REGION1_DSP_ST 0x1C58 409 #define RK3568_SMART0_REGION1_SCL_CTRL 0x1C60 410 #define RK3568_SMART0_REGION1_SCL_FACTOR_YRGB 0x1C64 411 #define RK3568_SMART0_REGION1_SCL_FACTOR_CBR 0x1C68 412 #define RK3568_SMART0_REGION1_SCL_OFFSET 0x1C6C 413 #define RK3568_SMART0_REGION2_CTRL 0x1C70 414 #define RK3568_SMART0_REGION2_YRGB_MST 0x1C74 415 #define RK3568_SMART0_REGION2_CBR_MST 0x1C78 416 #define RK3568_SMART0_REGION2_VIR 0x1C7C 417 #define RK3568_SMART0_REGION2_ACT_INFO 0x1C80 418 #define RK3568_SMART0_REGION2_DSP_INFO 0x1C84 419 #define RK3568_SMART0_REGION2_DSP_ST 0x1C88 420 #define RK3568_SMART0_REGION2_SCL_CTRL 0x1C90 421 #define RK3568_SMART0_REGION2_SCL_FACTOR_YRGB 0x1C94 422 #define RK3568_SMART0_REGION2_SCL_FACTOR_CBR 0x1C98 423 #define RK3568_SMART0_REGION2_SCL_OFFSET 0x1C9C 424 #define RK3568_SMART0_REGION3_CTRL 0x1CA0 425 #define RK3568_SMART0_REGION3_YRGB_MST 0x1CA4 426 #define RK3568_SMART0_REGION3_CBR_MST 0x1CA8 427 #define RK3568_SMART0_REGION3_VIR 0x1CAC 428 #define RK3568_SMART0_REGION3_ACT_INFO 0x1CB0 429 #define RK3568_SMART0_REGION3_DSP_INFO 0x1CB4 430 #define RK3568_SMART0_REGION3_DSP_ST 0x1CB8 431 #define RK3568_SMART0_REGION3_SCL_CTRL 0x1CC0 432 #define RK3568_SMART0_REGION3_SCL_FACTOR_YRGB 0x1CC4 433 #define RK3568_SMART0_REGION3_SCL_FACTOR_CBR 0x1CC8 434 #define RK3568_SMART0_REGION3_SCL_OFFSET 0x1CCC 435 436 #define RK3568_SMART1_CTRL0 0x1E00 437 #define RK3568_SMART1_CTRL1 0x1E04 438 #define RK3568_SMART1_REGION0_CTRL 0x1E10 439 #define RK3568_SMART1_REGION0_YRGB_MST 0x1E14 440 #define RK3568_SMART1_REGION0_CBR_MST 0x1E18 441 #define RK3568_SMART1_REGION0_VIR 0x1E1C 442 #define RK3568_SMART1_REGION0_ACT_INFO 0x1E20 443 #define RK3568_SMART1_REGION0_DSP_INFO 0x1E24 444 #define RK3568_SMART1_REGION0_DSP_ST 0x1E28 445 #define RK3568_SMART1_REGION0_SCL_CTRL 0x1E30 446 #define RK3568_SMART1_REGION0_SCL_FACTOR_YRGB 0x1E34 447 #define RK3568_SMART1_REGION0_SCL_FACTOR_CBR 0x1E38 448 #define RK3568_SMART1_REGION0_SCL_OFFSET 0x1E3C 449 #define RK3568_SMART1_REGION1_CTRL 0x1E40 450 #define RK3568_SMART1_REGION1_YRGB_MST 0x1E44 451 #define RK3568_SMART1_REGION1_CBR_MST 0x1E48 452 #define RK3568_SMART1_REGION1_VIR 0x1E4C 453 #define RK3568_SMART1_REGION1_ACT_INFO 0x1E50 454 #define RK3568_SMART1_REGION1_DSP_INFO 0x1E54 455 #define RK3568_SMART1_REGION1_DSP_ST 0x1E58 456 #define RK3568_SMART1_REGION1_SCL_CTRL 0x1E60 457 #define RK3568_SMART1_REGION1_SCL_FACTOR_YRGB 0x1E64 458 #define RK3568_SMART1_REGION1_SCL_FACTOR_CBR 0x1E68 459 #define RK3568_SMART1_REGION1_SCL_OFFSET 0x1E6C 460 #define RK3568_SMART1_REGION2_CTRL 0x1E70 461 #define RK3568_SMART1_REGION2_YRGB_MST 0x1E74 462 #define RK3568_SMART1_REGION2_CBR_MST 0x1E78 463 #define RK3568_SMART1_REGION2_VIR 0x1E7C 464 #define RK3568_SMART1_REGION2_ACT_INFO 0x1E80 465 #define RK3568_SMART1_REGION2_DSP_INFO 0x1E84 466 #define RK3568_SMART1_REGION2_DSP_ST 0x1E88 467 #define RK3568_SMART1_REGION2_SCL_CTRL 0x1E90 468 #define RK3568_SMART1_REGION2_SCL_FACTOR_YRGB 0x1E94 469 #define RK3568_SMART1_REGION2_SCL_FACTOR_CBR 0x1E98 470 #define RK3568_SMART1_REGION2_SCL_OFFSET 0x1E9C 471 #define RK3568_SMART1_REGION3_CTRL 0x1EA0 472 #define RK3568_SMART1_REGION3_YRGB_MST 0x1EA4 473 #define RK3568_SMART1_REGION3_CBR_MST 0x1EA8 474 #define RK3568_SMART1_REGION3_VIR 0x1EAC 475 #define RK3568_SMART1_REGION3_ACT_INFO 0x1EB0 476 #define RK3568_SMART1_REGION3_DSP_INFO 0x1EB4 477 #define RK3568_SMART1_REGION3_DSP_ST 0x1EB8 478 #define RK3568_SMART1_REGION3_SCL_CTRL 0x1EC0 479 #define RK3568_SMART1_REGION3_SCL_FACTOR_YRGB 0x1EC4 480 #define RK3568_SMART1_REGION3_SCL_FACTOR_CBR 0x1EC8 481 #define RK3568_SMART1_REGION3_SCL_OFFSET 0x1ECC 482 483 #define RK3568_MAX_REG 0x1ED0 484 485 #define RK3568_GRF_VO_CON1 0x0364 486 #define GRF_BT656_CLK_INV_SHIFT 1 487 #define GRF_BT1120_CLK_INV_SHIFT 2 488 #define GRF_RGB_DCLK_INV_SHIFT 3 489 490 #define VOP2_LAYER_MAX 8 491 492 #define VOP_FEATURE_OUTPUT_10BIT BIT(0) 493 494 enum vop2_csc_format { 495 CSC_BT601L, 496 CSC_BT709L, 497 CSC_BT601F, 498 CSC_BT2020, 499 }; 500 501 enum vop2_pol { 502 HSYNC_POSITIVE = 0, 503 VSYNC_POSITIVE = 1, 504 DEN_NEGATIVE = 2, 505 DCLK_INVERT = 3 506 }; 507 508 #define _VOP_REG(off, _mask, _shift, _write_mask) \ 509 { \ 510 .offset = off, \ 511 .mask = _mask, \ 512 .shift = _shift, \ 513 .write_mask = _write_mask, \ 514 } 515 516 #define VOP_REG(off, _mask, _shift) \ 517 _VOP_REG(off, _mask, _shift, false) 518 enum dither_down_mode { 519 RGB888_TO_RGB565 = 0x0, 520 RGB888_TO_RGB666 = 0x1 521 }; 522 523 enum vop2_video_ports_id { 524 VOP2_VP0, 525 VOP2_VP1, 526 VOP2_VP2, 527 VOP2_VP3, 528 VOP2_VP_MAX, 529 }; 530 531 /* This define must same with kernel win phy id */ 532 enum vop2_layer_phy_id { 533 ROCKCHIP_VOP2_CLUSTER0 = 0, 534 ROCKCHIP_VOP2_CLUSTER1, 535 ROCKCHIP_VOP2_ESMART0, 536 ROCKCHIP_VOP2_ESMART1, 537 ROCKCHIP_VOP2_SMART0, 538 ROCKCHIP_VOP2_SMART1, 539 ROCKCHIP_VOP2_CLUSTER2, 540 ROCKCHIP_VOP2_CLUSTER3, 541 ROCKCHIP_VOP2_ESMART2, 542 ROCKCHIP_VOP2_ESMART3, 543 }; 544 545 struct vop2_win_data { 546 char *name; 547 u8 phys_id; 548 u8 win_sel_port_offset; 549 u8 layer_sel_win_id; 550 u32 reg_offset; 551 }; 552 553 struct vop2_vp_data { 554 u32 feature; 555 u8 pre_scan_max_dly; 556 struct vop_rect max_output; 557 }; 558 559 struct vop2_vp_plane_mask { 560 u8 primary_plane_id; /* use this win to show logo */ 561 u8 attached_layers_nr; /* number layers attach to this vp */ 562 u8 attached_layers[VOP2_LAYER_MAX]; /* the layers attached to this vp */ 563 u32 plane_mask; 564 }; 565 566 struct vop2_data { 567 u32 version; 568 struct vop2_vp_data *vp_data; 569 struct vop2_win_data *win_data; 570 struct vop2_vp_plane_mask *plane_mask; 571 u8 nr_vps; 572 u8 nr_layers; 573 u8 nr_mixers; 574 u8 nr_gammas; 575 }; 576 577 struct vop2 { 578 u32 *regsbak; 579 void *regs; 580 void *grf; 581 u32 reg_len; 582 u32 version; 583 bool global_init; 584 const struct vop2_data *data; 585 struct vop2_vp_plane_mask vp_plane_mask[VOP2_VP_MAX]; 586 }; 587 588 static struct vop2 *rockchip_vop2; 589 590 static u8 vop2_vp_primary_plane_order[VOP2_VP_MAX] = { 591 ROCKCHIP_VOP2_SMART0, 592 ROCKCHIP_VOP2_SMART1, 593 ROCKCHIP_VOP2_ESMART1, 594 }; 595 596 static int vop2_get_primary_plane(struct vop2 *vop2, u32 plane_mask) 597 { 598 int i = 0; 599 600 for (i = 0; i < vop2->data->nr_vps; i++) { 601 if (plane_mask & BIT(vop2_vp_primary_plane_order[i])) 602 return vop2_vp_primary_plane_order[i]; 603 } 604 605 return ROCKCHIP_VOP2_SMART0; 606 } 607 608 static inline u16 scl_cal_scale(int src, int dst, int shift) 609 { 610 return ((src * 2 - 3) << (shift - 1)) / (dst - 1); 611 } 612 613 static inline u16 scl_cal_scale2(int src, int dst) 614 { 615 return ((src - 1) << 12) / (dst - 1); 616 } 617 618 static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v) 619 { 620 writel(v, vop2->regs + offset); 621 vop2->regsbak[offset >> 2] = v; 622 } 623 624 static inline u32 vop2_readl(struct vop2 *vop2, u32 offset) 625 { 626 return readl(vop2->regs + offset); 627 } 628 629 static inline void vop2_mask_write(struct vop2 *vop2, u32 offset, 630 u32 mask, u32 shift, u32 v, 631 bool write_mask) 632 { 633 if (!mask) 634 return; 635 636 if (write_mask) { 637 v = ((v & mask) << shift) | (mask << (shift + 16)); 638 } else { 639 u32 cached_val = vop2->regsbak[offset >> 2]; 640 641 v = (cached_val & ~(mask << shift)) | ((v & mask) << shift); 642 vop2->regsbak[offset >> 2] = v; 643 } 644 645 writel(v, vop2->regs + offset); 646 } 647 648 static inline void vop2_grf_writel(struct vop2 *vop, u32 offset, 649 u32 mask, u32 shift, u32 v) 650 { 651 u32 val = 0; 652 653 val = (v << shift) | (mask << (shift + 16)); 654 writel(val, vop->grf + offset); 655 } 656 657 static inline int us_to_vertical_line(struct drm_display_mode *mode, int us) 658 { 659 return us * mode->clock / mode->htotal / 1000; 660 } 661 662 static bool is_yuv_output(u32 bus_format) 663 { 664 switch (bus_format) { 665 case MEDIA_BUS_FMT_YUV8_1X24: 666 case MEDIA_BUS_FMT_YUV10_1X30: 667 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 668 case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 669 return true; 670 default: 671 return false; 672 } 673 } 674 675 static int vop2_convert_csc_mode(int csc_mode) 676 { 677 switch (csc_mode) { 678 case V4L2_COLORSPACE_SMPTE170M: 679 case V4L2_COLORSPACE_470_SYSTEM_M: 680 case V4L2_COLORSPACE_470_SYSTEM_BG: 681 return CSC_BT601L; 682 case V4L2_COLORSPACE_REC709: 683 case V4L2_COLORSPACE_SMPTE240M: 684 case V4L2_COLORSPACE_DEFAULT: 685 return CSC_BT709L; 686 case V4L2_COLORSPACE_JPEG: 687 return CSC_BT601F; 688 case V4L2_COLORSPACE_BT2020: 689 return CSC_BT2020; 690 default: 691 return CSC_BT709L; 692 } 693 } 694 695 static bool is_uv_swap(u32 bus_format, u32 output_mode) 696 { 697 /* 698 * FIXME: 699 * 700 * There is no media type for YUV444 output, 701 * so when out_mode is AAAA or P888, assume output is YUV444 on 702 * yuv format. 703 * 704 * From H/W testing, YUV444 mode need a rb swap. 705 */ 706 if ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 || 707 bus_format == MEDIA_BUS_FMT_YUV10_1X30) && 708 (output_mode == ROCKCHIP_OUT_MODE_AAAA || 709 output_mode == ROCKCHIP_OUT_MODE_P888)) 710 return true; 711 else 712 return false; 713 } 714 715 static inline bool is_hot_plug_devices(int output_type) 716 { 717 switch (output_type) { 718 case DRM_MODE_CONNECTOR_HDMIA: 719 case DRM_MODE_CONNECTOR_HDMIB: 720 case DRM_MODE_CONNECTOR_TV: 721 case DRM_MODE_CONNECTOR_DisplayPort: 722 case DRM_MODE_CONNECTOR_VGA: 723 case DRM_MODE_CONNECTOR_Unknown: 724 return true; 725 default: 726 return false; 727 } 728 } 729 730 static int rockchip_vop2_gamma_lut_init(struct vop2 *vop2, 731 struct display_state *state) 732 { 733 struct connector_state *conn_state = &state->conn_state; 734 struct crtc_state *cstate = &state->crtc_state; 735 struct resource gamma_res; 736 fdt_size_t lut_size; 737 int i, lut_len, ret = 0; 738 u32 *lut_regs; 739 u32 *lut_val; 740 u32 r, g, b; 741 u32 vp_offset = cstate->crtc_id * 0x100; 742 struct base2_disp_info *disp_info = conn_state->disp_info; 743 static int gamma_lut_en_num = 1; 744 745 if (gamma_lut_en_num > vop2->data->nr_gammas) { 746 printf("warn: only %d vp support gamma\n", vop2->data->nr_gammas); 747 return 0; 748 } 749 750 if (!disp_info) 751 return 0; 752 753 if (!disp_info->gamma_lut_data.size) 754 return 0; 755 756 ret = ofnode_read_resource_byname(cstate->node, "gamma_lut", &gamma_res); 757 if (ret) 758 printf("failed to get gamma lut res\n"); 759 lut_regs = (u32 *)gamma_res.start; 760 lut_size = gamma_res.end - gamma_res.start + 1; 761 if (lut_regs == (u32 *)FDT_ADDR_T_NONE) { 762 printf("failed to get gamma lut register\n"); 763 return 0; 764 } 765 lut_len = lut_size / 4; 766 if (lut_len != 256 && lut_len != 1024) { 767 printf("Warning: unsupport gamma lut table[%d]\n", lut_len); 768 return 0; 769 } 770 lut_val = (u32 *)calloc(1, lut_size); 771 for (i = 0; i < lut_len; i++) { 772 r = disp_info->gamma_lut_data.lred[i] * (lut_len - 1) / 0xffff; 773 g = disp_info->gamma_lut_data.lgreen[i] * (lut_len - 1) / 0xffff; 774 b = disp_info->gamma_lut_data.lblue[i] * (lut_len - 1) / 0xffff; 775 776 lut_val[i] = b * lut_len * lut_len + g * lut_len + r; 777 } 778 779 for (i = 0; i < lut_len; i++) 780 writel(lut_val[i], lut_regs + i); 781 782 vop2_mask_write(vop2, RK3568_SYS_LUT_PORT_SEL, 783 GAMMA_PORT_SEL_MASK, GAMMA_PORT_SEL_SHIFT, 784 cstate->crtc_id , false); 785 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 786 EN_MASK, DSP_LUT_EN_SHIFT, 1, false); 787 gamma_lut_en_num++; 788 789 return 0; 790 } 791 792 static int rockchip_vop2_cubic_lut_init(struct vop2 *vop2, 793 struct display_state *state) 794 { 795 struct connector_state *conn_state = &state->conn_state; 796 struct crtc_state *cstate = &state->crtc_state; 797 int i, cubic_lut_len; 798 u32 vp_offset = cstate->crtc_id * 0x100; 799 struct base2_disp_info *disp_info = conn_state->disp_info; 800 struct base2_cubic_lut_data *lut = &conn_state->disp_info->cubic_lut_data; 801 u32 *cubic_lut_addr; 802 803 if (!disp_info || CONFIG_ROCKCHIP_CUBIC_LUT_SIZE == 0) 804 return 0; 805 806 if (!disp_info->cubic_lut_data.size) 807 return 0; 808 809 cubic_lut_addr = (u32 *)get_cubic_lut_buffer(cstate->crtc_id); 810 cubic_lut_len = disp_info->cubic_lut_data.size; 811 812 for (i = 0; i < cubic_lut_len / 2; i++) { 813 *cubic_lut_addr++ = ((lut->lred[2 * i]) & 0xfff) + 814 ((lut->lgreen[2 * i] & 0xfff) << 12) + 815 ((lut->lblue[2 * i] & 0xff) << 24); 816 *cubic_lut_addr++ = ((lut->lblue[2 * i] & 0xf00) >> 8) + 817 ((lut->lred[2 * i + 1] & 0xfff) << 4) + 818 ((lut->lgreen[2 * i + 1] & 0xfff) << 16) + 819 ((lut->lblue[2 * i + 1] & 0xf) << 28); 820 *cubic_lut_addr++ = (lut->lblue[2 * i + 1] & 0xff0) >> 4; 821 *cubic_lut_addr++ = 0; 822 } 823 824 if (cubic_lut_len % 2) { 825 *cubic_lut_addr++ = (lut->lred[2 * i] & 0xfff) + 826 ((lut->lgreen[2 * i] & 0xfff) << 12) + 827 ((lut->lblue[2 * i] & 0xff) << 24); 828 *cubic_lut_addr++ = (lut->lblue[2 * i] & 0xf00) >> 8; 829 *cubic_lut_addr++ = 0; 830 *cubic_lut_addr = 0; 831 } 832 833 vop2_writel(vop2, RK3568_VP0_3D_LUT_MST + vp_offset, 834 get_cubic_lut_buffer(cstate->crtc_id)); 835 vop2_mask_write(vop2, RK3568_SYS_AXI_LUT_CTRL, 836 EN_MASK, LUT_DMA_EN_SHIFT, 1, false); 837 vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset, 838 EN_MASK, VP0_3D_LUT_EN_SHIFT, 1, false); 839 vop2_mask_write(vop2, RK3568_VP0_3D_LUT_CTRL + vp_offset, 840 EN_MASK, VP0_3D_LUT_UPDATE_SHIFT, 1, false); 841 842 return 0; 843 } 844 845 static void vop2_post_config(struct display_state *state, struct vop2 *vop2) 846 { 847 struct connector_state *conn_state = &state->conn_state; 848 struct drm_display_mode *mode = &conn_state->mode; 849 struct crtc_state *cstate = &state->crtc_state; 850 u32 vp_offset = (cstate->crtc_id * 0x100); 851 u16 vtotal = mode->crtc_vtotal; 852 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 853 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 854 u16 hdisplay = mode->crtc_hdisplay; 855 u16 vdisplay = mode->crtc_vdisplay; 856 u16 hsize = 857 hdisplay * (conn_state->overscan.left_margin + 858 conn_state->overscan.right_margin) / 200; 859 u16 vsize = 860 vdisplay * (conn_state->overscan.top_margin + 861 conn_state->overscan.bottom_margin) / 200; 862 u16 hact_end, vact_end; 863 u32 val; 864 u32 bg_ovl_dly, bg_dly, pre_scan_dly; 865 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 866 867 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 868 vsize = round_down(vsize, 2); 869 870 hact_st += hdisplay * (100 - conn_state->overscan.left_margin) / 200; 871 hact_end = hact_st + hsize; 872 val = hact_st << 16; 873 val |= hact_end; 874 875 vop2_writel(vop2, RK3568_VP0_POST_DSP_HACT_INFO + vp_offset, val); 876 vact_st += vdisplay * (100 - conn_state->overscan.top_margin) / 200; 877 vact_end = vact_st + vsize; 878 val = vact_st << 16; 879 val |= vact_end; 880 vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO + vp_offset, val); 881 val = scl_cal_scale2(vdisplay, vsize) << 16; 882 val |= scl_cal_scale2(hdisplay, hsize); 883 vop2_writel(vop2, RK3568_VP0_POST_SCL_FACTOR_YRGB + vp_offset, val); 884 #define POST_HORIZONTAL_SCALEDOWN_EN(x) ((x) << 0) 885 #define POST_VERTICAL_SCALEDOWN_EN(x) ((x) << 1) 886 vop2_writel(vop2, RK3568_VP0_POST_SCL_CTRL + vp_offset, 887 POST_HORIZONTAL_SCALEDOWN_EN(hdisplay != hsize) | 888 POST_VERTICAL_SCALEDOWN_EN(vdisplay != vsize)); 889 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 890 u16 vact_st_f1 = vtotal + vact_st + 1; 891 u16 vact_end_f1 = vact_st_f1 + vsize; 892 893 val = vact_st_f1 << 16 | vact_end_f1; 894 vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO_F1 + vp_offset, val); 895 } 896 897 bg_ovl_dly = cstate->crtc->vps[cstate->crtc_id].bg_ovl_dly; 898 bg_dly = vop2->data->vp_data[cstate->crtc_id].pre_scan_max_dly; 899 bg_dly -= bg_ovl_dly; 900 pre_scan_dly = bg_dly + (hdisplay >> 1) - 1; 901 pre_scan_dly = (pre_scan_dly << 16) | hsync_len; 902 vop2_mask_write(vop2, RK3568_VP0_BG_MIX_CTRL + cstate->crtc_id * 4, 903 BG_MIX_CTRL_MASK, BG_MIX_CTRL_SHIFT, bg_dly, false); 904 vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + vp_offset, pre_scan_dly); 905 } 906 907 static void vop2_global_initial(struct vop2 *vop2, struct display_state *state) 908 { 909 struct crtc_state *cstate = &state->crtc_state; 910 int i, j, port_mux = 0, total_used_layer = 0; 911 u8 shift = 0; 912 int layer_phy_id = 0; 913 u32 layer_nr = 0; 914 struct vop2_win_data *win_data; 915 struct vop2_vp_plane_mask *plane_mask; 916 917 if (vop2->global_init) 918 return; 919 920 /* OTP must enable at the first time, otherwise mirror layer register is error */ 921 if (soc_is_rk3566()) 922 vop2_mask_write(vop2, RK3568_SYS_OTP_WIN_EN, EN_MASK, 923 OTP_WIN_EN_SHIFT, 1, false); 924 925 memcpy(vop2->regsbak, vop2->regs, vop2->reg_len); 926 vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, 927 OVL_PORT_MUX_REG_DONE_IMD_SHIFT, 1, false); 928 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 929 IF_CTRL_REG_DONE_IMD_SHIFT, 1, false); 930 931 if (cstate->crtc->assign_plane) {/* dts assign plane */ 932 u32 plane_mask; 933 int primary_plane_id; 934 935 for (i = 0; i < vop2->data->nr_vps; i++) { 936 plane_mask = cstate->crtc->vps[i].plane_mask; 937 vop2->vp_plane_mask[i].plane_mask = plane_mask; 938 layer_nr = hweight32(plane_mask); /* use bitmap to store plane mask */ 939 vop2->vp_plane_mask[i].attached_layers_nr = layer_nr; 940 primary_plane_id = vop2_get_primary_plane(vop2, plane_mask); 941 vop2->vp_plane_mask[i].primary_plane_id = primary_plane_id; 942 vop2->vp_plane_mask[i].plane_mask = plane_mask; 943 944 /* plane mask[bitmap] convert into layer phy id[enum vop2_layer_phy_id]*/ 945 for (j = 0; j < layer_nr; j++) { 946 vop2->vp_plane_mask[i].attached_layers[j] = ffs(plane_mask) - 1; 947 plane_mask &= ~BIT(vop2->vp_plane_mask[i].attached_layers[j]); 948 } 949 } 950 } else {/* need soft assign plane mask */ 951 /* find the first unplug devices and set it as main display */ 952 int main_vp_index = -1; 953 int active_vp_num = 0; 954 955 for (i = 0; i < vop2->data->nr_vps; i++) { 956 if (cstate->crtc->vps[i].enable) 957 active_vp_num++; 958 } 959 printf("VOP have %d active VP\n", active_vp_num); 960 961 if (soc_is_rk3566() && active_vp_num > 2) 962 printf("ERROR: rk3566 only support 2 display output!!\n"); 963 plane_mask = vop2->data->plane_mask; 964 plane_mask += (active_vp_num - 1) * VOP2_VP_MAX; 965 966 for (i = 0; i < vop2->data->nr_vps; i++) { 967 if (!is_hot_plug_devices(cstate->crtc->vps[i].output_type)) { 968 vop2->vp_plane_mask[i] = plane_mask[0]; /* the first store main display plane mask*/ 969 main_vp_index = i; 970 } 971 } 972 973 /* if no find unplug devices, use vp0 as main display */ 974 if (main_vp_index < 0) { 975 main_vp_index = 0; 976 vop2->vp_plane_mask[0] = plane_mask[0]; 977 } 978 979 j = 1; /* plane_mask[0] store main display, so we from plane_mask[1] */ 980 981 /* init other display except main display */ 982 for (i = 0; i < vop2->data->nr_vps; i++) { 983 if (i == main_vp_index || !cstate->crtc->vps[i].enable) /* main display or no connect devices */ 984 continue; 985 vop2->vp_plane_mask[i] = plane_mask[j++]; 986 } 987 988 /* store plane mask for vop2_fixup_dts */ 989 for (i = 0; i < vop2->data->nr_vps; i++) { 990 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 991 for (j = 0; j < layer_nr; j++) { 992 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 993 vop2->vp_plane_mask[i].plane_mask |= BIT(layer_phy_id); 994 } 995 } 996 } 997 998 for (i = 0; i < vop2->data->nr_vps; i++) { 999 printf("vp%d have layer nr:%d[", i, vop2->vp_plane_mask[i].attached_layers_nr); 1000 for (j = 0; j < vop2->vp_plane_mask[i].attached_layers_nr; j++) 1001 printf("%d ", vop2->vp_plane_mask[i].attached_layers[j]); 1002 printf("], primary plane: %d\n", vop2->vp_plane_mask[i].primary_plane_id); 1003 } 1004 1005 shift = 0; 1006 /* layer sel win id */ 1007 for (i = 0; i < vop2->data->nr_vps; i++) { 1008 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 1009 for (j = 0; j < layer_nr; j++) { 1010 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 1011 win_data = &vop2->data->win_data[layer_phy_id]; 1012 vop2_mask_write(vop2, RK3568_OVL_LAYER_SEL, LAYER_SEL_MASK, 1013 shift, win_data->layer_sel_win_id, false); 1014 shift += 4; 1015 } 1016 } 1017 1018 /* win sel port */ 1019 for (i = 0; i < vop2->data->nr_vps; i++) { 1020 layer_nr = vop2->vp_plane_mask[i].attached_layers_nr; 1021 for (j = 0; j < layer_nr; j++) { 1022 if (!cstate->crtc->vps[i].enable) 1023 continue; 1024 layer_phy_id = vop2->vp_plane_mask[i].attached_layers[j]; 1025 win_data = &vop2->data->win_data[layer_phy_id]; 1026 shift = win_data->win_sel_port_offset * 2; 1027 vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, LAYER_SEL_PORT_MASK, 1028 LAYER_SEL_PORT_SHIFT + shift, i, false); 1029 } 1030 } 1031 1032 /** 1033 * port mux config 1034 */ 1035 for (i = 0; i < vop2->data->nr_vps; i++) { 1036 shift = i * 4; 1037 if (cstate->crtc->vps[i].enable) { 1038 total_used_layer += vop2->vp_plane_mask[i].attached_layers_nr; 1039 port_mux = total_used_layer - 1; 1040 } else { 1041 port_mux = 8; 1042 } 1043 1044 if (i == vop2->data->nr_vps - 1) 1045 port_mux = vop2->data->nr_mixers; 1046 1047 cstate->crtc->vps[i].bg_ovl_dly = (vop2->data->nr_mixers - port_mux) << 1; 1048 vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, PORT_MUX_MASK, 1049 PORT_MUX_SHIFT + shift, port_mux, false); 1050 } 1051 1052 vop2_writel(vop2, RK3568_AUTO_GATING_CTRL, 0); 1053 1054 vop2->global_init = true; 1055 } 1056 1057 static int vop2_initial(struct vop2 *vop2, struct display_state *state) 1058 { 1059 struct crtc_state *cstate = &state->crtc_state; 1060 struct connector_state *conn_state = &state->conn_state; 1061 struct drm_display_mode *mode = &conn_state->mode; 1062 char dclk_name[9]; 1063 struct clk dclk; 1064 int ret; 1065 1066 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 1067 ret = clk_set_defaults(cstate->dev); 1068 if (ret) 1069 debug("%s clk_set_defaults failed %d\n", __func__, ret); 1070 snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", cstate->crtc_id); 1071 ret = clk_get_by_name(cstate->dev, dclk_name, &dclk); 1072 if (!ret) 1073 ret = clk_set_rate(&dclk, mode->clock * 1000); 1074 if (IS_ERR_VALUE(ret)) { 1075 printf("%s: Failed to set vp%d dclk[%d khz]: ret=%d\n", 1076 __func__, cstate->crtc_id, mode->clock, ret); 1077 return ret; 1078 } 1079 1080 vop2_global_initial(vop2, state); 1081 rockchip_vop2_gamma_lut_init(vop2, state); 1082 rockchip_vop2_cubic_lut_init(vop2, state); 1083 1084 return 0; 1085 } 1086 1087 /* 1088 * VOP2 have multi video ports. 1089 * video port ------- crtc 1090 */ 1091 static int rockchip_vop2_preinit(struct display_state *state) 1092 { 1093 struct crtc_state *cstate = &state->crtc_state; 1094 const struct vop2_data *vop2_data = cstate->crtc->data; 1095 1096 if (!rockchip_vop2) { 1097 rockchip_vop2 = calloc(1, sizeof(struct vop2)); 1098 if (!rockchip_vop2) 1099 return -ENOMEM; 1100 rockchip_vop2->regs = dev_read_addr_ptr(cstate->dev); 1101 rockchip_vop2->regsbak = malloc(RK3568_MAX_REG); 1102 rockchip_vop2->reg_len = RK3568_MAX_REG; 1103 rockchip_vop2->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 1104 if (rockchip_vop2->grf <= 0) 1105 printf("%s: Get syscon grf failed (ret=%p)\n", __func__, rockchip_vop2->grf); 1106 1107 rockchip_vop2->version = vop2_data->version; 1108 rockchip_vop2->data = vop2_data; 1109 } 1110 1111 cstate->private = rockchip_vop2; 1112 cstate->max_output = vop2_data->vp_data[cstate->crtc_id].max_output; 1113 cstate->feature = vop2_data->vp_data[cstate->crtc_id].feature; 1114 1115 return 0; 1116 } 1117 1118 static int rockchip_vop2_init(struct display_state *state) 1119 { 1120 struct crtc_state *cstate = &state->crtc_state; 1121 struct connector_state *conn_state = &state->conn_state; 1122 struct drm_display_mode *mode = &conn_state->mode; 1123 struct vop2 *vop2 = cstate->private; 1124 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 1125 u16 hdisplay = mode->crtc_hdisplay; 1126 u16 htotal = mode->crtc_htotal; 1127 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 1128 u16 hact_end = hact_st + hdisplay; 1129 u16 vdisplay = mode->crtc_vdisplay; 1130 u16 vtotal = mode->crtc_vtotal; 1131 u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; 1132 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 1133 u16 vact_end = vact_st + vdisplay; 1134 bool yuv_overlay = false; 1135 u32 vp_offset = (cstate->crtc_id * 0x100); 1136 u32 val; 1137 bool dclk_inv; 1138 u8 dither_down_en = 0; 1139 u8 pre_dither_down_en = 0; 1140 1141 vop2_initial(vop2, state); 1142 dclk_inv = (mode->flags & DRM_MODE_FLAG_PPIXDATA) ? 0 : 1; 1143 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 1144 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 1145 1146 if (conn_state->output_if & VOP_OUTPUT_IF_RGB) { 1147 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 1148 1, false); 1149 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 1150 RGB_MUX_SHIFT, cstate->crtc_id, false); 1151 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 1152 IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, !!dclk_inv, 1153 false); 1154 vop2_grf_writel(vop2, RK3568_GRF_VO_CON1, EN_MASK, 1155 GRF_RGB_DCLK_INV_SHIFT, !dclk_inv); 1156 } 1157 1158 if (conn_state->output_if & VOP_OUTPUT_IF_BT1120) { 1159 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 1160 1, false); 1161 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, 1162 BT1120_EN_SHIFT, 1, false); 1163 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 1164 RGB_MUX_SHIFT, cstate->crtc_id, false); 1165 vop2_grf_writel(vop2, RK3568_GRF_VO_CON1, EN_MASK, 1166 GRF_BT1120_CLK_INV_SHIFT, !dclk_inv); 1167 } 1168 1169 if (conn_state->output_if & VOP_OUTPUT_IF_BT656) { 1170 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT, 1171 1, false); 1172 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 1173 RGB_MUX_SHIFT, cstate->crtc_id, false); 1174 vop2_grf_writel(vop2, RK3568_GRF_VO_CON1, EN_MASK, 1175 GRF_BT656_CLK_INV_SHIFT, !dclk_inv); 1176 } 1177 1178 if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) { 1179 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT, 1180 1, false); 1181 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 1182 LVDS0_MUX_SHIFT, cstate->crtc_id, false); 1183 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 1184 IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, dclk_inv, false); 1185 } 1186 1187 if (conn_state->output_if & VOP_OUTPUT_IF_LVDS1) { 1188 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS1_EN_SHIFT, 1189 1, false); 1190 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 1191 LVDS1_MUX_SHIFT, cstate->crtc_id, false); 1192 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 1193 IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, dclk_inv, false); 1194 } 1195 1196 if (conn_state->output_flags & 1197 (ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE | 1198 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)) { 1199 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 1200 LVDS_DUAL_EN_SHIFT, 1, false); 1201 if (conn_state->output_flags & 1202 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 1203 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 1204 LVDS_DUAL_LEFT_RIGHT_EN_SHIFT, 1, 1205 false); 1206 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 1207 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 1208 LVDS_DUAL_SWAP_EN_SHIFT, 1, false); 1209 } 1210 1211 if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) { 1212 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT, 1213 1, false); 1214 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 1215 MIPI0_MUX_SHIFT, cstate->crtc_id, false); 1216 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 1217 IF_CRTL_MIPI_DCLK_POL_SHIT, !!dclk_inv, false); 1218 } 1219 1220 if (conn_state->output_if & VOP_OUTPUT_IF_MIPI1) { 1221 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI1_EN_SHIFT, 1222 1, false); 1223 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 1224 MIPI1_MUX_SHIFT, cstate->crtc_id, false); 1225 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 1226 IF_CRTL_MIPI_DCLK_POL_SHIT, !!dclk_inv, false); 1227 } 1228 1229 if (conn_state->output_flags & 1230 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 1231 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 1232 MIPI_DUAL_EN_SHIFT, 1, false); 1233 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 1234 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 1235 EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1, 1236 false); 1237 } 1238 1239 if (conn_state->output_if & VOP_OUTPUT_IF_eDP0) { 1240 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, EDP0_EN_SHIFT, 1241 1, false); 1242 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 1243 EDP0_MUX_SHIFT, cstate->crtc_id, false); 1244 } 1245 1246 if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) { 1247 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT, 1248 1, false); 1249 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 1250 HDMI0_MUX_SHIFT, cstate->crtc_id, false); 1251 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 1252 IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false); 1253 vop2_mask_write(vop2, RK3568_DSP_IF_POL, 1254 IF_CRTL_HDMI_PIN_POL_MASK, 1255 IF_CRTL_HDMI_PIN_POL_SHIT, val, false); 1256 } 1257 1258 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA && 1259 !(cstate->feature & VOP_FEATURE_OUTPUT_10BIT)) 1260 conn_state->output_mode = ROCKCHIP_OUT_MODE_P888; 1261 1262 if (is_uv_swap(conn_state->bus_format, conn_state->output_mode)) 1263 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 1264 DATA_SWAP_MASK, DATA_SWAP_SHIFT, DSP_RB_SWAP, 1265 false); 1266 else 1267 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 1268 DATA_SWAP_MASK, DATA_SWAP_SHIFT, 0, 1269 false); 1270 1271 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, OUT_MODE_MASK, 1272 OUT_MODE_SHIFT, conn_state->output_mode, false); 1273 1274 switch (conn_state->bus_format) { 1275 case MEDIA_BUS_FMT_RGB565_1X16: 1276 dither_down_en = 1; 1277 break; 1278 case MEDIA_BUS_FMT_RGB666_1X18: 1279 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: 1280 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 1281 case MEDIA_BUS_FMT_RGB666_1X7X3_JEIDA: 1282 dither_down_en = 1; 1283 break; 1284 case MEDIA_BUS_FMT_YUV8_1X24: 1285 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 1286 dither_down_en = 0; 1287 pre_dither_down_en = 1; 1288 break; 1289 case MEDIA_BUS_FMT_YUV10_1X30: 1290 case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 1291 case MEDIA_BUS_FMT_RGB888_1X24: 1292 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: 1293 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: 1294 default: 1295 dither_down_en = 0; 1296 pre_dither_down_en = 0; 1297 break; 1298 } 1299 1300 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA) 1301 pre_dither_down_en = 0; 1302 else 1303 pre_dither_down_en = 1; 1304 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1305 DITHER_DOWN_EN_SHIFT, dither_down_en, false); 1306 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1307 PRE_DITHER_DOWN_EN_SHIFT, pre_dither_down_en, false); 1308 1309 yuv_overlay = is_yuv_output(conn_state->bus_format) ? 1 : 0; 1310 vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, cstate->crtc_id, 1311 yuv_overlay, false); 1312 1313 cstate->yuv_overlay = yuv_overlay; 1314 1315 vop2_writel(vop2, RK3568_VP0_DSP_HTOTAL_HS_END + vp_offset, 1316 (htotal << 16) | hsync_len); 1317 val = hact_st << 16; 1318 val |= hact_end; 1319 vop2_writel(vop2, RK3568_VP0_DSP_HACT_ST_END + vp_offset, val); 1320 val = vact_st << 16; 1321 val |= vact_end; 1322 vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END + vp_offset, val); 1323 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 1324 u16 vact_st_f1 = vtotal + vact_st + 1; 1325 u16 vact_end_f1 = vact_st_f1 + vdisplay; 1326 1327 val = vact_st_f1 << 16 | vact_end_f1; 1328 vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END_F1 + vp_offset, 1329 val); 1330 1331 val = vtotal << 16 | (vtotal + vsync_len); 1332 vop2_writel(vop2, RK3568_VP0_DSP_VS_ST_END_F1 + vp_offset, val); 1333 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1334 INTERLACE_EN_SHIFT, 1, false); 1335 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1336 P2I_EN_SHIFT, 1, false); 1337 vtotal += vtotal + 1; 1338 } else { 1339 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1340 INTERLACE_EN_SHIFT, 0, false); 1341 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1342 P2I_EN_SHIFT, 0, false); 1343 } 1344 vop2_writel(vop2, RK3568_VP0_DSP_VTOTAL_VS_END + vp_offset, 1345 (vtotal << 16) | vsync_len); 1346 val = !!(mode->flags & DRM_MODE_FLAG_DBLCLK); 1347 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1348 CORE_DCLK_DIV_EN_SHIFT, val, false); 1349 1350 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420) 1351 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 1352 DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0x3, false); 1353 else 1354 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 1355 DCLK_DIV2_MASK, DCLK_DIV2_SHIFT, 0, false); 1356 1357 if (yuv_overlay) 1358 val = 0x20010200; 1359 else 1360 val = 0; 1361 vop2_writel(vop2, RK3568_VP0_DSP_BG + vp_offset, val); 1362 1363 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1364 POST_DSP_OUT_R2Y_SHIFT, yuv_overlay, false); 1365 1366 vop2_post_config(state, vop2); 1367 1368 return 0; 1369 } 1370 1371 static int rockchip_vop2_set_plane(struct display_state *state) 1372 { 1373 struct crtc_state *cstate = &state->crtc_state; 1374 struct connector_state *conn_state = &state->conn_state; 1375 struct drm_display_mode *mode = &conn_state->mode; 1376 u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty; 1377 struct vop2 *vop2 = cstate->private; 1378 int src_w = cstate->src_w; 1379 int src_h = cstate->src_h; 1380 int crtc_x = cstate->crtc_x; 1381 int crtc_y = cstate->crtc_y; 1382 int crtc_w = cstate->crtc_w; 1383 int crtc_h = cstate->crtc_h; 1384 int xvir = cstate->xvir; 1385 int y_mirror = 0; 1386 int csc_mode; 1387 u32 win_offset; 1388 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id); 1389 u8 primary_plane_id = vop2->vp_plane_mask[cstate->crtc_id].primary_plane_id; 1390 1391 win_offset = vop2->data->win_data[primary_plane_id].reg_offset; 1392 if (crtc_w > cstate->max_output.width) { 1393 printf("ERROR: output w[%d] exceeded max width[%d]\n", 1394 crtc_w, cstate->max_output.width); 1395 return -EINVAL; 1396 } 1397 1398 act_info = (src_h - 1) << 16; 1399 act_info |= (src_w - 1) & 0xffff; 1400 1401 dsp_info = (crtc_h - 1) << 16; 1402 dsp_info |= (crtc_w - 1) & 0xffff; 1403 1404 dsp_stx = crtc_x; 1405 dsp_sty = crtc_y; 1406 dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); 1407 1408 if (mode->flags & DRM_MODE_FLAG_YMIRROR) 1409 y_mirror = 1; 1410 else 1411 y_mirror = 0; 1412 1413 if (y_mirror) 1414 cstate->dma_addr += (src_h - 1) * xvir * 4; 1415 vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, EN_MASK, 1416 YMIRROR_EN_SHIFT, y_mirror, false); 1417 1418 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 1419 WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format, 1420 false); 1421 vop2_writel(vop2, RK3568_ESMART0_REGION0_VIR + win_offset, xvir); 1422 vop2_writel(vop2, RK3568_ESMART0_REGION0_YRGB_MST + win_offset, 1423 cstate->dma_addr); 1424 1425 vop2_writel(vop2, RK3568_ESMART0_REGION0_ACT_INFO + win_offset, 1426 act_info); 1427 vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_INFO + win_offset, 1428 dsp_info); 1429 vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_ST + win_offset, dsp_st); 1430 1431 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK, 1432 WIN_EN_SHIFT, 1, false); 1433 1434 csc_mode = vop2_convert_csc_mode(conn_state->color_space); 1435 vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, EN_MASK, 1436 RGB2YUV_EN_SHIFT, 1437 is_yuv_output(conn_state->bus_format), false); 1438 vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, CSC_MODE_MASK, 1439 CSC_MODE_SHIFT, csc_mode, false); 1440 1441 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 1442 return 0; 1443 } 1444 1445 static int rockchip_vop2_prepare(struct display_state *state) 1446 { 1447 return 0; 1448 } 1449 1450 static int rockchip_vop2_enable(struct display_state *state) 1451 { 1452 struct crtc_state *cstate = &state->crtc_state; 1453 struct vop2 *vop2 = cstate->private; 1454 u32 vp_offset = (cstate->crtc_id * 0x100); 1455 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id); 1456 1457 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1458 STANDBY_EN_SHIFT, 0, false); 1459 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 1460 1461 return 0; 1462 } 1463 1464 static int rockchip_vop2_disable(struct display_state *state) 1465 { 1466 struct crtc_state *cstate = &state->crtc_state; 1467 struct vop2 *vop2 = cstate->private; 1468 u32 vp_offset = (cstate->crtc_id * 0x100); 1469 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id); 1470 1471 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1472 STANDBY_EN_SHIFT, 1, false); 1473 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 1474 1475 return 0; 1476 } 1477 1478 static int rockchip_vop2_fixup_dts(struct display_state *state, void *blob) 1479 { 1480 struct crtc_state *cstate = &state->crtc_state; 1481 struct vop2 *vop2 = cstate->private; 1482 ofnode vp_node; 1483 struct device_node *port_parent_node = cstate->ports_node; 1484 static bool vop_fix_dts; 1485 const char *path; 1486 u32 plane_mask = 0; 1487 int vp_id = 0; 1488 1489 if (vop_fix_dts) 1490 return 0; 1491 1492 ofnode_for_each_subnode(vp_node, np_to_ofnode(port_parent_node)) { 1493 path = vp_node.np->full_name; 1494 plane_mask = vop2->vp_plane_mask[vp_id].plane_mask; 1495 1496 printf("vp%d, plane_mask:0x%x, primary-id:%d\n", 1497 vp_id, plane_mask, 1498 vop2->vp_plane_mask[vp_id].primary_plane_id); 1499 1500 do_fixup_by_path_u32(blob, path, "rockchip,plane-mask", 1501 plane_mask, 1); 1502 do_fixup_by_path_u32(blob, path, "rockchip,primary-plane", 1503 vop2->vp_plane_mask[vp_id].primary_plane_id, 1); 1504 vp_id++; 1505 } 1506 1507 vop_fix_dts = true; 1508 1509 return 0; 1510 } 1511 1512 static struct vop2_vp_plane_mask rk356x_vp_plane_mask[VOP2_VP_MAX][VOP2_VP_MAX] = { 1513 { /* one display policy */ 1514 {/* main display */ 1515 .primary_plane_id = ROCKCHIP_VOP2_SMART0, 1516 .attached_layers_nr = 6, 1517 .attached_layers = { 1518 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0, 1519 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1 1520 }, 1521 }, 1522 {/* second display */}, 1523 {/* third display */}, 1524 {/* fourth display */}, 1525 }, 1526 1527 { /* two display policy */ 1528 {/* main display */ 1529 .primary_plane_id = ROCKCHIP_VOP2_SMART0, 1530 .attached_layers_nr = 3, 1531 .attached_layers = { 1532 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0 1533 }, 1534 }, 1535 1536 {/* second display */ 1537 .primary_plane_id = ROCKCHIP_VOP2_SMART1, 1538 .attached_layers_nr = 3, 1539 .attached_layers = { 1540 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_ESMART1, ROCKCHIP_VOP2_SMART1 1541 }, 1542 }, 1543 {/* third display */}, 1544 {/* fourth display */}, 1545 }, 1546 1547 { /* three display policy */ 1548 {/* main display */ 1549 .primary_plane_id = ROCKCHIP_VOP2_SMART0, 1550 .attached_layers_nr = 3, 1551 .attached_layers = { 1552 ROCKCHIP_VOP2_CLUSTER0, ROCKCHIP_VOP2_ESMART0, ROCKCHIP_VOP2_SMART0 1553 }, 1554 }, 1555 1556 {/* second display */ 1557 .primary_plane_id = ROCKCHIP_VOP2_SMART1, 1558 .attached_layers_nr = 2, 1559 .attached_layers = { 1560 ROCKCHIP_VOP2_CLUSTER1, ROCKCHIP_VOP2_SMART1 1561 }, 1562 }, 1563 1564 {/* third display */ 1565 .primary_plane_id = ROCKCHIP_VOP2_ESMART1, 1566 .attached_layers_nr = 1, 1567 .attached_layers = { ROCKCHIP_VOP2_ESMART1 }, 1568 }, 1569 1570 {/* fourth display */}, 1571 }, 1572 1573 {/* reserved for four display policy */}, 1574 }; 1575 1576 static struct vop2_win_data rk3568_win_data[6] = { 1577 { 1578 .name = "Cluster0", 1579 .phys_id = ROCKCHIP_VOP2_CLUSTER0, 1580 .win_sel_port_offset = 0, 1581 .layer_sel_win_id = 0, 1582 .reg_offset = 0, 1583 }, 1584 1585 { 1586 .name = "Cluster1", 1587 .phys_id = ROCKCHIP_VOP2_CLUSTER1, 1588 .win_sel_port_offset = 1, 1589 .layer_sel_win_id = 1, 1590 .reg_offset = 0x200, 1591 }, 1592 1593 { 1594 .name = "Esmart0", 1595 .phys_id = ROCKCHIP_VOP2_ESMART0, 1596 .win_sel_port_offset = 4, 1597 .layer_sel_win_id = 2, 1598 .reg_offset = 0, 1599 }, 1600 1601 { 1602 .name = "Esmart1", 1603 .phys_id = ROCKCHIP_VOP2_ESMART1, 1604 .win_sel_port_offset = 5, 1605 .layer_sel_win_id = 6, 1606 .reg_offset = 0x200, 1607 }, 1608 1609 { 1610 .name = "Smart0", 1611 .phys_id = ROCKCHIP_VOP2_SMART0, 1612 .win_sel_port_offset = 6, 1613 .layer_sel_win_id = 3, 1614 .reg_offset = 0x400, 1615 }, 1616 1617 { 1618 .name = "Smart1", 1619 .phys_id = ROCKCHIP_VOP2_SMART1, 1620 .win_sel_port_offset = 7, 1621 .layer_sel_win_id = 7, 1622 .reg_offset = 0x600, 1623 }, 1624 }; 1625 1626 static struct vop2_vp_data rk3568_vp_data[3] = { 1627 { 1628 .feature = VOP_FEATURE_OUTPUT_10BIT, 1629 .pre_scan_max_dly = 42, 1630 .max_output = {4096, 2304}, 1631 }, 1632 { 1633 .feature = 0, 1634 .pre_scan_max_dly = 40, 1635 .max_output = {2048, 1536}, 1636 }, 1637 { 1638 .feature = 0, 1639 .pre_scan_max_dly = 40, 1640 .max_output = {1920, 1080}, 1641 }, 1642 }; 1643 1644 const struct vop2_data rk3568_vop = { 1645 .nr_vps = 3, 1646 .vp_data = rk3568_vp_data, 1647 .win_data = rk3568_win_data, 1648 .plane_mask = rk356x_vp_plane_mask[0], 1649 .nr_layers = 6, 1650 .nr_mixers = 5, 1651 .nr_gammas = 1, 1652 }; 1653 1654 const struct rockchip_crtc_funcs rockchip_vop2_funcs = { 1655 .preinit = rockchip_vop2_preinit, 1656 .prepare = rockchip_vop2_prepare, 1657 .init = rockchip_vop2_init, 1658 .set_plane = rockchip_vop2_set_plane, 1659 .enable = rockchip_vop2_enable, 1660 .disable = rockchip_vop2_disable, 1661 .fixup_dts = rockchip_vop2_fixup_dts, 1662 }; 1663