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/unaligned.h> 14 #include <asm/io.h> 15 #include <linux/list.h> 16 #include <linux/media-bus-format.h> 17 #include <clk.h> 18 #include <asm/arch/clock.h> 19 #include <linux/err.h> 20 #include <dm/device.h> 21 #include <dm/read.h> 22 #include <syscon.h> 23 24 #include "rockchip_display.h" 25 #include "rockchip_crtc.h" 26 #include "rockchip_connector.h" 27 28 /* System registers definition */ 29 #define RK3568_REG_CFG_DONE 0x000 30 #define CFG_DONE_EN BIT(15) 31 32 #define RK3568_VERSION_INFO 0x004 33 34 #define EN_MASK 1 35 36 #define RK3568_DSP_IF_EN 0x028 37 #define RGB_EN_SHIFT 0 38 #define HDMI0_EN_SHIFT 1 39 #define EDP0_EN_SHIFT 3 40 #define MIPI0_EN_SHIFT 4 41 #define MIPI1_EN_SHIFT 20 42 #define LVDS0_EN_SHIFT 5 43 #define LVDS1_EN_SHIFT 24 44 #define BT1120_EN_SHIFT 6 45 #define BT656_EN_SHIFT 7 46 #define IF_MUX_MASK 3 47 #define RGB_MUX_SHIFT 8 48 #define HDMI0_MUX_SHIFT 10 49 #define EDP0_MUX_SHIFT 14 50 #define MIPI0_MUX_SHIFT 16 51 #define MIPI1_MUX_SHIFT 21 52 #define LVDS0_MUX_SHIFT 5 53 #define LVDS1_MUX_SHIFT 25 54 55 #define RK3568_DSP_IF_CTRL 0x02c 56 #define LVDS_DUAL_EN_SHIFT 0 57 #define LVDS_DUAL_LEFT_RIGHT_EN_SHIFT 1 58 #define LVDS_DUAL_SWAP_EN_SHIFT 2 59 #define RK3568_DSP_IF_POL 0x030 60 #define IF_CTRL_REG_DONE_IMD_MASK 1 61 #define IF_CTRL_REG_DONE_IMD_SHIFT 28 62 #define IF_CRTL_MIPI_DCLK_POL_SHIT 19 63 #define IF_CRTL_EDP_DCLK_POL_SHIT 15 64 #define IF_CRTL_HDMI_DCLK_POL_SHIT 7 65 #define IF_CRTL_HDMI_PIN_POL_MASK 0x7 66 #define IF_CRTL_HDMI_PIN_POL_SHIT 4 67 #define IF_CRTL_RGB_LVDS_DCLK_POL_SHIT 3 68 #define RK3568_VP0_LINE_FLAG 0x70 69 #define RK3568_VP1_LINE_FLAG 0x74 70 #define RK3568_VP2_LINE_FLAG 0x78 71 #define RK3568_SYS0_INT_EN 0x80 72 #define RK3568_SYS0_INT_CLR 0x84 73 #define RK3568_SYS0_INT_STATUS 0x88 74 #define RK3568_SYS1_INT_EN 0x90 75 #define RK3568_SYS1_INT_CLR 0x94 76 #define RK3568_SYS1_INT_STATUS 0x98 77 #define RK3568_VP0_INT_EN 0xA0 78 #define RK3568_VP0_INT_CLR 0xA4 79 #define RK3568_VP0_INT_STATUS 0xA8 80 #define RK3568_VP1_INT_EN 0xB0 81 #define RK3568_VP1_INT_CLR 0xB4 82 #define RK3568_VP1_INT_STATUS 0xB8 83 #define RK3568_VP2_INT_EN 0xC0 84 #define RK3568_VP2_INT_CLR 0xC4 85 #define RK3568_VP2_INT_STATUS 0xC8 86 87 /* Video Port registers definition */ 88 #define RK3568_VP0_DSP_CTRL 0xC00 89 #define OUT_MODE_MASK 0xf 90 #define OUT_MODE_SHIFT 0 91 #define DATA_SWAP_MASK 0x1f 92 #define DATA_SWAP_SHIFT 8 93 #define DSP_RB_SWAP 2 94 #define CORE_DCLK_DIV_EN_SHIFT 4 95 #define P2I_EN_SHIFT 5 96 #define INTERLACE_EN_SHIFT 7 97 #define POST_DSP_OUT_R2Y_SHIFT 15 98 #define PRE_DITHER_DOWN_EN_SHIFT 16 99 #define DITHER_DOWN_EN_SHIFT 17 100 #define STANDBY_EN_SHIFT 31 101 102 #define RK3568_VP0_MIPI_CTRL 0xC04 103 #define DCLK_DIV2_SHIFT 4 104 #define DCLK_DIV2_MASK 0x3 105 #define MIPI_DUAL_EN_SHIFT 20 106 #define MIPI_DUAL_SWAP_EN_SHIFT 21 107 108 #define RK3568_VP0_COLOR_BAR_CTRL 0xC08 109 #define RK3568_VP0_DSP_BG 0xC2C 110 #define RK3568_VP0_PRE_SCAN_HTIMING 0xC30 111 #define RK3568_VP0_POST_DSP_HACT_INFO 0xC34 112 #define RK3568_VP0_POST_DSP_VACT_INFO 0xC38 113 #define RK3568_VP0_POST_SCL_FACTOR_YRGB 0xC3C 114 #define RK3568_VP0_POST_SCL_CTRL 0xC40 115 #define RK3568_VP0_POST_DSP_VACT_INFO_F1 0xC44 116 #define RK3568_VP0_DSP_HTOTAL_HS_END 0xC48 117 #define RK3568_VP0_DSP_HACT_ST_END 0xC4C 118 #define RK3568_VP0_DSP_VTOTAL_VS_END 0xC50 119 #define RK3568_VP0_DSP_VACT_ST_END 0xC54 120 #define RK3568_VP0_DSP_VS_ST_END_F1 0xC58 121 #define RK3568_VP0_DSP_VACT_ST_END_F1 0xC5C 122 123 #define RK3568_VP1_DSP_CTRL 0xD00 124 #define RK3568_VP1_MIPI_CTRL 0xD04 125 #define RK3568_VP1_COLOR_BAR_CTRL 0xD08 126 #define RK3568_VP1_PRE_SCAN_HTIMING 0xD30 127 #define RK3568_VP1_POST_DSP_HACT_INFO 0xD34 128 #define RK3568_VP1_POST_DSP_VACT_INFO 0xD38 129 #define RK3568_VP1_POST_SCL_FACTOR_YRGB 0xD3C 130 #define RK3568_VP1_POST_SCL_CTRL 0xD40 131 #define RK3568_VP1_DSP_HACT_INFO 0xD34 132 #define RK3568_VP1_DSP_VACT_INFO 0xD38 133 #define RK3568_VP1_POST_DSP_VACT_INFO_F1 0xD44 134 #define RK3568_VP1_DSP_HTOTAL_HS_END 0xD48 135 #define RK3568_VP1_DSP_HACT_ST_END 0xD4C 136 #define RK3568_VP1_DSP_VTOTAL_VS_END 0xD50 137 #define RK3568_VP1_DSP_VACT_ST_END 0xD54 138 #define RK3568_VP1_DSP_VS_ST_END_F1 0xD58 139 #define RK3568_VP1_DSP_VACT_ST_END_F1 0xD5C 140 141 #define RK3568_VP2_DSP_CTRL 0xE00 142 #define RK3568_VP2_MIPI_CTRL 0xE04 143 #define RK3568_VP2_COLOR_BAR_CTRL 0xE08 144 #define RK3568_VP2_PRE_SCAN_HTIMING 0xE30 145 #define RK3568_VP2_POST_DSP_HACT_INFO 0xE34 146 #define RK3568_VP2_POST_DSP_VACT_INFO 0xE38 147 #define RK3568_VP2_POST_SCL_FACTOR_YRGB 0xE3C 148 #define RK3568_VP2_POST_SCL_CTRL 0xE40 149 #define RK3568_VP2_DSP_HACT_INFO 0xE34 150 #define RK3568_VP2_DSP_VACT_INFO 0xE38 151 #define RK3568_VP2_POST_DSP_VACT_INFO_F1 0xE44 152 #define RK3568_VP2_DSP_HTOTAL_HS_END 0xE48 153 #define RK3568_VP2_DSP_HACT_ST_END 0xE4C 154 #define RK3568_VP2_DSP_VTOTAL_VS_END 0xE50 155 #define RK3568_VP2_DSP_VACT_ST_END 0xE54 156 #define RK3568_VP2_DSP_VS_ST_END_F1 0xE58 157 #define RK3568_VP2_DSP_VACT_ST_END_F1 0xE5C 158 159 /* Overlay registers definition */ 160 #define RK3568_OVL_CTRL 0x600 161 #define OVL_PORT_MUX_REG_DONE_IMD_SHIFT 28 162 #define RK3568_OVL_LAYER_SEL 0x604 163 #define LAYER_SEL_MASK 0xf 164 165 #define RK3568_OVL_PORT_SEL 0x608 166 #define PORT_MUX_MASK 0xf 167 #define PORT_MUX_SHIFT 0 168 #define LAYER_SEL_PORT_MASK 0x3 169 #define LAYER_SEL_PORT_SHIFT 24 170 171 #define RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL 0x610 172 #define RK3568_CLUSTER0_MIX_DST_COLOR_CTRL 0x614 173 #define RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL 0x618 174 #define RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL 0x61C 175 #define RK3568_MIX0_SRC_COLOR_CTRL 0x650 176 #define RK3568_MIX0_DST_COLOR_CTRL 0x654 177 #define RK3568_MIX0_SRC_ALPHA_CTRL 0x658 178 #define RK3568_MIX0_DST_ALPHA_CTRL 0x65C 179 #define RK3568_HDR0_SRC_COLOR_CTRL 0x6C0 180 #define RK3568_HDR0_DST_COLOR_CTRL 0x6C4 181 #define RK3568_HDR0_SRC_ALPHA_CTRL 0x6C8 182 #define RK3568_HDR0_DST_ALPHA_CTRL 0x6CC 183 #define RK3568_VP0_BG_MIX_CTRL 0x6E0 184 #define RK3568_VP1_BG_MIX_CTRL 0x6E4 185 #define RK3568_VP2_BG_MIX_CTRL 0x6E8 186 #define RK3568_CLUSTER_DLY_NUM 0x6F0 187 #define RK3568_SMART_DLY_NUM 0x6F8 188 189 /* Cluster0 register definition */ 190 #define RK3568_CLUSTER0_WIN0_CTRL0 0x1000 191 #define RK3568_CLUSTER0_WIN0_CTRL1 0x1004 192 #define RK3568_CLUSTER0_WIN0_YRGB_MST 0x1010 193 #define RK3568_CLUSTER0_WIN0_CBR_MST 0x1014 194 #define RK3568_CLUSTER0_WIN0_VIR 0x1018 195 #define RK3568_CLUSTER0_WIN0_ACT_INFO 0x1020 196 #define RK3568_CLUSTER0_WIN0_DSP_INFO 0x1024 197 #define RK3568_CLUSTER0_WIN0_DSP_ST 0x1028 198 #define RK3568_CLUSTER0_WIN0_SCL_FACTOR_YRGB 0x1030 199 #define RK3568_CLUSTER0_WIN0_AFBCD_ROTATE_MODE 0x1054 200 #define RK3568_CLUSTER0_WIN0_AFBCD_HDR_PTR 0x1058 201 #define RK3568_CLUSTER0_WIN0_AFBCD_VIR_WIDTH 0x105C 202 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_SIZE 0x1060 203 #define RK3568_CLUSTER0_WIN0_AFBCD_PIC_OFFSET 0x1064 204 #define RK3568_CLUSTER0_WIN0_AFBCD_DSP_OFFSET 0x1068 205 #define RK3568_CLUSTER0_WIN0_AFBCD_CTRL 0x106C 206 207 #define RK3568_CLUSTER0_WIN1_CTRL0 0x1080 208 #define RK3568_CLUSTER0_WIN1_CTRL1 0x1084 209 #define RK3568_CLUSTER0_WIN1_YRGB_MST 0x1090 210 #define RK3568_CLUSTER0_WIN1_CBR_MST 0x1094 211 #define RK3568_CLUSTER0_WIN1_VIR 0x1098 212 #define RK3568_CLUSTER0_WIN1_ACT_INFO 0x10A0 213 #define RK3568_CLUSTER0_WIN1_DSP_INFO 0x10A4 214 #define RK3568_CLUSTER0_WIN1_DSP_ST 0x10A8 215 #define RK3568_CLUSTER0_WIN1_SCL_FACTOR_YRGB 0x10B0 216 #define RK3568_CLUSTER0_WIN1_AFBCD_ROTATE_MODE 0x10D4 217 #define RK3568_CLUSTER0_WIN1_AFBCD_HDR_PTR 0x10D8 218 #define RK3568_CLUSTER0_WIN1_AFBCD_VIR_WIDTH 0x10DC 219 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_SIZE 0x10E0 220 #define RK3568_CLUSTER0_WIN1_AFBCD_PIC_OFFSET 0x10E4 221 #define RK3568_CLUSTER0_WIN1_AFBCD_DSP_OFFSET 0x10E8 222 #define RK3568_CLUSTER0_WIN1_AFBCD_CTRL 0x10EC 223 224 #define RK3568_CLUSTER0_CTRL 0x1100 225 226 #define RK3568_CLUSTER1_WIN0_CTRL0 0x1200 227 #define RK3568_CLUSTER1_WIN0_CTRL1 0x1204 228 #define RK3568_CLUSTER1_WIN0_YRGB_MST 0x1210 229 #define RK3568_CLUSTER1_WIN0_CBR_MST 0x1214 230 #define RK3568_CLUSTER1_WIN0_VIR 0x1218 231 #define RK3568_CLUSTER1_WIN0_ACT_INFO 0x1220 232 #define RK3568_CLUSTER1_WIN0_DSP_INFO 0x1224 233 #define RK3568_CLUSTER1_WIN0_DSP_ST 0x1228 234 #define RK3568_CLUSTER1_WIN0_SCL_FACTOR_YRGB 0x1230 235 #define RK3568_CLUSTER1_WIN0_AFBCD_ROTATE_MODE 0x1254 236 #define RK3568_CLUSTER1_WIN0_AFBCD_HDR_PTR 0x1258 237 #define RK3568_CLUSTER1_WIN0_AFBCD_VIR_WIDTH 0x125C 238 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_SIZE 0x1260 239 #define RK3568_CLUSTER1_WIN0_AFBCD_PIC_OFFSET 0x1264 240 #define RK3568_CLUSTER1_WIN0_AFBCD_DSP_OFFSET 0x1268 241 #define RK3568_CLUSTER1_WIN0_AFBCD_CTRL 0x126C 242 243 #define RK3568_CLUSTER1_WIN1_CTRL0 0x1280 244 #define RK3568_CLUSTER1_WIN1_CTRL1 0x1284 245 #define RK3568_CLUSTER1_WIN1_YRGB_MST 0x1290 246 #define RK3568_CLUSTER1_WIN1_CBR_MST 0x1294 247 #define RK3568_CLUSTER1_WIN1_VIR 0x1298 248 #define RK3568_CLUSTER1_WIN1_ACT_INFO 0x12A0 249 #define RK3568_CLUSTER1_WIN1_DSP_INFO 0x12A4 250 #define RK3568_CLUSTER1_WIN1_DSP_ST 0x12A8 251 #define RK3568_CLUSTER1_WIN1_SCL_FACTOR_YRGB 0x12B0 252 #define RK3568_CLUSTER1_WIN1_AFBCD_ROTATE_MODE 0x12D4 253 #define RK3568_CLUSTER1_WIN1_AFBCD_HDR_PTR 0x12D8 254 #define RK3568_CLUSTER1_WIN1_AFBCD_VIR_WIDTH 0x12DC 255 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_SIZE 0x12E0 256 #define RK3568_CLUSTER1_WIN1_AFBCD_PIC_OFFSET 0x12E4 257 #define RK3568_CLUSTER1_WIN1_AFBCD_DSP_OFFSET 0x12E8 258 #define RK3568_CLUSTER1_WIN1_AFBCD_CTRL 0x12EC 259 260 #define RK3568_CLUSTER1_CTRL 0x1300 261 262 /* Esmart register definition */ 263 #define RK3568_ESMART0_CTRL0 0x1800 264 #define RGB2YUV_EN_SHIFT 1 265 #define CSC_MODE_SHIFT 2 266 #define CSC_MODE_MASK 0x3 267 268 #define RK3568_ESMART0_CTRL1 0x1804 269 #define YMIRROR_EN_SHIFT 31 270 #define RK3568_ESMART0_REGION0_CTRL 0x1810 271 #define REGION0_RB_SWAP_SHIFT 14 272 #define WIN_EN_SHIFT 0 273 #define WIN_FORMAT_MASK 0x1f 274 #define WIN_FORMAT_SHIFT 1 275 276 #define RK3568_ESMART0_REGION0_YRGB_MST 0x1814 277 #define RK3568_ESMART0_REGION0_CBR_MST 0x1818 278 #define RK3568_ESMART0_REGION0_VIR 0x181C 279 #define RK3568_ESMART0_REGION0_ACT_INFO 0x1820 280 #define RK3568_ESMART0_REGION0_DSP_INFO 0x1824 281 #define RK3568_ESMART0_REGION0_DSP_ST 0x1828 282 #define RK3568_ESMART0_REGION0_SCL_CTRL 0x1830 283 #define RK3568_ESMART0_REGION0_SCL_FACTOR_YRGB 0x1834 284 #define RK3568_ESMART0_REGION0_SCL_FACTOR_CBR 0x1838 285 #define RK3568_ESMART0_REGION0_SCL_OFFSET 0x183C 286 #define RK3568_ESMART0_REGION1_CTRL 0x1840 287 #define RK3568_ESMART0_REGION1_YRGB_MST 0x1844 288 #define RK3568_ESMART0_REGION1_CBR_MST 0x1848 289 #define RK3568_ESMART0_REGION1_VIR 0x184C 290 #define RK3568_ESMART0_REGION1_ACT_INFO 0x1850 291 #define RK3568_ESMART0_REGION1_DSP_INFO 0x1854 292 #define RK3568_ESMART0_REGION1_DSP_ST 0x1858 293 #define RK3568_ESMART0_REGION1_SCL_CTRL 0x1860 294 #define RK3568_ESMART0_REGION1_SCL_FACTOR_YRGB 0x1864 295 #define RK3568_ESMART0_REGION1_SCL_FACTOR_CBR 0x1868 296 #define RK3568_ESMART0_REGION1_SCL_OFFSET 0x186C 297 #define RK3568_ESMART0_REGION2_CTRL 0x1870 298 #define RK3568_ESMART0_REGION2_YRGB_MST 0x1874 299 #define RK3568_ESMART0_REGION2_CBR_MST 0x1878 300 #define RK3568_ESMART0_REGION2_VIR 0x187C 301 #define RK3568_ESMART0_REGION2_ACT_INFO 0x1880 302 #define RK3568_ESMART0_REGION2_DSP_INFO 0x1884 303 #define RK3568_ESMART0_REGION2_DSP_ST 0x1888 304 #define RK3568_ESMART0_REGION2_SCL_CTRL 0x1890 305 #define RK3568_ESMART0_REGION2_SCL_FACTOR_YRGB 0x1894 306 #define RK3568_ESMART0_REGION2_SCL_FACTOR_CBR 0x1898 307 #define RK3568_ESMART0_REGION2_SCL_OFFSET 0x189C 308 #define RK3568_ESMART0_REGION3_CTRL 0x18A0 309 #define RK3568_ESMART0_REGION3_YRGB_MST 0x18A4 310 #define RK3568_ESMART0_REGION3_CBR_MST 0x18A8 311 #define RK3568_ESMART0_REGION3_VIR 0x18AC 312 #define RK3568_ESMART0_REGION3_ACT_INFO 0x18B0 313 #define RK3568_ESMART0_REGION3_DSP_INFO 0x18B4 314 #define RK3568_ESMART0_REGION3_DSP_ST 0x18B8 315 #define RK3568_ESMART0_REGION3_SCL_CTRL 0x18C0 316 #define RK3568_ESMART0_REGION3_SCL_FACTOR_YRGB 0x18C4 317 #define RK3568_ESMART0_REGION3_SCL_FACTOR_CBR 0x18C8 318 #define RK3568_ESMART0_REGION3_SCL_OFFSET 0x18CC 319 320 #define RK3568_ESMART1_CTRL0 0x1A00 321 #define RK3568_ESMART1_CTRL1 0x1A04 322 #define RK3568_ESMART1_REGION0_CTRL 0x1A10 323 #define RK3568_ESMART1_REGION0_YRGB_MST 0x1A14 324 #define RK3568_ESMART1_REGION0_CBR_MST 0x1A18 325 #define RK3568_ESMART1_REGION0_VIR 0x1A1C 326 #define RK3568_ESMART1_REGION0_ACT_INFO 0x1A20 327 #define RK3568_ESMART1_REGION0_DSP_INFO 0x1A24 328 #define RK3568_ESMART1_REGION0_DSP_ST 0x1A28 329 #define RK3568_ESMART1_REGION0_SCL_CTRL 0x1A30 330 #define RK3568_ESMART1_REGION0_SCL_FACTOR_YRGB 0x1A34 331 #define RK3568_ESMART1_REGION0_SCL_FACTOR_CBR 0x1A38 332 #define RK3568_ESMART1_REGION0_SCL_OFFSET 0x1A3C 333 #define RK3568_ESMART1_REGION1_CTRL 0x1A40 334 #define RK3568_ESMART1_REGION1_YRGB_MST 0x1A44 335 #define RK3568_ESMART1_REGION1_CBR_MST 0x1A48 336 #define RK3568_ESMART1_REGION1_VIR 0x1A4C 337 #define RK3568_ESMART1_REGION1_ACT_INFO 0x1A50 338 #define RK3568_ESMART1_REGION1_DSP_INFO 0x1A54 339 #define RK3568_ESMART1_REGION1_DSP_ST 0x1A58 340 #define RK3568_ESMART1_REGION1_SCL_CTRL 0x1A60 341 #define RK3568_ESMART1_REGION1_SCL_FACTOR_YRGB 0x1A64 342 #define RK3568_ESMART1_REGION1_SCL_FACTOR_CBR 0x1A68 343 #define RK3568_ESMART1_REGION1_SCL_OFFSET 0x1A6C 344 #define RK3568_ESMART1_REGION2_CTRL 0x1A70 345 #define RK3568_ESMART1_REGION2_YRGB_MST 0x1A74 346 #define RK3568_ESMART1_REGION2_CBR_MST 0x1A78 347 #define RK3568_ESMART1_REGION2_VIR 0x1A7C 348 #define RK3568_ESMART1_REGION2_ACT_INFO 0x1A80 349 #define RK3568_ESMART1_REGION2_DSP_INFO 0x1A84 350 #define RK3568_ESMART1_REGION2_DSP_ST 0x1A88 351 #define RK3568_ESMART1_REGION2_SCL_CTRL 0x1A90 352 #define RK3568_ESMART1_REGION2_SCL_FACTOR_YRGB 0x1A94 353 #define RK3568_ESMART1_REGION2_SCL_FACTOR_CBR 0x1A98 354 #define RK3568_ESMART1_REGION2_SCL_OFFSET 0x1A9C 355 #define RK3568_ESMART1_REGION3_CTRL 0x1AA0 356 #define RK3568_ESMART1_REGION3_YRGB_MST 0x1AA4 357 #define RK3568_ESMART1_REGION3_CBR_MST 0x1AA8 358 #define RK3568_ESMART1_REGION3_VIR 0x1AAC 359 #define RK3568_ESMART1_REGION3_ACT_INFO 0x1AB0 360 #define RK3568_ESMART1_REGION3_DSP_INFO 0x1AB4 361 #define RK3568_ESMART1_REGION3_DSP_ST 0x1AB8 362 #define RK3568_ESMART1_REGION3_SCL_CTRL 0x1AC0 363 #define RK3568_ESMART1_REGION3_SCL_FACTOR_YRGB 0x1AC4 364 #define RK3568_ESMART1_REGION3_SCL_FACTOR_CBR 0x1AC8 365 #define RK3568_ESMART1_REGION3_SCL_OFFSET 0x1ACC 366 367 #define RK3568_SMART0_CTRL0 0x1C00 368 #define RK3568_SMART0_CTRL1 0x1C04 369 #define RK3568_SMART0_REGION0_CTRL 0x1C10 370 #define RK3568_SMART0_REGION0_YRGB_MST 0x1C14 371 #define RK3568_SMART0_REGION0_CBR_MST 0x1C18 372 #define RK3568_SMART0_REGION0_VIR 0x1C1C 373 #define RK3568_SMART0_REGION0_ACT_INFO 0x1C20 374 #define RK3568_SMART0_REGION0_DSP_INFO 0x1C24 375 #define RK3568_SMART0_REGION0_DSP_ST 0x1C28 376 #define RK3568_SMART0_REGION0_SCL_CTRL 0x1C30 377 #define RK3568_SMART0_REGION0_SCL_FACTOR_YRGB 0x1C34 378 #define RK3568_SMART0_REGION0_SCL_FACTOR_CBR 0x1C38 379 #define RK3568_SMART0_REGION0_SCL_OFFSET 0x1C3C 380 #define RK3568_SMART0_REGION1_CTRL 0x1C40 381 #define RK3568_SMART0_REGION1_YRGB_MST 0x1C44 382 #define RK3568_SMART0_REGION1_CBR_MST 0x1C48 383 #define RK3568_SMART0_REGION1_VIR 0x1C4C 384 #define RK3568_SMART0_REGION1_ACT_INFO 0x1C50 385 #define RK3568_SMART0_REGION1_DSP_INFO 0x1C54 386 #define RK3568_SMART0_REGION1_DSP_ST 0x1C58 387 #define RK3568_SMART0_REGION1_SCL_CTRL 0x1C60 388 #define RK3568_SMART0_REGION1_SCL_FACTOR_YRGB 0x1C64 389 #define RK3568_SMART0_REGION1_SCL_FACTOR_CBR 0x1C68 390 #define RK3568_SMART0_REGION1_SCL_OFFSET 0x1C6C 391 #define RK3568_SMART0_REGION2_CTRL 0x1C70 392 #define RK3568_SMART0_REGION2_YRGB_MST 0x1C74 393 #define RK3568_SMART0_REGION2_CBR_MST 0x1C78 394 #define RK3568_SMART0_REGION2_VIR 0x1C7C 395 #define RK3568_SMART0_REGION2_ACT_INFO 0x1C80 396 #define RK3568_SMART0_REGION2_DSP_INFO 0x1C84 397 #define RK3568_SMART0_REGION2_DSP_ST 0x1C88 398 #define RK3568_SMART0_REGION2_SCL_CTRL 0x1C90 399 #define RK3568_SMART0_REGION2_SCL_FACTOR_YRGB 0x1C94 400 #define RK3568_SMART0_REGION2_SCL_FACTOR_CBR 0x1C98 401 #define RK3568_SMART0_REGION2_SCL_OFFSET 0x1C9C 402 #define RK3568_SMART0_REGION3_CTRL 0x1CA0 403 #define RK3568_SMART0_REGION3_YRGB_MST 0x1CA4 404 #define RK3568_SMART0_REGION3_CBR_MST 0x1CA8 405 #define RK3568_SMART0_REGION3_VIR 0x1CAC 406 #define RK3568_SMART0_REGION3_ACT_INFO 0x1CB0 407 #define RK3568_SMART0_REGION3_DSP_INFO 0x1CB4 408 #define RK3568_SMART0_REGION3_DSP_ST 0x1CB8 409 #define RK3568_SMART0_REGION3_SCL_CTRL 0x1CC0 410 #define RK3568_SMART0_REGION3_SCL_FACTOR_YRGB 0x1CC4 411 #define RK3568_SMART0_REGION3_SCL_FACTOR_CBR 0x1CC8 412 #define RK3568_SMART0_REGION3_SCL_OFFSET 0x1CCC 413 414 #define RK3568_SMART1_CTRL0 0x1E00 415 #define RK3568_SMART1_CTRL1 0x1E04 416 #define RK3568_SMART1_REGION0_CTRL 0x1E10 417 #define RK3568_SMART1_REGION0_YRGB_MST 0x1E14 418 #define RK3568_SMART1_REGION0_CBR_MST 0x1E18 419 #define RK3568_SMART1_REGION0_VIR 0x1E1C 420 #define RK3568_SMART1_REGION0_ACT_INFO 0x1E20 421 #define RK3568_SMART1_REGION0_DSP_INFO 0x1E24 422 #define RK3568_SMART1_REGION0_DSP_ST 0x1E28 423 #define RK3568_SMART1_REGION0_SCL_CTRL 0x1E30 424 #define RK3568_SMART1_REGION0_SCL_FACTOR_YRGB 0x1E34 425 #define RK3568_SMART1_REGION0_SCL_FACTOR_CBR 0x1E38 426 #define RK3568_SMART1_REGION0_SCL_OFFSET 0x1E3C 427 #define RK3568_SMART1_REGION1_CTRL 0x1E40 428 #define RK3568_SMART1_REGION1_YRGB_MST 0x1E44 429 #define RK3568_SMART1_REGION1_CBR_MST 0x1E48 430 #define RK3568_SMART1_REGION1_VIR 0x1E4C 431 #define RK3568_SMART1_REGION1_ACT_INFO 0x1E50 432 #define RK3568_SMART1_REGION1_DSP_INFO 0x1E54 433 #define RK3568_SMART1_REGION1_DSP_ST 0x1E58 434 #define RK3568_SMART1_REGION1_SCL_CTRL 0x1E60 435 #define RK3568_SMART1_REGION1_SCL_FACTOR_YRGB 0x1E64 436 #define RK3568_SMART1_REGION1_SCL_FACTOR_CBR 0x1E68 437 #define RK3568_SMART1_REGION1_SCL_OFFSET 0x1E6C 438 #define RK3568_SMART1_REGION2_CTRL 0x1E70 439 #define RK3568_SMART1_REGION2_YRGB_MST 0x1E74 440 #define RK3568_SMART1_REGION2_CBR_MST 0x1E78 441 #define RK3568_SMART1_REGION2_VIR 0x1E7C 442 #define RK3568_SMART1_REGION2_ACT_INFO 0x1E80 443 #define RK3568_SMART1_REGION2_DSP_INFO 0x1E84 444 #define RK3568_SMART1_REGION2_DSP_ST 0x1E88 445 #define RK3568_SMART1_REGION2_SCL_CTRL 0x1E90 446 #define RK3568_SMART1_REGION2_SCL_FACTOR_YRGB 0x1E94 447 #define RK3568_SMART1_REGION2_SCL_FACTOR_CBR 0x1E98 448 #define RK3568_SMART1_REGION2_SCL_OFFSET 0x1E9C 449 #define RK3568_SMART1_REGION3_CTRL 0x1EA0 450 #define RK3568_SMART1_REGION3_YRGB_MST 0x1EA4 451 #define RK3568_SMART1_REGION3_CBR_MST 0x1EA8 452 #define RK3568_SMART1_REGION3_VIR 0x1EAC 453 #define RK3568_SMART1_REGION3_ACT_INFO 0x1EB0 454 #define RK3568_SMART1_REGION3_DSP_INFO 0x1EB4 455 #define RK3568_SMART1_REGION3_DSP_ST 0x1EB8 456 #define RK3568_SMART1_REGION3_SCL_CTRL 0x1EC0 457 #define RK3568_SMART1_REGION3_SCL_FACTOR_YRGB 0x1EC4 458 #define RK3568_SMART1_REGION3_SCL_FACTOR_CBR 0x1EC8 459 #define RK3568_SMART1_REGION3_SCL_OFFSET 0x1ECC 460 461 #define RK3568_MAX_REG 0x1ED0 462 463 #define RK3568_GRF_VO_CON1 0x0364 464 #define GRF_BT656_CLK_INV_SHIFT 1 465 #define GRF_BT1120_CLK_INV_SHIFT 2 466 #define GRF_RGB_DCLK_INV_SHIFT 3 467 468 #define VOP2_LAYER_MAX 8 469 #define VOP2_MAX_VP 4 470 471 enum vop2_csc_format { 472 CSC_BT601L, 473 CSC_BT709L, 474 CSC_BT601F, 475 CSC_BT2020, 476 }; 477 478 enum vop2_pol { 479 HSYNC_POSITIVE = 0, 480 VSYNC_POSITIVE = 1, 481 DEN_NEGATIVE = 2, 482 DCLK_INVERT = 3 483 }; 484 485 #define _VOP_REG(off, _mask, _shift, _write_mask) \ 486 { \ 487 .offset = off, \ 488 .mask = _mask, \ 489 .shift = _shift, \ 490 .write_mask = _write_mask, \ 491 } 492 493 #define VOP_REG(off, _mask, _shift) \ 494 _VOP_REG(off, _mask, _shift, false) 495 enum dither_down_mode { 496 RGB888_TO_RGB565 = 0x0, 497 RGB888_TO_RGB666 = 0x1 498 }; 499 500 enum vop2_video_ports_id { 501 VOP2_VP0, 502 VOP2_VP1, 503 VOP2_VP2, 504 VOP2_VP3, 505 VOP2_VP_MAX, 506 }; 507 508 struct vop2_layer { 509 uint8_t id; 510 /** 511 * @win_phys_id: window id of the layer selected. 512 * Every layer must make sure to select different 513 * windows of others. 514 */ 515 uint8_t win_phys_id; 516 }; 517 518 struct vop2_win { 519 uint8_t id; 520 uint8_t layer_id; 521 uint8_t phys_id; 522 }; 523 524 struct vop2_data { 525 u32 version; 526 struct vop_rect max_output[VOP2_MAX_VP]; 527 /** 528 * win_id: id of window attach to VP0,VP1,VP2,VP3, 529 * Only support one window for one VP in u-boot. 530 * 531 */ 532 uint8_t win_id[VOP2_MAX_VP]; 533 uint8_t nr_vps; 534 uint8_t nr_layers; 535 /** 536 * win_sel_id: from register LAYER_SEL 537 * 538 */ 539 uint8_t win_sel_id[VOP2_LAYER_MAX]; 540 }; 541 542 struct vop2 { 543 u32 *regsbak; 544 void *regs; 545 void *grf; 546 u32 reg_len; 547 u32 version; 548 const struct vop2_data *data; 549 /** 550 * @nr_wins: active wins attached to the video port 551 */ 552 uint8_t nr_wins[VOP2_VP_MAX]; 553 struct vop2_win win[VOP2_LAYER_MAX]; 554 struct vop2_layer layer[VOP2_LAYER_MAX]; 555 }; 556 557 static struct vop2 *rockchip_vop2; 558 static void vop2_setup_win_for_vp(struct display_state *state); 559 560 static inline uint16_t scl_cal_scale(int src, int dst, int shift) 561 { 562 return ((src * 2 - 3) << (shift - 1)) / (dst - 1); 563 } 564 565 static inline uint16_t scl_cal_scale2(int src, int dst) 566 { 567 return ((src - 1) << 12) / (dst - 1); 568 } 569 570 static inline void vop2_writel(struct vop2 *vop2, u32 offset, u32 v) 571 { 572 writel(v, vop2->regs + offset); 573 vop2->regsbak[offset >> 2] = v; 574 } 575 576 static inline u32 vop2_readl(struct vop2 *vop2, u32 offset) 577 { 578 return readl(vop2->regs + offset); 579 } 580 581 static inline void vop2_mask_write(struct vop2 *vop2, u32 offset, 582 u32 mask, u32 shift, u32 v, 583 bool write_mask) 584 { 585 if (!mask) 586 return; 587 588 if (write_mask) { 589 v = ((v & mask) << shift) | (mask << (shift + 16)); 590 } else { 591 u32 cached_val = vop2->regsbak[offset >> 2]; 592 593 v = (cached_val & ~(mask << shift)) | ((v & mask) << shift); 594 vop2->regsbak[offset >> 2] = v; 595 } 596 597 writel(v, vop2->regs + offset); 598 } 599 600 static inline void vop2_grf_writel(struct vop2 *vop, u32 offset, 601 u32 mask, u32 shift, u32 v) 602 { 603 u32 val = 0; 604 605 val = (v << shift) | (mask << (shift + 16)); 606 writel(val, vop->grf + offset); 607 } 608 609 static inline int us_to_vertical_line(struct drm_display_mode *mode, int us) 610 { 611 return us * mode->clock / mode->htotal / 1000; 612 } 613 614 static bool is_yuv_output(u32 bus_format) 615 { 616 switch (bus_format) { 617 case MEDIA_BUS_FMT_YUV8_1X24: 618 case MEDIA_BUS_FMT_YUV10_1X30: 619 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 620 case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 621 return true; 622 default: 623 return false; 624 } 625 } 626 627 static int vop2_convert_csc_mode(int csc_mode) 628 { 629 switch (csc_mode) { 630 case V4L2_COLORSPACE_SMPTE170M: 631 case V4L2_COLORSPACE_470_SYSTEM_M: 632 case V4L2_COLORSPACE_470_SYSTEM_BG: 633 return CSC_BT601L; 634 case V4L2_COLORSPACE_REC709: 635 case V4L2_COLORSPACE_SMPTE240M: 636 case V4L2_COLORSPACE_DEFAULT: 637 return CSC_BT709L; 638 case V4L2_COLORSPACE_JPEG: 639 return CSC_BT601F; 640 case V4L2_COLORSPACE_BT2020: 641 return CSC_BT2020; 642 default: 643 return CSC_BT709L; 644 } 645 } 646 647 static __maybe_unused bool is_uv_swap(u32 bus_format, u32 output_mode) 648 { 649 /* 650 * FIXME: 651 * 652 * There is no media type for YUV444 output, 653 * so when out_mode is AAAA or P888, assume output is YUV444 on 654 * yuv format. 655 * 656 * From H/W testing, YUV444 mode need a rb swap. 657 */ 658 if ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 || 659 bus_format == MEDIA_BUS_FMT_YUV10_1X30) && 660 (output_mode == ROCKCHIP_OUT_MODE_AAAA || 661 output_mode == ROCKCHIP_OUT_MODE_P888)) 662 return true; 663 else 664 return false; 665 } 666 667 static int rockchip_vop2_init_gamma(struct vop2 *vop2, 668 struct display_state *state) 669 { 670 return 0; 671 } 672 673 static void vop2_post_config(struct display_state *state, struct vop2 *vop2) 674 { 675 struct connector_state *conn_state = &state->conn_state; 676 struct drm_display_mode *mode = &conn_state->mode; 677 struct crtc_state *cstate = &state->crtc_state; 678 u32 vp_offset = (cstate->crtc_id * 0x100); 679 u16 vtotal = mode->crtc_vtotal; 680 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 681 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 682 u16 hdisplay = mode->crtc_hdisplay; 683 u16 vdisplay = mode->crtc_vdisplay; 684 u16 hsize = 685 hdisplay * (conn_state->overscan.left_margin + 686 conn_state->overscan.right_margin) / 200; 687 u16 vsize = 688 vdisplay * (conn_state->overscan.top_margin + 689 conn_state->overscan.bottom_margin) / 200; 690 u16 hact_end, vact_end; 691 u32 val; 692 u16 nr_mixers = 5, used_layer = 2, pre_scan_max_dly = 40; 693 u32 bg_ovl_dly, bg_dly, pre_scan_dly; 694 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 695 696 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 697 vsize = round_down(vsize, 2); 698 699 hact_st += hdisplay * (100 - conn_state->overscan.left_margin) / 200; 700 hact_end = hact_st + hsize; 701 val = hact_st << 16; 702 val |= hact_end; 703 704 vop2_writel(vop2, RK3568_VP0_POST_DSP_HACT_INFO + vp_offset, val); 705 vact_st += vdisplay * (100 - conn_state->overscan.top_margin) / 200; 706 vact_end = vact_st + vsize; 707 val = vact_st << 16; 708 val |= vact_end; 709 vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO + vp_offset, val); 710 val = scl_cal_scale2(vdisplay, vsize) << 16; 711 val |= scl_cal_scale2(hdisplay, hsize); 712 vop2_writel(vop2, RK3568_VP0_POST_SCL_FACTOR_YRGB + vp_offset, val); 713 #define POST_HORIZONTAL_SCALEDOWN_EN(x) ((x) << 0) 714 #define POST_VERTICAL_SCALEDOWN_EN(x) ((x) << 1) 715 vop2_writel(vop2, RK3568_VP0_POST_SCL_CTRL + vp_offset, 716 POST_HORIZONTAL_SCALEDOWN_EN(hdisplay != hsize) | 717 POST_VERTICAL_SCALEDOWN_EN(vdisplay != vsize)); 718 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 719 u16 vact_st_f1 = vtotal + vact_st + 1; 720 u16 vact_end_f1 = vact_st_f1 + vsize; 721 722 val = vact_st_f1 << 16 | vact_end_f1; 723 vop2_writel(vop2, RK3568_VP0_POST_DSP_VACT_INFO_F1 + vp_offset, val); 724 } 725 726 bg_ovl_dly = (nr_mixers - used_layer) << 1; 727 bg_dly = pre_scan_max_dly - bg_ovl_dly; 728 pre_scan_dly = bg_dly + (hdisplay >> 1) - 1; 729 pre_scan_dly = (pre_scan_dly << 16) | hsync_len; 730 vop2_writel(vop2, RK3568_VP0_PRE_SCAN_HTIMING + vp_offset, pre_scan_dly); 731 } 732 733 static void vop2_layer_map_initial(struct vop2 *vop2) 734 { 735 struct vop2_layer *layer; 736 struct vop2_win *win; 737 u32 layer_map, sel; 738 int i, j; 739 740 layer_map = vop2_readl(vop2, RK3568_OVL_LAYER_SEL); 741 742 for (i = 0; i < vop2->data->nr_layers; i++) { 743 sel = (layer_map >> (4 * i)) & 0xf; 744 layer = &vop2->layer[i]; 745 win = NULL; 746 for (j = 0; j < vop2->data->nr_layers; j++) { 747 if (sel == vop2->data->win_sel_id[j]) { 748 win = &vop2->win[j]; 749 break; 750 } 751 } 752 753 if (!win) { 754 printf("invalid layer map :0x%x\n", layer_map); 755 return; 756 } 757 758 layer->win_phys_id = j; 759 win->layer_id = i; 760 debug("layer%d select %d\n", i, j); 761 } 762 } 763 764 static int vop2_initial(struct vop2 *vop2, struct display_state *state) 765 { 766 struct crtc_state *cstate = &state->crtc_state; 767 struct connector_state *conn_state = &state->conn_state; 768 struct drm_display_mode *mode = &conn_state->mode; 769 char dclk_name[9]; 770 struct clk dclk; 771 uint8_t shift = 0; 772 int i, ret; 773 774 /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 775 ret = clk_set_defaults(cstate->dev); 776 if (ret) 777 debug("%s clk_set_defaults failed %d\n", __func__, ret); 778 snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", cstate->crtc_id); 779 ret = clk_get_by_name(cstate->dev, dclk_name, &dclk); 780 if (!ret) 781 ret = clk_set_rate(&dclk, mode->clock * 1000); 782 783 if (IS_ERR_VALUE(ret)) { 784 printf("%s: Failed to set dclk: ret=%d\n", __func__, ret); 785 return ret; 786 } 787 788 memcpy(vop2->regsbak, vop2->regs, vop2->reg_len); 789 790 rockchip_vop2_init_gamma(vop2, state); 791 vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, 792 OVL_PORT_MUX_REG_DONE_IMD_SHIFT, 1, false); 793 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 794 IF_CTRL_REG_DONE_IMD_SHIFT, 1, false); 795 for (i = 0; i < vop2->data->nr_vps - 1; i++) { 796 shift = i * 4; 797 vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, PORT_MUX_MASK, PORT_MUX_SHIFT + shift, 8, false); //todo 798 } 799 800 vop2_layer_map_initial(vop2); 801 802 return 0; 803 } 804 805 /* 806 * VOP2 have multi video ports. 807 * video port ------- crtc 808 */ 809 static int rockchip_vop2_preinit(struct display_state *state) 810 { 811 struct crtc_state *cstate = &state->crtc_state; 812 const struct vop2_data *vop2_data = cstate->crtc->data; 813 814 if (!rockchip_vop2) { 815 rockchip_vop2 = malloc(sizeof(struct vop2)); 816 if (!rockchip_vop2) 817 return -ENOMEM; 818 rockchip_vop2->regs = dev_read_addr_ptr(cstate->dev); 819 rockchip_vop2->regsbak = malloc(RK3568_MAX_REG); 820 rockchip_vop2->reg_len = RK3568_MAX_REG; 821 rockchip_vop2->grf = 822 syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 823 if (rockchip_vop2->grf <= 0) 824 printf("%s: Get syscon grf failed (ret=%p)\n", __func__, 825 rockchip_vop2->grf); 826 827 rockchip_vop2->version = vop2_data->version; 828 rockchip_vop2->data = vop2_data; 829 } 830 831 cstate->private = rockchip_vop2; 832 cstate->max_output = vop2_data->max_output[cstate->crtc_id]; 833 834 return 0; 835 } 836 837 static int rockchip_vop2_init(struct display_state *state) 838 { 839 struct crtc_state *cstate = &state->crtc_state; 840 struct connector_state *conn_state = &state->conn_state; 841 struct drm_display_mode *mode = &conn_state->mode; 842 //const struct rockchip_crtc *crtc = cstate->crtc; 843 //const struct vop2_data *vop2_data = crtc->data; 844 struct vop2 *vop2 = cstate->private; 845 u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; 846 u16 hdisplay = mode->crtc_hdisplay; 847 u16 htotal = mode->crtc_htotal; 848 u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start; 849 u16 hact_end = hact_st + hdisplay; 850 u16 vdisplay = mode->crtc_vdisplay; 851 u16 vtotal = mode->crtc_vtotal; 852 u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; 853 u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start; 854 u16 vact_end = vact_st + vdisplay; 855 bool yuv_overlay = false; 856 //bool yuv_overlay = false, post_r2y_en = false, post_y2r_en = false; 857 u32 vp_offset = (cstate->crtc_id * 0x100); 858 //struct clk dclk; 859 //fdt_size_t len; 860 u32 val; 861 //int ret; 862 bool dclk_inv; 863 uint8_t dither_down_en = 0; 864 uint8_t pre_dither_down_en = 0; 865 //uint8_t dither_down_mode = RGB888_TO_RGB666; 866 867 vop2_initial(vop2, state); 868 dclk_inv = (mode->flags & DRM_MODE_FLAG_PPIXDATA) ? 0 : 1; 869 val = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : BIT(HSYNC_POSITIVE); 870 val |= (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : BIT(VSYNC_POSITIVE); 871 872 if (conn_state->output_if & VOP_OUTPUT_IF_RGB) { 873 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 874 1, false); 875 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 876 RGB_MUX_SHIFT, cstate->crtc_id, false); 877 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 878 IF_CRTL_RGB_LVDS_DCLK_POL_SHIT, !!dclk_inv, 879 false); 880 vop2_grf_writel(vop2, RK3568_GRF_VO_CON1, EN_MASK, 881 GRF_RGB_DCLK_INV_SHIFT, !dclk_inv); 882 } 883 884 if (conn_state->output_if & VOP_OUTPUT_IF_BT1120) { 885 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, RGB_EN_SHIFT, 886 1, false); 887 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, 888 BT1120_EN_SHIFT, 1, false); 889 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 890 RGB_MUX_SHIFT, cstate->crtc_id, false); 891 vop2_grf_writel(vop2, RK3568_GRF_VO_CON1, EN_MASK, 892 GRF_BT1120_CLK_INV_SHIFT, !dclk_inv); 893 } 894 895 if (conn_state->output_if & VOP_OUTPUT_IF_BT656) { 896 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, BT656_EN_SHIFT, 897 1, false); 898 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 899 RGB_MUX_SHIFT, cstate->crtc_id, false); 900 vop2_grf_writel(vop2, RK3568_GRF_VO_CON1, EN_MASK, 901 GRF_BT656_CLK_INV_SHIFT, !dclk_inv); 902 } 903 904 if (conn_state->output_if & VOP_OUTPUT_IF_LVDS0) { 905 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS0_EN_SHIFT, 906 1, false); 907 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 908 LVDS0_MUX_SHIFT, cstate->crtc_id, false); 909 } 910 911 if (conn_state->output_if & VOP_OUTPUT_IF_LVDS1) { 912 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, LVDS1_EN_SHIFT, 913 1, false); 914 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 915 LVDS1_MUX_SHIFT, cstate->crtc_id, false); 916 } 917 918 if (conn_state->output_flags & 919 (ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE | 920 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE)) { 921 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 922 LVDS_DUAL_EN_SHIFT, 1, false); 923 if (conn_state->output_flags & 924 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) 925 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 926 LVDS_DUAL_LEFT_RIGHT_EN_SHIFT, 1, 927 false); 928 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 929 vop2_mask_write(vop2, RK3568_DSP_IF_CTRL, EN_MASK, 930 LVDS_DUAL_SWAP_EN_SHIFT, 1, false); 931 } 932 933 if (conn_state->output_if & VOP_OUTPUT_IF_MIPI0) { 934 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI0_EN_SHIFT, 935 1, false); 936 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 937 MIPI0_MUX_SHIFT, cstate->crtc_id, false); 938 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 939 IF_CRTL_MIPI_DCLK_POL_SHIT, ! !dclk_inv, false); 940 } 941 942 if (conn_state->output_if & VOP_OUTPUT_IF_MIPI1) { 943 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, MIPI1_EN_SHIFT, 944 1, false); 945 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 946 MIPI1_MUX_SHIFT, cstate->crtc_id, false); 947 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 948 IF_CRTL_MIPI_DCLK_POL_SHIT, ! !dclk_inv, false); 949 } 950 951 if (conn_state->output_flags & 952 ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE) { 953 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, EN_MASK, 954 MIPI_DUAL_EN_SHIFT, 1, false); 955 if (conn_state->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) 956 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, 957 EN_MASK, MIPI_DUAL_SWAP_EN_SHIFT, 1, 958 false); 959 } 960 961 if (conn_state->output_if & VOP_OUTPUT_IF_eDP0) { 962 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, EDP0_EN_SHIFT, 963 1, false); 964 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 965 EDP0_MUX_SHIFT, cstate->crtc_id, false); 966 } 967 968 if (conn_state->output_if & VOP_OUTPUT_IF_HDMI0) { 969 vop2_mask_write(vop2, RK3568_DSP_IF_EN, EN_MASK, HDMI0_EN_SHIFT, 970 1, false); 971 vop2_mask_write(vop2, RK3568_DSP_IF_EN, IF_MUX_MASK, 972 HDMI0_MUX_SHIFT, cstate->crtc_id, false); 973 vop2_mask_write(vop2, RK3568_DSP_IF_POL, EN_MASK, 974 IF_CRTL_HDMI_DCLK_POL_SHIT, 1, false); 975 vop2_mask_write(vop2, RK3568_DSP_IF_POL, 976 IF_CRTL_HDMI_PIN_POL_MASK, 977 IF_CRTL_HDMI_PIN_POL_SHIT, val, false); 978 } 979 980 if (is_uv_swap(conn_state->bus_format, conn_state->output_mode)) 981 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 982 DATA_SWAP_MASK, DATA_SWAP_SHIFT, DSP_RB_SWAP, 983 false); 984 else 985 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, 986 DATA_SWAP_MASK, DATA_SWAP_SHIFT, 0, 987 false); 988 989 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, OUT_MODE_MASK, 990 OUT_MODE_SHIFT, conn_state->output_mode, false); 991 992 switch (conn_state->bus_format) { 993 case MEDIA_BUS_FMT_RGB565_1X16: 994 dither_down_en = 1; 995 break; 996 case MEDIA_BUS_FMT_RGB666_1X18: 997 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: 998 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 999 case MEDIA_BUS_FMT_RGB666_1X7X3_JEIDA: 1000 dither_down_en = 1; 1001 break; 1002 case MEDIA_BUS_FMT_YUV8_1X24: 1003 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 1004 dither_down_en = 0; 1005 pre_dither_down_en = 1; 1006 break; 1007 case MEDIA_BUS_FMT_YUV10_1X30: 1008 case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 1009 case MEDIA_BUS_FMT_RGB888_1X24: 1010 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: 1011 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: 1012 default: 1013 dither_down_en = 0; 1014 pre_dither_down_en = 0; 1015 break; 1016 } 1017 1018 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_AAAA) 1019 pre_dither_down_en = 0; 1020 else 1021 pre_dither_down_en = 1; 1022 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1023 DITHER_DOWN_EN_SHIFT, dither_down_en, false); 1024 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1025 PRE_DITHER_DOWN_EN_SHIFT, pre_dither_down_en, false); 1026 1027 yuv_overlay = is_yuv_output(conn_state->bus_format) ? 1 : 0; 1028 vop2_mask_write(vop2, RK3568_OVL_CTRL, EN_MASK, cstate->crtc_id, 1029 yuv_overlay, false); 1030 1031 cstate->yuv_overlay = yuv_overlay; 1032 1033 vop2_writel(vop2, RK3568_VP0_DSP_HTOTAL_HS_END + vp_offset, 1034 (htotal << 16) | hsync_len); 1035 val = hact_st << 16; 1036 val |= hact_end; 1037 vop2_writel(vop2, RK3568_VP0_DSP_HACT_ST_END + vp_offset, val); 1038 val = vact_st << 16; 1039 val |= vact_end; 1040 vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END + vp_offset, val); 1041 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 1042 u16 vact_st_f1 = vtotal + vact_st + 1; 1043 u16 vact_end_f1 = vact_st_f1 + vdisplay; 1044 1045 val = vact_st_f1 << 16 | vact_end_f1; 1046 vop2_writel(vop2, RK3568_VP0_DSP_VACT_ST_END_F1 + vp_offset, 1047 val); 1048 1049 val = vtotal << 16 | (vtotal + vsync_len); 1050 vop2_writel(vop2, RK3568_VP0_DSP_VS_ST_END_F1 + vp_offset, val); 1051 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1052 INTERLACE_EN_SHIFT, 1, false); 1053 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1054 P2I_EN_SHIFT, 1, false); 1055 vtotal += vtotal + 1; 1056 } else { 1057 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1058 INTERLACE_EN_SHIFT, 0, false); 1059 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1060 P2I_EN_SHIFT, 0, false); 1061 } 1062 vop2_writel(vop2, RK3568_VP0_DSP_VTOTAL_VS_END + vp_offset, 1063 (vtotal << 16) | vsync_len); 1064 val = ! !(mode->flags & DRM_MODE_FLAG_DBLCLK); 1065 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1066 CORE_DCLK_DIV_EN_SHIFT, val, false); 1067 1068 if (conn_state->output_mode == ROCKCHIP_OUT_MODE_YUV420) 1069 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, DCLK_DIV2_MASK, 1070 DCLK_DIV2_SHIFT, 0x3, false); 1071 else 1072 vop2_mask_write(vop2, RK3568_VP0_MIPI_CTRL + vp_offset, DCLK_DIV2_MASK, 1073 DCLK_DIV2_SHIFT, 0, false); 1074 1075 if (yuv_overlay) 1076 val = 0x20010200; 1077 else 1078 val = 0; 1079 vop2_writel(vop2, RK3568_VP0_DSP_BG + vp_offset, val); 1080 1081 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1082 POST_DSP_OUT_R2Y_SHIFT, yuv_overlay, false); 1083 1084 vop2_post_config(state, vop2); 1085 vop2_setup_win_for_vp(state); 1086 1087 return 0; 1088 } 1089 1090 static void vop2_setup_win_for_vp(struct display_state *state) 1091 { 1092 struct crtc_state *cstate = &state->crtc_state; 1093 const struct rockchip_crtc *crtc = cstate->crtc; 1094 const struct vop2_data *vop2_data = crtc->data; 1095 struct vop2 *vop2 = cstate->private; 1096 u8 port_id = cstate->crtc_id; 1097 struct vop2_win *win; 1098 struct vop2_layer *layer; 1099 u8 used_layers = 0; 1100 u8 layer_id, win_phys_id, win_sel_id; 1101 u8 shift; 1102 int i; 1103 1104 for (i = 0; i < port_id; i++) 1105 used_layers += vop2->nr_wins[i]; 1106 1107 vop2->nr_wins[port_id]++; 1108 /* 1109 * Win and layer must map one by one, if a win is selected 1110 * by two layers, unexpected error may happen. 1111 * So when we attach a new win to a layer, we also move the 1112 * old win of the layer to the layer where the new win comes from. 1113 * 1114 */ 1115 layer = &vop2->layer[used_layers]; 1116 win = &vop2->win[port_id]; 1117 shift = port_id * 2; 1118 vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, LAYER_SEL_PORT_MASK, 1119 LAYER_SEL_PORT_SHIFT + shift, port_id, false); 1120 shift = used_layers * 4; 1121 win_phys_id = vop2->data->win_id[port_id]; 1122 win_sel_id = vop2->data->win_sel_id[win_phys_id]; 1123 vop2_mask_write(vop2, RK3568_OVL_LAYER_SEL, LAYER_SEL_PORT_MASK, shift, 1124 win_sel_id, false); 1125 layer_id = win->layer_id; 1126 win_phys_id = layer->win_phys_id; 1127 win->layer_id = layer->id; 1128 layer->win_phys_id = win->phys_id; 1129 layer = &vop2->layer[layer_id]; 1130 win = &vop2->win[win_phys_id]; 1131 shift = layer_id * 4; 1132 win_sel_id = vop2->data->win_sel_id[win_phys_id]; 1133 vop2_mask_write(vop2, RK3568_OVL_LAYER_SEL, LAYER_SEL_PORT_MASK, shift, 1134 win_sel_id, false); 1135 win->layer_id = layer_id; 1136 layer->win_phys_id = win_phys_id; 1137 1138 if (port_id == (vop2_data->nr_vps - 1)) 1139 used_layers = vop2_data->nr_layers; 1140 shift = port_id * 4; 1141 vop2_mask_write(vop2, RK3568_OVL_PORT_SEL, PORT_MUX_MASK, shift, 1142 used_layers, false); 1143 1144 if (port_id == 0) { 1145 vop2_writel(vop2, 0x604, 0x54760312); 1146 vop2_writel(vop2, 0x608, 0x84000781); 1147 vop2_writel(vop2, 0x6e0, 0x22000000); 1148 } else { 1149 vop2_writel(vop2, 0x604, 0x54720316); 1150 vop2_writel(vop2, 0x608, 0x84000708); 1151 vop2_writel(vop2, 0x6e4, 0x1e000000); 1152 } 1153 } 1154 1155 static int rockchip_vop2_set_plane(struct display_state *state) 1156 { 1157 struct crtc_state *cstate = &state->crtc_state; 1158 struct connector_state *conn_state = &state->conn_state; 1159 struct drm_display_mode *mode = &conn_state->mode; 1160 u32 act_info, dsp_info, dsp_st, dsp_stx, dsp_sty; 1161 struct vop2 *vop2 = cstate->private; 1162 int src_w = cstate->src_w; 1163 int src_h = cstate->src_h; 1164 int crtc_x = cstate->crtc_x; 1165 int crtc_y = cstate->crtc_y; 1166 int crtc_w = cstate->crtc_w; 1167 int crtc_h = cstate->crtc_h; 1168 int xvir = cstate->xvir; 1169 int y_mirror = 0; 1170 int csc_mode; 1171 u32 win_offset = cstate->crtc_id * 0x200; 1172 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id); 1173 1174 if (crtc_w > cstate->max_output.width) { 1175 printf("ERROR: output w[%d] exceeded max width[%d]\n", 1176 crtc_w, cstate->max_output.width); 1177 return -EINVAL; 1178 } 1179 1180 act_info = (src_h - 1) << 16; 1181 act_info |= (src_w - 1) & 0xffff; 1182 1183 dsp_info = (crtc_h - 1) << 16; 1184 dsp_info |= (crtc_w - 1) & 0xffff; 1185 1186 dsp_stx = crtc_x; 1187 dsp_sty = crtc_y; 1188 dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff); 1189 1190 if (mode->flags & DRM_MODE_FLAG_YMIRROR) 1191 y_mirror = 1; 1192 else 1193 y_mirror = 0; 1194 1195 if (y_mirror) 1196 cstate->dma_addr += (src_h - 1) * xvir * 4; 1197 vop2_mask_write(vop2, RK3568_ESMART0_CTRL1 + win_offset, EN_MASK, 1198 YMIRROR_EN_SHIFT, y_mirror, false); 1199 1200 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, 1201 WIN_FORMAT_MASK, WIN_FORMAT_SHIFT, cstate->format, 1202 false); 1203 vop2_writel(vop2, RK3568_ESMART0_REGION0_VIR + win_offset, xvir); 1204 vop2_writel(vop2, RK3568_ESMART0_REGION0_YRGB_MST + win_offset, 1205 cstate->dma_addr); 1206 1207 vop2_writel(vop2, RK3568_ESMART0_REGION0_ACT_INFO + win_offset, 1208 act_info); 1209 vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_INFO + win_offset, 1210 dsp_info); 1211 vop2_writel(vop2, RK3568_ESMART0_REGION0_DSP_ST + win_offset, dsp_st); 1212 1213 vop2_mask_write(vop2, RK3568_ESMART0_REGION0_CTRL + win_offset, EN_MASK, 1214 WIN_EN_SHIFT, 1, false); 1215 1216 csc_mode = vop2_convert_csc_mode(conn_state->color_space); 1217 vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, EN_MASK, 1218 RGB2YUV_EN_SHIFT, 1219 is_yuv_output(conn_state->bus_format), false); 1220 vop2_mask_write(vop2, RK3568_ESMART0_CTRL0 + win_offset, CSC_MODE_MASK, 1221 CSC_MODE_SHIFT, csc_mode, false); 1222 1223 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 1224 return 0; 1225 } 1226 1227 static int rockchip_vop2_prepare(struct display_state *state) 1228 { 1229 return 0; 1230 } 1231 1232 static int rockchip_vop2_enable(struct display_state *state) 1233 { 1234 struct crtc_state *cstate = &state->crtc_state; 1235 struct vop2 *vop2 = cstate->private; 1236 u32 vp_offset = (cstate->crtc_id * 0x100); 1237 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id); 1238 1239 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1240 STANDBY_EN_SHIFT, 0, false); 1241 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 1242 1243 return 0; 1244 } 1245 1246 static int rockchip_vop2_disable(struct display_state *state) 1247 { 1248 struct crtc_state *cstate = &state->crtc_state; 1249 struct vop2 *vop2 = cstate->private; 1250 u32 vp_offset = (cstate->crtc_id * 0x100); 1251 u32 cfg_done = CFG_DONE_EN | BIT(cstate->crtc_id); 1252 1253 vop2_mask_write(vop2, RK3568_VP0_DSP_CTRL + vp_offset, EN_MASK, 1254 STANDBY_EN_SHIFT, 1, false); 1255 vop2_writel(vop2, RK3568_REG_CFG_DONE, cfg_done); 1256 1257 return 0; 1258 } 1259 1260 const struct vop2_data rk3568_vop = { 1261 .nr_vps = 3, 1262 .max_output = { 1263 [VOP2_VP0] = {4096, 2304}, 1264 [VOP2_VP1] = {2048, 1536}, 1265 [VOP2_VP2] = {1920, 1080}, 1266 }, 1267 1268 /* 1269 * Cluster0-Win0: 0 1270 * Cluster1-Win0: 1 1271 * Esmart0-Win0: 2 1272 * Esmart1-Win0: 3 1273 * Smart0-Win0: 4 1274 * Smart1-Win0: 5 1275 */ 1276 .win_id = { 1277 [VOP2_VP0] = 2, 1278 [VOP2_VP1] = 3, 1279 [VOP2_VP2] = 4, 1280 }, 1281 1282 /** 1283 * Win select id: from register LAYER_SEL 1284 * 1285 * Cluster0-Win0: 0 1286 * Cluster1-Win0: 1 1287 * Esmart0-Win0: 2 1288 * Esmart1-Win0: 6 1289 * Smart0-Win0: 3 1290 * Smart1-Win0: 7 1291 */ 1292 .win_sel_id = {0, 1, 2, 6, 3, 7}, 1293 .nr_layers = 6, 1294 }; 1295 1296 const struct rockchip_crtc_funcs rockchip_vop2_funcs = { 1297 .preinit = rockchip_vop2_preinit, 1298 .prepare = rockchip_vop2_prepare, 1299 .init = rockchip_vop2_init, 1300 .set_plane = rockchip_vop2_set_plane, 1301 .enable = rockchip_vop2_enable, 1302 .disable = rockchip_vop2_disable, 1303 }; 1304