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 <boot_rkimg.h> 9 #include <config.h> 10 #include <common.h> 11 #include <errno.h> 12 #include <linux/libfdt.h> 13 #include <fdtdec.h> 14 #include <fdt_support.h> 15 #include <linux/hdmi.h> 16 #include <linux/list.h> 17 #include <linux/compat.h> 18 #include <linux/media-bus-format.h> 19 #include <malloc.h> 20 #include <video.h> 21 #include <video_rockchip.h> 22 #include <video_bridge.h> 23 #include <dm/device.h> 24 #include <dm/uclass-internal.h> 25 #include <asm/arch-rockchip/resource_img.h> 26 27 #include "bmp_helper.h" 28 #include "rockchip_display.h" 29 #include "rockchip_crtc.h" 30 #include "rockchip_connector.h" 31 #include "rockchip_bridge.h" 32 #include "rockchip_phy.h" 33 #include "rockchip_panel.h" 34 #include <dm.h> 35 #include <dm/of_access.h> 36 #include <dm/ofnode.h> 37 #include <asm/io.h> 38 39 #define DRIVER_VERSION "v1.0.1" 40 41 /*********************************************************************** 42 * Rockchip UBOOT DRM driver version 43 * 44 * v1.0.0 : add basic version for rockchip drm driver(hjc) 45 * v1.0.1 : add much dsi update(hjc) 46 * 47 **********************************************************************/ 48 49 #define RK_BLK_SIZE 512 50 #define BMP_PROCESSED_FLAG 8399 51 52 DECLARE_GLOBAL_DATA_PTR; 53 static LIST_HEAD(rockchip_display_list); 54 static LIST_HEAD(logo_cache_list); 55 56 static unsigned long memory_start; 57 static unsigned long cubic_lut_memory_start; 58 static unsigned long memory_end; 59 static struct base2_info base_parameter; 60 static u32 align_size = PAGE_SIZE; 61 62 /* 63 * the phy types are used by different connectors in public. 64 * The current version only has inno hdmi phy for hdmi and tve. 65 */ 66 enum public_use_phy { 67 NONE, 68 INNO_HDMI_PHY 69 }; 70 71 /* save public phy data */ 72 struct public_phy_data { 73 const struct rockchip_phy *phy_drv; 74 int phy_node; 75 int public_phy_type; 76 bool phy_init; 77 }; 78 79 int rockchip_get_baseparameter(void) 80 { 81 struct blk_desc *dev_desc; 82 disk_partition_t part_info; 83 int block_num = 2048; 84 char baseparameter_buf[block_num * RK_BLK_SIZE] __aligned(ARCH_DMA_MINALIGN); 85 int ret = 0; 86 87 dev_desc = rockchip_get_bootdev(); 88 if (!dev_desc) { 89 printf("%s: Could not find device\n", __func__); 90 return -ENOENT; 91 } 92 93 if (part_get_info_by_name(dev_desc, "baseparameter", &part_info) < 0) { 94 printf("Could not find baseparameter partition\n"); 95 return -ENOENT; 96 } 97 98 ret = blk_dread(dev_desc, part_info.start, block_num, (void *)baseparameter_buf); 99 if (ret < 0) { 100 printf("read baseparameter failed\n"); 101 return ret; 102 } 103 104 memcpy(&base_parameter, baseparameter_buf, sizeof(base_parameter)); 105 if (strncasecmp(base_parameter.head_flag, "BASP", 4)) { 106 printf("warning: bad baseparameter\n"); 107 memset(&base_parameter, 0, sizeof(base_parameter)); 108 } 109 rockchip_display_make_crc32_table(); 110 111 return ret; 112 } 113 114 struct base2_disp_info *rockchip_get_disp_info(int type, int id) 115 { 116 struct base2_disp_info *disp_info; 117 struct base2_disp_header *disp_header; 118 int i = 0, offset = -1; 119 u32 crc_val; 120 u32 base2_length; 121 void *base_parameter_addr = (void *)&base_parameter; 122 123 for (i = 0; i < 8; i++) { 124 disp_header = &base_parameter.disp_header[i]; 125 if (disp_header->connector_type == type && 126 disp_header->connector_id == id) { 127 printf("disp info %d, type:%d, id:%d\n", i, type, id); 128 offset = disp_header->offset; 129 break; 130 } 131 } 132 133 if (offset < 0) 134 return NULL; 135 disp_info = base_parameter_addr + offset; 136 if (disp_info->screen_info[0].type != type || 137 disp_info->screen_info[0].id != id) { 138 printf("base2_disp_info couldn't be found, screen_info type[%d] or id[%d] mismatched\n", 139 disp_info->screen_info[0].type, 140 disp_info->screen_info[0].id); 141 return NULL; 142 } 143 144 if (strncasecmp(disp_info->disp_head_flag, "DISP", 4)) 145 return NULL; 146 147 if (base_parameter.major_version == 3 && base_parameter.minor_version == 0) { 148 crc_val = rockchip_display_crc32c_cal((unsigned char *)disp_info, 149 sizeof(struct base2_disp_info) - 4); 150 if (crc_val != disp_info->crc2) { 151 printf("error: connector type[%d], id[%d] disp info crc2 check error\n", 152 type, id); 153 return NULL; 154 } 155 } else { 156 base2_length = sizeof(struct base2_disp_info) - sizeof(struct csc_info) - 157 sizeof(struct acm_data) - 10 * 1024 - 4; 158 crc_val = rockchip_display_crc32c_cal((unsigned char *)disp_info, base2_length - 4); 159 if (crc_val != disp_info->crc) { 160 printf("error: connector type[%d], id[%d] disp info crc check error\n", 161 type, id); 162 return NULL; 163 } 164 } 165 166 return disp_info; 167 } 168 169 /* check which kind of public phy does connector use */ 170 static int check_public_use_phy(struct rockchip_connector *conn) 171 { 172 int ret = NONE; 173 #ifdef CONFIG_ROCKCHIP_INNO_HDMI_PHY 174 175 if (!strncmp(dev_read_name(conn->dev), "tve", 3) || 176 !strncmp(dev_read_name(conn->dev), "hdmi", 4)) 177 ret = INNO_HDMI_PHY; 178 #endif 179 180 return ret; 181 } 182 183 /* 184 * get public phy driver and initialize it. 185 * The current version only has inno hdmi phy for hdmi and tve. 186 */ 187 static int get_public_phy(struct rockchip_connector *conn, 188 struct public_phy_data *data) 189 { 190 struct rockchip_phy *phy; 191 struct udevice *dev; 192 int ret = 0; 193 194 switch (data->public_phy_type) { 195 case INNO_HDMI_PHY: 196 #if defined(CONFIG_ROCKCHIP_RK3328) 197 ret = uclass_get_device_by_name(UCLASS_PHY, 198 "hdmiphy@ff430000", &dev); 199 #elif defined(CONFIG_ROCKCHIP_RK322X) 200 ret = uclass_get_device_by_name(UCLASS_PHY, 201 "hdmi-phy@12030000", &dev); 202 #else 203 ret = -EINVAL; 204 #endif 205 if (ret) { 206 printf("Warn: can't find phy driver\n"); 207 return 0; 208 } 209 210 phy = (struct rockchip_phy *)dev_get_driver_data(dev); 211 if (!phy) { 212 printf("failed to get phy driver\n"); 213 return 0; 214 } 215 216 ret = rockchip_phy_init(phy); 217 if (ret) { 218 printf("failed to init phy driver\n"); 219 return ret; 220 } 221 conn->phy = phy; 222 223 debug("inno hdmi phy init success, save it\n"); 224 data->phy_drv = conn->phy; 225 data->phy_init = true; 226 return 0; 227 default: 228 return -EINVAL; 229 } 230 } 231 232 static void init_display_buffer(ulong base) 233 { 234 memory_start = ALIGN(base + DRM_ROCKCHIP_FB_SIZE, align_size); 235 memory_end = memory_start; 236 cubic_lut_memory_start = ALIGN(memory_start + MEMORY_POOL_SIZE, align_size); 237 } 238 239 void *get_display_buffer(int size) 240 { 241 unsigned long roundup_memory = roundup(memory_end, PAGE_SIZE); 242 void *buf; 243 244 if (roundup_memory + size > memory_start + MEMORY_POOL_SIZE) { 245 printf("failed to alloc %dbyte memory to display\n", size); 246 return NULL; 247 } 248 buf = (void *)roundup_memory; 249 250 memory_end = roundup_memory + size; 251 252 return buf; 253 } 254 255 static unsigned long get_display_size(void) 256 { 257 return memory_end - memory_start; 258 } 259 260 static unsigned long get_single_cubic_lut_size(void) 261 { 262 ulong cubic_lut_size; 263 int cubic_lut_step = CONFIG_ROCKCHIP_CUBIC_LUT_SIZE; 264 265 /* This is depend on IC designed */ 266 cubic_lut_size = (cubic_lut_step * cubic_lut_step * cubic_lut_step + 1) / 2 * 16; 267 cubic_lut_size = roundup(cubic_lut_size, PAGE_SIZE); 268 269 return cubic_lut_size; 270 } 271 272 static unsigned long get_cubic_lut_offset(int crtc_id) 273 { 274 return crtc_id * get_single_cubic_lut_size(); 275 } 276 277 unsigned long get_cubic_lut_buffer(int crtc_id) 278 { 279 return cubic_lut_memory_start + crtc_id * get_single_cubic_lut_size(); 280 } 281 282 static unsigned long get_cubic_memory_size(void) 283 { 284 /* Max support 4 cubic lut */ 285 return get_single_cubic_lut_size() * 4; 286 } 287 288 bool can_direct_logo(int bpp) 289 { 290 return bpp == 16 || bpp == 32; 291 } 292 293 static int connector_phy_init(struct rockchip_connector *conn, 294 struct public_phy_data *data) 295 { 296 int type; 297 298 /* does this connector use public phy with others */ 299 type = check_public_use_phy(conn); 300 if (type == INNO_HDMI_PHY) { 301 /* there is no public phy was initialized */ 302 if (!data->phy_init) { 303 debug("start get public phy\n"); 304 data->public_phy_type = type; 305 if (get_public_phy(conn, data)) { 306 printf("can't find correct public phy type\n"); 307 free(data); 308 return -EINVAL; 309 } 310 return 0; 311 } 312 313 /* if this phy has been initialized, get it directly */ 314 conn->phy = (struct rockchip_phy *)data->phy_drv; 315 return 0; 316 } 317 318 return 0; 319 } 320 321 int rockchip_ofnode_get_display_mode(ofnode node, struct drm_display_mode *mode, u32 *bus_flags) 322 { 323 int hactive, vactive, pixelclock; 324 int hfront_porch, hback_porch, hsync_len; 325 int vfront_porch, vback_porch, vsync_len; 326 int val, flags = 0; 327 328 #define FDT_GET_BOOL(val, name) \ 329 val = ofnode_read_bool(node, name); 330 331 #define FDT_GET_INT(val, name) \ 332 val = ofnode_read_s32_default(node, name, -1); \ 333 if (val < 0) { \ 334 printf("Can't get %s\n", name); \ 335 return -ENXIO; \ 336 } 337 338 #define FDT_GET_INT_DEFAULT(val, name, default) \ 339 val = ofnode_read_s32_default(node, name, default); 340 341 FDT_GET_INT(hactive, "hactive"); 342 FDT_GET_INT(vactive, "vactive"); 343 FDT_GET_INT(pixelclock, "clock-frequency"); 344 FDT_GET_INT(hsync_len, "hsync-len"); 345 FDT_GET_INT(hfront_porch, "hfront-porch"); 346 FDT_GET_INT(hback_porch, "hback-porch"); 347 FDT_GET_INT(vsync_len, "vsync-len"); 348 FDT_GET_INT(vfront_porch, "vfront-porch"); 349 FDT_GET_INT(vback_porch, "vback-porch"); 350 FDT_GET_INT(val, "hsync-active"); 351 flags |= val ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; 352 FDT_GET_INT(val, "vsync-active"); 353 flags |= val ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; 354 355 FDT_GET_BOOL(val, "interlaced"); 356 flags |= val ? DRM_MODE_FLAG_INTERLACE : 0; 357 FDT_GET_BOOL(val, "doublescan"); 358 flags |= val ? DRM_MODE_FLAG_DBLSCAN : 0; 359 FDT_GET_BOOL(val, "doubleclk"); 360 flags |= val ? DISPLAY_FLAGS_DOUBLECLK : 0; 361 362 FDT_GET_INT(val, "de-active"); 363 *bus_flags |= val ? DRM_BUS_FLAG_DE_HIGH : DRM_BUS_FLAG_DE_LOW; 364 FDT_GET_INT(val, "pixelclk-active"); 365 *bus_flags |= val ? DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE : DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE; 366 367 FDT_GET_INT_DEFAULT(val, "screen-rotate", 0); 368 if (val == DRM_MODE_FLAG_XMIRROR) { 369 flags |= DRM_MODE_FLAG_XMIRROR; 370 } else if (val == DRM_MODE_FLAG_YMIRROR) { 371 flags |= DRM_MODE_FLAG_YMIRROR; 372 } else if (val == DRM_MODE_FLAG_XYMIRROR) { 373 flags |= DRM_MODE_FLAG_XMIRROR; 374 flags |= DRM_MODE_FLAG_YMIRROR; 375 } 376 mode->hdisplay = hactive; 377 mode->hsync_start = mode->hdisplay + hfront_porch; 378 mode->hsync_end = mode->hsync_start + hsync_len; 379 mode->htotal = mode->hsync_end + hback_porch; 380 381 mode->vdisplay = vactive; 382 mode->vsync_start = mode->vdisplay + vfront_porch; 383 mode->vsync_end = mode->vsync_start + vsync_len; 384 mode->vtotal = mode->vsync_end + vback_porch; 385 386 mode->clock = pixelclock / 1000; 387 mode->flags = flags; 388 mode->vrefresh = drm_mode_vrefresh(mode); 389 390 return 0; 391 } 392 393 static int display_get_force_timing_from_dts(ofnode node, 394 struct drm_display_mode *mode, 395 u32 *bus_flags) 396 { 397 int ret = 0; 398 399 ret = rockchip_ofnode_get_display_mode(node, mode, bus_flags); 400 401 if (ret) { 402 mode->clock = 74250; 403 mode->flags = 0x5; 404 mode->hdisplay = 1280; 405 mode->hsync_start = 1390; 406 mode->hsync_end = 1430; 407 mode->htotal = 1650; 408 mode->hskew = 0; 409 mode->vdisplay = 720; 410 mode->vsync_start = 725; 411 mode->vsync_end = 730; 412 mode->vtotal = 750; 413 mode->vrefresh = 60; 414 mode->picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9; 415 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 416 } 417 418 printf("route node %s force_timing, use %dx%dp%d as default mode\n", 419 ret ? "undefine" : "define", mode->hdisplay, mode->vdisplay, 420 mode->vscan); 421 422 return 0; 423 } 424 425 static int display_get_timing_from_dts(struct rockchip_panel *panel, 426 struct drm_display_mode *mode, 427 u32 *bus_flags) 428 { 429 struct ofnode_phandle_args args; 430 ofnode dt, timing, mcu_panel; 431 int ret; 432 433 mcu_panel = dev_read_subnode(panel->dev, "mcu-panel"); 434 dt = dev_read_subnode(panel->dev, "display-timings"); 435 if (ofnode_valid(dt)) { 436 ret = ofnode_parse_phandle_with_args(dt, "native-mode", NULL, 437 0, 0, &args); 438 if (ret) 439 return ret; 440 441 timing = args.node; 442 } else if (ofnode_valid(mcu_panel)) { 443 dt = ofnode_find_subnode(mcu_panel, "display-timings"); 444 ret = ofnode_parse_phandle_with_args(dt, "native-mode", NULL, 445 0, 0, &args); 446 if (ret) 447 return ret; 448 449 timing = args.node; 450 } else { 451 timing = dev_read_subnode(panel->dev, "panel-timing"); 452 } 453 454 if (!ofnode_valid(timing)) { 455 printf("failed to get display timings from DT\n"); 456 return -ENXIO; 457 } 458 459 rockchip_ofnode_get_display_mode(timing, mode, bus_flags); 460 461 return 0; 462 } 463 464 static int display_get_timing(struct display_state *state) 465 { 466 struct connector_state *conn_state = &state->conn_state; 467 struct drm_display_mode *mode = &conn_state->mode; 468 const struct drm_display_mode *m; 469 struct rockchip_panel *panel = conn_state->connector->panel; 470 471 if (panel->funcs->get_mode) 472 return panel->funcs->get_mode(panel, mode); 473 474 if (dev_of_valid(panel->dev) && 475 !display_get_timing_from_dts(panel, mode, &conn_state->bus_flags)) { 476 printf("Using display timing dts\n"); 477 return 0; 478 } 479 480 if (panel->data) { 481 m = (const struct drm_display_mode *)panel->data; 482 memcpy(mode, m, sizeof(*m)); 483 printf("Using display timing from compatible panel driver\n"); 484 return 0; 485 } 486 487 return -ENODEV; 488 } 489 490 static int display_pre_init(void) 491 { 492 struct display_state *state; 493 int ret = 0; 494 495 list_for_each_entry(state, &rockchip_display_list, head) { 496 struct connector_state *conn_state = &state->conn_state; 497 struct crtc_state *crtc_state = &state->crtc_state; 498 struct rockchip_crtc *crtc = crtc_state->crtc; 499 500 ret = rockchip_connector_pre_init(state); 501 if (ret) 502 printf("pre init conn error\n"); 503 504 crtc->vps[crtc_state->crtc_id].output_type = conn_state->type; 505 } 506 return ret; 507 } 508 509 static int display_use_force_mode(struct display_state *state) 510 { 511 struct connector_state *conn_state = &state->conn_state; 512 struct drm_display_mode *mode = &conn_state->mode; 513 514 conn_state->bpc = 8; 515 memcpy(mode, &state->force_mode, sizeof(struct drm_display_mode)); 516 conn_state->bus_format = state->force_bus_format; 517 518 return 0; 519 } 520 521 static int display_get_edid_mode(struct display_state *state) 522 { 523 int ret = 0; 524 struct connector_state *conn_state = &state->conn_state; 525 struct drm_display_mode *mode = &conn_state->mode; 526 int bpc; 527 528 ret = edid_get_drm_mode(conn_state->edid, sizeof(conn_state->edid), mode, &bpc); 529 if (!ret) { 530 conn_state->bpc = bpc; 531 edid_print_info((void *)&conn_state->edid); 532 } else { 533 conn_state->bpc = 8; 534 mode->clock = 74250; 535 mode->flags = 0x5; 536 mode->hdisplay = 1280; 537 mode->hsync_start = 1390; 538 mode->hsync_end = 1430; 539 mode->htotal = 1650; 540 mode->hskew = 0; 541 mode->vdisplay = 720; 542 mode->vsync_start = 725; 543 mode->vsync_end = 730; 544 mode->vtotal = 750; 545 mode->vrefresh = 60; 546 mode->picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9; 547 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 548 549 printf("error: %s get mode from edid failed, use 720p60 as default mode\n", 550 state->conn_state.connector->dev->name); 551 } 552 553 return ret; 554 } 555 556 static int display_mode_valid(struct display_state *state) 557 { 558 struct connector_state *conn_state = &state->conn_state; 559 struct rockchip_connector *conn = conn_state->connector; 560 const struct rockchip_connector_funcs *conn_funcs = conn->funcs; 561 struct crtc_state *crtc_state = &state->crtc_state; 562 const struct rockchip_crtc *crtc = crtc_state->crtc; 563 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 564 int ret; 565 566 if (conn_funcs->mode_valid && state->enabled_at_spl == false) { 567 ret = conn_funcs->mode_valid(conn, state); 568 if (ret) 569 return ret; 570 } 571 572 if (crtc_funcs->mode_valid) { 573 ret = crtc_funcs->mode_valid(state); 574 if (ret) 575 return ret; 576 } 577 578 return 0; 579 } 580 581 static int display_mode_fixup(struct display_state *state) 582 { 583 struct crtc_state *crtc_state = &state->crtc_state; 584 const struct rockchip_crtc *crtc = crtc_state->crtc; 585 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 586 int ret; 587 588 if (crtc_funcs->mode_fixup) { 589 ret = crtc_funcs->mode_fixup(state); 590 if (ret) 591 return ret; 592 } 593 594 return 0; 595 } 596 597 static int display_init(struct display_state *state) 598 { 599 struct connector_state *conn_state = &state->conn_state; 600 struct rockchip_connector *conn = conn_state->connector; 601 struct crtc_state *crtc_state = &state->crtc_state; 602 struct rockchip_crtc *crtc = crtc_state->crtc; 603 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 604 struct drm_display_mode *mode = &conn_state->mode; 605 const char *compatible; 606 int ret = 0; 607 static bool __print_once = false; 608 #ifdef CONFIG_SPL_BUILD 609 struct spl_display_info *spl_disp_info = (struct spl_display_info *)CONFIG_SPL_VIDEO_BUF; 610 #endif 611 if (!__print_once) { 612 __print_once = true; 613 printf("Rockchip UBOOT DRM driver version: %s\n", DRIVER_VERSION); 614 } 615 616 if (state->is_init) 617 return 0; 618 619 if (!crtc_funcs) { 620 printf("failed to find crtc functions\n"); 621 return -ENXIO; 622 } 623 624 #ifdef CONFIG_SPL_BUILD 625 if (state->conn_state.type == DRM_MODE_CONNECTOR_HDMIA) 626 state->enabled_at_spl = spl_disp_info->enabled == 1 ? true : false; 627 if (state->enabled_at_spl) 628 printf("HDMI enabled at SPL\n"); 629 #endif 630 if (crtc_state->crtc->active && !crtc_state->ports_node && 631 memcmp(&crtc_state->crtc->active_mode, &conn_state->mode, 632 sizeof(struct drm_display_mode))) { 633 printf("%s has been used for output type: %d, mode: %dx%dp%d\n", 634 crtc_state->dev->name, 635 crtc_state->crtc->active_mode.type, 636 crtc_state->crtc->active_mode.hdisplay, 637 crtc_state->crtc->active_mode.vdisplay, 638 crtc_state->crtc->active_mode.vrefresh); 639 return -ENODEV; 640 } 641 642 if (crtc_funcs->preinit) { 643 ret = crtc_funcs->preinit(state); 644 if (ret) 645 return ret; 646 } 647 648 if (state->enabled_at_spl == false) { 649 ret = rockchip_connector_init(state); 650 if (ret) 651 goto deinit; 652 } 653 654 /* 655 * support hotplug, but not connect; 656 */ 657 #ifdef CONFIG_DRM_ROCKCHIP_TVE 658 if (crtc->hdmi_hpd && conn_state->type == DRM_MODE_CONNECTOR_TV) { 659 printf("hdmi plugin ,skip tve\n"); 660 goto deinit; 661 } 662 #elif defined(CONFIG_DRM_ROCKCHIP_RK1000) 663 if (crtc->hdmi_hpd && conn_state->type == DRM_MODE_CONNECTOR_LVDS) { 664 printf("hdmi plugin ,skip tve\n"); 665 goto deinit; 666 } 667 #endif 668 669 ret = rockchip_connector_detect(state); 670 #if defined(CONFIG_DRM_ROCKCHIP_TVE) || defined(CONFIG_DRM_ROCKCHIP_RK1000) 671 if (conn_state->type == DRM_MODE_CONNECTOR_HDMIA) 672 crtc->hdmi_hpd = ret; 673 if (state->enabled_at_spl) 674 crtc->hdmi_hpd = true; 675 #endif 676 if (!ret && !state->force_output) 677 goto deinit; 678 679 ret = 0; 680 if (state->enabled_at_spl == true) { 681 #ifdef CONFIG_SPL_BUILD 682 struct drm_display_mode *mode = &conn_state->mode; 683 684 memcpy(mode, &spl_disp_info->mode, sizeof(*mode)); 685 conn_state->bus_format = spl_disp_info->bus_format; 686 687 printf("%s get display mode from spl:%dx%d, bus format:0x%x\n", 688 conn->dev->name, mode->hdisplay, mode->vdisplay, conn_state->bus_format); 689 #endif 690 } else if (conn->panel) { 691 ret = display_get_timing(state); 692 if (!ret) 693 conn_state->bpc = conn->panel->bpc; 694 #if defined(CONFIG_I2C_EDID) 695 if (ret < 0 && conn->funcs->get_edid) { 696 rockchip_panel_prepare(conn->panel); 697 ret = conn->funcs->get_edid(conn, state); 698 if (!ret) 699 display_get_edid_mode(state); 700 } 701 #endif 702 } else if (conn->bridge) { 703 ret = video_bridge_read_edid(conn->bridge->dev, 704 conn_state->edid, EDID_SIZE); 705 if (ret > 0) { 706 #if defined(CONFIG_I2C_EDID) 707 display_get_edid_mode(state); 708 #endif 709 } else { 710 ret = video_bridge_get_timing(conn->bridge->dev); 711 } 712 } else if (conn->funcs->get_timing) { 713 ret = conn->funcs->get_timing(conn, state); 714 } else if (conn->funcs->get_edid) { 715 ret = conn->funcs->get_edid(conn, state); 716 #if defined(CONFIG_I2C_EDID) 717 if (!ret) 718 display_get_edid_mode(state); 719 #endif 720 } 721 722 if (!ret && conn_state->secondary) { 723 struct rockchip_connector *connector = conn_state->secondary; 724 725 if (connector->panel) { 726 if (connector->panel->funcs->get_mode) { 727 struct drm_display_mode *_mode = drm_mode_create(); 728 729 ret = connector->panel->funcs->get_mode(connector->panel, _mode); 730 if (!ret && !drm_mode_equal(_mode, mode)) 731 ret = -EINVAL; 732 733 drm_mode_destroy(_mode); 734 } 735 } 736 } 737 738 if (ret && !state->force_output) 739 goto deinit; 740 if (state->force_output) 741 display_use_force_mode(state); 742 743 if (display_mode_valid(state)) 744 goto deinit; 745 746 /* rk356x series drive mipi pixdata on posedge */ 747 compatible = dev_read_string(conn->dev, "compatible"); 748 if (!strcmp(compatible, "rockchip,rk3568-mipi-dsi")) { 749 conn_state->bus_flags &= ~DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE; 750 conn_state->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE; 751 } 752 753 printf("%s: %s detailed mode clock %u kHz, flags[%x]\n" 754 " H: %04d %04d %04d %04d\n" 755 " V: %04d %04d %04d %04d\n" 756 "bus_format: %x\n", 757 conn->dev->name, 758 state->force_output ? "use force output" : "", 759 mode->clock, mode->flags, 760 mode->hdisplay, mode->hsync_start, 761 mode->hsync_end, mode->htotal, 762 mode->vdisplay, mode->vsync_start, 763 mode->vsync_end, mode->vtotal, 764 conn_state->bus_format); 765 766 if (display_mode_fixup(state)) 767 goto deinit; 768 769 if (conn->bridge) 770 rockchip_bridge_mode_set(conn->bridge, &conn_state->mode); 771 772 if (crtc_funcs->init && state->enabled_at_spl == false) { 773 ret = crtc_funcs->init(state); 774 if (ret) 775 goto deinit; 776 } 777 state->is_init = 1; 778 779 crtc_state->crtc->active = true; 780 memcpy(&crtc_state->crtc->active_mode, 781 &conn_state->mode, sizeof(struct drm_display_mode)); 782 783 return 0; 784 785 deinit: 786 rockchip_connector_deinit(state); 787 return ret; 788 } 789 790 int display_send_mcu_cmd(struct display_state *state, u32 type, u32 val) 791 { 792 struct crtc_state *crtc_state = &state->crtc_state; 793 const struct rockchip_crtc *crtc = crtc_state->crtc; 794 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 795 int ret; 796 797 if (!state->is_init) 798 return -EINVAL; 799 800 if (crtc_funcs->send_mcu_cmd) { 801 ret = crtc_funcs->send_mcu_cmd(state, type, val); 802 if (ret) 803 return ret; 804 } 805 806 return 0; 807 } 808 809 static int display_set_plane(struct display_state *state) 810 { 811 struct crtc_state *crtc_state = &state->crtc_state; 812 const struct rockchip_crtc *crtc = crtc_state->crtc; 813 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 814 int ret; 815 816 if (!state->is_init) 817 return -EINVAL; 818 819 if (crtc_funcs->set_plane) { 820 ret = crtc_funcs->set_plane(state); 821 if (ret) 822 return ret; 823 } 824 825 return 0; 826 } 827 828 static int display_enable(struct display_state *state) 829 { 830 struct crtc_state *crtc_state = &state->crtc_state; 831 const struct rockchip_crtc *crtc = crtc_state->crtc; 832 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 833 834 if (!state->is_init) 835 return -EINVAL; 836 837 if (state->is_enable) 838 return 0; 839 840 if (crtc_funcs->prepare) 841 crtc_funcs->prepare(state); 842 843 if (state->enabled_at_spl == false) 844 rockchip_connector_pre_enable(state); 845 846 if (crtc_funcs->enable) 847 crtc_funcs->enable(state); 848 849 if (state->enabled_at_spl == false) 850 rockchip_connector_enable(state); 851 852 if (crtc_state->soft_te) 853 crtc_funcs->apply_soft_te(state); 854 855 state->is_enable = true; 856 857 return 0; 858 } 859 860 static int display_disable(struct display_state *state) 861 { 862 struct crtc_state *crtc_state = &state->crtc_state; 863 const struct rockchip_crtc *crtc = crtc_state->crtc; 864 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 865 866 if (!state->is_init) 867 return 0; 868 869 if (!state->is_enable) 870 return 0; 871 872 rockchip_connector_disable(state); 873 874 if (crtc_funcs->disable) 875 crtc_funcs->disable(state); 876 877 rockchip_connector_post_disable(state); 878 879 state->is_enable = 0; 880 state->is_init = 0; 881 882 return 0; 883 } 884 885 static int display_check(struct display_state *state) 886 { 887 struct connector_state *conn_state = &state->conn_state; 888 struct rockchip_connector *conn = conn_state->connector; 889 const struct rockchip_connector_funcs *conn_funcs = conn->funcs; 890 struct crtc_state *crtc_state = &state->crtc_state; 891 const struct rockchip_crtc *crtc = crtc_state->crtc; 892 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 893 int ret; 894 895 if (!state->is_init) 896 return 0; 897 898 if (conn_funcs->check) { 899 ret = conn_funcs->check(conn, state); 900 if (ret) 901 goto check_fail; 902 } 903 904 if (crtc_funcs->check) { 905 ret = crtc_funcs->check(state); 906 if (ret) 907 goto check_fail; 908 } 909 910 if (crtc_funcs->plane_check) { 911 ret = crtc_funcs->plane_check(state); 912 if (ret) 913 goto check_fail; 914 } 915 916 return 0; 917 918 check_fail: 919 state->is_init = false; 920 return ret; 921 } 922 923 static int display_logo(struct display_state *state) 924 { 925 struct crtc_state *crtc_state = &state->crtc_state; 926 struct connector_state *conn_state = &state->conn_state; 927 struct logo_info *logo = &state->logo; 928 int hdisplay, vdisplay, ret; 929 930 ret = display_init(state); 931 if (!state->is_init || ret) 932 return -ENODEV; 933 934 switch (logo->bpp) { 935 case 16: 936 crtc_state->format = ROCKCHIP_FMT_RGB565; 937 break; 938 case 24: 939 crtc_state->format = ROCKCHIP_FMT_RGB888; 940 break; 941 case 32: 942 crtc_state->format = ROCKCHIP_FMT_ARGB8888; 943 break; 944 default: 945 printf("can't support bmp bits[%d]\n", logo->bpp); 946 return -EINVAL; 947 } 948 hdisplay = conn_state->mode.crtc_hdisplay; 949 vdisplay = conn_state->mode.vdisplay; 950 crtc_state->src_rect.w = logo->width; 951 crtc_state->src_rect.h = logo->height; 952 crtc_state->src_rect.x = 0; 953 crtc_state->src_rect.y = 0; 954 crtc_state->ymirror = logo->ymirror; 955 crtc_state->rb_swap = 0; 956 957 crtc_state->dma_addr = (u32)(unsigned long)logo->mem + logo->offset; 958 crtc_state->xvir = ALIGN(crtc_state->src_rect.w * logo->bpp, 32) >> 5; 959 960 if (state->logo_mode == ROCKCHIP_DISPLAY_FULLSCREEN) { 961 crtc_state->crtc_rect.x = 0; 962 crtc_state->crtc_rect.y = 0; 963 crtc_state->crtc_rect.w = hdisplay; 964 crtc_state->crtc_rect.h = vdisplay; 965 } else { 966 if (crtc_state->src_rect.w >= hdisplay) { 967 crtc_state->crtc_rect.x = 0; 968 crtc_state->crtc_rect.w = hdisplay; 969 } else { 970 crtc_state->crtc_rect.x = (hdisplay - crtc_state->src_rect.w) / 2; 971 crtc_state->crtc_rect.w = crtc_state->src_rect.w; 972 } 973 974 if (crtc_state->src_rect.h >= vdisplay) { 975 crtc_state->crtc_rect.y = 0; 976 crtc_state->crtc_rect.h = vdisplay; 977 } else { 978 crtc_state->crtc_rect.y = (vdisplay - crtc_state->src_rect.h) / 2; 979 crtc_state->crtc_rect.h = crtc_state->src_rect.h; 980 } 981 } 982 983 display_check(state); 984 display_set_plane(state); 985 display_enable(state); 986 987 return 0; 988 } 989 990 static int get_crtc_id(ofnode connect, bool is_ports_node) 991 { 992 struct device_node *port_node; 993 struct device_node *remote; 994 int phandle; 995 int val; 996 997 if (is_ports_node) { 998 port_node = of_get_parent(connect.np); 999 if (!port_node) 1000 goto err; 1001 1002 val = ofnode_read_u32_default(np_to_ofnode(port_node), "reg", -1); 1003 if (val < 0) 1004 goto err; 1005 } else { 1006 phandle = ofnode_read_u32_default(connect, "remote-endpoint", -1); 1007 if (phandle < 0) 1008 goto err; 1009 1010 remote = of_find_node_by_phandle(phandle); 1011 if (!remote) 1012 goto err; 1013 1014 val = ofnode_read_u32_default(np_to_ofnode(remote), "reg", -1); 1015 if (val < 0) 1016 goto err; 1017 } 1018 1019 return val; 1020 err: 1021 printf("Can't get crtc id, default set to id = 0\n"); 1022 return 0; 1023 } 1024 1025 static int get_crtc_mcu_mode(struct crtc_state *crtc_state, struct device_node *port_node, 1026 bool is_ports_node) 1027 { 1028 ofnode mcu_node, vp_node; 1029 int total_pixel, cs_pst, cs_pend, rw_pst, rw_pend; 1030 1031 if (is_ports_node) { 1032 vp_node = np_to_ofnode(port_node); 1033 mcu_node = ofnode_find_subnode(vp_node, "mcu-timing"); 1034 if (!ofnode_valid(mcu_node)) 1035 return -ENODEV; 1036 } else { 1037 mcu_node = dev_read_subnode(crtc_state->dev, "mcu-timing"); 1038 if (!ofnode_valid(mcu_node)) 1039 return -ENODEV; 1040 } 1041 1042 #define FDT_GET_MCU_INT(val, name) \ 1043 do { \ 1044 val = ofnode_read_s32_default(mcu_node, name, -1); \ 1045 if (val < 0) { \ 1046 printf("Can't get %s\n", name); \ 1047 return -ENXIO; \ 1048 } \ 1049 } while (0) 1050 1051 FDT_GET_MCU_INT(total_pixel, "mcu-pix-total"); 1052 FDT_GET_MCU_INT(cs_pst, "mcu-cs-pst"); 1053 FDT_GET_MCU_INT(cs_pend, "mcu-cs-pend"); 1054 FDT_GET_MCU_INT(rw_pst, "mcu-rw-pst"); 1055 FDT_GET_MCU_INT(rw_pend, "mcu-rw-pend"); 1056 1057 crtc_state->mcu_timing.mcu_pix_total = total_pixel; 1058 crtc_state->mcu_timing.mcu_cs_pst = cs_pst; 1059 crtc_state->mcu_timing.mcu_cs_pend = cs_pend; 1060 crtc_state->mcu_timing.mcu_rw_pst = rw_pst; 1061 crtc_state->mcu_timing.mcu_rw_pend = rw_pend; 1062 1063 return 0; 1064 } 1065 1066 struct rockchip_logo_cache *find_or_alloc_logo_cache(const char *bmp) 1067 { 1068 struct rockchip_logo_cache *tmp, *logo_cache = NULL; 1069 1070 list_for_each_entry(tmp, &logo_cache_list, head) { 1071 if (!strcmp(tmp->name, bmp)) { 1072 logo_cache = tmp; 1073 break; 1074 } 1075 } 1076 1077 if (!logo_cache) { 1078 logo_cache = malloc(sizeof(*logo_cache)); 1079 if (!logo_cache) { 1080 printf("failed to alloc memory for logo cache\n"); 1081 return NULL; 1082 } 1083 memset(logo_cache, 0, sizeof(*logo_cache)); 1084 strcpy(logo_cache->name, bmp); 1085 INIT_LIST_HEAD(&logo_cache->head); 1086 list_add_tail(&logo_cache->head, &logo_cache_list); 1087 } 1088 1089 return logo_cache; 1090 } 1091 1092 /* Note: used only for rkfb kernel driver */ 1093 static int load_kernel_bmp_logo(struct logo_info *logo, const char *bmp_name) 1094 { 1095 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 1096 void *dst = NULL; 1097 int len, size; 1098 struct bmp_header *header; 1099 1100 if (!logo || !bmp_name) 1101 return -EINVAL; 1102 1103 header = malloc(RK_BLK_SIZE); 1104 if (!header) 1105 return -ENOMEM; 1106 1107 len = rockchip_read_resource_file(header, bmp_name, 0, RK_BLK_SIZE); 1108 if (len != RK_BLK_SIZE) { 1109 free(header); 1110 return -EINVAL; 1111 } 1112 size = get_unaligned_le32(&header->file_size); 1113 dst = (void *)(memory_start + MEMORY_POOL_SIZE / 2); 1114 len = rockchip_read_resource_file(dst, bmp_name, 0, size); 1115 if (len != size) { 1116 printf("failed to load bmp %s\n", bmp_name); 1117 free(header); 1118 return -ENOENT; 1119 } 1120 1121 logo->mem = dst; 1122 #endif 1123 1124 return 0; 1125 } 1126 1127 static int load_bmp_logo(struct logo_info *logo, const char *bmp_name) 1128 { 1129 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 1130 struct rockchip_logo_cache *logo_cache; 1131 struct bmp_header *header; 1132 void *dst = NULL, *pdst; 1133 int size, len; 1134 int ret = 0; 1135 int reserved = 0; 1136 int dst_size; 1137 1138 if (!logo || !bmp_name) 1139 return -EINVAL; 1140 logo_cache = find_or_alloc_logo_cache(bmp_name); 1141 if (!logo_cache) 1142 return -ENOMEM; 1143 1144 if (logo_cache->logo.mem) { 1145 memcpy(logo, &logo_cache->logo, sizeof(*logo)); 1146 return 0; 1147 } 1148 1149 header = malloc(RK_BLK_SIZE); 1150 if (!header) 1151 return -ENOMEM; 1152 1153 len = rockchip_read_resource_file(header, bmp_name, 0, RK_BLK_SIZE); 1154 if (len != RK_BLK_SIZE) { 1155 ret = -EINVAL; 1156 goto free_header; 1157 } 1158 1159 logo->bpp = get_unaligned_le16(&header->bit_count); 1160 logo->width = get_unaligned_le32(&header->width); 1161 logo->height = get_unaligned_le32(&header->height); 1162 dst_size = logo->width * logo->height * logo->bpp >> 3; 1163 reserved = get_unaligned_le32(&header->reserved); 1164 if (logo->height < 0) 1165 logo->height = -logo->height; 1166 size = get_unaligned_le32(&header->file_size); 1167 if (!can_direct_logo(logo->bpp)) { 1168 if (size > MEMORY_POOL_SIZE) { 1169 printf("failed to use boot buf as temp bmp buffer\n"); 1170 ret = -ENOMEM; 1171 goto free_header; 1172 } 1173 pdst = get_display_buffer(size); 1174 1175 } else { 1176 pdst = get_display_buffer(size); 1177 dst = pdst; 1178 } 1179 1180 len = rockchip_read_resource_file(pdst, bmp_name, 0, size); 1181 if (len != size) { 1182 printf("failed to load bmp %s\n", bmp_name); 1183 ret = -ENOENT; 1184 goto free_header; 1185 } 1186 1187 if (!can_direct_logo(logo->bpp)) { 1188 /* 1189 * TODO: force use 16bpp if bpp less than 16; 1190 */ 1191 logo->bpp = (logo->bpp <= 16) ? 16 : logo->bpp; 1192 dst_size = logo->width * logo->height * logo->bpp >> 3; 1193 dst = get_display_buffer(dst_size); 1194 if (!dst) { 1195 ret = -ENOMEM; 1196 goto free_header; 1197 } 1198 if (bmpdecoder(pdst, dst, logo->bpp)) { 1199 printf("failed to decode bmp %s\n", bmp_name); 1200 ret = -EINVAL; 1201 goto free_header; 1202 } 1203 1204 logo->offset = 0; 1205 logo->ymirror = 0; 1206 } else { 1207 logo->offset = get_unaligned_le32(&header->data_offset); 1208 if (reserved == BMP_PROCESSED_FLAG) 1209 logo->ymirror = 0; 1210 else 1211 logo->ymirror = 1; 1212 } 1213 logo->mem = dst; 1214 1215 memcpy(&logo_cache->logo, logo, sizeof(*logo)); 1216 1217 flush_dcache_range((ulong)dst, ALIGN((ulong)dst + dst_size, CONFIG_SYS_CACHELINE_SIZE)); 1218 1219 free_header: 1220 1221 free(header); 1222 1223 return ret; 1224 #else 1225 return -EINVAL; 1226 #endif 1227 } 1228 1229 void rockchip_show_fbbase(ulong fbbase) 1230 { 1231 struct display_state *s; 1232 1233 list_for_each_entry(s, &rockchip_display_list, head) { 1234 s->logo.mode = ROCKCHIP_DISPLAY_FULLSCREEN; 1235 s->logo.mem = (char *)fbbase; 1236 s->logo.width = DRM_ROCKCHIP_FB_WIDTH; 1237 s->logo.height = DRM_ROCKCHIP_FB_HEIGHT; 1238 s->logo.bpp = 32; 1239 s->logo.ymirror = 0; 1240 1241 display_logo(s); 1242 } 1243 } 1244 1245 int rockchip_show_bmp(const char *bmp) 1246 { 1247 struct display_state *s; 1248 int ret = 0; 1249 1250 if (!bmp) { 1251 list_for_each_entry(s, &rockchip_display_list, head) 1252 display_disable(s); 1253 return -ENOENT; 1254 } 1255 1256 list_for_each_entry(s, &rockchip_display_list, head) { 1257 s->logo.mode = s->charge_logo_mode; 1258 if (load_bmp_logo(&s->logo, bmp)) 1259 continue; 1260 ret = display_logo(s); 1261 } 1262 1263 return ret; 1264 } 1265 1266 int rockchip_show_logo(void) 1267 { 1268 struct display_state *s; 1269 int ret = 0; 1270 1271 list_for_each_entry(s, &rockchip_display_list, head) { 1272 s->logo.mode = s->logo_mode; 1273 if (load_bmp_logo(&s->logo, s->ulogo_name)) 1274 printf("failed to display uboot logo\n"); 1275 else 1276 ret = display_logo(s); 1277 1278 /* Load kernel bmp in rockchip_display_fixup() later */ 1279 } 1280 1281 return ret; 1282 } 1283 1284 int rockchip_vop_dump(const char *cmd) 1285 { 1286 struct display_state *state; 1287 struct crtc_state *crtc_state; 1288 struct rockchip_crtc *crtc; 1289 const struct rockchip_crtc_funcs *crtc_funcs; 1290 int ret = -EINVAL; 1291 1292 list_for_each_entry(state, &rockchip_display_list, head) { 1293 if (!state->is_init) 1294 continue; 1295 crtc_state = &state->crtc_state; 1296 crtc = crtc_state->crtc; 1297 crtc_funcs = crtc->funcs; 1298 1299 if (!cmd) 1300 ret = crtc_funcs->active_regs_dump(state); 1301 else if (!strcmp(cmd, "a") || !strcmp(cmd, "all")) 1302 ret = crtc_funcs->regs_dump(state); 1303 if (!ret) 1304 break; 1305 } 1306 1307 if (ret) 1308 ret = CMD_RET_USAGE; 1309 1310 return ret; 1311 } 1312 1313 enum { 1314 PORT_DIR_IN, 1315 PORT_DIR_OUT, 1316 }; 1317 1318 static const struct device_node *rockchip_of_graph_get_port_by_id(ofnode node, int id) 1319 { 1320 ofnode ports, port; 1321 u32 reg; 1322 1323 ports = ofnode_find_subnode(node, "ports"); 1324 if (!ofnode_valid(ports)) 1325 return NULL; 1326 1327 ofnode_for_each_subnode(port, ports) { 1328 if (ofnode_read_u32(port, "reg", ®)) 1329 continue; 1330 1331 if (reg == id) 1332 break; 1333 } 1334 1335 if (reg == id) 1336 return ofnode_to_np(port); 1337 1338 return NULL; 1339 } 1340 1341 static const struct device_node *rockchip_of_graph_get_port_parent(ofnode port) 1342 { 1343 ofnode parent; 1344 int is_ports_node; 1345 1346 parent = ofnode_get_parent(port); 1347 is_ports_node = strstr(ofnode_to_np(parent)->full_name, "ports") ? 1 : 0; 1348 if (is_ports_node) 1349 parent = ofnode_get_parent(parent); 1350 1351 return ofnode_to_np(parent); 1352 } 1353 1354 const struct device_node * 1355 rockchip_of_graph_get_endpoint_by_regs(ofnode node, int port, int endpoint) 1356 { 1357 const struct device_node *port_node; 1358 ofnode ep; 1359 u32 reg; 1360 1361 port_node = rockchip_of_graph_get_port_by_id(node, port); 1362 if (!port_node) 1363 return NULL; 1364 1365 ofnode_for_each_subnode(ep, np_to_ofnode(port_node)) { 1366 if (ofnode_read_u32(ep, "reg", ®)) 1367 break; 1368 if (reg == endpoint) 1369 break; 1370 } 1371 1372 if (!ofnode_valid(ep)) 1373 return NULL; 1374 1375 return ofnode_to_np(ep); 1376 } 1377 1378 static const struct device_node * 1379 rockchip_of_graph_get_remote_node(ofnode node, int port, int endpoint) 1380 { 1381 const struct device_node *ep_node; 1382 ofnode ep; 1383 uint phandle; 1384 1385 ep_node = rockchip_of_graph_get_endpoint_by_regs(node, port, endpoint); 1386 if (!ep_node) 1387 return NULL; 1388 1389 if (ofnode_read_u32(np_to_ofnode(ep_node), "remote-endpoint", &phandle)) 1390 return NULL; 1391 1392 ep = ofnode_get_by_phandle(phandle); 1393 if (!ofnode_valid(ep)) 1394 return NULL; 1395 1396 return ofnode_to_np(ep); 1397 } 1398 1399 static int rockchip_of_find_panel(struct udevice *dev, struct rockchip_panel **panel) 1400 { 1401 const struct device_node *ep_node, *panel_node; 1402 ofnode panel_ofnode, port; 1403 struct udevice *panel_dev; 1404 int ret = 0; 1405 1406 *panel = NULL; 1407 panel_ofnode = dev_read_subnode(dev, "panel"); 1408 if (ofnode_valid(panel_ofnode) && ofnode_is_available(panel_ofnode)) { 1409 ret = uclass_get_device_by_ofnode(UCLASS_PANEL, panel_ofnode, 1410 &panel_dev); 1411 if (!ret) 1412 goto found; 1413 } 1414 1415 ep_node = rockchip_of_graph_get_remote_node(dev->node, PORT_DIR_OUT, 0); 1416 if (!ep_node) 1417 return -ENODEV; 1418 1419 port = ofnode_get_parent(np_to_ofnode(ep_node)); 1420 if (!ofnode_valid(port)) 1421 return -ENODEV; 1422 1423 panel_node = rockchip_of_graph_get_port_parent(port); 1424 if (!panel_node) 1425 return -ENODEV; 1426 1427 ret = uclass_get_device_by_ofnode(UCLASS_PANEL, np_to_ofnode(panel_node), &panel_dev); 1428 if (!ret) 1429 goto found; 1430 1431 return -ENODEV; 1432 1433 found: 1434 *panel = (struct rockchip_panel *)dev_get_driver_data(panel_dev); 1435 return 0; 1436 } 1437 1438 static int rockchip_of_find_bridge(struct udevice *dev, struct rockchip_bridge **bridge) 1439 { 1440 const struct device_node *ep_node, *bridge_node; 1441 ofnode port; 1442 struct udevice *bridge_dev; 1443 int ret = 0; 1444 1445 ep_node = rockchip_of_graph_get_remote_node(dev->node, PORT_DIR_OUT, 0); 1446 if (!ep_node) 1447 return -ENODEV; 1448 1449 port = ofnode_get_parent(np_to_ofnode(ep_node)); 1450 if (!ofnode_valid(port)) 1451 return -ENODEV; 1452 1453 bridge_node = rockchip_of_graph_get_port_parent(port); 1454 if (!bridge_node) 1455 return -ENODEV; 1456 1457 ret = uclass_get_device_by_ofnode(UCLASS_VIDEO_BRIDGE, np_to_ofnode(bridge_node), 1458 &bridge_dev); 1459 if (!ret) 1460 goto found; 1461 1462 return -ENODEV; 1463 1464 found: 1465 *bridge = (struct rockchip_bridge *)dev_get_driver_data(bridge_dev); 1466 return 0; 1467 } 1468 1469 static int rockchip_of_find_panel_or_bridge(struct udevice *dev, struct rockchip_panel **panel, 1470 struct rockchip_bridge **bridge) 1471 { 1472 int ret = 0; 1473 1474 if (*panel) 1475 return 0; 1476 1477 *panel = NULL; 1478 *bridge = NULL; 1479 1480 if (panel) { 1481 ret = rockchip_of_find_panel(dev, panel); 1482 if (!ret) 1483 return 0; 1484 } 1485 1486 if (ret) { 1487 ret = rockchip_of_find_bridge(dev, bridge); 1488 if (!ret) 1489 ret = rockchip_of_find_panel_or_bridge((*bridge)->dev, panel, 1490 &(*bridge)->next_bridge); 1491 } 1492 1493 return ret; 1494 } 1495 1496 static struct rockchip_phy *rockchip_of_find_phy(struct udevice *dev) 1497 { 1498 struct udevice *phy_dev; 1499 int ret; 1500 1501 ret = uclass_get_device_by_phandle(UCLASS_PHY, dev, "phys", &phy_dev); 1502 if (ret) 1503 return NULL; 1504 1505 return (struct rockchip_phy *)dev_get_driver_data(phy_dev); 1506 } 1507 1508 static struct udevice *rockchip_of_find_connector_device(ofnode endpoint) 1509 { 1510 ofnode ep, port, ports, conn; 1511 uint phandle; 1512 struct udevice *dev; 1513 int ret; 1514 1515 if (ofnode_read_u32(endpoint, "remote-endpoint", &phandle)) 1516 return NULL; 1517 1518 ep = ofnode_get_by_phandle(phandle); 1519 if (!ofnode_valid(ep) || !ofnode_is_available(ep)) 1520 return NULL; 1521 1522 port = ofnode_get_parent(ep); 1523 if (!ofnode_valid(port)) 1524 return NULL; 1525 1526 ports = ofnode_get_parent(port); 1527 if (!ofnode_valid(ports)) 1528 return NULL; 1529 1530 conn = ofnode_get_parent(ports); 1531 if (!ofnode_valid(conn) || !ofnode_is_available(conn)) 1532 return NULL; 1533 1534 ret = uclass_get_device_by_ofnode(UCLASS_DISPLAY, conn, &dev); 1535 if (ret) 1536 return NULL; 1537 1538 return dev; 1539 } 1540 1541 static struct rockchip_connector *rockchip_of_get_connector(ofnode endpoint) 1542 { 1543 struct rockchip_connector *conn; 1544 struct udevice *dev; 1545 int ret; 1546 1547 dev = rockchip_of_find_connector_device(endpoint); 1548 if (!dev) { 1549 printf("Warn: can't find connect driver\n"); 1550 return NULL; 1551 } 1552 1553 conn = get_rockchip_connector_by_device(dev); 1554 if (!conn) 1555 return NULL; 1556 ret = rockchip_of_find_panel_or_bridge(dev, &conn->panel, &conn->bridge); 1557 if (ret) 1558 debug("Warn: no find panel or bridge\n"); 1559 1560 conn->phy = rockchip_of_find_phy(dev); 1561 1562 return conn; 1563 } 1564 1565 static struct rockchip_connector *rockchip_get_split_connector(struct rockchip_connector *conn) 1566 { 1567 char *conn_name; 1568 struct device_node *split_node; 1569 struct udevice *split_dev; 1570 struct rockchip_connector *split_conn; 1571 bool split_mode; 1572 int ret; 1573 1574 split_mode = ofnode_read_bool(conn->dev->node, "split-mode"); 1575 if (!split_mode) 1576 return NULL; 1577 1578 switch (conn->type) { 1579 case DRM_MODE_CONNECTOR_DisplayPort: 1580 conn_name = "dp"; 1581 break; 1582 case DRM_MODE_CONNECTOR_eDP: 1583 conn_name = "edp"; 1584 break; 1585 case DRM_MODE_CONNECTOR_HDMIA: 1586 conn_name = "hdmi"; 1587 break; 1588 default: 1589 return NULL; 1590 } 1591 1592 split_node = of_alias_get_dev(conn_name, !conn->id); 1593 if (!split_node || !of_device_is_available(split_node)) 1594 return NULL; 1595 1596 ret = uclass_get_device_by_ofnode(UCLASS_DISPLAY, np_to_ofnode(split_node), &split_dev); 1597 if (ret) 1598 return NULL; 1599 1600 split_conn = get_rockchip_connector_by_device(split_dev); 1601 if (!split_conn) 1602 return NULL; 1603 ret = rockchip_of_find_panel_or_bridge(split_dev, &split_conn->panel, &split_conn->bridge); 1604 if (ret) 1605 debug("Warn: no find panel or bridge\n"); 1606 1607 split_conn->phy = rockchip_of_find_phy(split_dev); 1608 1609 return split_conn; 1610 } 1611 1612 static bool rockchip_get_display_path_status(ofnode endpoint) 1613 { 1614 ofnode ep; 1615 uint phandle; 1616 1617 if (ofnode_read_u32(endpoint, "remote-endpoint", &phandle)) 1618 return false; 1619 1620 ep = ofnode_get_by_phandle(phandle); 1621 if (!ofnode_valid(ep) || !ofnode_is_available(ep)) 1622 return false; 1623 1624 return true; 1625 } 1626 1627 #if defined(CONFIG_ROCKCHIP_RK3568) 1628 static int rockchip_display_fixup_dts(void *blob) 1629 { 1630 ofnode route_node, route_subnode, conn_ep, conn_port; 1631 const struct device_node *route_sub_devnode; 1632 const struct device_node *ep_node, *conn_ep_dev_node; 1633 u32 phandle; 1634 int conn_ep_offset; 1635 const char *route_sub_path, *path; 1636 1637 /* Don't go further if new variant after 1638 * reading PMUGRF_SOC_CON15 1639 */ 1640 if ((readl(0xfdc20100) & GENMASK(15, 14))) 1641 return 0; 1642 1643 route_node = ofnode_path("/display-subsystem/route"); 1644 if (!ofnode_valid(route_node)) 1645 return -EINVAL; 1646 1647 ofnode_for_each_subnode(route_subnode, route_node) { 1648 if (!ofnode_is_available(route_subnode)) 1649 continue; 1650 1651 route_sub_devnode = ofnode_to_np(route_subnode); 1652 route_sub_path = route_sub_devnode->full_name; 1653 if (!strstr(ofnode_get_name(route_subnode), "dsi") && 1654 !strstr(ofnode_get_name(route_subnode), "edp")) 1655 return 0; 1656 1657 phandle = ofnode_read_u32_default(route_subnode, "connect", -1); 1658 if (phandle < 0) { 1659 printf("Warn: can't find connect node's handle\n"); 1660 continue; 1661 } 1662 1663 ep_node = of_find_node_by_phandle(phandle); 1664 if (!ofnode_valid(np_to_ofnode(ep_node))) { 1665 printf("Warn: can't find endpoint node from phandle\n"); 1666 continue; 1667 } 1668 1669 ofnode_read_u32(np_to_ofnode(ep_node), "remote-endpoint", &phandle); 1670 conn_ep = ofnode_get_by_phandle(phandle); 1671 if (!ofnode_valid(conn_ep) || !ofnode_is_available(conn_ep)) 1672 return -ENODEV; 1673 1674 conn_port = ofnode_get_parent(conn_ep); 1675 if (!ofnode_valid(conn_port)) 1676 return -ENODEV; 1677 1678 ofnode_for_each_subnode(conn_ep, conn_port) { 1679 conn_ep_dev_node = ofnode_to_np(conn_ep); 1680 path = conn_ep_dev_node->full_name; 1681 ofnode_read_u32(conn_ep, "remote-endpoint", &phandle); 1682 conn_ep_offset = fdt_path_offset(blob, path); 1683 1684 if (!ofnode_is_available(conn_ep) && 1685 strstr(ofnode_get_name(conn_ep), "endpoint@0")) { 1686 do_fixup_by_path_u32(blob, route_sub_path, 1687 "connect", phandle, 1); 1688 fdt_status_okay(blob, conn_ep_offset); 1689 1690 } else if (ofnode_is_available(conn_ep) && 1691 strstr(ofnode_get_name(conn_ep), "endpoint@1")) { 1692 fdt_status_disabled(blob, conn_ep_offset); 1693 } 1694 } 1695 } 1696 1697 return 0; 1698 } 1699 #endif 1700 1701 static int rockchip_display_probe(struct udevice *dev) 1702 { 1703 struct video_priv *uc_priv = dev_get_uclass_priv(dev); 1704 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 1705 const void *blob = gd->fdt_blob; 1706 int phandle; 1707 struct udevice *crtc_dev; 1708 struct rockchip_crtc *crtc; 1709 struct rockchip_connector *conn, *split_conn; 1710 struct display_state *s; 1711 const char *name; 1712 int ret; 1713 ofnode node, route_node, timing_node; 1714 struct device_node *port_node, *vop_node, *ep_node, *port_parent_node; 1715 struct public_phy_data *data; 1716 bool is_ports_node = false; 1717 1718 #if defined(CONFIG_ROCKCHIP_RK3568) 1719 rockchip_display_fixup_dts((void *)blob); 1720 #endif 1721 /* Before relocation we don't need to do anything */ 1722 if (!(gd->flags & GD_FLG_RELOC)) 1723 return 0; 1724 1725 data = malloc(sizeof(struct public_phy_data)); 1726 if (!data) { 1727 printf("failed to alloc phy data\n"); 1728 return -ENOMEM; 1729 } 1730 data->phy_init = false; 1731 1732 init_display_buffer(plat->base); 1733 1734 route_node = dev_read_subnode(dev, "route"); 1735 if (!ofnode_valid(route_node)) 1736 return -ENODEV; 1737 1738 ofnode_for_each_subnode(node, route_node) { 1739 if (!ofnode_is_available(node)) 1740 continue; 1741 phandle = ofnode_read_u32_default(node, "connect", -1); 1742 if (phandle < 0) { 1743 printf("Warn: can't find connect node's handle\n"); 1744 continue; 1745 } 1746 ep_node = of_find_node_by_phandle(phandle); 1747 if (!ofnode_valid(np_to_ofnode(ep_node))) { 1748 printf("Warn: can't find endpoint node from phandle\n"); 1749 continue; 1750 } 1751 port_node = of_get_parent(ep_node); 1752 if (!ofnode_valid(np_to_ofnode(port_node))) { 1753 printf("Warn: can't find port node from phandle\n"); 1754 continue; 1755 } 1756 1757 port_parent_node = of_get_parent(port_node); 1758 if (!ofnode_valid(np_to_ofnode(port_parent_node))) { 1759 printf("Warn: can't find port parent node from phandle\n"); 1760 continue; 1761 } 1762 1763 is_ports_node = strstr(port_parent_node->full_name, "ports") ? 1 : 0; 1764 if (is_ports_node) { 1765 vop_node = of_get_parent(port_parent_node); 1766 if (!ofnode_valid(np_to_ofnode(vop_node))) { 1767 printf("Warn: can't find crtc node from phandle\n"); 1768 continue; 1769 } 1770 } else { 1771 vop_node = port_parent_node; 1772 } 1773 1774 ret = uclass_get_device_by_ofnode(UCLASS_VIDEO_CRTC, 1775 np_to_ofnode(vop_node), 1776 &crtc_dev); 1777 if (ret) { 1778 printf("Warn: can't find crtc driver %d\n", ret); 1779 continue; 1780 } 1781 crtc = (struct rockchip_crtc *)dev_get_driver_data(crtc_dev); 1782 1783 conn = rockchip_of_get_connector(np_to_ofnode(ep_node)); 1784 if (!conn) { 1785 printf("Warn: can't get connect driver\n"); 1786 continue; 1787 } 1788 split_conn = rockchip_get_split_connector(conn); 1789 1790 s = malloc(sizeof(*s)); 1791 if (!s) 1792 continue; 1793 1794 memset(s, 0, sizeof(*s)); 1795 1796 INIT_LIST_HEAD(&s->head); 1797 ret = ofnode_read_string_index(node, "logo,uboot", 0, &name); 1798 if (!ret) 1799 memcpy(s->ulogo_name, name, strlen(name)); 1800 ret = ofnode_read_string_index(node, "logo,kernel", 0, &name); 1801 if (!ret) 1802 memcpy(s->klogo_name, name, strlen(name)); 1803 ret = ofnode_read_string_index(node, "logo,mode", 0, &name); 1804 if (!strcmp(name, "fullscreen")) 1805 s->logo_mode = ROCKCHIP_DISPLAY_FULLSCREEN; 1806 else 1807 s->logo_mode = ROCKCHIP_DISPLAY_CENTER; 1808 ret = ofnode_read_string_index(node, "charge_logo,mode", 0, &name); 1809 if (!strcmp(name, "fullscreen")) 1810 s->charge_logo_mode = ROCKCHIP_DISPLAY_FULLSCREEN; 1811 else 1812 s->charge_logo_mode = ROCKCHIP_DISPLAY_CENTER; 1813 1814 s->force_output = ofnode_read_bool(node, "force-output"); 1815 1816 if (s->force_output) { 1817 timing_node = ofnode_find_subnode(node, "force_timing"); 1818 ret = display_get_force_timing_from_dts(timing_node, 1819 &s->force_mode, 1820 &s->conn_state.bus_flags); 1821 if (ofnode_read_u32(node, "force-bus-format", &s->force_bus_format)) 1822 s->force_bus_format = MEDIA_BUS_FMT_RGB888_1X24; 1823 } 1824 1825 s->blob = blob; 1826 s->conn_state.connector = conn; 1827 s->conn_state.secondary = NULL; 1828 s->conn_state.type = conn->type; 1829 if (split_conn) { 1830 s->conn_state.secondary = split_conn; 1831 s->conn_state.output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE; 1832 s->conn_state.output_flags |= conn->id ? ROCKCHIP_OUTPUT_DATA_SWAP : 0; 1833 } 1834 s->conn_state.overscan.left_margin = 100; 1835 s->conn_state.overscan.right_margin = 100; 1836 s->conn_state.overscan.top_margin = 100; 1837 s->conn_state.overscan.bottom_margin = 100; 1838 s->crtc_state.node = np_to_ofnode(vop_node); 1839 s->crtc_state.dev = crtc_dev; 1840 s->crtc_state.crtc = crtc; 1841 s->crtc_state.crtc_id = get_crtc_id(np_to_ofnode(ep_node), is_ports_node); 1842 s->node = node; 1843 1844 if (is_ports_node) { /* only vop2 will get into here */ 1845 ofnode vp_node = np_to_ofnode(port_node); 1846 static bool get_plane_mask_from_dts; 1847 1848 s->crtc_state.ports_node = port_parent_node; 1849 if (!get_plane_mask_from_dts) { 1850 ofnode vp_sub_node; 1851 int vp_id = 0; 1852 bool vp_enable = false; 1853 1854 ofnode_for_each_subnode(vp_node, np_to_ofnode(port_parent_node)) { 1855 int cursor_plane = -1; 1856 1857 vp_id = ofnode_read_u32_default(vp_node, "reg", 0); 1858 1859 s->crtc_state.crtc->vps[vp_id].xmirror_en = 1860 ofnode_read_bool(vp_node, "xmirror-enable"); 1861 1862 ret = ofnode_read_u32_default(vp_node, "rockchip,plane-mask", 0); 1863 1864 cursor_plane = ofnode_read_u32_default(vp_node, "cursor-win-id", -1); 1865 s->crtc_state.crtc->vps[vp_id].cursor_plane = cursor_plane; 1866 if (ret) { 1867 s->crtc_state.crtc->vps[vp_id].plane_mask = ret; 1868 s->crtc_state.crtc->assign_plane |= true; 1869 s->crtc_state.crtc->vps[vp_id].primary_plane_id = 1870 ofnode_read_u32_default(vp_node, "rockchip,primary-plane", U8_MAX); 1871 printf("get vp%d plane mask:0x%x, primary id:%d, cursor_plane:%d, from dts\n", 1872 vp_id, 1873 s->crtc_state.crtc->vps[vp_id].plane_mask, 1874 s->crtc_state.crtc->vps[vp_id].primary_plane_id == U8_MAX ? -1 : 1875 s->crtc_state.crtc->vps[vp_id].primary_plane_id, 1876 cursor_plane); 1877 } 1878 1879 /* To check current vp status */ 1880 vp_enable = false; 1881 ofnode_for_each_subnode(vp_sub_node, vp_node) 1882 vp_enable |= rockchip_get_display_path_status(vp_sub_node); 1883 s->crtc_state.crtc->vps[vp_id].enable = vp_enable; 1884 } 1885 get_plane_mask_from_dts = true; 1886 } 1887 } 1888 1889 get_crtc_mcu_mode(&s->crtc_state, port_node, is_ports_node); 1890 1891 ret = ofnode_read_u32_default(s->crtc_state.node, 1892 "rockchip,dual-channel-swap", 0); 1893 s->crtc_state.dual_channel_swap = ret; 1894 1895 if (connector_phy_init(conn, data)) { 1896 printf("Warn: Failed to init phy drivers\n"); 1897 free(s); 1898 continue; 1899 } 1900 list_add_tail(&s->head, &rockchip_display_list); 1901 } 1902 1903 if (list_empty(&rockchip_display_list)) { 1904 debug("Failed to found available display route\n"); 1905 return -ENODEV; 1906 } 1907 rockchip_get_baseparameter(); 1908 display_pre_init(); 1909 1910 uc_priv->xsize = DRM_ROCKCHIP_FB_WIDTH; 1911 uc_priv->ysize = DRM_ROCKCHIP_FB_HEIGHT; 1912 uc_priv->bpix = VIDEO_BPP32; 1913 1914 #ifdef CONFIG_DRM_ROCKCHIP_VIDEO_FRAMEBUFFER 1915 rockchip_show_fbbase(plat->base); 1916 video_set_flush_dcache(dev, true); 1917 #endif 1918 1919 return 0; 1920 } 1921 1922 void rockchip_display_fixup(void *blob) 1923 { 1924 const struct rockchip_connector_funcs *conn_funcs; 1925 const struct rockchip_crtc_funcs *crtc_funcs; 1926 struct rockchip_connector *conn; 1927 const struct rockchip_crtc *crtc; 1928 struct display_state *s; 1929 int offset; 1930 int ret; 1931 const struct device_node *np; 1932 const char *path; 1933 const char *cacm_header; 1934 u64 aligned_memory_size; 1935 1936 if (fdt_node_offset_by_compatible(blob, 0, "rockchip,drm-logo") >= 0) { 1937 list_for_each_entry(s, &rockchip_display_list, head) { 1938 ret = load_bmp_logo(&s->logo, s->klogo_name); 1939 if (ret < 0) { 1940 s->is_klogo_valid = false; 1941 printf("VP%d fail to load kernel logo\n", s->crtc_state.crtc_id); 1942 } else { 1943 s->is_klogo_valid = true; 1944 } 1945 } 1946 1947 if (!get_display_size()) 1948 return; 1949 1950 aligned_memory_size = (u64)ALIGN(get_display_size(), align_size); 1951 offset = fdt_update_reserved_memory(blob, "rockchip,drm-logo", 1952 (u64)memory_start, 1953 aligned_memory_size); 1954 if (offset < 0) 1955 printf("failed to reserve drm-loader-logo memory\n"); 1956 1957 if (get_cubic_memory_size()) { 1958 aligned_memory_size = (u64)ALIGN(get_cubic_memory_size(), align_size); 1959 offset = fdt_update_reserved_memory(blob, "rockchip,drm-cubic-lut", 1960 (u64)cubic_lut_memory_start, 1961 aligned_memory_size); 1962 if (offset < 0) 1963 printf("failed to reserve drm-cubic-lut memory\n"); 1964 } 1965 } else { 1966 printf("can't found rockchip,drm-logo, use rockchip,fb-logo\n"); 1967 /* Compatible with rkfb display, only need reserve memory */ 1968 offset = fdt_update_reserved_memory(blob, "rockchip,fb-logo", 1969 (u64)memory_start, 1970 MEMORY_POOL_SIZE); 1971 if (offset < 0) 1972 printf("failed to reserve fb-loader-logo memory\n"); 1973 else 1974 list_for_each_entry(s, &rockchip_display_list, head) 1975 load_kernel_bmp_logo(&s->logo, s->klogo_name); 1976 return; 1977 } 1978 1979 list_for_each_entry(s, &rockchip_display_list, head) { 1980 /* 1981 * If plane mask is not set in dts, fixup dts to assign it 1982 * whether crtc is initialized or not. 1983 */ 1984 if (s->crtc_state.crtc->funcs->fixup_dts && !s->crtc_state.crtc->assign_plane) 1985 s->crtc_state.crtc->funcs->fixup_dts(s, blob); 1986 1987 if (!s->is_init || !s->is_klogo_valid) 1988 continue; 1989 1990 conn = s->conn_state.connector; 1991 if (!conn) 1992 continue; 1993 conn_funcs = conn->funcs; 1994 if (!conn_funcs) { 1995 printf("failed to get exist connector\n"); 1996 continue; 1997 } 1998 1999 if (s->conn_state.secondary) { 2000 s->conn_state.mode.clock *= 2; 2001 s->conn_state.mode.hdisplay *= 2; 2002 } 2003 2004 crtc = s->crtc_state.crtc; 2005 if (!crtc) 2006 continue; 2007 2008 crtc_funcs = crtc->funcs; 2009 if (!crtc_funcs) { 2010 printf("failed to get exist crtc\n"); 2011 continue; 2012 } 2013 2014 np = ofnode_to_np(s->node); 2015 path = np->full_name; 2016 fdt_increase_size(blob, 0x400); 2017 #define FDT_SET_U32(name, val) \ 2018 do_fixup_by_path_u32(blob, path, name, val, 1); 2019 2020 offset = s->logo.offset + (u32)(unsigned long)s->logo.mem 2021 - memory_start; 2022 FDT_SET_U32("logo,offset", offset); 2023 FDT_SET_U32("logo,width", s->logo.width); 2024 FDT_SET_U32("logo,height", s->logo.height); 2025 FDT_SET_U32("logo,bpp", s->logo.bpp); 2026 FDT_SET_U32("logo,ymirror", s->logo.ymirror); 2027 FDT_SET_U32("video,clock", s->conn_state.mode.clock); 2028 FDT_SET_U32("video,hdisplay", s->conn_state.mode.hdisplay); 2029 FDT_SET_U32("video,vdisplay", s->conn_state.mode.vdisplay); 2030 FDT_SET_U32("video,crtc_hsync_end", s->conn_state.mode.crtc_hsync_end); 2031 FDT_SET_U32("video,crtc_vsync_end", s->conn_state.mode.crtc_vsync_end); 2032 FDT_SET_U32("video,vrefresh", 2033 drm_mode_vrefresh(&s->conn_state.mode)); 2034 FDT_SET_U32("video,flags", s->conn_state.mode.flags); 2035 FDT_SET_U32("video,aspect_ratio", s->conn_state.mode.picture_aspect_ratio); 2036 FDT_SET_U32("overscan,left_margin", s->conn_state.overscan.left_margin); 2037 FDT_SET_U32("overscan,right_margin", s->conn_state.overscan.right_margin); 2038 FDT_SET_U32("overscan,top_margin", s->conn_state.overscan.top_margin); 2039 FDT_SET_U32("overscan,bottom_margin", s->conn_state.overscan.bottom_margin); 2040 2041 if (s->conn_state.disp_info) { 2042 cacm_header = (const char*)&s->conn_state.disp_info->cacm_header; 2043 2044 FDT_SET_U32("bcsh,brightness", s->conn_state.disp_info->bcsh_info.brightness); 2045 FDT_SET_U32("bcsh,contrast", s->conn_state.disp_info->bcsh_info.contrast); 2046 FDT_SET_U32("bcsh,saturation", s->conn_state.disp_info->bcsh_info.saturation); 2047 FDT_SET_U32("bcsh,hue", s->conn_state.disp_info->bcsh_info.hue); 2048 2049 if (!strncasecmp(cacm_header, "CACM", 4)) { 2050 FDT_SET_U32("post_csc,hue", 2051 s->conn_state.disp_info->csc_info.hue); 2052 FDT_SET_U32("post_csc,saturation", 2053 s->conn_state.disp_info->csc_info.saturation); 2054 FDT_SET_U32("post_csc,contrast", 2055 s->conn_state.disp_info->csc_info.contrast); 2056 FDT_SET_U32("post_csc,brightness", 2057 s->conn_state.disp_info->csc_info.brightness); 2058 FDT_SET_U32("post_csc,r_gain", 2059 s->conn_state.disp_info->csc_info.r_gain); 2060 FDT_SET_U32("post_csc,g_gain", 2061 s->conn_state.disp_info->csc_info.g_gain); 2062 FDT_SET_U32("post_csc,b_gain", 2063 s->conn_state.disp_info->csc_info.b_gain); 2064 FDT_SET_U32("post_csc,r_offset", 2065 s->conn_state.disp_info->csc_info.r_offset); 2066 FDT_SET_U32("post_csc,g_offset", 2067 s->conn_state.disp_info->csc_info.g_offset); 2068 FDT_SET_U32("post_csc,b_offset", 2069 s->conn_state.disp_info->csc_info.b_offset); 2070 FDT_SET_U32("post_csc,csc_enable", 2071 s->conn_state.disp_info->csc_info.csc_enable); 2072 } 2073 } 2074 2075 if (s->conn_state.disp_info->cubic_lut_data.size && 2076 CONFIG_ROCKCHIP_CUBIC_LUT_SIZE) 2077 FDT_SET_U32("cubic_lut,offset", get_cubic_lut_offset(s->crtc_state.crtc_id)); 2078 2079 #undef FDT_SET_U32 2080 } 2081 } 2082 2083 int rockchip_display_bind(struct udevice *dev) 2084 { 2085 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 2086 2087 plat->size = DRM_ROCKCHIP_FB_SIZE + MEMORY_POOL_SIZE; 2088 2089 return 0; 2090 } 2091 2092 static const struct udevice_id rockchip_display_ids[] = { 2093 { .compatible = "rockchip,display-subsystem" }, 2094 { } 2095 }; 2096 2097 U_BOOT_DRIVER(rockchip_display) = { 2098 .name = "rockchip_display", 2099 .id = UCLASS_VIDEO, 2100 .of_match = rockchip_display_ids, 2101 .bind = rockchip_display_bind, 2102 .probe = rockchip_display_probe, 2103 }; 2104 2105 static int do_rockchip_logo_show(cmd_tbl_t *cmdtp, int flag, int argc, 2106 char *const argv[]) 2107 { 2108 if (argc != 1) 2109 return CMD_RET_USAGE; 2110 2111 rockchip_show_logo(); 2112 2113 return 0; 2114 } 2115 2116 static int do_rockchip_show_bmp(cmd_tbl_t *cmdtp, int flag, int argc, 2117 char *const argv[]) 2118 { 2119 if (argc != 2) 2120 return CMD_RET_USAGE; 2121 2122 rockchip_show_bmp(argv[1]); 2123 2124 return 0; 2125 } 2126 2127 static int do_rockchip_vop_dump(cmd_tbl_t *cmdtp, int flag, int argc, 2128 char *const argv[]) 2129 { 2130 int ret; 2131 2132 if (argc < 1 || argc > 2) 2133 return CMD_RET_USAGE; 2134 2135 ret = rockchip_vop_dump(argv[1]); 2136 2137 return ret; 2138 } 2139 2140 U_BOOT_CMD( 2141 rockchip_show_logo, 1, 1, do_rockchip_logo_show, 2142 "load and display log from resource partition", 2143 NULL 2144 ); 2145 2146 U_BOOT_CMD( 2147 rockchip_show_bmp, 2, 1, do_rockchip_show_bmp, 2148 "load and display bmp from resource partition", 2149 " <bmp_name>" 2150 ); 2151 2152 U_BOOT_CMD( 2153 vop_dump, 2, 1, do_rockchip_vop_dump, 2154 "dump vop regs", 2155 " [a/all]" 2156 ); 2157