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