1 /* 2 * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <asm/unaligned.h> 8 #include <config.h> 9 #include <common.h> 10 #include <errno.h> 11 #include <linux/libfdt.h> 12 #include <fdtdec.h> 13 #include <fdt_support.h> 14 #include <linux/hdmi.h> 15 #include <linux/list.h> 16 #include <linux/compat.h> 17 #include <linux/media-bus-format.h> 18 #include <malloc.h> 19 #include <video.h> 20 #include <video_rockchip.h> 21 #include <video_bridge.h> 22 #include <dm/device.h> 23 #include <dm/uclass-internal.h> 24 #include <asm/arch-rockchip/resource_img.h> 25 26 #include "bmp_helper.h" 27 #include "rockchip_display.h" 28 #include "rockchip_crtc.h" 29 #include "rockchip_connector.h" 30 #include "rockchip_bridge.h" 31 #include "rockchip_phy.h" 32 #include "rockchip_panel.h" 33 #include <dm.h> 34 #include <dm/of_access.h> 35 #include <dm/ofnode.h> 36 #include <asm/io.h> 37 38 #define DRIVER_VERSION "v1.0.1" 39 40 /*********************************************************************** 41 * Rockchip UBOOT DRM driver version 42 * 43 * v1.0.0 : add basic version for rockchip drm driver(hjc) 44 * v1.0.1 : add much dsi update(hjc) 45 * 46 **********************************************************************/ 47 48 #define RK_BLK_SIZE 512 49 #define BMP_PROCESSED_FLAG 8399 50 51 DECLARE_GLOBAL_DATA_PTR; 52 static LIST_HEAD(rockchip_display_list); 53 static LIST_HEAD(logo_cache_list); 54 55 static unsigned long memory_start; 56 static unsigned long memory_end; 57 58 /* 59 * the phy types are used by different connectors in public. 60 * The current version only has inno hdmi phy for hdmi and tve. 61 */ 62 enum public_use_phy { 63 NONE, 64 INNO_HDMI_PHY 65 }; 66 67 /* save public phy data */ 68 struct public_phy_data { 69 const struct rockchip_phy *phy_drv; 70 int phy_node; 71 int public_phy_type; 72 bool phy_init; 73 }; 74 75 /* check which kind of public phy does connector use */ 76 static int check_public_use_phy(struct display_state *state) 77 { 78 int ret = NONE; 79 #ifdef CONFIG_ROCKCHIP_INNO_HDMI_PHY 80 struct connector_state *conn_state = &state->conn_state; 81 82 if (!strncmp(dev_read_name(conn_state->dev), "tve", 3) || 83 !strncmp(dev_read_name(conn_state->dev), "hdmi", 4)) 84 ret = INNO_HDMI_PHY; 85 #endif 86 87 return ret; 88 } 89 90 /* 91 * get public phy driver and initialize it. 92 * The current version only has inno hdmi phy for hdmi and tve. 93 */ 94 static int get_public_phy(struct display_state *state, 95 struct public_phy_data *data) 96 { 97 struct connector_state *conn_state = &state->conn_state; 98 struct rockchip_phy *phy; 99 struct udevice *dev; 100 int ret = 0; 101 102 switch (data->public_phy_type) { 103 case INNO_HDMI_PHY: 104 #if defined(CONFIG_ROCKCHIP_RK3328) 105 ret = uclass_get_device_by_name(UCLASS_PHY, 106 "hdmiphy@ff430000", &dev); 107 #elif defined(CONFIG_ROCKCHIP_RK322X) 108 ret = uclass_get_device_by_name(UCLASS_PHY, 109 "hdmi-phy@12030000", &dev); 110 #else 111 ret = -EINVAL; 112 #endif 113 if (ret) { 114 printf("Warn: can't find phy driver\n"); 115 return 0; 116 } 117 118 phy = (struct rockchip_phy *)dev_get_driver_data(dev); 119 if (!phy) { 120 printf("failed to get phy driver\n"); 121 return 0; 122 } 123 124 ret = rockchip_phy_init(phy); 125 if (ret) { 126 printf("failed to init phy driver\n"); 127 return ret; 128 } 129 conn_state->phy = phy; 130 131 debug("inno hdmi phy init success, save it\n"); 132 data->phy_drv = conn_state->phy; 133 data->phy_init = true; 134 return 0; 135 default: 136 return -EINVAL; 137 } 138 } 139 140 static void init_display_buffer(ulong base) 141 { 142 memory_start = base + DRM_ROCKCHIP_FB_SIZE; 143 memory_end = memory_start; 144 } 145 146 void *get_display_buffer(int size) 147 { 148 unsigned long roundup_memory = roundup(memory_end, PAGE_SIZE); 149 void *buf; 150 151 if (roundup_memory + size > memory_start + MEMORY_POOL_SIZE) { 152 printf("failed to alloc %dbyte memory to display\n", size); 153 return NULL; 154 } 155 buf = (void *)roundup_memory; 156 157 memory_end = roundup_memory + size; 158 159 return buf; 160 } 161 162 static unsigned long get_display_size(void) 163 { 164 return memory_end - memory_start; 165 } 166 167 bool can_direct_logo(int bpp) 168 { 169 return bpp == 24 || bpp == 32; 170 } 171 172 static int connector_phy_init(struct display_state *state, 173 struct public_phy_data *data) 174 { 175 struct connector_state *conn_state = &state->conn_state; 176 int type; 177 178 /* does this connector use public phy with others */ 179 type = check_public_use_phy(state); 180 if (type == INNO_HDMI_PHY) { 181 /* there is no public phy was initialized */ 182 if (!data->phy_init) { 183 debug("start get public phy\n"); 184 data->public_phy_type = type; 185 if (get_public_phy(state, data)) { 186 printf("can't find correct public phy type\n"); 187 free(data); 188 return -EINVAL; 189 } 190 return 0; 191 } 192 193 /* if this phy has been initialized, get it directly */ 194 conn_state->phy = (struct rockchip_phy *)data->phy_drv; 195 return 0; 196 } 197 198 return 0; 199 } 200 201 static int connector_panel_init(struct display_state *state) 202 { 203 struct connector_state *conn_state = &state->conn_state; 204 struct panel_state *panel_state = &state->panel_state; 205 const struct rockchip_panel *panel = panel_state->panel; 206 ofnode dsp_lut_node; 207 int ret, len; 208 209 if (!panel) 210 return 0; 211 212 dsp_lut_node = dev_read_subnode(panel->dev, "dsp-lut"); 213 if (!ofnode_valid(dsp_lut_node)) { 214 debug("%s can not find dsp-lut node\n", __func__); 215 return 0; 216 } 217 218 ofnode_get_property(dsp_lut_node, "gamma-lut", &len); 219 if (len > 0) { 220 conn_state->gamma.size = len / sizeof(u32); 221 conn_state->gamma.lut = malloc(len); 222 if (!conn_state->gamma.lut) { 223 printf("malloc gamma lut failed\n"); 224 return -ENOMEM; 225 } 226 ret = ofnode_read_u32_array(dsp_lut_node, "gamma-lut", 227 conn_state->gamma.lut, 228 conn_state->gamma.size); 229 if (ret) { 230 printf("Cannot decode gamma_lut\n"); 231 conn_state->gamma.lut = NULL; 232 return -EINVAL; 233 } 234 panel_state->dsp_lut_node = dsp_lut_node; 235 } 236 237 return 0; 238 } 239 240 int drm_mode_vrefresh(const struct drm_display_mode *mode) 241 { 242 int refresh = 0; 243 unsigned int calc_val; 244 245 if (mode->vrefresh > 0) { 246 refresh = mode->vrefresh; 247 } else if (mode->htotal > 0 && mode->vtotal > 0) { 248 int vtotal; 249 250 vtotal = mode->vtotal; 251 /* work out vrefresh the value will be x1000 */ 252 calc_val = (mode->clock * 1000); 253 calc_val /= mode->htotal; 254 refresh = (calc_val + vtotal / 2) / vtotal; 255 256 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 257 refresh *= 2; 258 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 259 refresh /= 2; 260 if (mode->vscan > 1) 261 refresh /= mode->vscan; 262 } 263 return refresh; 264 } 265 266 static int display_get_timing_from_dts(struct panel_state *panel_state, 267 struct drm_display_mode *mode) 268 { 269 struct rockchip_panel *panel = panel_state->panel; 270 int phandle; 271 int hactive, vactive, pixelclock; 272 int hfront_porch, hback_porch, hsync_len; 273 int vfront_porch, vback_porch, vsync_len; 274 int val, flags = 0; 275 ofnode timing, native_mode; 276 277 timing = dev_read_subnode(panel->dev, "display-timings"); 278 if (!ofnode_valid(timing)) 279 return -ENODEV; 280 281 native_mode = ofnode_find_subnode(timing, "timing"); 282 if (!ofnode_valid(native_mode)) { 283 phandle = ofnode_read_u32_default(timing, "native-mode", -1); 284 native_mode = np_to_ofnode(of_find_node_by_phandle(phandle)); 285 if (!ofnode_valid(native_mode)) { 286 printf("failed to get display timings from DT\n"); 287 return -ENXIO; 288 } 289 } 290 291 #define FDT_GET_INT(val, name) \ 292 val = ofnode_read_s32_default(native_mode, name, -1); \ 293 if (val < 0) { \ 294 printf("Can't get %s\n", name); \ 295 return -ENXIO; \ 296 } 297 298 #define FDT_GET_INT_DEFAULT(val, name, default) \ 299 val = ofnode_read_s32_default(native_mode, name, default); 300 301 FDT_GET_INT(hactive, "hactive"); 302 FDT_GET_INT(vactive, "vactive"); 303 FDT_GET_INT(pixelclock, "clock-frequency"); 304 FDT_GET_INT(hsync_len, "hsync-len"); 305 FDT_GET_INT(hfront_porch, "hfront-porch"); 306 FDT_GET_INT(hback_porch, "hback-porch"); 307 FDT_GET_INT(vsync_len, "vsync-len"); 308 FDT_GET_INT(vfront_porch, "vfront-porch"); 309 FDT_GET_INT(vback_porch, "vback-porch"); 310 FDT_GET_INT(val, "hsync-active"); 311 flags |= val ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; 312 FDT_GET_INT(val, "vsync-active"); 313 flags |= val ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; 314 FDT_GET_INT(val, "pixelclk-active"); 315 flags |= val ? DRM_MODE_FLAG_PPIXDATA : 0; 316 317 FDT_GET_INT_DEFAULT(val, "screen-rotate", 0); 318 if (val == DRM_MODE_FLAG_XMIRROR) { 319 flags |= DRM_MODE_FLAG_XMIRROR; 320 } else if (val == DRM_MODE_FLAG_YMIRROR) { 321 flags |= DRM_MODE_FLAG_YMIRROR; 322 } else if (val == DRM_MODE_FLAG_XYMIRROR) { 323 flags |= DRM_MODE_FLAG_XMIRROR; 324 flags |= DRM_MODE_FLAG_YMIRROR; 325 } 326 mode->hdisplay = hactive; 327 mode->hsync_start = mode->hdisplay + hfront_porch; 328 mode->hsync_end = mode->hsync_start + hsync_len; 329 mode->htotal = mode->hsync_end + hback_porch; 330 331 mode->vdisplay = vactive; 332 mode->vsync_start = mode->vdisplay + vfront_porch; 333 mode->vsync_end = mode->vsync_start + vsync_len; 334 mode->vtotal = mode->vsync_end + vback_porch; 335 336 mode->clock = pixelclock / 1000; 337 mode->flags = flags; 338 339 return 0; 340 } 341 342 /** 343 * drm_mode_max_resolution_filter - mark modes out of vop max resolution 344 * @edid_data: structure store mode list 345 * @max_output: vop max output resolution 346 */ 347 void drm_mode_max_resolution_filter(struct hdmi_edid_data *edid_data, 348 struct vop_rect *max_output) 349 { 350 int i; 351 352 for (i = 0; i < edid_data->modes; i++) { 353 if (edid_data->mode_buf[i].hdisplay > max_output->width || 354 edid_data->mode_buf[i].vdisplay > max_output->height) 355 edid_data->mode_buf[i].invalid = true; 356 } 357 } 358 359 /** 360 * drm_mode_set_crtcinfo - set CRTC modesetting timing parameters 361 * @p: mode 362 * @adjust_flags: a combination of adjustment flags 363 * 364 * Setup the CRTC modesetting timing parameters for @p, adjusting if necessary. 365 * 366 * - The CRTC_INTERLACE_HALVE_V flag can be used to halve vertical timings of 367 * interlaced modes. 368 * - The CRTC_STEREO_DOUBLE flag can be used to compute the timings for 369 * buffers containing two eyes (only adjust the timings when needed, eg. for 370 * "frame packing" or "side by side full"). 371 * - The CRTC_NO_DBLSCAN and CRTC_NO_VSCAN flags request that adjustment *not* 372 * be performed for doublescan and vscan > 1 modes respectively. 373 */ 374 void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) 375 { 376 if ((p == NULL) || ((p->type & DRM_MODE_TYPE_CRTC_C) == DRM_MODE_TYPE_BUILTIN)) 377 return; 378 379 if (p->flags & DRM_MODE_FLAG_DBLCLK) 380 p->crtc_clock = 2 * p->clock; 381 else 382 p->crtc_clock = p->clock; 383 p->crtc_hdisplay = p->hdisplay; 384 p->crtc_hsync_start = p->hsync_start; 385 p->crtc_hsync_end = p->hsync_end; 386 p->crtc_htotal = p->htotal; 387 p->crtc_hskew = p->hskew; 388 p->crtc_vdisplay = p->vdisplay; 389 p->crtc_vsync_start = p->vsync_start; 390 p->crtc_vsync_end = p->vsync_end; 391 p->crtc_vtotal = p->vtotal; 392 393 if (p->flags & DRM_MODE_FLAG_INTERLACE) { 394 if (adjust_flags & CRTC_INTERLACE_HALVE_V) { 395 p->crtc_vdisplay /= 2; 396 p->crtc_vsync_start /= 2; 397 p->crtc_vsync_end /= 2; 398 p->crtc_vtotal /= 2; 399 } 400 } 401 402 if (!(adjust_flags & CRTC_NO_DBLSCAN)) { 403 if (p->flags & DRM_MODE_FLAG_DBLSCAN) { 404 p->crtc_vdisplay *= 2; 405 p->crtc_vsync_start *= 2; 406 p->crtc_vsync_end *= 2; 407 p->crtc_vtotal *= 2; 408 } 409 } 410 411 if (!(adjust_flags & CRTC_NO_VSCAN)) { 412 if (p->vscan > 1) { 413 p->crtc_vdisplay *= p->vscan; 414 p->crtc_vsync_start *= p->vscan; 415 p->crtc_vsync_end *= p->vscan; 416 p->crtc_vtotal *= p->vscan; 417 } 418 } 419 420 if (adjust_flags & CRTC_STEREO_DOUBLE) { 421 unsigned int layout = p->flags & DRM_MODE_FLAG_3D_MASK; 422 423 switch (layout) { 424 case DRM_MODE_FLAG_3D_FRAME_PACKING: 425 p->crtc_clock *= 2; 426 p->crtc_vdisplay += p->crtc_vtotal; 427 p->crtc_vsync_start += p->crtc_vtotal; 428 p->crtc_vsync_end += p->crtc_vtotal; 429 p->crtc_vtotal += p->crtc_vtotal; 430 break; 431 } 432 } 433 434 p->crtc_vblank_start = min(p->crtc_vsync_start, p->crtc_vdisplay); 435 p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal); 436 p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay); 437 p->crtc_hblank_end = max(p->crtc_hsync_end, p->crtc_htotal); 438 } 439 440 /** 441 * drm_mode_is_420_only - if a given videomode can be only supported in YCBCR420 442 * output format 443 * 444 * @connector: drm connector under action. 445 * @mode: video mode to be tested. 446 * 447 * Returns: 448 * true if the mode can be supported in YCBCR420 format 449 * false if not. 450 */ 451 bool drm_mode_is_420_only(const struct drm_display_info *display, 452 struct drm_display_mode *mode) 453 { 454 u8 vic = drm_match_cea_mode(mode); 455 456 return test_bit(vic, display->hdmi.y420_vdb_modes); 457 } 458 459 /** 460 * drm_mode_is_420_also - if a given videomode can be supported in YCBCR420 461 * output format also (along with RGB/YCBCR444/422) 462 * 463 * @display: display under action. 464 * @mode: video mode to be tested. 465 * 466 * Returns: 467 * true if the mode can be support YCBCR420 format 468 * false if not. 469 */ 470 bool drm_mode_is_420_also(const struct drm_display_info *display, 471 struct drm_display_mode *mode) 472 { 473 u8 vic = drm_match_cea_mode(mode); 474 475 return test_bit(vic, display->hdmi.y420_cmdb_modes); 476 } 477 478 /** 479 * drm_mode_is_420 - if a given videomode can be supported in YCBCR420 480 * output format 481 * 482 * @display: display under action. 483 * @mode: video mode to be tested. 484 * 485 * Returns: 486 * true if the mode can be supported in YCBCR420 format 487 * false if not. 488 */ 489 bool drm_mode_is_420(const struct drm_display_info *display, 490 struct drm_display_mode *mode) 491 { 492 return drm_mode_is_420_only(display, mode) || 493 drm_mode_is_420_also(display, mode); 494 } 495 496 static int display_get_timing(struct display_state *state) 497 { 498 struct connector_state *conn_state = &state->conn_state; 499 struct drm_display_mode *mode = &conn_state->mode; 500 const struct drm_display_mode *m; 501 struct panel_state *panel_state = &state->panel_state; 502 const struct rockchip_panel *panel = panel_state->panel; 503 504 if (dev_of_valid(panel->dev) && 505 !display_get_timing_from_dts(panel_state, mode)) { 506 printf("Using display timing dts\n"); 507 return 0; 508 } 509 510 if (panel->data) { 511 m = (const struct drm_display_mode *)panel->data; 512 memcpy(mode, m, sizeof(*m)); 513 printf("Using display timing from compatible panel driver\n"); 514 return 0; 515 } 516 517 return -ENODEV; 518 } 519 520 static int display_init(struct display_state *state) 521 { 522 struct connector_state *conn_state = &state->conn_state; 523 struct panel_state *panel_state = &state->panel_state; 524 const struct rockchip_connector *conn = conn_state->connector; 525 const struct rockchip_connector_funcs *conn_funcs = conn->funcs; 526 struct crtc_state *crtc_state = &state->crtc_state; 527 struct rockchip_crtc *crtc = crtc_state->crtc; 528 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 529 struct drm_display_mode *mode = &conn_state->mode; 530 int ret = 0; 531 static bool __print_once = false; 532 #if defined(CONFIG_I2C_EDID) 533 int bpc; 534 #endif 535 if (!__print_once) { 536 __print_once = true; 537 printf("Rockchip UBOOT DRM driver version: %s\n", DRIVER_VERSION); 538 } 539 540 if (state->is_init) 541 return 0; 542 543 if (!conn_funcs || !crtc_funcs) { 544 printf("failed to find connector or crtc functions\n"); 545 return -ENXIO; 546 } 547 548 if (crtc_state->crtc->active && 549 memcmp(&crtc_state->crtc->active_mode, &conn_state->mode, 550 sizeof(struct drm_display_mode))) { 551 printf("%s has been used for output type: %d, mode: %dx%dp%d\n", 552 crtc_state->dev->name, 553 crtc_state->crtc->active_mode.type, 554 crtc_state->crtc->active_mode.hdisplay, 555 crtc_state->crtc->active_mode.vdisplay, 556 crtc_state->crtc->active_mode.vrefresh); 557 return -ENODEV; 558 } 559 560 if (crtc_funcs->preinit) { 561 ret = crtc_funcs->preinit(state); 562 if (ret) 563 return ret; 564 } 565 566 if (panel_state->panel) 567 rockchip_panel_init(panel_state->panel); 568 569 if (conn_funcs->init) { 570 ret = conn_funcs->init(state); 571 if (ret) 572 goto deinit; 573 } 574 575 if (conn_state->phy) 576 rockchip_phy_init(conn_state->phy); 577 578 /* 579 * support hotplug, but not connect; 580 */ 581 #ifdef CONFIG_ROCKCHIP_DRM_TVE 582 if (crtc->hdmi_hpd && conn_state->type == DRM_MODE_CONNECTOR_TV) { 583 printf("hdmi plugin ,skip tve\n"); 584 goto deinit; 585 } 586 #elif defined(CONFIG_DRM_ROCKCHIP_RK1000) 587 if (crtc->hdmi_hpd && conn_state->type == DRM_MODE_CONNECTOR_LVDS) { 588 printf("hdmi plugin ,skip tve\n"); 589 goto deinit; 590 } 591 #endif 592 if (conn_funcs->detect) { 593 ret = conn_funcs->detect(state); 594 #if defined(CONFIG_ROCKCHIP_DRM_TVE) || defined(CONFIG_DRM_ROCKCHIP_RK1000) 595 if (conn_state->type == DRM_MODE_CONNECTOR_HDMIA) 596 crtc->hdmi_hpd = ret; 597 #endif 598 if (!ret) 599 goto deinit; 600 } 601 602 if (panel_state->panel) { 603 ret = display_get_timing(state); 604 if (!ret) 605 conn_state->bpc = panel_state->panel->bpc; 606 #if defined(CONFIG_I2C_EDID) 607 if (ret < 0 && conn_funcs->get_edid) { 608 rockchip_panel_prepare(panel_state->panel); 609 610 ret = conn_funcs->get_edid(state); 611 if (!ret) { 612 ret = edid_get_drm_mode((void *)&conn_state->edid, 613 sizeof(conn_state->edid), 614 mode, &bpc); 615 if (!ret) { 616 conn_state->bpc = bpc; 617 edid_print_info((void *)&conn_state->edid); 618 } 619 } 620 } 621 #endif 622 } else if (conn_state->bridge) { 623 ret = video_bridge_read_edid(conn_state->bridge->dev, 624 conn_state->edid, EDID_SIZE); 625 if (ret > 0) { 626 #if defined(CONFIG_I2C_EDID) 627 ret = edid_get_drm_mode(conn_state->edid, ret, mode, 628 &bpc); 629 if (!ret) { 630 conn_state->bpc = bpc; 631 edid_print_info((void *)&conn_state->edid); 632 } 633 #endif 634 } else { 635 ret = video_bridge_get_timing(conn_state->bridge->dev); 636 } 637 } else if (conn_funcs->get_timing) { 638 ret = conn_funcs->get_timing(state); 639 } else if (conn_funcs->get_edid) { 640 ret = conn_funcs->get_edid(state); 641 #if defined(CONFIG_I2C_EDID) 642 if (!ret) { 643 ret = edid_get_drm_mode((void *)&conn_state->edid, 644 sizeof(conn_state->edid), mode, 645 &bpc); 646 if (!ret) { 647 conn_state->bpc = bpc; 648 edid_print_info((void *)&conn_state->edid); 649 } 650 } 651 #endif 652 } 653 654 if (ret) 655 goto deinit; 656 657 printf("Detailed mode clock %u kHz, flags[%x]\n" 658 " H: %04d %04d %04d %04d\n" 659 " V: %04d %04d %04d %04d\n" 660 "bus_format: %x\n", 661 mode->clock, mode->flags, 662 mode->hdisplay, mode->hsync_start, 663 mode->hsync_end, mode->htotal, 664 mode->vdisplay, mode->vsync_start, 665 mode->vsync_end, mode->vtotal, 666 conn_state->bus_format); 667 668 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); 669 670 if (conn_state->bridge) 671 rockchip_bridge_mode_set(conn_state->bridge, &conn_state->mode); 672 673 if (crtc_funcs->init) { 674 ret = crtc_funcs->init(state); 675 if (ret) 676 goto deinit; 677 } 678 state->is_init = 1; 679 680 crtc_state->crtc->active = true; 681 memcpy(&crtc_state->crtc->active_mode, 682 &conn_state->mode, sizeof(struct drm_display_mode)); 683 684 return 0; 685 686 deinit: 687 if (conn_funcs->deinit) 688 conn_funcs->deinit(state); 689 return ret; 690 } 691 692 int display_send_mcu_cmd(struct display_state *state, u32 type, u32 val) 693 { 694 struct crtc_state *crtc_state = &state->crtc_state; 695 const struct rockchip_crtc *crtc = crtc_state->crtc; 696 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 697 int ret; 698 699 if (!state->is_init) 700 return -EINVAL; 701 702 if (crtc_funcs->send_mcu_cmd) { 703 ret = crtc_funcs->send_mcu_cmd(state, type, val); 704 if (ret) 705 return ret; 706 } 707 708 return 0; 709 } 710 711 static int display_set_plane(struct display_state *state) 712 { 713 struct crtc_state *crtc_state = &state->crtc_state; 714 const struct rockchip_crtc *crtc = crtc_state->crtc; 715 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 716 int ret; 717 718 if (!state->is_init) 719 return -EINVAL; 720 721 if (crtc_funcs->set_plane) { 722 ret = crtc_funcs->set_plane(state); 723 if (ret) 724 return ret; 725 } 726 727 return 0; 728 } 729 730 static int display_enable(struct display_state *state) 731 { 732 struct connector_state *conn_state = &state->conn_state; 733 const struct rockchip_connector *conn = conn_state->connector; 734 const struct rockchip_connector_funcs *conn_funcs = conn->funcs; 735 struct crtc_state *crtc_state = &state->crtc_state; 736 const struct rockchip_crtc *crtc = crtc_state->crtc; 737 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 738 struct panel_state *panel_state = &state->panel_state; 739 740 if (!state->is_init) 741 return -EINVAL; 742 743 if (state->is_enable) 744 return 0; 745 746 if (crtc_funcs->prepare) 747 crtc_funcs->prepare(state); 748 749 if (conn_funcs->prepare) 750 conn_funcs->prepare(state); 751 752 if (conn_state->bridge) 753 rockchip_bridge_pre_enable(conn_state->bridge); 754 755 if (panel_state->panel) 756 rockchip_panel_prepare(panel_state->panel); 757 758 if (crtc_funcs->enable) 759 crtc_funcs->enable(state); 760 761 if (conn_funcs->enable) 762 conn_funcs->enable(state); 763 764 if (conn_state->bridge) 765 rockchip_bridge_enable(conn_state->bridge); 766 767 if (panel_state->panel) 768 rockchip_panel_enable(panel_state->panel); 769 770 state->is_enable = true; 771 772 return 0; 773 } 774 775 static int display_disable(struct display_state *state) 776 { 777 struct connector_state *conn_state = &state->conn_state; 778 const struct rockchip_connector *conn = conn_state->connector; 779 const struct rockchip_connector_funcs *conn_funcs = conn->funcs; 780 struct crtc_state *crtc_state = &state->crtc_state; 781 const struct rockchip_crtc *crtc = crtc_state->crtc; 782 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 783 struct panel_state *panel_state = &state->panel_state; 784 785 if (!state->is_init) 786 return 0; 787 788 if (!state->is_enable) 789 return 0; 790 791 if (panel_state->panel) 792 rockchip_panel_disable(panel_state->panel); 793 794 if (conn_state->bridge) 795 rockchip_bridge_disable(conn_state->bridge); 796 797 if (conn_funcs->disable) 798 conn_funcs->disable(state); 799 800 if (crtc_funcs->disable) 801 crtc_funcs->disable(state); 802 803 if (panel_state->panel) 804 rockchip_panel_unprepare(panel_state->panel); 805 806 if (conn_state->bridge) 807 rockchip_bridge_post_disable(conn_state->bridge); 808 809 if (conn_funcs->unprepare) 810 conn_funcs->unprepare(state); 811 812 state->is_enable = 0; 813 state->is_init = 0; 814 815 return 0; 816 } 817 818 static int display_logo(struct display_state *state) 819 { 820 struct crtc_state *crtc_state = &state->crtc_state; 821 struct connector_state *conn_state = &state->conn_state; 822 struct logo_info *logo = &state->logo; 823 int hdisplay, vdisplay, ret; 824 825 ret = display_init(state); 826 if (!state->is_init || ret) 827 return -ENODEV; 828 829 switch (logo->bpp) { 830 case 16: 831 crtc_state->format = ROCKCHIP_FMT_RGB565; 832 break; 833 case 24: 834 crtc_state->format = ROCKCHIP_FMT_RGB888; 835 break; 836 case 32: 837 crtc_state->format = ROCKCHIP_FMT_ARGB8888; 838 break; 839 default: 840 printf("can't support bmp bits[%d]\n", logo->bpp); 841 return -EINVAL; 842 } 843 hdisplay = conn_state->mode.hdisplay; 844 vdisplay = conn_state->mode.vdisplay; 845 crtc_state->src_w = logo->width; 846 crtc_state->src_h = logo->height; 847 crtc_state->src_x = 0; 848 crtc_state->src_y = 0; 849 crtc_state->ymirror = logo->ymirror; 850 851 crtc_state->dma_addr = (u32)(unsigned long)logo->mem + logo->offset; 852 crtc_state->xvir = ALIGN(crtc_state->src_w * logo->bpp, 32) >> 5; 853 854 if (logo->mode == ROCKCHIP_DISPLAY_FULLSCREEN) { 855 crtc_state->crtc_x = 0; 856 crtc_state->crtc_y = 0; 857 crtc_state->crtc_w = hdisplay; 858 crtc_state->crtc_h = vdisplay; 859 } else { 860 if (crtc_state->src_w >= hdisplay) { 861 crtc_state->crtc_x = 0; 862 crtc_state->crtc_w = hdisplay; 863 } else { 864 crtc_state->crtc_x = (hdisplay - crtc_state->src_w) / 2; 865 crtc_state->crtc_w = crtc_state->src_w; 866 } 867 868 if (crtc_state->src_h >= vdisplay) { 869 crtc_state->crtc_y = 0; 870 crtc_state->crtc_h = vdisplay; 871 } else { 872 crtc_state->crtc_y = (vdisplay - crtc_state->src_h) / 2; 873 crtc_state->crtc_h = crtc_state->src_h; 874 } 875 } 876 877 display_set_plane(state); 878 display_enable(state); 879 880 return 0; 881 } 882 883 static int get_crtc_id(ofnode connect) 884 { 885 int phandle; 886 struct device_node *remote; 887 int val; 888 889 phandle = ofnode_read_u32_default(connect, "remote-endpoint", -1); 890 if (phandle < 0) 891 goto err; 892 remote = of_find_node_by_phandle(phandle); 893 val = ofnode_read_u32_default(np_to_ofnode(remote), "reg", -1); 894 if (val < 0) 895 goto err; 896 897 return val; 898 err: 899 printf("Can't get crtc id, default set to id = 0\n"); 900 return 0; 901 } 902 903 static int get_crtc_mcu_mode(struct crtc_state *crtc_state) 904 { 905 ofnode mcu_node; 906 int total_pixel, cs_pst, cs_pend, rw_pst, rw_pend; 907 908 mcu_node = dev_read_subnode(crtc_state->dev, "mcu-timing"); 909 if (!ofnode_valid(mcu_node)) 910 return -ENODEV; 911 912 #define FDT_GET_MCU_INT(val, name) \ 913 do { \ 914 val = ofnode_read_s32_default(mcu_node, name, -1); \ 915 if (val < 0) { \ 916 printf("Can't get %s\n", name); \ 917 return -ENXIO; \ 918 } \ 919 } while (0) 920 921 FDT_GET_MCU_INT(total_pixel, "mcu-pix-total"); 922 FDT_GET_MCU_INT(cs_pst, "mcu-cs-pst"); 923 FDT_GET_MCU_INT(cs_pend, "mcu-cs-pend"); 924 FDT_GET_MCU_INT(rw_pst, "mcu-rw-pst"); 925 FDT_GET_MCU_INT(rw_pend, "mcu-rw-pend"); 926 927 crtc_state->mcu_timing.mcu_pix_total = total_pixel; 928 crtc_state->mcu_timing.mcu_cs_pst = cs_pst; 929 crtc_state->mcu_timing.mcu_cs_pend = cs_pend; 930 crtc_state->mcu_timing.mcu_rw_pst = rw_pst; 931 crtc_state->mcu_timing.mcu_rw_pend = rw_pend; 932 933 return 0; 934 } 935 936 struct rockchip_logo_cache *find_or_alloc_logo_cache(const char *bmp) 937 { 938 struct rockchip_logo_cache *tmp, *logo_cache = NULL; 939 940 list_for_each_entry(tmp, &logo_cache_list, head) { 941 if (!strcmp(tmp->name, bmp)) { 942 logo_cache = tmp; 943 break; 944 } 945 } 946 947 if (!logo_cache) { 948 logo_cache = malloc(sizeof(*logo_cache)); 949 if (!logo_cache) { 950 printf("failed to alloc memory for logo cache\n"); 951 return NULL; 952 } 953 memset(logo_cache, 0, sizeof(*logo_cache)); 954 strcpy(logo_cache->name, bmp); 955 INIT_LIST_HEAD(&logo_cache->head); 956 list_add_tail(&logo_cache->head, &logo_cache_list); 957 } 958 959 return logo_cache; 960 } 961 962 /* Note: used only for rkfb kernel driver */ 963 static int load_kernel_bmp_logo(struct logo_info *logo, const char *bmp_name) 964 { 965 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 966 void *dst = NULL; 967 int len, size; 968 struct bmp_header *header; 969 970 if (!logo || !bmp_name) 971 return -EINVAL; 972 973 header = malloc(RK_BLK_SIZE); 974 if (!header) 975 return -ENOMEM; 976 977 len = rockchip_read_resource_file(header, bmp_name, 0, RK_BLK_SIZE); 978 if (len != RK_BLK_SIZE) { 979 free(header); 980 return -EINVAL; 981 } 982 size = get_unaligned_le32(&header->file_size); 983 dst = (void *)(memory_start + MEMORY_POOL_SIZE / 2); 984 len = rockchip_read_resource_file(dst, bmp_name, 0, size); 985 if (len != size) { 986 printf("failed to load bmp %s\n", bmp_name); 987 free(header); 988 return -ENOENT; 989 } 990 991 logo->mem = dst; 992 #endif 993 994 return 0; 995 } 996 997 static int load_bmp_logo(struct logo_info *logo, const char *bmp_name) 998 { 999 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 1000 struct rockchip_logo_cache *logo_cache; 1001 struct bmp_header *header; 1002 void *dst = NULL, *pdst; 1003 int size, len; 1004 int ret = 0; 1005 int reserved = 0; 1006 1007 if (!logo || !bmp_name) 1008 return -EINVAL; 1009 logo_cache = find_or_alloc_logo_cache(bmp_name); 1010 if (!logo_cache) 1011 return -ENOMEM; 1012 1013 if (logo_cache->logo.mem) { 1014 memcpy(logo, &logo_cache->logo, sizeof(*logo)); 1015 return 0; 1016 } 1017 1018 header = malloc(RK_BLK_SIZE); 1019 if (!header) 1020 return -ENOMEM; 1021 1022 len = rockchip_read_resource_file(header, bmp_name, 0, RK_BLK_SIZE); 1023 if (len != RK_BLK_SIZE) { 1024 ret = -EINVAL; 1025 goto free_header; 1026 } 1027 1028 logo->bpp = get_unaligned_le16(&header->bit_count); 1029 logo->width = get_unaligned_le32(&header->width); 1030 logo->height = get_unaligned_le32(&header->height); 1031 reserved = get_unaligned_le32(&header->reserved); 1032 if (logo->height < 0) 1033 logo->height = -logo->height; 1034 size = get_unaligned_le32(&header->file_size); 1035 if (!can_direct_logo(logo->bpp)) { 1036 if (size > MEMORY_POOL_SIZE) { 1037 printf("failed to use boot buf as temp bmp buffer\n"); 1038 ret = -ENOMEM; 1039 goto free_header; 1040 } 1041 pdst = get_display_buffer(size); 1042 1043 } else { 1044 pdst = get_display_buffer(size); 1045 dst = pdst; 1046 } 1047 1048 len = rockchip_read_resource_file(pdst, bmp_name, 0, size); 1049 if (len != size) { 1050 printf("failed to load bmp %s\n", bmp_name); 1051 ret = -ENOENT; 1052 goto free_header; 1053 } 1054 1055 if (!can_direct_logo(logo->bpp)) { 1056 int dst_size; 1057 /* 1058 * TODO: force use 16bpp if bpp less than 16; 1059 */ 1060 logo->bpp = (logo->bpp <= 16) ? 16 : logo->bpp; 1061 dst_size = logo->width * logo->height * logo->bpp >> 3; 1062 1063 dst = get_display_buffer(dst_size); 1064 if (!dst) { 1065 ret = -ENOMEM; 1066 goto free_header; 1067 } 1068 if (bmpdecoder(pdst, dst, logo->bpp)) { 1069 printf("failed to decode bmp %s\n", bmp_name); 1070 ret = -EINVAL; 1071 goto free_header; 1072 } 1073 flush_dcache_range((ulong)dst, 1074 ALIGN((ulong)dst + dst_size, 1075 CONFIG_SYS_CACHELINE_SIZE)); 1076 1077 logo->offset = 0; 1078 logo->ymirror = 0; 1079 } else { 1080 logo->offset = get_unaligned_le32(&header->data_offset); 1081 if (reserved == BMP_PROCESSED_FLAG) 1082 logo->ymirror = 0; 1083 else 1084 logo->ymirror = 1; 1085 } 1086 logo->mem = dst; 1087 1088 memcpy(&logo_cache->logo, logo, sizeof(*logo)); 1089 1090 free_header: 1091 1092 free(header); 1093 1094 return ret; 1095 #else 1096 return -EINVAL; 1097 #endif 1098 } 1099 1100 void rockchip_show_fbbase(ulong fbbase) 1101 { 1102 struct display_state *s; 1103 1104 list_for_each_entry(s, &rockchip_display_list, head) { 1105 s->logo.mode = ROCKCHIP_DISPLAY_FULLSCREEN; 1106 s->logo.mem = (char *)fbbase; 1107 s->logo.width = DRM_ROCKCHIP_FB_WIDTH; 1108 s->logo.height = DRM_ROCKCHIP_FB_HEIGHT; 1109 s->logo.bpp = 32; 1110 s->logo.ymirror = 0; 1111 1112 display_logo(s); 1113 } 1114 } 1115 1116 int rockchip_show_bmp(const char *bmp) 1117 { 1118 struct display_state *s; 1119 int ret = 0; 1120 1121 if (!bmp) { 1122 list_for_each_entry(s, &rockchip_display_list, head) 1123 display_disable(s); 1124 return -ENOENT; 1125 } 1126 1127 list_for_each_entry(s, &rockchip_display_list, head) { 1128 s->logo.mode = s->charge_logo_mode; 1129 if (load_bmp_logo(&s->logo, bmp)) 1130 continue; 1131 ret = display_logo(s); 1132 } 1133 1134 return ret; 1135 } 1136 1137 int rockchip_show_logo(void) 1138 { 1139 struct display_state *s; 1140 int ret = 0; 1141 1142 list_for_each_entry(s, &rockchip_display_list, head) { 1143 s->logo.mode = s->logo_mode; 1144 if (load_bmp_logo(&s->logo, s->ulogo_name)) 1145 printf("failed to display uboot logo\n"); 1146 else 1147 ret = display_logo(s); 1148 1149 /* Load kernel bmp in rockchip_display_fixup() later */ 1150 } 1151 1152 return ret; 1153 } 1154 1155 enum { 1156 PORT_DIR_IN, 1157 PORT_DIR_OUT, 1158 }; 1159 1160 static struct rockchip_panel *rockchip_of_find_panel(struct udevice *dev) 1161 { 1162 ofnode panel_node, ports, port, ep; 1163 struct udevice *panel_dev; 1164 int ret; 1165 1166 panel_node = dev_read_subnode(dev, "panel"); 1167 if (ofnode_valid(panel_node) && ofnode_is_available(panel_node)) { 1168 ret = uclass_get_device_by_ofnode(UCLASS_PANEL, panel_node, 1169 &panel_dev); 1170 if (!ret) 1171 goto found; 1172 } 1173 1174 ports = dev_read_subnode(dev, "ports"); 1175 if (!ofnode_valid(ports)) 1176 return NULL; 1177 1178 ofnode_for_each_subnode(port, ports) { 1179 u32 reg; 1180 1181 if (ofnode_read_u32(port, "reg", ®)) 1182 continue; 1183 1184 if (reg != PORT_DIR_OUT) 1185 continue; 1186 1187 ofnode_for_each_subnode(ep, port) { 1188 ofnode _ep, _port; 1189 uint phandle; 1190 1191 if (ofnode_read_u32(ep, "remote-endpoint", &phandle)) 1192 continue; 1193 1194 _ep = ofnode_get_by_phandle(phandle); 1195 if (!ofnode_valid(_ep)) 1196 continue; 1197 1198 _port = ofnode_get_parent(_ep); 1199 if (!ofnode_valid(_port)) 1200 continue; 1201 1202 panel_node = ofnode_get_parent(_port); 1203 if (!ofnode_valid(panel_node)) 1204 continue; 1205 1206 ret = uclass_get_device_by_ofnode(UCLASS_PANEL, 1207 panel_node, 1208 &panel_dev); 1209 if (!ret) 1210 goto found; 1211 } 1212 } 1213 1214 return NULL; 1215 1216 found: 1217 return (struct rockchip_panel *)dev_get_driver_data(panel_dev); 1218 } 1219 1220 static struct rockchip_bridge *rockchip_of_find_bridge(struct udevice *conn_dev) 1221 { 1222 ofnode node, ports, port, ep; 1223 struct udevice *dev; 1224 int ret; 1225 1226 ports = dev_read_subnode(conn_dev, "ports"); 1227 if (!ofnode_valid(ports)) 1228 return NULL; 1229 1230 ofnode_for_each_subnode(port, ports) { 1231 u32 reg; 1232 1233 if (ofnode_read_u32(port, "reg", ®)) 1234 continue; 1235 1236 if (reg != PORT_DIR_OUT) 1237 continue; 1238 1239 ofnode_for_each_subnode(ep, port) { 1240 ofnode _ep, _port, _ports; 1241 uint phandle; 1242 1243 if (ofnode_read_u32(ep, "remote-endpoint", &phandle)) 1244 continue; 1245 1246 _ep = ofnode_get_by_phandle(phandle); 1247 if (!ofnode_valid(_ep)) 1248 continue; 1249 1250 _port = ofnode_get_parent(_ep); 1251 if (!ofnode_valid(_port)) 1252 continue; 1253 1254 _ports = ofnode_get_parent(_port); 1255 if (!ofnode_valid(_ports)) 1256 continue; 1257 1258 node = ofnode_get_parent(_ports); 1259 if (!ofnode_valid(node)) 1260 continue; 1261 1262 ret = uclass_get_device_by_ofnode(UCLASS_VIDEO_BRIDGE, 1263 node, &dev); 1264 if (!ret) 1265 goto found; 1266 } 1267 } 1268 1269 return NULL; 1270 1271 found: 1272 return (struct rockchip_bridge *)dev_get_driver_data(dev); 1273 } 1274 1275 static struct udevice *rockchip_of_find_connector(ofnode endpoint) 1276 { 1277 ofnode ep, port, ports, conn; 1278 uint phandle; 1279 struct udevice *dev; 1280 int ret; 1281 1282 if (ofnode_read_u32(endpoint, "remote-endpoint", &phandle)) 1283 return NULL; 1284 1285 ep = ofnode_get_by_phandle(phandle); 1286 if (!ofnode_valid(ep) || !ofnode_is_available(ep)) 1287 return NULL; 1288 1289 port = ofnode_get_parent(ep); 1290 if (!ofnode_valid(port)) 1291 return NULL; 1292 1293 ports = ofnode_get_parent(port); 1294 if (!ofnode_valid(ports)) 1295 return NULL; 1296 1297 conn = ofnode_get_parent(ports); 1298 if (!ofnode_valid(conn) || !ofnode_is_available(conn)) 1299 return NULL; 1300 1301 ret = uclass_get_device_by_ofnode(UCLASS_DISPLAY, conn, &dev); 1302 if (ret) 1303 return NULL; 1304 1305 return dev; 1306 } 1307 1308 static struct rockchip_phy *rockchip_of_find_phy(struct udevice *dev) 1309 { 1310 struct udevice *phy_dev; 1311 int ret; 1312 1313 ret = uclass_get_device_by_phandle(UCLASS_PHY, dev, "phys", &phy_dev); 1314 if (ret) 1315 return NULL; 1316 1317 return (struct rockchip_phy *)dev_get_driver_data(phy_dev); 1318 } 1319 1320 #if defined(CONFIG_ROCKCHIP_RK3568) 1321 static int rockchip_display_fixup_dts(void *blob) 1322 { 1323 ofnode route_node, route_subnode, conn_ep, conn_port; 1324 const struct device_node *route_sub_devnode; 1325 const struct device_node *ep_node, *conn_ep_dev_node; 1326 u32 phandle; 1327 int conn_ep_offset; 1328 const char *route_sub_path, *path; 1329 1330 /* Don't go further if new variant after 1331 * reading PMUGRF_SOC_CON15 1332 */ 1333 if ((readl(0xfdc20100) & GENMASK(15, 14))) 1334 return 0; 1335 1336 route_node = ofnode_path("/display-subsystem/route"); 1337 if (!ofnode_valid(route_node)) 1338 return -EINVAL; 1339 1340 ofnode_for_each_subnode(route_subnode, route_node) { 1341 if (!ofnode_is_available(route_subnode)) 1342 continue; 1343 1344 route_sub_devnode = ofnode_to_np(route_subnode); 1345 route_sub_path = route_sub_devnode->full_name; 1346 if (!strstr(ofnode_get_name(route_subnode), "dsi") && 1347 !strstr(ofnode_get_name(route_subnode), "edp")) 1348 return 0; 1349 1350 phandle = ofnode_read_u32_default(route_subnode, "connect", -1); 1351 if (phandle < 0) { 1352 printf("Warn: can't find connect node's handle\n"); 1353 continue; 1354 } 1355 1356 ep_node = of_find_node_by_phandle(phandle); 1357 if (!ofnode_valid(np_to_ofnode(ep_node))) { 1358 printf("Warn: can't find endpoint node from phandle\n"); 1359 continue; 1360 } 1361 1362 ofnode_read_u32(np_to_ofnode(ep_node), "remote-endpoint", &phandle); 1363 conn_ep = ofnode_get_by_phandle(phandle); 1364 if (!ofnode_valid(conn_ep) || !ofnode_is_available(conn_ep)) 1365 return -ENODEV; 1366 1367 conn_port = ofnode_get_parent(conn_ep); 1368 if (!ofnode_valid(conn_port)) 1369 return -ENODEV; 1370 1371 ofnode_for_each_subnode(conn_ep, conn_port) { 1372 conn_ep_dev_node = ofnode_to_np(conn_ep); 1373 path = conn_ep_dev_node->full_name; 1374 ofnode_read_u32(conn_ep, "remote-endpoint", &phandle); 1375 conn_ep_offset = fdt_path_offset(blob, path); 1376 1377 if (!ofnode_is_available(conn_ep) && 1378 strstr(ofnode_get_name(conn_ep), "endpoint@0")) { 1379 do_fixup_by_path_u32(blob, route_sub_path, 1380 "connect", phandle, 1); 1381 fdt_status_okay(blob, conn_ep_offset); 1382 1383 } else if (ofnode_is_available(conn_ep) && 1384 strstr(ofnode_get_name(conn_ep), "endpoint@1")) { 1385 fdt_status_disabled(blob, conn_ep_offset); 1386 } 1387 } 1388 } 1389 1390 return 0; 1391 } 1392 #endif 1393 1394 static int rockchip_display_probe(struct udevice *dev) 1395 { 1396 struct video_priv *uc_priv = dev_get_uclass_priv(dev); 1397 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 1398 const void *blob = gd->fdt_blob; 1399 int phandle; 1400 struct udevice *crtc_dev, *conn_dev; 1401 struct rockchip_crtc *crtc; 1402 const struct rockchip_connector *conn; 1403 struct rockchip_panel *panel = NULL; 1404 struct rockchip_bridge *bridge = NULL; 1405 struct rockchip_phy *phy = NULL; 1406 struct display_state *s; 1407 const char *name; 1408 int ret; 1409 ofnode node, route_node; 1410 struct device_node *port_node, *vop_node, *ep_node, *port_parent_node; 1411 struct public_phy_data *data; 1412 bool is_ports_node = false; 1413 1414 #if defined(CONFIG_ROCKCHIP_RK3568) 1415 rockchip_display_fixup_dts((void *)blob); 1416 #endif 1417 1418 /* Before relocation we don't need to do anything */ 1419 if (!(gd->flags & GD_FLG_RELOC)) 1420 return 0; 1421 1422 data = malloc(sizeof(struct public_phy_data)); 1423 if (!data) { 1424 printf("failed to alloc phy data\n"); 1425 return -ENOMEM; 1426 } 1427 data->phy_init = false; 1428 1429 init_display_buffer(plat->base); 1430 1431 route_node = dev_read_subnode(dev, "route"); 1432 if (!ofnode_valid(route_node)) 1433 return -ENODEV; 1434 1435 ofnode_for_each_subnode(node, route_node) { 1436 if (!ofnode_is_available(node)) 1437 continue; 1438 phandle = ofnode_read_u32_default(node, "connect", -1); 1439 if (phandle < 0) { 1440 printf("Warn: can't find connect node's handle\n"); 1441 continue; 1442 } 1443 ep_node = of_find_node_by_phandle(phandle); 1444 if (!ofnode_valid(np_to_ofnode(ep_node))) { 1445 printf("Warn: can't find endpoint node from phandle\n"); 1446 continue; 1447 } 1448 port_node = of_get_parent(ep_node); 1449 if (!ofnode_valid(np_to_ofnode(port_node))) { 1450 printf("Warn: can't find port node from phandle\n"); 1451 continue; 1452 } 1453 1454 port_parent_node = of_get_parent(port_node); 1455 if (!ofnode_valid(np_to_ofnode(port_parent_node))) { 1456 printf("Warn: can't find port parent node from phandle\n"); 1457 continue; 1458 } 1459 1460 is_ports_node = strstr(port_parent_node->full_name, "ports") ? 1 : 0; 1461 if (is_ports_node) { 1462 vop_node = of_get_parent(port_parent_node); 1463 if (!ofnode_valid(np_to_ofnode(vop_node))) { 1464 printf("Warn: can't find crtc node from phandle\n"); 1465 continue; 1466 } 1467 } else { 1468 vop_node = port_parent_node; 1469 } 1470 1471 ret = uclass_get_device_by_ofnode(UCLASS_VIDEO_CRTC, 1472 np_to_ofnode(vop_node), 1473 &crtc_dev); 1474 if (ret) { 1475 printf("Warn: can't find crtc driver %d\n", ret); 1476 continue; 1477 } 1478 crtc = (struct rockchip_crtc *)dev_get_driver_data(crtc_dev); 1479 1480 conn_dev = rockchip_of_find_connector(np_to_ofnode(ep_node)); 1481 if (!conn_dev) { 1482 printf("Warn: can't find connect driver\n"); 1483 continue; 1484 } 1485 1486 conn = (const struct rockchip_connector *)dev_get_driver_data(conn_dev); 1487 1488 phy = rockchip_of_find_phy(conn_dev); 1489 1490 bridge = rockchip_of_find_bridge(conn_dev); 1491 if (bridge) 1492 panel = rockchip_of_find_panel(bridge->dev); 1493 else 1494 panel = rockchip_of_find_panel(conn_dev); 1495 1496 s = malloc(sizeof(*s)); 1497 if (!s) 1498 continue; 1499 1500 memset(s, 0, sizeof(*s)); 1501 1502 INIT_LIST_HEAD(&s->head); 1503 ret = ofnode_read_string_index(node, "logo,uboot", 0, &name); 1504 if (!ret) 1505 memcpy(s->ulogo_name, name, strlen(name)); 1506 ret = ofnode_read_string_index(node, "logo,kernel", 0, &name); 1507 if (!ret) 1508 memcpy(s->klogo_name, name, strlen(name)); 1509 ret = ofnode_read_string_index(node, "logo,mode", 0, &name); 1510 if (!strcmp(name, "fullscreen")) 1511 s->logo_mode = ROCKCHIP_DISPLAY_FULLSCREEN; 1512 else 1513 s->logo_mode = ROCKCHIP_DISPLAY_CENTER; 1514 ret = ofnode_read_string_index(node, "charge_logo,mode", 0, &name); 1515 if (!strcmp(name, "fullscreen")) 1516 s->charge_logo_mode = ROCKCHIP_DISPLAY_FULLSCREEN; 1517 else 1518 s->charge_logo_mode = ROCKCHIP_DISPLAY_CENTER; 1519 1520 s->blob = blob; 1521 s->panel_state.panel = panel; 1522 s->conn_state.node = conn_dev->node; 1523 s->conn_state.dev = conn_dev; 1524 s->conn_state.connector = conn; 1525 s->conn_state.phy = phy; 1526 s->conn_state.bridge = bridge; 1527 s->conn_state.overscan.left_margin = 100; 1528 s->conn_state.overscan.right_margin = 100; 1529 s->conn_state.overscan.top_margin = 100; 1530 s->conn_state.overscan.bottom_margin = 100; 1531 s->crtc_state.node = np_to_ofnode(vop_node); 1532 s->crtc_state.dev = crtc_dev; 1533 s->crtc_state.crtc = crtc; 1534 s->crtc_state.crtc_id = get_crtc_id(np_to_ofnode(ep_node)); 1535 s->node = node; 1536 1537 if (bridge) 1538 bridge->state = s; 1539 1540 if (panel) 1541 panel->state = s; 1542 1543 get_crtc_mcu_mode(&s->crtc_state); 1544 1545 ret = ofnode_read_u32_default(s->crtc_state.node, 1546 "rockchip,dual-channel-swap", 0); 1547 s->crtc_state.dual_channel_swap = ret; 1548 if (connector_panel_init(s)) { 1549 printf("Warn: Failed to init panel drivers\n"); 1550 free(s); 1551 continue; 1552 } 1553 1554 if (connector_phy_init(s, data)) { 1555 printf("Warn: Failed to init phy drivers\n"); 1556 free(s); 1557 continue; 1558 } 1559 list_add_tail(&s->head, &rockchip_display_list); 1560 } 1561 1562 if (list_empty(&rockchip_display_list)) { 1563 debug("Failed to found available display route\n"); 1564 return -ENODEV; 1565 } 1566 1567 uc_priv->xsize = DRM_ROCKCHIP_FB_WIDTH; 1568 uc_priv->ysize = DRM_ROCKCHIP_FB_HEIGHT; 1569 uc_priv->bpix = VIDEO_BPP32; 1570 1571 #ifdef CONFIG_DRM_ROCKCHIP_VIDEO_FRAMEBUFFER 1572 rockchip_show_fbbase(plat->base); 1573 video_set_flush_dcache(dev, true); 1574 #endif 1575 1576 return 0; 1577 } 1578 1579 void rockchip_display_fixup(void *blob) 1580 { 1581 const struct rockchip_connector_funcs *conn_funcs; 1582 const struct rockchip_crtc_funcs *crtc_funcs; 1583 const struct rockchip_connector *conn; 1584 const struct rockchip_crtc *crtc; 1585 struct display_state *s; 1586 int offset; 1587 const struct device_node *np; 1588 const char *path; 1589 1590 if (fdt_node_offset_by_compatible(blob, 0, "rockchip,drm-logo") >= 0) { 1591 list_for_each_entry(s, &rockchip_display_list, head) 1592 load_bmp_logo(&s->logo, s->klogo_name); 1593 1594 if (!get_display_size()) 1595 return; 1596 1597 offset = fdt_update_reserved_memory(blob, "rockchip,drm-logo", 1598 (u64)memory_start, 1599 (u64)get_display_size()); 1600 if (offset < 0) 1601 printf("failed to reserve drm-loader-logo memory\n"); 1602 } else { 1603 printf("can't found rockchip,drm-logo, use rockchip,fb-logo\n"); 1604 /* Compatible with rkfb display, only need reserve memory */ 1605 offset = fdt_update_reserved_memory(blob, "rockchip,fb-logo", 1606 (u64)memory_start, 1607 MEMORY_POOL_SIZE); 1608 if (offset < 0) 1609 printf("failed to reserve fb-loader-logo memory\n"); 1610 else 1611 list_for_each_entry(s, &rockchip_display_list, head) 1612 load_kernel_bmp_logo(&s->logo, s->klogo_name); 1613 return; 1614 } 1615 1616 list_for_each_entry(s, &rockchip_display_list, head) { 1617 conn = s->conn_state.connector; 1618 if (!conn) 1619 continue; 1620 conn_funcs = conn->funcs; 1621 if (!conn_funcs) { 1622 printf("failed to get exist connector\n"); 1623 continue; 1624 } 1625 1626 crtc = s->crtc_state.crtc; 1627 if (!crtc) 1628 continue; 1629 1630 crtc_funcs = crtc->funcs; 1631 if (!crtc_funcs) { 1632 printf("failed to get exist crtc\n"); 1633 continue; 1634 } 1635 1636 if (crtc_funcs->fixup_dts) 1637 crtc_funcs->fixup_dts(s, blob); 1638 1639 if (conn_funcs->fixup_dts) 1640 conn_funcs->fixup_dts(s, blob); 1641 1642 np = ofnode_to_np(s->node); 1643 path = np->full_name; 1644 fdt_increase_size(blob, 0x400); 1645 #define FDT_SET_U32(name, val) \ 1646 do_fixup_by_path_u32(blob, path, name, val, 1); 1647 1648 offset = s->logo.offset + (u32)(unsigned long)s->logo.mem 1649 - memory_start; 1650 FDT_SET_U32("logo,offset", offset); 1651 FDT_SET_U32("logo,width", s->logo.width); 1652 FDT_SET_U32("logo,height", s->logo.height); 1653 FDT_SET_U32("logo,bpp", s->logo.bpp); 1654 FDT_SET_U32("logo,ymirror", s->logo.ymirror); 1655 FDT_SET_U32("video,hdisplay", s->conn_state.mode.hdisplay); 1656 FDT_SET_U32("video,vdisplay", s->conn_state.mode.vdisplay); 1657 FDT_SET_U32("video,crtc_hsync_end", s->conn_state.mode.crtc_hsync_end); 1658 FDT_SET_U32("video,crtc_vsync_end", s->conn_state.mode.crtc_vsync_end); 1659 FDT_SET_U32("video,vrefresh", 1660 drm_mode_vrefresh(&s->conn_state.mode)); 1661 FDT_SET_U32("video,flags", s->conn_state.mode.flags); 1662 FDT_SET_U32("video,aspect_ratio", s->conn_state.mode.picture_aspect_ratio); 1663 FDT_SET_U32("overscan,left_margin", s->conn_state.overscan.left_margin); 1664 FDT_SET_U32("overscan,right_margin", s->conn_state.overscan.right_margin); 1665 FDT_SET_U32("overscan,top_margin", s->conn_state.overscan.top_margin); 1666 FDT_SET_U32("overscan,bottom_margin", s->conn_state.overscan.bottom_margin); 1667 #undef FDT_SET_U32 1668 } 1669 } 1670 1671 int rockchip_display_bind(struct udevice *dev) 1672 { 1673 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 1674 1675 plat->size = DRM_ROCKCHIP_FB_SIZE + MEMORY_POOL_SIZE; 1676 1677 return 0; 1678 } 1679 1680 static const struct udevice_id rockchip_display_ids[] = { 1681 { .compatible = "rockchip,display-subsystem" }, 1682 { } 1683 }; 1684 1685 U_BOOT_DRIVER(rockchip_display) = { 1686 .name = "rockchip_display", 1687 .id = UCLASS_VIDEO, 1688 .of_match = rockchip_display_ids, 1689 .bind = rockchip_display_bind, 1690 .probe = rockchip_display_probe, 1691 }; 1692 1693 static int do_rockchip_logo_show(cmd_tbl_t *cmdtp, int flag, int argc, 1694 char *const argv[]) 1695 { 1696 if (argc != 1) 1697 return CMD_RET_USAGE; 1698 1699 rockchip_show_logo(); 1700 1701 return 0; 1702 } 1703 1704 static int do_rockchip_show_bmp(cmd_tbl_t *cmdtp, int flag, int argc, 1705 char *const argv[]) 1706 { 1707 if (argc != 2) 1708 return CMD_RET_USAGE; 1709 1710 rockchip_show_bmp(argv[1]); 1711 1712 return 0; 1713 } 1714 1715 U_BOOT_CMD( 1716 rockchip_show_logo, 1, 1, do_rockchip_logo_show, 1717 "load and display log from resource partition", 1718 NULL 1719 ); 1720 1721 U_BOOT_CMD( 1722 rockchip_show_bmp, 2, 1, do_rockchip_show_bmp, 1723 "load and display bmp from resource partition", 1724 " <bmp_name>" 1725 ); 1726