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