xref: /OK3568_Linux_fs/u-boot/drivers/video/drm/rockchip_dw_hdmi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <boot_rkimg.h>
9*4882a593Smuzhiyun #include <asm/io.h>
10*4882a593Smuzhiyun #include <asm/gpio.h>
11*4882a593Smuzhiyun #include <dm/of_access.h>
12*4882a593Smuzhiyun #include <dm/device.h>
13*4882a593Smuzhiyun #include <linux/dw_hdmi.h>
14*4882a593Smuzhiyun #include <linux/hdmi.h>
15*4882a593Smuzhiyun #include <linux/media-bus-format.h>
16*4882a593Smuzhiyun #include "rockchip_display.h"
17*4882a593Smuzhiyun #include "rockchip_crtc.h"
18*4882a593Smuzhiyun #include "rockchip_connector.h"
19*4882a593Smuzhiyun #include "dw_hdmi.h"
20*4882a593Smuzhiyun #include "rockchip_dw_hdmi.h"
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define HDMI_SEL_LCDC(x, bit)  ((((x) & 1) << bit) | (1 << (16 + bit)))
23*4882a593Smuzhiyun #define RK3288_GRF_SOC_CON6		0x025C
24*4882a593Smuzhiyun #define RK3288_HDMI_LCDC_SEL		BIT(4)
25*4882a593Smuzhiyun #define RK3399_GRF_SOC_CON20		0x6250
26*4882a593Smuzhiyun #define RK3399_HDMI_LCDC_SEL		BIT(6)
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define RK3228_IO_3V_DOMAIN              ((7 << 4) | (7 << (4 + 16)))
29*4882a593Smuzhiyun #define RK3328_IO_3V_DOMAIN              (7 << (9 + 16))
30*4882a593Smuzhiyun #define RK3328_IO_5V_DOMAIN              ((7 << 9) | (3 << (9 + 16)))
31*4882a593Smuzhiyun #define RK3328_IO_CTRL_BY_HDMI           ((1 << 13) | (1 << (13 + 16)))
32*4882a593Smuzhiyun #define RK3328_IO_DDC_IN_MSK             ((3 << 10) | (3 << (10 + 16)))
33*4882a593Smuzhiyun #define RK3228_IO_DDC_IN_MSK             ((3 << 13) | (3 << (13 + 16)))
34*4882a593Smuzhiyun #define RK3228_GRF_SOC_CON2              0x0408
35*4882a593Smuzhiyun #define RK3228_GRF_SOC_CON6              0x0418
36*4882a593Smuzhiyun #define RK3328_GRF_SOC_CON2              0x0408
37*4882a593Smuzhiyun #define RK3328_GRF_SOC_CON3              0x040c
38*4882a593Smuzhiyun #define RK3328_GRF_SOC_CON4              0x0410
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #define RK3528_GPIO0A_IOMUX_SEL_H	0x4
41*4882a593Smuzhiyun #define RK3528_GPIO0A_PULL 		0x200
42*4882a593Smuzhiyun #define RK3528_DDC_PULL			(0xf00 << 16)
43*4882a593Smuzhiyun #define RK3528_VO_GRF_HDMI_MASK		0x60014
44*4882a593Smuzhiyun #define RK3528_HDMI_SNKDET_SEL		((BIT(6) << 16) | BIT(6))
45*4882a593Smuzhiyun #define RK3528_HDMI_SNKDET		BIT(21)
46*4882a593Smuzhiyun #define RK3528_HDMI_CECIN_MSK		((BIT(2) << 16) | BIT(2))
47*4882a593Smuzhiyun #define RK3528_HDMI_SDAIN_MSK		((BIT(1) << 16) | BIT(1))
48*4882a593Smuzhiyun #define RK3528_HDMI_SCLIN_MSK		((BIT(0) << 16) | BIT(0))
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun #define RK3528_GPIO_SWPORT_DR_L		0x0000
51*4882a593Smuzhiyun #define RK3528_GPIO0_A2_DR		((BIT(2) << 16) | BIT(2))
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun #define RK3568_GRF_VO_CON1               0x0364
54*4882a593Smuzhiyun #define RK3568_HDMI_SDAIN_MSK            ((1 << 15) | (1 << (15 + 16)))
55*4882a593Smuzhiyun #define RK3568_HDMI_SCLIN_MSK            ((1 << 14) | (1 << (14 + 16)))
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
58*4882a593Smuzhiyun 	{
59*4882a593Smuzhiyun 		30666000, {
60*4882a593Smuzhiyun 			{ 0x00b3, 0x0000 },
61*4882a593Smuzhiyun 			{ 0x2153, 0x0000 },
62*4882a593Smuzhiyun 			{ 0x40f3, 0x0000 },
63*4882a593Smuzhiyun 		},
64*4882a593Smuzhiyun 	},  {
65*4882a593Smuzhiyun 		36800000, {
66*4882a593Smuzhiyun 			{ 0x00b3, 0x0000 },
67*4882a593Smuzhiyun 			{ 0x2153, 0x0000 },
68*4882a593Smuzhiyun 			{ 0x40a2, 0x0001 },
69*4882a593Smuzhiyun 		},
70*4882a593Smuzhiyun 	},  {
71*4882a593Smuzhiyun 		46000000, {
72*4882a593Smuzhiyun 			{ 0x00b3, 0x0000 },
73*4882a593Smuzhiyun 			{ 0x2142, 0x0001 },
74*4882a593Smuzhiyun 			{ 0x40a2, 0x0001 },
75*4882a593Smuzhiyun 		},
76*4882a593Smuzhiyun 	},  {
77*4882a593Smuzhiyun 		61333000, {
78*4882a593Smuzhiyun 			{ 0x0072, 0x0001 },
79*4882a593Smuzhiyun 			{ 0x2142, 0x0001 },
80*4882a593Smuzhiyun 			{ 0x40a2, 0x0001 },
81*4882a593Smuzhiyun 		},
82*4882a593Smuzhiyun 	},  {
83*4882a593Smuzhiyun 		73600000, {
84*4882a593Smuzhiyun 			{ 0x0072, 0x0001 },
85*4882a593Smuzhiyun 			{ 0x2142, 0x0001 },
86*4882a593Smuzhiyun 			{ 0x4061, 0x0002 },
87*4882a593Smuzhiyun 		},
88*4882a593Smuzhiyun 	},  {
89*4882a593Smuzhiyun 		92000000, {
90*4882a593Smuzhiyun 			{ 0x0072, 0x0001 },
91*4882a593Smuzhiyun 			{ 0x2145, 0x0002 },
92*4882a593Smuzhiyun 			{ 0x4061, 0x0002 },
93*4882a593Smuzhiyun 		},
94*4882a593Smuzhiyun 	},  {
95*4882a593Smuzhiyun 		122666000, {
96*4882a593Smuzhiyun 			{ 0x0051, 0x0002 },
97*4882a593Smuzhiyun 			{ 0x2145, 0x0002 },
98*4882a593Smuzhiyun 			{ 0x4061, 0x0002 },
99*4882a593Smuzhiyun 		},
100*4882a593Smuzhiyun 	},  {
101*4882a593Smuzhiyun 		147200000, {
102*4882a593Smuzhiyun 			{ 0x0051, 0x0002 },
103*4882a593Smuzhiyun 			{ 0x2145, 0x0002 },
104*4882a593Smuzhiyun 			{ 0x4064, 0x0003 },
105*4882a593Smuzhiyun 		},
106*4882a593Smuzhiyun 	},  {
107*4882a593Smuzhiyun 		184000000, {
108*4882a593Smuzhiyun 			{ 0x0051, 0x0002 },
109*4882a593Smuzhiyun 			{ 0x214c, 0x0003 },
110*4882a593Smuzhiyun 			{ 0x4064, 0x0003 },
111*4882a593Smuzhiyun 		},
112*4882a593Smuzhiyun 	},  {
113*4882a593Smuzhiyun 		226666000, {
114*4882a593Smuzhiyun 			{ 0x0040, 0x0003 },
115*4882a593Smuzhiyun 			{ 0x214c, 0x0003 },
116*4882a593Smuzhiyun 			{ 0x4064, 0x0003 },
117*4882a593Smuzhiyun 		},
118*4882a593Smuzhiyun 	},  {
119*4882a593Smuzhiyun 		272000000, {
120*4882a593Smuzhiyun 			{ 0x0040, 0x0003 },
121*4882a593Smuzhiyun 			{ 0x214c, 0x0003 },
122*4882a593Smuzhiyun 			{ 0x5a64, 0x0003 },
123*4882a593Smuzhiyun 		},
124*4882a593Smuzhiyun 	},  {
125*4882a593Smuzhiyun 		340000000, {
126*4882a593Smuzhiyun 			{ 0x0040, 0x0003 },
127*4882a593Smuzhiyun 			{ 0x3b4c, 0x0003 },
128*4882a593Smuzhiyun 			{ 0x5a64, 0x0003 },
129*4882a593Smuzhiyun 		},
130*4882a593Smuzhiyun 	},  {
131*4882a593Smuzhiyun 		600000000, {
132*4882a593Smuzhiyun 			{ 0x1a40, 0x0003 },
133*4882a593Smuzhiyun 			{ 0x3b4c, 0x0003 },
134*4882a593Smuzhiyun 			{ 0x5a64, 0x0003 },
135*4882a593Smuzhiyun 		},
136*4882a593Smuzhiyun 	},  {
137*4882a593Smuzhiyun 		~0UL, {
138*4882a593Smuzhiyun 			{ 0x0000, 0x0000 },
139*4882a593Smuzhiyun 			{ 0x0000, 0x0000 },
140*4882a593Smuzhiyun 			{ 0x0000, 0x0000 },
141*4882a593Smuzhiyun 		},
142*4882a593Smuzhiyun 	}
143*4882a593Smuzhiyun };
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun static const struct dw_hdmi_mpll_config rockchip_mpll_cfg_420[] = {
146*4882a593Smuzhiyun 	{
147*4882a593Smuzhiyun 		30666000, {
148*4882a593Smuzhiyun 			{ 0x00b7, 0x0000 },
149*4882a593Smuzhiyun 			{ 0x2157, 0x0000 },
150*4882a593Smuzhiyun 			{ 0x40f7, 0x0000 },
151*4882a593Smuzhiyun 		},
152*4882a593Smuzhiyun 	},  {
153*4882a593Smuzhiyun 		92000000, {
154*4882a593Smuzhiyun 			{ 0x00b7, 0x0000 },
155*4882a593Smuzhiyun 			{ 0x2143, 0x0001 },
156*4882a593Smuzhiyun 			{ 0x40a3, 0x0001 },
157*4882a593Smuzhiyun 		},
158*4882a593Smuzhiyun 	},  {
159*4882a593Smuzhiyun 		184000000, {
160*4882a593Smuzhiyun 			{ 0x0073, 0x0001 },
161*4882a593Smuzhiyun 			{ 0x2146, 0x0002 },
162*4882a593Smuzhiyun 			{ 0x4062, 0x0002 },
163*4882a593Smuzhiyun 		},
164*4882a593Smuzhiyun 	},  {
165*4882a593Smuzhiyun 		340000000, {
166*4882a593Smuzhiyun 			{ 0x0052, 0x0003 },
167*4882a593Smuzhiyun 			{ 0x214d, 0x0003 },
168*4882a593Smuzhiyun 			{ 0x4065, 0x0003 },
169*4882a593Smuzhiyun 		},
170*4882a593Smuzhiyun 	},  {
171*4882a593Smuzhiyun 		600000000, {
172*4882a593Smuzhiyun 			{ 0x0041, 0x0003 },
173*4882a593Smuzhiyun 			{ 0x3b4d, 0x0003 },
174*4882a593Smuzhiyun 			{ 0x5a65, 0x0003 },
175*4882a593Smuzhiyun 		},
176*4882a593Smuzhiyun 	},  {
177*4882a593Smuzhiyun 		~0UL, {
178*4882a593Smuzhiyun 			{ 0x0000, 0x0000 },
179*4882a593Smuzhiyun 			{ 0x0000, 0x0000 },
180*4882a593Smuzhiyun 			{ 0x0000, 0x0000 },
181*4882a593Smuzhiyun 		},
182*4882a593Smuzhiyun 	}
183*4882a593Smuzhiyun };
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
186*4882a593Smuzhiyun 	/*      pixelclk    bpp8    bpp10   bpp12 */
187*4882a593Smuzhiyun 	{
188*4882a593Smuzhiyun 		600000000, { 0x0000, 0x0000, 0x0000 },
189*4882a593Smuzhiyun 	},  {
190*4882a593Smuzhiyun 		~0UL,      { 0x0000, 0x0000, 0x0000},
191*4882a593Smuzhiyun 	}
192*4882a593Smuzhiyun };
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun static struct dw_hdmi_phy_config rockchip_phy_config[] = {
195*4882a593Smuzhiyun 	/*pixelclk   symbol   term   vlev*/
196*4882a593Smuzhiyun 	{ 74250000,  0x8009, 0x0004, 0x0272},
197*4882a593Smuzhiyun 	{ 165000000, 0x802b, 0x0004, 0x0209},
198*4882a593Smuzhiyun 	{ 297000000, 0x8039, 0x0005, 0x028d},
199*4882a593Smuzhiyun 	{ 594000000, 0x8039, 0x0000, 0x019d},
200*4882a593Smuzhiyun 	{ ~0UL,	     0x0000, 0x0000, 0x0000},
201*4882a593Smuzhiyun 	{ ~0UL,	     0x0000, 0x0000, 0x0000}
202*4882a593Smuzhiyun };
203*4882a593Smuzhiyun 
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)204*4882a593Smuzhiyun static unsigned int drm_rk_select_color(struct hdmi_edid_data *edid_data,
205*4882a593Smuzhiyun 					struct base_screen_info *screen_info,
206*4882a593Smuzhiyun 					enum dw_hdmi_devtype dev_type,
207*4882a593Smuzhiyun 					bool output_bus_format_rgb)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun 	struct drm_display_info *info = &edid_data->display_info;
210*4882a593Smuzhiyun 	struct drm_display_mode *mode = edid_data->preferred_mode;
211*4882a593Smuzhiyun 	int max_tmds_clock = info->max_tmds_clock;
212*4882a593Smuzhiyun 	bool support_dc = false;
213*4882a593Smuzhiyun 	bool mode_420 = drm_mode_is_420(info, mode);
214*4882a593Smuzhiyun 	unsigned int color_depth = 8;
215*4882a593Smuzhiyun 	unsigned int base_color = DRM_HDMI_OUTPUT_YCBCR444;
216*4882a593Smuzhiyun 	unsigned int color_format = DRM_HDMI_OUTPUT_DEFAULT_RGB;
217*4882a593Smuzhiyun 	unsigned long tmdsclock, pixclock = mode->clock;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	if (screen_info)
220*4882a593Smuzhiyun 		base_color = screen_info->format;
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	switch (base_color) {
223*4882a593Smuzhiyun 	case DRM_HDMI_OUTPUT_YCBCR_HQ:
224*4882a593Smuzhiyun 		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
225*4882a593Smuzhiyun 			color_format = DRM_HDMI_OUTPUT_YCBCR444;
226*4882a593Smuzhiyun 		else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
227*4882a593Smuzhiyun 			color_format = DRM_HDMI_OUTPUT_YCBCR422;
228*4882a593Smuzhiyun 		else if (mode_420)
229*4882a593Smuzhiyun 			color_format = DRM_HDMI_OUTPUT_YCBCR420;
230*4882a593Smuzhiyun 		break;
231*4882a593Smuzhiyun 	case DRM_HDMI_OUTPUT_YCBCR_LQ:
232*4882a593Smuzhiyun 		if (mode_420)
233*4882a593Smuzhiyun 			color_format = DRM_HDMI_OUTPUT_YCBCR420;
234*4882a593Smuzhiyun 		else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
235*4882a593Smuzhiyun 			color_format = DRM_HDMI_OUTPUT_YCBCR422;
236*4882a593Smuzhiyun 		else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
237*4882a593Smuzhiyun 			color_format = DRM_HDMI_OUTPUT_YCBCR444;
238*4882a593Smuzhiyun 		break;
239*4882a593Smuzhiyun 	case DRM_HDMI_OUTPUT_YCBCR420:
240*4882a593Smuzhiyun 		if (mode_420)
241*4882a593Smuzhiyun 			color_format = DRM_HDMI_OUTPUT_YCBCR420;
242*4882a593Smuzhiyun 		break;
243*4882a593Smuzhiyun 	case DRM_HDMI_OUTPUT_YCBCR422:
244*4882a593Smuzhiyun 		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
245*4882a593Smuzhiyun 			color_format = DRM_HDMI_OUTPUT_YCBCR422;
246*4882a593Smuzhiyun 		break;
247*4882a593Smuzhiyun 	case DRM_HDMI_OUTPUT_YCBCR444:
248*4882a593Smuzhiyun 		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
249*4882a593Smuzhiyun 			color_format = DRM_HDMI_OUTPUT_YCBCR444;
250*4882a593Smuzhiyun 		break;
251*4882a593Smuzhiyun 	case DRM_HDMI_OUTPUT_DEFAULT_RGB:
252*4882a593Smuzhiyun 	default:
253*4882a593Smuzhiyun 		break;
254*4882a593Smuzhiyun 	}
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	if (output_bus_format_rgb)
257*4882a593Smuzhiyun 		color_format = DRM_HDMI_OUTPUT_DEFAULT_RGB;
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	if (color_format == DRM_HDMI_OUTPUT_DEFAULT_RGB &&
260*4882a593Smuzhiyun 	    info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30)
261*4882a593Smuzhiyun 		support_dc = true;
262*4882a593Smuzhiyun 	if (color_format == DRM_HDMI_OUTPUT_YCBCR444 &&
263*4882a593Smuzhiyun 	    (info->edid_hdmi_dc_modes &
264*4882a593Smuzhiyun 	     (DRM_EDID_HDMI_DC_Y444 | DRM_EDID_HDMI_DC_30)))
265*4882a593Smuzhiyun 		support_dc = true;
266*4882a593Smuzhiyun 	if (color_format == DRM_HDMI_OUTPUT_YCBCR422)
267*4882a593Smuzhiyun 		support_dc = true;
268*4882a593Smuzhiyun 	if (color_format == DRM_HDMI_OUTPUT_YCBCR420 &&
269*4882a593Smuzhiyun 	    info->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
270*4882a593Smuzhiyun 		support_dc = true;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
273*4882a593Smuzhiyun 		pixclock *= 2;
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	if (screen_info && screen_info->depth == 10)
276*4882a593Smuzhiyun 		color_depth = screen_info->depth;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	if (color_format == DRM_HDMI_OUTPUT_YCBCR422 || color_depth == 8)
279*4882a593Smuzhiyun 		tmdsclock = pixclock;
280*4882a593Smuzhiyun 	else
281*4882a593Smuzhiyun 		tmdsclock = pixclock * color_depth / 8;
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 	if (color_format == DRM_HDMI_OUTPUT_YCBCR420)
284*4882a593Smuzhiyun 		tmdsclock /= 2;
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	if (!max_tmds_clock)
287*4882a593Smuzhiyun 		max_tmds_clock = 340000;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	switch (dev_type) {
290*4882a593Smuzhiyun 	case RK3368_HDMI:
291*4882a593Smuzhiyun 		max_tmds_clock = min(max_tmds_clock, 340000);
292*4882a593Smuzhiyun 		break;
293*4882a593Smuzhiyun 	case RK3328_HDMI:
294*4882a593Smuzhiyun 	case RK3228_HDMI:
295*4882a593Smuzhiyun 		max_tmds_clock = min(max_tmds_clock, 371250);
296*4882a593Smuzhiyun 		break;
297*4882a593Smuzhiyun 	default:
298*4882a593Smuzhiyun 		max_tmds_clock = min(max_tmds_clock, 594000);
299*4882a593Smuzhiyun 		break;
300*4882a593Smuzhiyun 	}
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	if (tmdsclock > max_tmds_clock) {
303*4882a593Smuzhiyun 		if (max_tmds_clock >= 594000) {
304*4882a593Smuzhiyun 			color_depth = 8;
305*4882a593Smuzhiyun 		} else if (max_tmds_clock > 340000) {
306*4882a593Smuzhiyun 			if (drm_mode_is_420(info, mode))
307*4882a593Smuzhiyun 				color_format = DRM_HDMI_OUTPUT_YCBCR420;
308*4882a593Smuzhiyun 		} else {
309*4882a593Smuzhiyun 			color_depth = 8;
310*4882a593Smuzhiyun 			if (drm_mode_is_420(info, mode))
311*4882a593Smuzhiyun 				color_format = DRM_HDMI_OUTPUT_YCBCR420;
312*4882a593Smuzhiyun 		}
313*4882a593Smuzhiyun 	}
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	if (color_depth > 8 && support_dc) {
316*4882a593Smuzhiyun 		if (dev_type == RK3288_HDMI)
317*4882a593Smuzhiyun 			return MEDIA_BUS_FMT_RGB101010_1X30;
318*4882a593Smuzhiyun 		switch (color_format) {
319*4882a593Smuzhiyun 		case DRM_HDMI_OUTPUT_YCBCR444:
320*4882a593Smuzhiyun 			return MEDIA_BUS_FMT_YUV10_1X30;
321*4882a593Smuzhiyun 		case DRM_HDMI_OUTPUT_YCBCR422:
322*4882a593Smuzhiyun 			return MEDIA_BUS_FMT_UYVY10_1X20;
323*4882a593Smuzhiyun 		case DRM_HDMI_OUTPUT_YCBCR420:
324*4882a593Smuzhiyun 			return MEDIA_BUS_FMT_UYYVYY10_0_5X30;
325*4882a593Smuzhiyun 		default:
326*4882a593Smuzhiyun 			return MEDIA_BUS_FMT_RGB101010_1X30;
327*4882a593Smuzhiyun 		}
328*4882a593Smuzhiyun 	} else {
329*4882a593Smuzhiyun 		if (dev_type == RK3288_HDMI)
330*4882a593Smuzhiyun 			return MEDIA_BUS_FMT_RGB888_1X24;
331*4882a593Smuzhiyun 		switch (color_format) {
332*4882a593Smuzhiyun 		case DRM_HDMI_OUTPUT_YCBCR444:
333*4882a593Smuzhiyun 			return MEDIA_BUS_FMT_YUV8_1X24;
334*4882a593Smuzhiyun 		case DRM_HDMI_OUTPUT_YCBCR422:
335*4882a593Smuzhiyun 			return MEDIA_BUS_FMT_UYVY8_1X16;
336*4882a593Smuzhiyun 		case DRM_HDMI_OUTPUT_YCBCR420:
337*4882a593Smuzhiyun 			return MEDIA_BUS_FMT_UYYVYY8_0_5X24;
338*4882a593Smuzhiyun 		default:
339*4882a593Smuzhiyun 			return MEDIA_BUS_FMT_RGB888_1X24;
340*4882a593Smuzhiyun 		}
341*4882a593Smuzhiyun 	}
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun 
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)344*4882a593Smuzhiyun void drm_rk_selete_output(struct hdmi_edid_data *edid_data,
345*4882a593Smuzhiyun 			  struct connector_state *conn_state,
346*4882a593Smuzhiyun 			  unsigned int *bus_format,
347*4882a593Smuzhiyun 			  struct overscan *overscan,
348*4882a593Smuzhiyun 			  enum dw_hdmi_devtype dev_type,
349*4882a593Smuzhiyun 			  bool output_bus_format_rgb)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun 	struct base2_disp_info *base2_parameter = conn_state->disp_info;
352*4882a593Smuzhiyun 	const struct base_overscan *scan;
353*4882a593Smuzhiyun 	struct base_screen_info *screen_info = NULL;
354*4882a593Smuzhiyun 	struct base2_screen_info *screen_info2 = NULL;
355*4882a593Smuzhiyun 	int max_scan = 100;
356*4882a593Smuzhiyun 	int min_scan = 51;
357*4882a593Smuzhiyun #ifdef CONFIG_SPL_BUILD
358*4882a593Smuzhiyun 	int i, screen_size;
359*4882a593Smuzhiyun #else
360*4882a593Smuzhiyun 	int ret, i, screen_size;
361*4882a593Smuzhiyun 	int offset = 0;
362*4882a593Smuzhiyun 	bool found = false;
363*4882a593Smuzhiyun 	struct blk_desc *dev_desc;
364*4882a593Smuzhiyun 	disk_partition_t part_info;
365*4882a593Smuzhiyun 	char baseparameter_buf[8 * RK_BLK_SIZE] __aligned(ARCH_DMA_MINALIGN);
366*4882a593Smuzhiyun 	struct base_disp_info base_parameter;
367*4882a593Smuzhiyun #endif
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	overscan->left_margin = max_scan;
370*4882a593Smuzhiyun 	overscan->right_margin = max_scan;
371*4882a593Smuzhiyun 	overscan->top_margin = max_scan;
372*4882a593Smuzhiyun 	overscan->bottom_margin = max_scan;
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 	if (dev_type == RK3288_HDMI || output_bus_format_rgb)
375*4882a593Smuzhiyun 		*bus_format = MEDIA_BUS_FMT_RGB888_1X24;
376*4882a593Smuzhiyun 	else
377*4882a593Smuzhiyun 		*bus_format = MEDIA_BUS_FMT_YUV8_1X24;
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun #ifdef CONFIG_SPL_BUILD
380*4882a593Smuzhiyun 	scan = &base2_parameter->overscan_info;
381*4882a593Smuzhiyun 	screen_size = sizeof(base2_parameter->screen_info) /
382*4882a593Smuzhiyun 		sizeof(base2_parameter->screen_info[0]);
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 	for (i = 0; i < screen_size; i++) {
385*4882a593Smuzhiyun 		if (base2_parameter->screen_info[i].type ==
386*4882a593Smuzhiyun 		    DRM_MODE_CONNECTOR_HDMIA) {
387*4882a593Smuzhiyun 			screen_info2 =
388*4882a593Smuzhiyun 				&base2_parameter->screen_info[i];
389*4882a593Smuzhiyun 			break;
390*4882a593Smuzhiyun 		}
391*4882a593Smuzhiyun 	}
392*4882a593Smuzhiyun 	screen_info = malloc(sizeof(*screen_info));
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	screen_info->type = screen_info2->type;
395*4882a593Smuzhiyun 	screen_info->mode = screen_info2->resolution;
396*4882a593Smuzhiyun 	screen_info->format = screen_info2->format;
397*4882a593Smuzhiyun 	screen_info->depth = screen_info2->depthc;
398*4882a593Smuzhiyun 	screen_info->feature = screen_info2->feature;
399*4882a593Smuzhiyun #else
400*4882a593Smuzhiyun 	if (!base2_parameter) {
401*4882a593Smuzhiyun 		dev_desc = rockchip_get_bootdev();
402*4882a593Smuzhiyun 		if (!dev_desc) {
403*4882a593Smuzhiyun 			printf("%s: Could not find device\n", __func__);
404*4882a593Smuzhiyun 			goto null_basep;
405*4882a593Smuzhiyun 		}
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 		ret = part_get_info_by_name(dev_desc, "baseparameter",
408*4882a593Smuzhiyun 					    &part_info);
409*4882a593Smuzhiyun 		if (ret < 0) {
410*4882a593Smuzhiyun 			printf("Could not find baseparameter partition\n");
411*4882a593Smuzhiyun 			goto null_basep;
412*4882a593Smuzhiyun 		}
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun read_aux:
415*4882a593Smuzhiyun 		ret = blk_dread(dev_desc, part_info.start + offset, 1,
416*4882a593Smuzhiyun 				(void *)baseparameter_buf);
417*4882a593Smuzhiyun 		if (ret < 0) {
418*4882a593Smuzhiyun 			printf("read baseparameter failed\n");
419*4882a593Smuzhiyun 			goto null_basep;
420*4882a593Smuzhiyun 		}
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 		memcpy(&base_parameter, baseparameter_buf,
423*4882a593Smuzhiyun 		       sizeof(base_parameter));
424*4882a593Smuzhiyun 		scan = &base_parameter.scan;
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 		screen_size = sizeof(base_parameter.screen_list) /
427*4882a593Smuzhiyun 			sizeof(base_parameter.screen_list[0]);
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 		for (i = 0; i < screen_size; i++) {
430*4882a593Smuzhiyun 			if (base_parameter.screen_list[i].type ==
431*4882a593Smuzhiyun 			    DRM_MODE_CONNECTOR_HDMIA) {
432*4882a593Smuzhiyun 				found = true;
433*4882a593Smuzhiyun 				screen_info = &base_parameter.screen_list[i];
434*4882a593Smuzhiyun 				break;
435*4882a593Smuzhiyun 			}
436*4882a593Smuzhiyun 		}
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 		if (!found && !offset) {
439*4882a593Smuzhiyun 			printf("hdmi info isn't saved in main block\n");
440*4882a593Smuzhiyun 			offset += 16;
441*4882a593Smuzhiyun 			goto read_aux;
442*4882a593Smuzhiyun 		}
443*4882a593Smuzhiyun 	} else {
444*4882a593Smuzhiyun 		scan = &base2_parameter->overscan_info;
445*4882a593Smuzhiyun 		screen_size = sizeof(base2_parameter->screen_info) /
446*4882a593Smuzhiyun 			sizeof(base2_parameter->screen_info[0]);
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 		for (i = 0; i < screen_size; i++) {
449*4882a593Smuzhiyun 			if (base2_parameter->screen_info[i].type ==
450*4882a593Smuzhiyun 			    DRM_MODE_CONNECTOR_HDMIA) {
451*4882a593Smuzhiyun 				screen_info2 =
452*4882a593Smuzhiyun 					&base2_parameter->screen_info[i];
453*4882a593Smuzhiyun 				break;
454*4882a593Smuzhiyun 			}
455*4882a593Smuzhiyun 		}
456*4882a593Smuzhiyun 		screen_info = malloc(sizeof(*screen_info));
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 		screen_info->type = screen_info2->type;
459*4882a593Smuzhiyun 		screen_info->mode = screen_info2->resolution;
460*4882a593Smuzhiyun 		screen_info->format = screen_info2->format;
461*4882a593Smuzhiyun 		screen_info->depth = screen_info2->depthc;
462*4882a593Smuzhiyun 		screen_info->feature = screen_info2->feature;
463*4882a593Smuzhiyun 	}
464*4882a593Smuzhiyun #endif
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	if (scan->leftscale < min_scan && scan->leftscale > 0)
467*4882a593Smuzhiyun 		overscan->left_margin = min_scan;
468*4882a593Smuzhiyun 	else if (scan->leftscale < max_scan && scan->leftscale > 0)
469*4882a593Smuzhiyun 		overscan->left_margin = scan->leftscale;
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun 	if (scan->rightscale < min_scan && scan->rightscale > 0)
472*4882a593Smuzhiyun 		overscan->right_margin = min_scan;
473*4882a593Smuzhiyun 	else if (scan->rightscale < max_scan && scan->rightscale > 0)
474*4882a593Smuzhiyun 		overscan->right_margin = scan->rightscale;
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun 	if (scan->topscale < min_scan && scan->topscale > 0)
477*4882a593Smuzhiyun 		overscan->top_margin = min_scan;
478*4882a593Smuzhiyun 	else if (scan->topscale < max_scan && scan->topscale > 0)
479*4882a593Smuzhiyun 		overscan->top_margin = scan->topscale;
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 	if (scan->bottomscale < min_scan && scan->bottomscale > 0)
482*4882a593Smuzhiyun 		overscan->bottom_margin = min_scan;
483*4882a593Smuzhiyun 	else if (scan->bottomscale < max_scan && scan->bottomscale > 0)
484*4882a593Smuzhiyun 		overscan->bottom_margin = scan->bottomscale;
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun #ifndef CONFIG_SPL_BUILD
487*4882a593Smuzhiyun null_basep:
488*4882a593Smuzhiyun #endif
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun 	if (screen_info)
491*4882a593Smuzhiyun 		printf("base_parameter.mode:%dx%d\n",
492*4882a593Smuzhiyun 		       screen_info->mode.hdisplay,
493*4882a593Smuzhiyun 		       screen_info->mode.vdisplay);
494*4882a593Smuzhiyun 	drm_rk_select_mode(edid_data, screen_info);
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 	*bus_format = drm_rk_select_color(edid_data, screen_info,
497*4882a593Smuzhiyun 					  dev_type, output_bus_format_rgb);
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun 
inno_dw_hdmi_set_domain(void * grf,int status)500*4882a593Smuzhiyun void inno_dw_hdmi_set_domain(void *grf, int status)
501*4882a593Smuzhiyun {
502*4882a593Smuzhiyun 	if (status)
503*4882a593Smuzhiyun 		writel(RK3328_IO_5V_DOMAIN, grf + RK3328_GRF_SOC_CON4);
504*4882a593Smuzhiyun 	else
505*4882a593Smuzhiyun 		writel(RK3328_IO_3V_DOMAIN, grf + RK3328_GRF_SOC_CON4);
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun 
dw_hdmi_set_iomux(void * grf,void * gpio_base,struct gpio_desc * hpd_gpiod,int dev_type)508*4882a593Smuzhiyun void dw_hdmi_set_iomux(void *grf, void *gpio_base, struct gpio_desc *hpd_gpiod,
509*4882a593Smuzhiyun 		       int dev_type)
510*4882a593Smuzhiyun {
511*4882a593Smuzhiyun 	u32 val = 0;
512*4882a593Smuzhiyun 	int i = 400;
513*4882a593Smuzhiyun #ifdef CONFIG_SPL_BUILD
514*4882a593Smuzhiyun 	void *gpio0_ioc = (void *)RK3528_GPIO0_IOC_BASE;
515*4882a593Smuzhiyun #endif
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun 	switch (dev_type) {
518*4882a593Smuzhiyun 	case RK3328_HDMI:
519*4882a593Smuzhiyun 		writel(RK3328_IO_DDC_IN_MSK, grf + RK3328_GRF_SOC_CON2);
520*4882a593Smuzhiyun 		writel(RK3328_IO_CTRL_BY_HDMI, grf + RK3328_GRF_SOC_CON3);
521*4882a593Smuzhiyun 		break;
522*4882a593Smuzhiyun 	case RK3228_HDMI:
523*4882a593Smuzhiyun 		writel(RK3228_IO_3V_DOMAIN, grf + RK3228_GRF_SOC_CON6);
524*4882a593Smuzhiyun 		writel(RK3228_IO_DDC_IN_MSK, grf + RK3228_GRF_SOC_CON2);
525*4882a593Smuzhiyun 		break;
526*4882a593Smuzhiyun 	case RK3528_HDMI:
527*4882a593Smuzhiyun 		writel(RK3528_HDMI_SDAIN_MSK | RK3528_HDMI_SCLIN_MSK |
528*4882a593Smuzhiyun 		       RK3528_HDMI_SNKDET_SEL,
529*4882a593Smuzhiyun 		       grf + RK3528_VO_GRF_HDMI_MASK);
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun #ifdef CONFIG_SPL_BUILD
532*4882a593Smuzhiyun 		val = (0x11 << 16) | 0x11;
533*4882a593Smuzhiyun 		writel(val, gpio0_ioc + RK3528_GPIO0A_IOMUX_SEL_H);
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 		writel(RK3528_DDC_PULL, gpio0_ioc + RK3528_GPIO0A_PULL);
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 		/* gpio0_a2's input enable is controlled by gpio output data bit */
538*4882a593Smuzhiyun 		writel(RK3528_GPIO0_A2_DR, gpio_base + RK3528_GPIO_SWPORT_DR_L);
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 		while (i--) {
541*4882a593Smuzhiyun 			val = readl(gpio_base + 0x70) & BIT(2);
542*4882a593Smuzhiyun 			if (val)
543*4882a593Smuzhiyun 				break;
544*4882a593Smuzhiyun 			mdelay(5);
545*4882a593Smuzhiyun 		}
546*4882a593Smuzhiyun #else
547*4882a593Smuzhiyun 		writel(val, grf + RK3528_VO_GRF_HDMI_MASK);
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 		/* gpio0_a2's input enable is controlled by gpio output data bit */
550*4882a593Smuzhiyun 		writel(RK3528_GPIO0_A2_DR, gpio_base + RK3528_GPIO_SWPORT_DR_L);
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun 		if (dm_gpio_is_valid(hpd_gpiod)) {
553*4882a593Smuzhiyun 			while (i--) {
554*4882a593Smuzhiyun 				val = dm_gpio_get_value(hpd_gpiod);
555*4882a593Smuzhiyun 				if (val)
556*4882a593Smuzhiyun 					break;
557*4882a593Smuzhiyun 				mdelay(5);
558*4882a593Smuzhiyun 			}
559*4882a593Smuzhiyun 		}
560*4882a593Smuzhiyun #endif
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun 		if (val)
563*4882a593Smuzhiyun 			val = RK3528_HDMI_SNKDET | BIT(5);
564*4882a593Smuzhiyun 		else
565*4882a593Smuzhiyun 			val = RK3528_HDMI_SNKDET;
566*4882a593Smuzhiyun 		writel(val, grf + RK3528_VO_GRF_HDMI_MASK);
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun 		break;
569*4882a593Smuzhiyun 	case RK3568_HDMI:
570*4882a593Smuzhiyun 		writel(RK3568_HDMI_SDAIN_MSK | RK3568_HDMI_SCLIN_MSK,
571*4882a593Smuzhiyun 		       grf + RK3568_GRF_VO_CON1);
572*4882a593Smuzhiyun 		break;
573*4882a593Smuzhiyun 	default:
574*4882a593Smuzhiyun 		break;
575*4882a593Smuzhiyun 	}
576*4882a593Smuzhiyun }
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun static const struct dw_hdmi_phy_ops inno_dw_hdmi_phy_ops = {
579*4882a593Smuzhiyun 	.init = inno_dw_hdmi_phy_init,
580*4882a593Smuzhiyun 	.disable = inno_dw_hdmi_phy_disable,
581*4882a593Smuzhiyun 	.read_hpd = inno_dw_hdmi_phy_read_hpd,
582*4882a593Smuzhiyun 	.mode_valid = inno_dw_hdmi_mode_valid,
583*4882a593Smuzhiyun };
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun static const struct rockchip_connector_funcs rockchip_dw_hdmi_funcs = {
586*4882a593Smuzhiyun 	.init = rockchip_dw_hdmi_init,
587*4882a593Smuzhiyun 	.deinit = rockchip_dw_hdmi_deinit,
588*4882a593Smuzhiyun 	.prepare = rockchip_dw_hdmi_prepare,
589*4882a593Smuzhiyun 	.enable = rockchip_dw_hdmi_enable,
590*4882a593Smuzhiyun 	.disable = rockchip_dw_hdmi_disable,
591*4882a593Smuzhiyun 	.get_timing = rockchip_dw_hdmi_get_timing,
592*4882a593Smuzhiyun 	.detect = rockchip_dw_hdmi_detect,
593*4882a593Smuzhiyun 	.get_edid = rockchip_dw_hdmi_get_edid,
594*4882a593Smuzhiyun };
595*4882a593Smuzhiyun 
596*4882a593Smuzhiyun const struct dw_hdmi_plat_data rk3288_hdmi_drv_data = {
597*4882a593Smuzhiyun 	.vop_sel_bit = 4,
598*4882a593Smuzhiyun 	.grf_vop_sel_reg = RK3288_GRF_SOC_CON6,
599*4882a593Smuzhiyun 	.mpll_cfg   = rockchip_mpll_cfg,
600*4882a593Smuzhiyun 	.cur_ctr    = rockchip_cur_ctr,
601*4882a593Smuzhiyun 	.phy_config = rockchip_phy_config,
602*4882a593Smuzhiyun 	.dev_type   = RK3288_HDMI,
603*4882a593Smuzhiyun };
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = {
606*4882a593Smuzhiyun 	.vop_sel_bit = 0,
607*4882a593Smuzhiyun 	.grf_vop_sel_reg = 0,
608*4882a593Smuzhiyun 	.phy_ops    = &inno_dw_hdmi_phy_ops,
609*4882a593Smuzhiyun 	.phy_name   = "inno_dw_hdmi_phy2",
610*4882a593Smuzhiyun 	.dev_type   = RK3328_HDMI,
611*4882a593Smuzhiyun };
612*4882a593Smuzhiyun 
613*4882a593Smuzhiyun const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = {
614*4882a593Smuzhiyun 	.vop_sel_bit = 0,
615*4882a593Smuzhiyun 	.grf_vop_sel_reg = 0,
616*4882a593Smuzhiyun 	.phy_ops    = &inno_dw_hdmi_phy_ops,
617*4882a593Smuzhiyun 	.phy_name   = "inno_dw_hdmi_phy",
618*4882a593Smuzhiyun 	.dev_type   = RK3228_HDMI,
619*4882a593Smuzhiyun };
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun const struct dw_hdmi_plat_data rk3368_hdmi_drv_data = {
622*4882a593Smuzhiyun 	.mpll_cfg   = rockchip_mpll_cfg,
623*4882a593Smuzhiyun 	.cur_ctr    = rockchip_cur_ctr,
624*4882a593Smuzhiyun 	.phy_config = rockchip_phy_config,
625*4882a593Smuzhiyun 	.mpll_cfg_420 = rockchip_mpll_cfg_420,
626*4882a593Smuzhiyun 	.dev_type   = RK3368_HDMI,
627*4882a593Smuzhiyun };
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
630*4882a593Smuzhiyun 	.vop_sel_bit = 6,
631*4882a593Smuzhiyun 	.grf_vop_sel_reg = RK3399_GRF_SOC_CON20,
632*4882a593Smuzhiyun 	.mpll_cfg   = rockchip_mpll_cfg,
633*4882a593Smuzhiyun 	.cur_ctr    = rockchip_cur_ctr,
634*4882a593Smuzhiyun 	.phy_config = rockchip_phy_config,
635*4882a593Smuzhiyun 	.mpll_cfg_420 = rockchip_mpll_cfg_420,
636*4882a593Smuzhiyun 	.dev_type   = RK3399_HDMI,
637*4882a593Smuzhiyun };
638*4882a593Smuzhiyun 
639*4882a593Smuzhiyun const struct dw_hdmi_plat_data rk3528_hdmi_drv_data = {
640*4882a593Smuzhiyun 	.vop_sel_bit = 0,
641*4882a593Smuzhiyun 	.grf_vop_sel_reg = 0,
642*4882a593Smuzhiyun 	.phy_ops    = &inno_dw_hdmi_phy_ops,
643*4882a593Smuzhiyun 	.phy_name   = "inno_dw_hdmi_phy2",
644*4882a593Smuzhiyun 	.dev_type   = RK3528_HDMI,
645*4882a593Smuzhiyun };
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = {
648*4882a593Smuzhiyun 	.vop_sel_bit = 0,
649*4882a593Smuzhiyun 	.grf_vop_sel_reg = 0,
650*4882a593Smuzhiyun 	.mpll_cfg   = rockchip_mpll_cfg,
651*4882a593Smuzhiyun 	.cur_ctr    = rockchip_cur_ctr,
652*4882a593Smuzhiyun 	.phy_config = rockchip_phy_config,
653*4882a593Smuzhiyun 	.mpll_cfg_420 = rockchip_mpll_cfg_420,
654*4882a593Smuzhiyun 	.dev_type   = RK3568_HDMI,
655*4882a593Smuzhiyun };
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun #ifdef CONFIG_SPL_BUILD
rockchip_spl_dw_hdmi_probe(struct connector_state * conn_state)658*4882a593Smuzhiyun int rockchip_spl_dw_hdmi_probe(struct connector_state *conn_state)
659*4882a593Smuzhiyun {
660*4882a593Smuzhiyun 	conn_state->connector = malloc(sizeof(struct rockchip_connector));
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun 	memset(conn_state->connector, 0, sizeof(*conn_state->connector));
663*4882a593Smuzhiyun 	rockchip_connector_bind(conn_state->connector, NULL, 0, &rockchip_dw_hdmi_funcs,
664*4882a593Smuzhiyun 				(void *)&rk3528_hdmi_drv_data,
665*4882a593Smuzhiyun 				DRM_MODE_CONNECTOR_HDMIA);
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun 	return 0;
668*4882a593Smuzhiyun }
669*4882a593Smuzhiyun #else
rockchip_dw_hdmi_probe(struct udevice * dev)670*4882a593Smuzhiyun static int rockchip_dw_hdmi_probe(struct udevice *dev)
671*4882a593Smuzhiyun {
672*4882a593Smuzhiyun 	int id;
673*4882a593Smuzhiyun 	struct rockchip_connector *conn = dev_get_priv(dev);
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun 	id = of_alias_get_id(ofnode_to_np(dev->node), "hdmi");
676*4882a593Smuzhiyun 	if (id < 0)
677*4882a593Smuzhiyun 		id = 0;
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun 	rockchip_connector_bind(conn, dev, id, &rockchip_dw_hdmi_funcs, NULL,
680*4882a593Smuzhiyun 				DRM_MODE_CONNECTOR_HDMIA);
681*4882a593Smuzhiyun 
682*4882a593Smuzhiyun 	return 0;
683*4882a593Smuzhiyun }
684*4882a593Smuzhiyun #endif
685*4882a593Smuzhiyun 
686*4882a593Smuzhiyun static const struct udevice_id rockchip_dw_hdmi_ids[] = {
687*4882a593Smuzhiyun 	{
688*4882a593Smuzhiyun 	 .compatible = "rockchip,rk3528-dw-hdmi",
689*4882a593Smuzhiyun 	 .data = (ulong)&rk3528_hdmi_drv_data,
690*4882a593Smuzhiyun 	}, {
691*4882a593Smuzhiyun 	 .compatible = "rockchip,rk3568-dw-hdmi",
692*4882a593Smuzhiyun 	 .data = (ulong)&rk3568_hdmi_drv_data,
693*4882a593Smuzhiyun 	}, {
694*4882a593Smuzhiyun 	 .compatible = "rockchip,rk3399-dw-hdmi",
695*4882a593Smuzhiyun 	 .data = (ulong)&rk3399_hdmi_drv_data,
696*4882a593Smuzhiyun 	}, {
697*4882a593Smuzhiyun 	 .compatible = "rockchip,rk3368-dw-hdmi",
698*4882a593Smuzhiyun 	 .data = (ulong)&rk3368_hdmi_drv_data,
699*4882a593Smuzhiyun 	}, {
700*4882a593Smuzhiyun 	 .compatible = "rockchip,rk3288-dw-hdmi",
701*4882a593Smuzhiyun 	 .data = (ulong)&rk3288_hdmi_drv_data,
702*4882a593Smuzhiyun 	}, {
703*4882a593Smuzhiyun 	 .compatible = "rockchip,rk3328-dw-hdmi",
704*4882a593Smuzhiyun 	 .data = (ulong)&rk3328_hdmi_drv_data,
705*4882a593Smuzhiyun 	}, {
706*4882a593Smuzhiyun 	 .compatible = "rockchip,rk3128-inno-hdmi",
707*4882a593Smuzhiyun 	 .data = (ulong)&rk3228_hdmi_drv_data,
708*4882a593Smuzhiyun 	}, {
709*4882a593Smuzhiyun 	 .compatible = "rockchip,rk3228-dw-hdmi",
710*4882a593Smuzhiyun 	 .data = (ulong)&rk3228_hdmi_drv_data,
711*4882a593Smuzhiyun 	}, {}
712*4882a593Smuzhiyun };
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun U_BOOT_DRIVER(rockchip_dw_hdmi) = {
715*4882a593Smuzhiyun 	.name = "rockchip_dw_hdmi",
716*4882a593Smuzhiyun 	.id = UCLASS_DISPLAY,
717*4882a593Smuzhiyun 	.of_match = rockchip_dw_hdmi_ids,
718*4882a593Smuzhiyun #ifndef CONFIG_SPL_BUILD
719*4882a593Smuzhiyun 	.probe	= rockchip_dw_hdmi_probe,
720*4882a593Smuzhiyun #endif
721*4882a593Smuzhiyun 	.priv_auto_alloc_size = sizeof(struct rockchip_connector),
722*4882a593Smuzhiyun };
723