xref: /rk3399_rockchip-uboot/drivers/video/drm/rockchip_dw_hdmi.c (revision 6a3f45483155d9acf4c48780594ec9ed5adccdbe)
1f5e7d251SAlgea Cao /*
2f5e7d251SAlgea Cao  * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
3f5e7d251SAlgea Cao  *
4f5e7d251SAlgea Cao  * SPDX-License-Identifier:	GPL-2.0+
5f5e7d251SAlgea Cao  */
6f5e7d251SAlgea Cao 
7f5e7d251SAlgea Cao #include <common.h>
88e2bab3fSAlgea Cao #include <boot_rkimg.h>
98e2bab3fSAlgea Cao #include <asm/io.h>
10cb24dc0eSAlgea Cao #include <asm/gpio.h>
110594ce39SZhang Yubing #include <dm/of_access.h>
12f5e7d251SAlgea Cao #include <dm/device.h>
13f5e7d251SAlgea Cao #include <linux/dw_hdmi.h>
148e2bab3fSAlgea Cao #include <linux/hdmi.h>
158e2bab3fSAlgea Cao #include <linux/media-bus-format.h>
16f5e7d251SAlgea Cao #include "rockchip_display.h"
17f5e7d251SAlgea Cao #include "rockchip_crtc.h"
18f5e7d251SAlgea Cao #include "rockchip_connector.h"
19f5e7d251SAlgea Cao #include "dw_hdmi.h"
20f5e7d251SAlgea Cao #include "rockchip_dw_hdmi.h"
21f5e7d251SAlgea Cao 
22f5e7d251SAlgea Cao #define HDMI_SEL_LCDC(x, bit)  ((((x) & 1) << bit) | (1 << (16 + bit)))
23f5e7d251SAlgea Cao #define RK3288_GRF_SOC_CON6		0x025C
24f5e7d251SAlgea Cao #define RK3288_HDMI_LCDC_SEL		BIT(4)
25f5e7d251SAlgea Cao #define RK3399_GRF_SOC_CON20		0x6250
26f5e7d251SAlgea Cao #define RK3399_HDMI_LCDC_SEL		BIT(6)
27f5e7d251SAlgea Cao 
288e2bab3fSAlgea Cao #define RK3228_IO_3V_DOMAIN              ((7 << 4) | (7 << (4 + 16)))
298e2bab3fSAlgea Cao #define RK3328_IO_3V_DOMAIN              (7 << (9 + 16))
308e2bab3fSAlgea Cao #define RK3328_IO_5V_DOMAIN              ((7 << 9) | (3 << (9 + 16)))
318e2bab3fSAlgea Cao #define RK3328_IO_CTRL_BY_HDMI           ((1 << 13) | (1 << (13 + 16)))
328e2bab3fSAlgea Cao #define RK3328_IO_DDC_IN_MSK             ((3 << 10) | (3 << (10 + 16)))
338e2bab3fSAlgea Cao #define RK3228_IO_DDC_IN_MSK             ((3 << 13) | (3 << (13 + 16)))
348e2bab3fSAlgea Cao #define RK3228_GRF_SOC_CON2              0x0408
358e2bab3fSAlgea Cao #define RK3228_GRF_SOC_CON6              0x0418
368e2bab3fSAlgea Cao #define RK3328_GRF_SOC_CON2              0x0408
378e2bab3fSAlgea Cao #define RK3328_GRF_SOC_CON3              0x040c
388e2bab3fSAlgea Cao #define RK3328_GRF_SOC_CON4              0x0410
398e2bab3fSAlgea Cao 
40*6a3f4548SSandy Huang #define RK3528_GPIO0A_IOMUX_SEL_H	0x4
41*6a3f4548SSandy Huang #define RK3528_GPIO0A_PULL 		0x200
42*6a3f4548SSandy Huang #define RK3528_DDC_PULL			(0xf00 << 16)
43cb24dc0eSAlgea Cao #define RK3528_VO_GRF_HDMI_MASK		0x60014
44cb24dc0eSAlgea Cao #define RK3528_HDMI_SNKDET_SEL		((BIT(6) << 16) | BIT(6))
45cb24dc0eSAlgea Cao #define RK3528_HDMI_SNKDET		BIT(21)
46cb24dc0eSAlgea Cao #define RK3528_HDMI_CECIN_MSK		((BIT(2) << 16) | BIT(2))
47cb24dc0eSAlgea Cao #define RK3528_HDMI_SDAIN_MSK		((BIT(1) << 16) | BIT(1))
48cb24dc0eSAlgea Cao #define RK3528_HDMI_SCLIN_MSK		((BIT(0) << 16) | BIT(0))
49cb24dc0eSAlgea Cao 
50cb24dc0eSAlgea Cao #define RK3528_GPIO_SWPORT_DR_L		0x0000
51cb24dc0eSAlgea Cao #define RK3528_GPIO0_A2_DR		((BIT(2) << 16) | BIT(2))
52cb24dc0eSAlgea Cao 
535ccad8f6SAlgea Cao #define RK3568_GRF_VO_CON1               0x0364
545ccad8f6SAlgea Cao #define RK3568_HDMI_SDAIN_MSK            ((1 << 15) | (1 << (15 + 16)))
555ccad8f6SAlgea Cao #define RK3568_HDMI_SCLIN_MSK            ((1 << 14) | (1 << (14 + 16)))
565ccad8f6SAlgea Cao 
57f5e7d251SAlgea Cao static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
58f5e7d251SAlgea Cao 	{
59f5e7d251SAlgea Cao 		30666000, {
60f5e7d251SAlgea Cao 			{ 0x00b3, 0x0000 },
61f5e7d251SAlgea Cao 			{ 0x2153, 0x0000 },
62f5e7d251SAlgea Cao 			{ 0x40f3, 0x0000 },
63f5e7d251SAlgea Cao 		},
64f5e7d251SAlgea Cao 	},  {
65f5e7d251SAlgea Cao 		36800000, {
66f5e7d251SAlgea Cao 			{ 0x00b3, 0x0000 },
67f5e7d251SAlgea Cao 			{ 0x2153, 0x0000 },
68f5e7d251SAlgea Cao 			{ 0x40a2, 0x0001 },
69f5e7d251SAlgea Cao 		},
70f5e7d251SAlgea Cao 	},  {
71f5e7d251SAlgea Cao 		46000000, {
72f5e7d251SAlgea Cao 			{ 0x00b3, 0x0000 },
73f5e7d251SAlgea Cao 			{ 0x2142, 0x0001 },
74f5e7d251SAlgea Cao 			{ 0x40a2, 0x0001 },
75f5e7d251SAlgea Cao 		},
76f5e7d251SAlgea Cao 	},  {
77f5e7d251SAlgea Cao 		61333000, {
78f5e7d251SAlgea Cao 			{ 0x0072, 0x0001 },
79f5e7d251SAlgea Cao 			{ 0x2142, 0x0001 },
80f5e7d251SAlgea Cao 			{ 0x40a2, 0x0001 },
81f5e7d251SAlgea Cao 		},
82f5e7d251SAlgea Cao 	},  {
83f5e7d251SAlgea Cao 		73600000, {
84f5e7d251SAlgea Cao 			{ 0x0072, 0x0001 },
85f5e7d251SAlgea Cao 			{ 0x2142, 0x0001 },
86f5e7d251SAlgea Cao 			{ 0x4061, 0x0002 },
87f5e7d251SAlgea Cao 		},
88f5e7d251SAlgea Cao 	},  {
89f5e7d251SAlgea Cao 		92000000, {
90f5e7d251SAlgea Cao 			{ 0x0072, 0x0001 },
91f5e7d251SAlgea Cao 			{ 0x2145, 0x0002 },
92f5e7d251SAlgea Cao 			{ 0x4061, 0x0002 },
93f5e7d251SAlgea Cao 		},
94f5e7d251SAlgea Cao 	},  {
95f5e7d251SAlgea Cao 		122666000, {
96f5e7d251SAlgea Cao 			{ 0x0051, 0x0002 },
97f5e7d251SAlgea Cao 			{ 0x2145, 0x0002 },
98f5e7d251SAlgea Cao 			{ 0x4061, 0x0002 },
99f5e7d251SAlgea Cao 		},
100f5e7d251SAlgea Cao 	},  {
101f5e7d251SAlgea Cao 		147200000, {
102f5e7d251SAlgea Cao 			{ 0x0051, 0x0002 },
103f5e7d251SAlgea Cao 			{ 0x2145, 0x0002 },
104f5e7d251SAlgea Cao 			{ 0x4064, 0x0003 },
105f5e7d251SAlgea Cao 		},
106f5e7d251SAlgea Cao 	},  {
107f5e7d251SAlgea Cao 		184000000, {
108f5e7d251SAlgea Cao 			{ 0x0051, 0x0002 },
109f5e7d251SAlgea Cao 			{ 0x214c, 0x0003 },
110f5e7d251SAlgea Cao 			{ 0x4064, 0x0003 },
111f5e7d251SAlgea Cao 		},
112f5e7d251SAlgea Cao 	},  {
113f5e7d251SAlgea Cao 		226666000, {
114f5e7d251SAlgea Cao 			{ 0x0040, 0x0003 },
115f5e7d251SAlgea Cao 			{ 0x214c, 0x0003 },
116f5e7d251SAlgea Cao 			{ 0x4064, 0x0003 },
117f5e7d251SAlgea Cao 		},
118f5e7d251SAlgea Cao 	},  {
119f5e7d251SAlgea Cao 		272000000, {
120f5e7d251SAlgea Cao 			{ 0x0040, 0x0003 },
121f5e7d251SAlgea Cao 			{ 0x214c, 0x0003 },
122f5e7d251SAlgea Cao 			{ 0x5a64, 0x0003 },
123f5e7d251SAlgea Cao 		},
124f5e7d251SAlgea Cao 	},  {
125f5e7d251SAlgea Cao 		340000000, {
126f5e7d251SAlgea Cao 			{ 0x0040, 0x0003 },
127f5e7d251SAlgea Cao 			{ 0x3b4c, 0x0003 },
128f5e7d251SAlgea Cao 			{ 0x5a64, 0x0003 },
129f5e7d251SAlgea Cao 		},
130f5e7d251SAlgea Cao 	},  {
131f5e7d251SAlgea Cao 		600000000, {
132f5e7d251SAlgea Cao 			{ 0x1a40, 0x0003 },
133f5e7d251SAlgea Cao 			{ 0x3b4c, 0x0003 },
134f5e7d251SAlgea Cao 			{ 0x5a64, 0x0003 },
135f5e7d251SAlgea Cao 		},
136f5e7d251SAlgea Cao 	},  {
137f5e7d251SAlgea Cao 		~0UL, {
138f5e7d251SAlgea Cao 			{ 0x0000, 0x0000 },
139f5e7d251SAlgea Cao 			{ 0x0000, 0x0000 },
140f5e7d251SAlgea Cao 			{ 0x0000, 0x0000 },
141f5e7d251SAlgea Cao 		},
142f5e7d251SAlgea Cao 	}
143f5e7d251SAlgea Cao };
144f5e7d251SAlgea Cao 
1458e2bab3fSAlgea Cao static const struct dw_hdmi_mpll_config rockchip_mpll_cfg_420[] = {
1468e2bab3fSAlgea Cao 	{
1478e2bab3fSAlgea Cao 		30666000, {
1488e2bab3fSAlgea Cao 			{ 0x00b7, 0x0000 },
1498e2bab3fSAlgea Cao 			{ 0x2157, 0x0000 },
1508e2bab3fSAlgea Cao 			{ 0x40f7, 0x0000 },
1518e2bab3fSAlgea Cao 		},
1528e2bab3fSAlgea Cao 	},  {
1538e2bab3fSAlgea Cao 		92000000, {
1548e2bab3fSAlgea Cao 			{ 0x00b7, 0x0000 },
1558e2bab3fSAlgea Cao 			{ 0x2143, 0x0001 },
1568e2bab3fSAlgea Cao 			{ 0x40a3, 0x0001 },
1578e2bab3fSAlgea Cao 		},
1588e2bab3fSAlgea Cao 	},  {
1598e2bab3fSAlgea Cao 		184000000, {
1608e2bab3fSAlgea Cao 			{ 0x0073, 0x0001 },
1618e2bab3fSAlgea Cao 			{ 0x2146, 0x0002 },
1628e2bab3fSAlgea Cao 			{ 0x4062, 0x0002 },
1638e2bab3fSAlgea Cao 		},
1648e2bab3fSAlgea Cao 	},  {
1658e2bab3fSAlgea Cao 		340000000, {
1668e2bab3fSAlgea Cao 			{ 0x0052, 0x0003 },
1678e2bab3fSAlgea Cao 			{ 0x214d, 0x0003 },
1688e2bab3fSAlgea Cao 			{ 0x4065, 0x0003 },
1698e2bab3fSAlgea Cao 		},
1708e2bab3fSAlgea Cao 	},  {
1718e2bab3fSAlgea Cao 		600000000, {
1728e2bab3fSAlgea Cao 			{ 0x0041, 0x0003 },
1738e2bab3fSAlgea Cao 			{ 0x3b4d, 0x0003 },
1748e2bab3fSAlgea Cao 			{ 0x5a65, 0x0003 },
1758e2bab3fSAlgea Cao 		},
1768e2bab3fSAlgea Cao 	},  {
1778e2bab3fSAlgea Cao 		~0UL, {
1788e2bab3fSAlgea Cao 			{ 0x0000, 0x0000 },
1798e2bab3fSAlgea Cao 			{ 0x0000, 0x0000 },
1808e2bab3fSAlgea Cao 			{ 0x0000, 0x0000 },
1818e2bab3fSAlgea Cao 		},
1828e2bab3fSAlgea Cao 	}
1838e2bab3fSAlgea Cao };
1848e2bab3fSAlgea Cao 
185f5e7d251SAlgea Cao static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
186f5e7d251SAlgea Cao 	/*      pixelclk    bpp8    bpp10   bpp12 */
187f5e7d251SAlgea Cao 	{
188f5e7d251SAlgea Cao 		600000000, { 0x0000, 0x0000, 0x0000 },
189f5e7d251SAlgea Cao 	},  {
190f5e7d251SAlgea Cao 		~0UL,      { 0x0000, 0x0000, 0x0000},
191f5e7d251SAlgea Cao 	}
192f5e7d251SAlgea Cao };
193f5e7d251SAlgea Cao 
1947ff748e1SAlgea Cao static struct dw_hdmi_phy_config rockchip_phy_config[] = {
195f5e7d251SAlgea Cao 	/*pixelclk   symbol   term   vlev*/
196f5e7d251SAlgea Cao 	{ 74250000,  0x8009, 0x0004, 0x0272},
197f5e7d251SAlgea Cao 	{ 165000000, 0x802b, 0x0004, 0x0209},
198f5e7d251SAlgea Cao 	{ 297000000, 0x8039, 0x0005, 0x028d},
199f5e7d251SAlgea Cao 	{ 594000000, 0x8039, 0x0000, 0x019d},
2005ccad8f6SAlgea Cao 	{ ~0UL,	     0x0000, 0x0000, 0x0000},
201f5e7d251SAlgea Cao 	{ ~0UL,	     0x0000, 0x0000, 0x0000}
202f5e7d251SAlgea Cao };
203f5e7d251SAlgea Cao 
drm_rk_select_color(struct hdmi_edid_data * edid_data,struct base_screen_info * screen_info,enum dw_hdmi_devtype dev_type,bool output_bus_format_rgb)2048e2bab3fSAlgea Cao static unsigned int drm_rk_select_color(struct hdmi_edid_data *edid_data,
2058e2bab3fSAlgea Cao 					struct base_screen_info *screen_info,
20691e56900SLei Chen 					enum dw_hdmi_devtype dev_type,
20791e56900SLei Chen 					bool output_bus_format_rgb)
2088e2bab3fSAlgea Cao {
2098e2bab3fSAlgea Cao 	struct drm_display_info *info = &edid_data->display_info;
2108e2bab3fSAlgea Cao 	struct drm_display_mode *mode = edid_data->preferred_mode;
2118e2bab3fSAlgea Cao 	int max_tmds_clock = info->max_tmds_clock;
2128e2bab3fSAlgea Cao 	bool support_dc = false;
2138e2bab3fSAlgea Cao 	bool mode_420 = drm_mode_is_420(info, mode);
2148e2bab3fSAlgea Cao 	unsigned int color_depth = 8;
2158e2bab3fSAlgea Cao 	unsigned int base_color = DRM_HDMI_OUTPUT_YCBCR444;
2168e2bab3fSAlgea Cao 	unsigned int color_format = DRM_HDMI_OUTPUT_DEFAULT_RGB;
2178e2bab3fSAlgea Cao 	unsigned long tmdsclock, pixclock = mode->clock;
2188e2bab3fSAlgea Cao 
2198e2bab3fSAlgea Cao 	if (screen_info)
2208e2bab3fSAlgea Cao 		base_color = screen_info->format;
2218e2bab3fSAlgea Cao 
2228e2bab3fSAlgea Cao 	switch (base_color) {
2238e2bab3fSAlgea Cao 	case DRM_HDMI_OUTPUT_YCBCR_HQ:
2248e2bab3fSAlgea Cao 		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
2258e2bab3fSAlgea Cao 			color_format = DRM_HDMI_OUTPUT_YCBCR444;
2268e2bab3fSAlgea Cao 		else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
2278e2bab3fSAlgea Cao 			color_format = DRM_HDMI_OUTPUT_YCBCR422;
2288e2bab3fSAlgea Cao 		else if (mode_420)
2298e2bab3fSAlgea Cao 			color_format = DRM_HDMI_OUTPUT_YCBCR420;
2308e2bab3fSAlgea Cao 		break;
2318e2bab3fSAlgea Cao 	case DRM_HDMI_OUTPUT_YCBCR_LQ:
2328e2bab3fSAlgea Cao 		if (mode_420)
2338e2bab3fSAlgea Cao 			color_format = DRM_HDMI_OUTPUT_YCBCR420;
2348e2bab3fSAlgea Cao 		else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
2358e2bab3fSAlgea Cao 			color_format = DRM_HDMI_OUTPUT_YCBCR422;
2368e2bab3fSAlgea Cao 		else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
2378e2bab3fSAlgea Cao 			color_format = DRM_HDMI_OUTPUT_YCBCR444;
2388e2bab3fSAlgea Cao 		break;
2398e2bab3fSAlgea Cao 	case DRM_HDMI_OUTPUT_YCBCR420:
2408e2bab3fSAlgea Cao 		if (mode_420)
2418e2bab3fSAlgea Cao 			color_format = DRM_HDMI_OUTPUT_YCBCR420;
2428e2bab3fSAlgea Cao 		break;
2438e2bab3fSAlgea Cao 	case DRM_HDMI_OUTPUT_YCBCR422:
2448e2bab3fSAlgea Cao 		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
2458e2bab3fSAlgea Cao 			color_format = DRM_HDMI_OUTPUT_YCBCR422;
2468e2bab3fSAlgea Cao 		break;
2478e2bab3fSAlgea Cao 	case DRM_HDMI_OUTPUT_YCBCR444:
2488e2bab3fSAlgea Cao 		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
2498e2bab3fSAlgea Cao 			color_format = DRM_HDMI_OUTPUT_YCBCR444;
2508e2bab3fSAlgea Cao 		break;
2518e2bab3fSAlgea Cao 	case DRM_HDMI_OUTPUT_DEFAULT_RGB:
2528e2bab3fSAlgea Cao 	default:
2538e2bab3fSAlgea Cao 		break;
2548e2bab3fSAlgea Cao 	}
2558e2bab3fSAlgea Cao 
25691e56900SLei Chen 	if (output_bus_format_rgb)
25791e56900SLei Chen 		color_format = DRM_HDMI_OUTPUT_DEFAULT_RGB;
25891e56900SLei Chen 
2598e2bab3fSAlgea Cao 	if (color_format == DRM_HDMI_OUTPUT_DEFAULT_RGB &&
2608e2bab3fSAlgea Cao 	    info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30)
2618e2bab3fSAlgea Cao 		support_dc = true;
2628e2bab3fSAlgea Cao 	if (color_format == DRM_HDMI_OUTPUT_YCBCR444 &&
2638e2bab3fSAlgea Cao 	    (info->edid_hdmi_dc_modes &
2648e2bab3fSAlgea Cao 	     (DRM_EDID_HDMI_DC_Y444 | DRM_EDID_HDMI_DC_30)))
2658e2bab3fSAlgea Cao 		support_dc = true;
2668e2bab3fSAlgea Cao 	if (color_format == DRM_HDMI_OUTPUT_YCBCR422)
2678e2bab3fSAlgea Cao 		support_dc = true;
2688e2bab3fSAlgea Cao 	if (color_format == DRM_HDMI_OUTPUT_YCBCR420 &&
2698e2bab3fSAlgea Cao 	    info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
2708e2bab3fSAlgea Cao 		support_dc = true;
2718e2bab3fSAlgea Cao 
2728e2bab3fSAlgea Cao 	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
2738e2bab3fSAlgea Cao 		pixclock *= 2;
2748e2bab3fSAlgea Cao 
2758e2bab3fSAlgea Cao 	if (screen_info && screen_info->depth == 10)
2768e2bab3fSAlgea Cao 		color_depth = screen_info->depth;
2778e2bab3fSAlgea Cao 
2788e2bab3fSAlgea Cao 	if (color_format == DRM_HDMI_OUTPUT_YCBCR422 || color_depth == 8)
2798e2bab3fSAlgea Cao 		tmdsclock = pixclock;
2808e2bab3fSAlgea Cao 	else
2818e2bab3fSAlgea Cao 		tmdsclock = pixclock * color_depth / 8;
2828e2bab3fSAlgea Cao 
2838e2bab3fSAlgea Cao 	if (color_format == DRM_HDMI_OUTPUT_YCBCR420)
2848e2bab3fSAlgea Cao 		tmdsclock /= 2;
2858e2bab3fSAlgea Cao 
2868e2bab3fSAlgea Cao 	if (!max_tmds_clock)
2878e2bab3fSAlgea Cao 		max_tmds_clock = 340000;
2888e2bab3fSAlgea Cao 
2898e2bab3fSAlgea Cao 	switch (dev_type) {
2908e2bab3fSAlgea Cao 	case RK3368_HDMI:
2918e2bab3fSAlgea Cao 		max_tmds_clock = min(max_tmds_clock, 340000);
2928e2bab3fSAlgea Cao 		break;
2938e2bab3fSAlgea Cao 	case RK3328_HDMI:
2948e2bab3fSAlgea Cao 	case RK3228_HDMI:
2958e2bab3fSAlgea Cao 		max_tmds_clock = min(max_tmds_clock, 371250);
2968e2bab3fSAlgea Cao 		break;
2978e2bab3fSAlgea Cao 	default:
2988e2bab3fSAlgea Cao 		max_tmds_clock = min(max_tmds_clock, 594000);
2998e2bab3fSAlgea Cao 		break;
3008e2bab3fSAlgea Cao 	}
3018e2bab3fSAlgea Cao 
3028e2bab3fSAlgea Cao 	if (tmdsclock > max_tmds_clock) {
3038e2bab3fSAlgea Cao 		if (max_tmds_clock >= 594000) {
3048e2bab3fSAlgea Cao 			color_depth = 8;
3058e2bab3fSAlgea Cao 		} else if (max_tmds_clock > 340000) {
3068e2bab3fSAlgea Cao 			if (drm_mode_is_420(info, mode))
3078e2bab3fSAlgea Cao 				color_format = DRM_HDMI_OUTPUT_YCBCR420;
3088e2bab3fSAlgea Cao 		} else {
3098e2bab3fSAlgea Cao 			color_depth = 8;
3108e2bab3fSAlgea Cao 			if (drm_mode_is_420(info, mode))
3118e2bab3fSAlgea Cao 				color_format = DRM_HDMI_OUTPUT_YCBCR420;
3128e2bab3fSAlgea Cao 		}
3138e2bab3fSAlgea Cao 	}
3148e2bab3fSAlgea Cao 
3158e2bab3fSAlgea Cao 	if (color_depth > 8 && support_dc) {
3168e2bab3fSAlgea Cao 		if (dev_type == RK3288_HDMI)
3178e2bab3fSAlgea Cao 			return MEDIA_BUS_FMT_RGB101010_1X30;
3188e2bab3fSAlgea Cao 		switch (color_format) {
3198e2bab3fSAlgea Cao 		case DRM_HDMI_OUTPUT_YCBCR444:
3208e2bab3fSAlgea Cao 			return MEDIA_BUS_FMT_YUV10_1X30;
3218e2bab3fSAlgea Cao 		case DRM_HDMI_OUTPUT_YCBCR422:
3228e2bab3fSAlgea Cao 			return MEDIA_BUS_FMT_UYVY10_1X20;
3238e2bab3fSAlgea Cao 		case DRM_HDMI_OUTPUT_YCBCR420:
3248e2bab3fSAlgea Cao 			return MEDIA_BUS_FMT_UYYVYY10_0_5X30;
3258e2bab3fSAlgea Cao 		default:
3268e2bab3fSAlgea Cao 			return MEDIA_BUS_FMT_RGB101010_1X30;
3278e2bab3fSAlgea Cao 		}
3288e2bab3fSAlgea Cao 	} else {
3298e2bab3fSAlgea Cao 		if (dev_type == RK3288_HDMI)
3308e2bab3fSAlgea Cao 			return MEDIA_BUS_FMT_RGB888_1X24;
3318e2bab3fSAlgea Cao 		switch (color_format) {
3328e2bab3fSAlgea Cao 		case DRM_HDMI_OUTPUT_YCBCR444:
3338e2bab3fSAlgea Cao 			return MEDIA_BUS_FMT_YUV8_1X24;
3348e2bab3fSAlgea Cao 		case DRM_HDMI_OUTPUT_YCBCR422:
3358e2bab3fSAlgea Cao 			return MEDIA_BUS_FMT_UYVY8_1X16;
3368e2bab3fSAlgea Cao 		case DRM_HDMI_OUTPUT_YCBCR420:
3378e2bab3fSAlgea Cao 			return MEDIA_BUS_FMT_UYYVYY8_0_5X24;
3388e2bab3fSAlgea Cao 		default:
3398e2bab3fSAlgea Cao 			return MEDIA_BUS_FMT_RGB888_1X24;
3408e2bab3fSAlgea Cao 		}
3418e2bab3fSAlgea Cao 	}
3428e2bab3fSAlgea Cao }
3438e2bab3fSAlgea Cao 
drm_rk_selete_output(struct hdmi_edid_data * edid_data,struct connector_state * conn_state,unsigned int * bus_format,struct overscan * overscan,enum dw_hdmi_devtype dev_type,bool output_bus_format_rgb)3448e2bab3fSAlgea Cao void drm_rk_selete_output(struct hdmi_edid_data *edid_data,
3455ccb1b20SAlgea Cao 			  struct connector_state *conn_state,
3468e2bab3fSAlgea Cao 			  unsigned int *bus_format,
3478e2bab3fSAlgea Cao 			  struct overscan *overscan,
34891e56900SLei Chen 			  enum dw_hdmi_devtype dev_type,
34991e56900SLei Chen 			  bool output_bus_format_rgb)
3508e2bab3fSAlgea Cao {
3515ccb1b20SAlgea Cao 	struct base2_disp_info *base2_parameter = conn_state->disp_info;
3528e2bab3fSAlgea Cao 	const struct base_overscan *scan;
3538e2bab3fSAlgea Cao 	struct base_screen_info *screen_info = NULL;
3545ccb1b20SAlgea Cao 	struct base2_screen_info *screen_info2 = NULL;
3558e2bab3fSAlgea Cao 	int max_scan = 100;
3568e2bab3fSAlgea Cao 	int min_scan = 51;
357*6a3f4548SSandy Huang #ifdef CONFIG_SPL_BUILD
358*6a3f4548SSandy Huang 	int i, screen_size;
359*6a3f4548SSandy Huang #else
360*6a3f4548SSandy Huang 	int ret, i, screen_size;
361fc672cf1SAlgea Cao 	int offset = 0;
362fc672cf1SAlgea Cao 	bool found = false;
3638e2bab3fSAlgea Cao 	struct blk_desc *dev_desc;
3648e2bab3fSAlgea Cao 	disk_partition_t part_info;
3658e2bab3fSAlgea Cao 	char baseparameter_buf[8 * RK_BLK_SIZE] __aligned(ARCH_DMA_MINALIGN);
366*6a3f4548SSandy Huang 	struct base_disp_info base_parameter;
367*6a3f4548SSandy Huang #endif
3688e2bab3fSAlgea Cao 
3698e2bab3fSAlgea Cao 	overscan->left_margin = max_scan;
3708e2bab3fSAlgea Cao 	overscan->right_margin = max_scan;
3718e2bab3fSAlgea Cao 	overscan->top_margin = max_scan;
3728e2bab3fSAlgea Cao 	overscan->bottom_margin = max_scan;
3738e2bab3fSAlgea Cao 
37491e56900SLei Chen 	if (dev_type == RK3288_HDMI || output_bus_format_rgb)
3758e2bab3fSAlgea Cao 		*bus_format = MEDIA_BUS_FMT_RGB888_1X24;
3768e2bab3fSAlgea Cao 	else
3778e2bab3fSAlgea Cao 		*bus_format = MEDIA_BUS_FMT_YUV8_1X24;
3788e2bab3fSAlgea Cao 
379*6a3f4548SSandy Huang #ifdef CONFIG_SPL_BUILD
380*6a3f4548SSandy Huang 	scan = &base2_parameter->overscan_info;
381*6a3f4548SSandy Huang 	screen_size = sizeof(base2_parameter->screen_info) /
382*6a3f4548SSandy Huang 		sizeof(base2_parameter->screen_info[0]);
383*6a3f4548SSandy Huang 
384*6a3f4548SSandy Huang 	for (i = 0; i < screen_size; i++) {
385*6a3f4548SSandy Huang 		if (base2_parameter->screen_info[i].type ==
386*6a3f4548SSandy Huang 		    DRM_MODE_CONNECTOR_HDMIA) {
387*6a3f4548SSandy Huang 			screen_info2 =
388*6a3f4548SSandy Huang 				&base2_parameter->screen_info[i];
389*6a3f4548SSandy Huang 			break;
390*6a3f4548SSandy Huang 		}
391*6a3f4548SSandy Huang 	}
392*6a3f4548SSandy Huang 	screen_info = malloc(sizeof(*screen_info));
393*6a3f4548SSandy Huang 
394*6a3f4548SSandy Huang 	screen_info->type = screen_info2->type;
395*6a3f4548SSandy Huang 	screen_info->mode = screen_info2->resolution;
396*6a3f4548SSandy Huang 	screen_info->format = screen_info2->format;
397*6a3f4548SSandy Huang 	screen_info->depth = screen_info2->depthc;
398*6a3f4548SSandy Huang 	screen_info->feature = screen_info2->feature;
399*6a3f4548SSandy Huang #else
4005ccb1b20SAlgea Cao 	if (!base2_parameter) {
4018e2bab3fSAlgea Cao 		dev_desc = rockchip_get_bootdev();
4028e2bab3fSAlgea Cao 		if (!dev_desc) {
4038e2bab3fSAlgea Cao 			printf("%s: Could not find device\n", __func__);
4042eab0e46SAlgea Cao 			goto null_basep;
4058e2bab3fSAlgea Cao 		}
4068e2bab3fSAlgea Cao 
4075ccb1b20SAlgea Cao 		ret = part_get_info_by_name(dev_desc, "baseparameter",
4085ccb1b20SAlgea Cao 					    &part_info);
4095ccb1b20SAlgea Cao 		if (ret < 0) {
4108e2bab3fSAlgea Cao 			printf("Could not find baseparameter partition\n");
4112eab0e46SAlgea Cao 			goto null_basep;
4128e2bab3fSAlgea Cao 		}
4138e2bab3fSAlgea Cao 
414fc672cf1SAlgea Cao read_aux:
415fc672cf1SAlgea Cao 		ret = blk_dread(dev_desc, part_info.start + offset, 1,
4168e2bab3fSAlgea Cao 				(void *)baseparameter_buf);
4178e2bab3fSAlgea Cao 		if (ret < 0) {
4188e2bab3fSAlgea Cao 			printf("read baseparameter failed\n");
4192eab0e46SAlgea Cao 			goto null_basep;
4208e2bab3fSAlgea Cao 		}
4218e2bab3fSAlgea Cao 
4225ccb1b20SAlgea Cao 		memcpy(&base_parameter, baseparameter_buf,
4235ccb1b20SAlgea Cao 		       sizeof(base_parameter));
4248e2bab3fSAlgea Cao 		scan = &base_parameter.scan;
4258e2bab3fSAlgea Cao 
4265ccb1b20SAlgea Cao 		screen_size = sizeof(base_parameter.screen_list) /
4275ccb1b20SAlgea Cao 			sizeof(base_parameter.screen_list[0]);
4285ccb1b20SAlgea Cao 
4295ccb1b20SAlgea Cao 		for (i = 0; i < screen_size; i++) {
4305ccb1b20SAlgea Cao 			if (base_parameter.screen_list[i].type ==
4315ccb1b20SAlgea Cao 			    DRM_MODE_CONNECTOR_HDMIA) {
432fc672cf1SAlgea Cao 				found = true;
4335ccb1b20SAlgea Cao 				screen_info = &base_parameter.screen_list[i];
4345ccb1b20SAlgea Cao 				break;
4355ccb1b20SAlgea Cao 			}
4365ccb1b20SAlgea Cao 		}
437fc672cf1SAlgea Cao 
438fc672cf1SAlgea Cao 		if (!found && !offset) {
439fc672cf1SAlgea Cao 			printf("hdmi info isn't saved in main block\n");
440fc672cf1SAlgea Cao 			offset += 16;
441fc672cf1SAlgea Cao 			goto read_aux;
442fc672cf1SAlgea Cao 		}
4435ccb1b20SAlgea Cao 	} else {
4445ccb1b20SAlgea Cao 		scan = &base2_parameter->overscan_info;
4455ccb1b20SAlgea Cao 		screen_size = sizeof(base2_parameter->screen_info) /
4465ccb1b20SAlgea Cao 			sizeof(base2_parameter->screen_info[0]);
4475ccb1b20SAlgea Cao 
4485ccb1b20SAlgea Cao 		for (i = 0; i < screen_size; i++) {
4495ccb1b20SAlgea Cao 			if (base2_parameter->screen_info[i].type ==
4505ccb1b20SAlgea Cao 			    DRM_MODE_CONNECTOR_HDMIA) {
4515ccb1b20SAlgea Cao 				screen_info2 =
4525ccb1b20SAlgea Cao 					&base2_parameter->screen_info[i];
4535ccb1b20SAlgea Cao 				break;
4545ccb1b20SAlgea Cao 			}
4555ccb1b20SAlgea Cao 		}
4565ccb1b20SAlgea Cao 		screen_info = malloc(sizeof(*screen_info));
4575ccb1b20SAlgea Cao 
4585ccb1b20SAlgea Cao 		screen_info->type = screen_info2->type;
4595ccb1b20SAlgea Cao 		screen_info->mode = screen_info2->resolution;
4605ccb1b20SAlgea Cao 		screen_info->format = screen_info2->format;
4615ccb1b20SAlgea Cao 		screen_info->depth = screen_info2->depthc;
4625ccb1b20SAlgea Cao 		screen_info->feature = screen_info2->feature;
4635ccb1b20SAlgea Cao 	}
464*6a3f4548SSandy Huang #endif
4655ccb1b20SAlgea Cao 
4668e2bab3fSAlgea Cao 	if (scan->leftscale < min_scan && scan->leftscale > 0)
4678e2bab3fSAlgea Cao 		overscan->left_margin = min_scan;
4688e2bab3fSAlgea Cao 	else if (scan->leftscale < max_scan && scan->leftscale > 0)
4698e2bab3fSAlgea Cao 		overscan->left_margin = scan->leftscale;
4708e2bab3fSAlgea Cao 
4718e2bab3fSAlgea Cao 	if (scan->rightscale < min_scan && scan->rightscale > 0)
4728e2bab3fSAlgea Cao 		overscan->right_margin = min_scan;
4738e2bab3fSAlgea Cao 	else if (scan->rightscale < max_scan && scan->rightscale > 0)
4748e2bab3fSAlgea Cao 		overscan->right_margin = scan->rightscale;
4758e2bab3fSAlgea Cao 
4768e2bab3fSAlgea Cao 	if (scan->topscale < min_scan && scan->topscale > 0)
4778e2bab3fSAlgea Cao 		overscan->top_margin = min_scan;
4788e2bab3fSAlgea Cao 	else if (scan->topscale < max_scan && scan->topscale > 0)
4798e2bab3fSAlgea Cao 		overscan->top_margin = scan->topscale;
4808e2bab3fSAlgea Cao 
4818e2bab3fSAlgea Cao 	if (scan->bottomscale < min_scan && scan->bottomscale > 0)
4828e2bab3fSAlgea Cao 		overscan->bottom_margin = min_scan;
4838e2bab3fSAlgea Cao 	else if (scan->bottomscale < max_scan && scan->bottomscale > 0)
4848e2bab3fSAlgea Cao 		overscan->bottom_margin = scan->bottomscale;
4858e2bab3fSAlgea Cao 
486*6a3f4548SSandy Huang #ifndef CONFIG_SPL_BUILD
4872eab0e46SAlgea Cao null_basep:
488*6a3f4548SSandy Huang #endif
4898e2bab3fSAlgea Cao 
4908e2bab3fSAlgea Cao 	if (screen_info)
4918e2bab3fSAlgea Cao 		printf("base_parameter.mode:%dx%d\n",
4928e2bab3fSAlgea Cao 		       screen_info->mode.hdisplay,
4938e2bab3fSAlgea Cao 		       screen_info->mode.vdisplay);
4948e2bab3fSAlgea Cao 	drm_rk_select_mode(edid_data, screen_info);
4958e2bab3fSAlgea Cao 
4968e2bab3fSAlgea Cao 	*bus_format = drm_rk_select_color(edid_data, screen_info,
49791e56900SLei Chen 					  dev_type, output_bus_format_rgb);
4988e2bab3fSAlgea Cao }
4998e2bab3fSAlgea Cao 
inno_dw_hdmi_set_domain(void * grf,int status)5008e2bab3fSAlgea Cao void inno_dw_hdmi_set_domain(void *grf, int status)
5018e2bab3fSAlgea Cao {
5028e2bab3fSAlgea Cao 	if (status)
5038e2bab3fSAlgea Cao 		writel(RK3328_IO_5V_DOMAIN, grf + RK3328_GRF_SOC_CON4);
5048e2bab3fSAlgea Cao 	else
5058e2bab3fSAlgea Cao 		writel(RK3328_IO_3V_DOMAIN, grf + RK3328_GRF_SOC_CON4);
5068e2bab3fSAlgea Cao }
5078e2bab3fSAlgea Cao 
dw_hdmi_set_iomux(void * grf,void * gpio_base,struct gpio_desc * hpd_gpiod,int dev_type)508cb24dc0eSAlgea Cao void dw_hdmi_set_iomux(void *grf, void *gpio_base, struct gpio_desc *hpd_gpiod,
509cb24dc0eSAlgea Cao 		       int dev_type)
5108e2bab3fSAlgea Cao {
511cb24dc0eSAlgea Cao 	u32 val = 0;
512fb5b9a60SAlgea Cao 	int i = 400;
513*6a3f4548SSandy Huang #ifdef CONFIG_SPL_BUILD
514*6a3f4548SSandy Huang 	void *gpio0_ioc = (void *)RK3528_GPIO0_IOC_BASE;
515*6a3f4548SSandy Huang #endif
516cb24dc0eSAlgea Cao 
5178e2bab3fSAlgea Cao 	switch (dev_type) {
5188e2bab3fSAlgea Cao 	case RK3328_HDMI:
5198e2bab3fSAlgea Cao 		writel(RK3328_IO_DDC_IN_MSK, grf + RK3328_GRF_SOC_CON2);
5208e2bab3fSAlgea Cao 		writel(RK3328_IO_CTRL_BY_HDMI, grf + RK3328_GRF_SOC_CON3);
5218e2bab3fSAlgea Cao 		break;
5228e2bab3fSAlgea Cao 	case RK3228_HDMI:
5238e2bab3fSAlgea Cao 		writel(RK3228_IO_3V_DOMAIN, grf + RK3228_GRF_SOC_CON6);
5248e2bab3fSAlgea Cao 		writel(RK3228_IO_DDC_IN_MSK, grf + RK3228_GRF_SOC_CON2);
5258e2bab3fSAlgea Cao 		break;
526cb24dc0eSAlgea Cao 	case RK3528_HDMI:
527cb24dc0eSAlgea Cao 		writel(RK3528_HDMI_SDAIN_MSK | RK3528_HDMI_SCLIN_MSK |
528cb24dc0eSAlgea Cao 		       RK3528_HDMI_SNKDET_SEL,
529cb24dc0eSAlgea Cao 		       grf + RK3528_VO_GRF_HDMI_MASK);
530cb24dc0eSAlgea Cao 
531*6a3f4548SSandy Huang #ifdef CONFIG_SPL_BUILD
532*6a3f4548SSandy Huang 		val = (0x11 << 16) | 0x11;
533*6a3f4548SSandy Huang 		writel(val, gpio0_ioc + RK3528_GPIO0A_IOMUX_SEL_H);
534*6a3f4548SSandy Huang 
535*6a3f4548SSandy Huang 		writel(RK3528_DDC_PULL, gpio0_ioc + RK3528_GPIO0A_PULL);
536*6a3f4548SSandy Huang 
537*6a3f4548SSandy Huang 		/* gpio0_a2's input enable is controlled by gpio output data bit */
538*6a3f4548SSandy Huang 		writel(RK3528_GPIO0_A2_DR, gpio_base + RK3528_GPIO_SWPORT_DR_L);
539*6a3f4548SSandy Huang 
540*6a3f4548SSandy Huang 		while (i--) {
541*6a3f4548SSandy Huang 			val = readl(gpio_base + 0x70) & BIT(2);
542*6a3f4548SSandy Huang 			if (val)
543*6a3f4548SSandy Huang 				break;
544*6a3f4548SSandy Huang 			mdelay(5);
545*6a3f4548SSandy Huang 		}
546*6a3f4548SSandy Huang #else
547cb24dc0eSAlgea Cao 		writel(val, grf + RK3528_VO_GRF_HDMI_MASK);
548cb24dc0eSAlgea Cao 
549cb24dc0eSAlgea Cao 		/* gpio0_a2's input enable is controlled by gpio output data bit */
550cb24dc0eSAlgea Cao 		writel(RK3528_GPIO0_A2_DR, gpio_base + RK3528_GPIO_SWPORT_DR_L);
551cb24dc0eSAlgea Cao 
552fb5b9a60SAlgea Cao 		if (dm_gpio_is_valid(hpd_gpiod)) {
553fb5b9a60SAlgea Cao 			while (i--) {
554cb24dc0eSAlgea Cao 				val = dm_gpio_get_value(hpd_gpiod);
555fb5b9a60SAlgea Cao 				if (val)
556fb5b9a60SAlgea Cao 					break;
557fb5b9a60SAlgea Cao 				mdelay(5);
558fb5b9a60SAlgea Cao 			}
559fb5b9a60SAlgea Cao 		}
560*6a3f4548SSandy Huang #endif
561cb24dc0eSAlgea Cao 
562cb24dc0eSAlgea Cao 		if (val)
563cb24dc0eSAlgea Cao 			val = RK3528_HDMI_SNKDET | BIT(5);
564cb24dc0eSAlgea Cao 		else
565cb24dc0eSAlgea Cao 			val = RK3528_HDMI_SNKDET;
566cb24dc0eSAlgea Cao 		writel(val, grf + RK3528_VO_GRF_HDMI_MASK);
567cb24dc0eSAlgea Cao 
568cb24dc0eSAlgea Cao 		break;
5695ccad8f6SAlgea Cao 	case RK3568_HDMI:
5705ccad8f6SAlgea Cao 		writel(RK3568_HDMI_SDAIN_MSK | RK3568_HDMI_SCLIN_MSK,
5715ccad8f6SAlgea Cao 		       grf + RK3568_GRF_VO_CON1);
5725ccad8f6SAlgea Cao 		break;
5738e2bab3fSAlgea Cao 	default:
5748e2bab3fSAlgea Cao 		break;
5758e2bab3fSAlgea Cao 	}
5768e2bab3fSAlgea Cao }
5778e2bab3fSAlgea Cao 
5788e2bab3fSAlgea Cao static const struct dw_hdmi_phy_ops inno_dw_hdmi_phy_ops = {
5798e2bab3fSAlgea Cao 	.init = inno_dw_hdmi_phy_init,
5808e2bab3fSAlgea Cao 	.disable = inno_dw_hdmi_phy_disable,
5818e2bab3fSAlgea Cao 	.read_hpd = inno_dw_hdmi_phy_read_hpd,
5828e2bab3fSAlgea Cao 	.mode_valid = inno_dw_hdmi_mode_valid,
5838e2bab3fSAlgea Cao };
5848e2bab3fSAlgea Cao 
585f5e7d251SAlgea Cao static const struct rockchip_connector_funcs rockchip_dw_hdmi_funcs = {
586f5e7d251SAlgea Cao 	.init = rockchip_dw_hdmi_init,
587f5e7d251SAlgea Cao 	.deinit = rockchip_dw_hdmi_deinit,
588f5e7d251SAlgea Cao 	.prepare = rockchip_dw_hdmi_prepare,
589f5e7d251SAlgea Cao 	.enable = rockchip_dw_hdmi_enable,
590f5e7d251SAlgea Cao 	.disable = rockchip_dw_hdmi_disable,
591f5e7d251SAlgea Cao 	.get_timing = rockchip_dw_hdmi_get_timing,
592f5e7d251SAlgea Cao 	.detect = rockchip_dw_hdmi_detect,
593f5e7d251SAlgea Cao 	.get_edid = rockchip_dw_hdmi_get_edid,
594f5e7d251SAlgea Cao };
595f5e7d251SAlgea Cao 
5968e2bab3fSAlgea Cao const struct dw_hdmi_plat_data rk3288_hdmi_drv_data = {
597f5e7d251SAlgea Cao 	.vop_sel_bit = 4,
598f5e7d251SAlgea Cao 	.grf_vop_sel_reg = RK3288_GRF_SOC_CON6,
5998e2bab3fSAlgea Cao 	.mpll_cfg   = rockchip_mpll_cfg,
6008e2bab3fSAlgea Cao 	.cur_ctr    = rockchip_cur_ctr,
6018e2bab3fSAlgea Cao 	.phy_config = rockchip_phy_config,
602f5e7d251SAlgea Cao 	.dev_type   = RK3288_HDMI,
603f5e7d251SAlgea Cao };
604f5e7d251SAlgea Cao 
6058e2bab3fSAlgea Cao const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = {
6068e2bab3fSAlgea Cao 	.vop_sel_bit = 0,
6078e2bab3fSAlgea Cao 	.grf_vop_sel_reg = 0,
6088e2bab3fSAlgea Cao 	.phy_ops    = &inno_dw_hdmi_phy_ops,
6098e2bab3fSAlgea Cao 	.phy_name   = "inno_dw_hdmi_phy2",
6108e2bab3fSAlgea Cao 	.dev_type   = RK3328_HDMI,
6118e2bab3fSAlgea Cao };
6128e2bab3fSAlgea Cao 
6138e2bab3fSAlgea Cao const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = {
6148e2bab3fSAlgea Cao 	.vop_sel_bit = 0,
6158e2bab3fSAlgea Cao 	.grf_vop_sel_reg = 0,
6168e2bab3fSAlgea Cao 	.phy_ops    = &inno_dw_hdmi_phy_ops,
6178e2bab3fSAlgea Cao 	.phy_name   = "inno_dw_hdmi_phy",
6188e2bab3fSAlgea Cao 	.dev_type   = RK3228_HDMI,
6198e2bab3fSAlgea Cao };
6208e2bab3fSAlgea Cao 
62184a1bd9cSAlgea Cao const struct dw_hdmi_plat_data rk3368_hdmi_drv_data = {
62284a1bd9cSAlgea Cao 	.mpll_cfg   = rockchip_mpll_cfg,
62384a1bd9cSAlgea Cao 	.cur_ctr    = rockchip_cur_ctr,
62484a1bd9cSAlgea Cao 	.phy_config = rockchip_phy_config,
62584a1bd9cSAlgea Cao 	.mpll_cfg_420 = rockchip_mpll_cfg_420,
62684a1bd9cSAlgea Cao 	.dev_type   = RK3368_HDMI,
62784a1bd9cSAlgea Cao };
62884a1bd9cSAlgea Cao 
6298e2bab3fSAlgea Cao const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
630f5e7d251SAlgea Cao 	.vop_sel_bit = 6,
631f5e7d251SAlgea Cao 	.grf_vop_sel_reg = RK3399_GRF_SOC_CON20,
632f5e7d251SAlgea Cao 	.mpll_cfg   = rockchip_mpll_cfg,
633f5e7d251SAlgea Cao 	.cur_ctr    = rockchip_cur_ctr,
634f5e7d251SAlgea Cao 	.phy_config = rockchip_phy_config,
6358e2bab3fSAlgea Cao 	.mpll_cfg_420 = rockchip_mpll_cfg_420,
636f5e7d251SAlgea Cao 	.dev_type   = RK3399_HDMI,
637f5e7d251SAlgea Cao };
638f5e7d251SAlgea Cao 
639cb24dc0eSAlgea Cao const struct dw_hdmi_plat_data rk3528_hdmi_drv_data = {
640cb24dc0eSAlgea Cao 	.vop_sel_bit = 0,
641cb24dc0eSAlgea Cao 	.grf_vop_sel_reg = 0,
642cb24dc0eSAlgea Cao 	.phy_ops    = &inno_dw_hdmi_phy_ops,
643cb24dc0eSAlgea Cao 	.phy_name   = "inno_dw_hdmi_phy2",
644cb24dc0eSAlgea Cao 	.dev_type   = RK3528_HDMI,
645cb24dc0eSAlgea Cao };
646cb24dc0eSAlgea Cao 
6475ccad8f6SAlgea Cao const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = {
6485ccad8f6SAlgea Cao 	.vop_sel_bit = 0,
6495ccad8f6SAlgea Cao 	.grf_vop_sel_reg = 0,
6505ccad8f6SAlgea Cao 	.mpll_cfg   = rockchip_mpll_cfg,
6515ccad8f6SAlgea Cao 	.cur_ctr    = rockchip_cur_ctr,
6525ccad8f6SAlgea Cao 	.phy_config = rockchip_phy_config,
6535ccad8f6SAlgea Cao 	.mpll_cfg_420 = rockchip_mpll_cfg_420,
6545ccad8f6SAlgea Cao 	.dev_type   = RK3568_HDMI,
6555ccad8f6SAlgea Cao };
6565ccad8f6SAlgea Cao 
657*6a3f4548SSandy Huang #ifdef CONFIG_SPL_BUILD
rockchip_spl_dw_hdmi_probe(struct connector_state * conn_state)658*6a3f4548SSandy Huang int rockchip_spl_dw_hdmi_probe(struct connector_state *conn_state)
659*6a3f4548SSandy Huang {
660*6a3f4548SSandy Huang 	conn_state->connector = malloc(sizeof(struct rockchip_connector));
661*6a3f4548SSandy Huang 
662*6a3f4548SSandy Huang 	memset(conn_state->connector, 0, sizeof(*conn_state->connector));
663*6a3f4548SSandy Huang 	rockchip_connector_bind(conn_state->connector, NULL, 0, &rockchip_dw_hdmi_funcs,
664*6a3f4548SSandy Huang 				(void *)&rk3528_hdmi_drv_data,
665*6a3f4548SSandy Huang 				DRM_MODE_CONNECTOR_HDMIA);
666*6a3f4548SSandy Huang 
667*6a3f4548SSandy Huang 	return 0;
668*6a3f4548SSandy Huang }
669*6a3f4548SSandy Huang #else
rockchip_dw_hdmi_probe(struct udevice * dev)6708e2bab3fSAlgea Cao static int rockchip_dw_hdmi_probe(struct udevice *dev)
6718e2bab3fSAlgea Cao {
6720594ce39SZhang Yubing 	int id;
6730594ce39SZhang Yubing 	struct rockchip_connector *conn = dev_get_priv(dev);
6740594ce39SZhang Yubing 
6750594ce39SZhang Yubing 	id = of_alias_get_id(ofnode_to_np(dev->node), "hdmi");
6760594ce39SZhang Yubing 	if (id < 0)
6770594ce39SZhang Yubing 		id = 0;
6780594ce39SZhang Yubing 
6790594ce39SZhang Yubing 	rockchip_connector_bind(conn, dev, id, &rockchip_dw_hdmi_funcs, NULL,
6800594ce39SZhang Yubing 				DRM_MODE_CONNECTOR_HDMIA);
6810594ce39SZhang Yubing 
6828e2bab3fSAlgea Cao 	return 0;
6838e2bab3fSAlgea Cao }
684*6a3f4548SSandy Huang #endif
6858e2bab3fSAlgea Cao 
686f5e7d251SAlgea Cao static const struct udevice_id rockchip_dw_hdmi_ids[] = {
687f5e7d251SAlgea Cao 	{
688cb24dc0eSAlgea Cao 	 .compatible = "rockchip,rk3528-dw-hdmi",
689cb24dc0eSAlgea Cao 	 .data = (ulong)&rk3528_hdmi_drv_data,
690cb24dc0eSAlgea Cao 	}, {
6915ccad8f6SAlgea Cao 	 .compatible = "rockchip,rk3568-dw-hdmi",
6920594ce39SZhang Yubing 	 .data = (ulong)&rk3568_hdmi_drv_data,
6935ccad8f6SAlgea Cao 	}, {
694f5e7d251SAlgea Cao 	 .compatible = "rockchip,rk3399-dw-hdmi",
6950594ce39SZhang Yubing 	 .data = (ulong)&rk3399_hdmi_drv_data,
696f5e7d251SAlgea Cao 	}, {
69784a1bd9cSAlgea Cao 	 .compatible = "rockchip,rk3368-dw-hdmi",
6980594ce39SZhang Yubing 	 .data = (ulong)&rk3368_hdmi_drv_data,
69984a1bd9cSAlgea Cao 	}, {
700f5e7d251SAlgea Cao 	 .compatible = "rockchip,rk3288-dw-hdmi",
7010594ce39SZhang Yubing 	 .data = (ulong)&rk3288_hdmi_drv_data,
7028e2bab3fSAlgea Cao 	}, {
7038e2bab3fSAlgea Cao 	 .compatible = "rockchip,rk3328-dw-hdmi",
7040594ce39SZhang Yubing 	 .data = (ulong)&rk3328_hdmi_drv_data,
7058e2bab3fSAlgea Cao 	}, {
7068e2bab3fSAlgea Cao 	 .compatible = "rockchip,rk3128-inno-hdmi",
7070594ce39SZhang Yubing 	 .data = (ulong)&rk3228_hdmi_drv_data,
7088e2bab3fSAlgea Cao 	}, {
7098e2bab3fSAlgea Cao 	 .compatible = "rockchip,rk3228-dw-hdmi",
7100594ce39SZhang Yubing 	 .data = (ulong)&rk3228_hdmi_drv_data,
711f5e7d251SAlgea Cao 	}, {}
712f5e7d251SAlgea Cao };
713f5e7d251SAlgea Cao 
714f5e7d251SAlgea Cao U_BOOT_DRIVER(rockchip_dw_hdmi) = {
715f5e7d251SAlgea Cao 	.name = "rockchip_dw_hdmi",
716f5e7d251SAlgea Cao 	.id = UCLASS_DISPLAY,
717f5e7d251SAlgea Cao 	.of_match = rockchip_dw_hdmi_ids,
718*6a3f4548SSandy Huang #ifndef CONFIG_SPL_BUILD
719f5e7d251SAlgea Cao 	.probe	= rockchip_dw_hdmi_probe,
720*6a3f4548SSandy Huang #endif
7210594ce39SZhang Yubing 	.priv_auto_alloc_size = sizeof(struct rockchip_connector),
722f5e7d251SAlgea Cao };
723