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