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) 1026 { 1027 ofnode mcu_node; 1028 int total_pixel, cs_pst, cs_pend, rw_pst, rw_pend; 1029 1030 mcu_node = dev_read_subnode(crtc_state->dev, "mcu-timing"); 1031 if (!ofnode_valid(mcu_node)) 1032 return -ENODEV; 1033 1034 #define FDT_GET_MCU_INT(val, name) \ 1035 do { \ 1036 val = ofnode_read_s32_default(mcu_node, name, -1); \ 1037 if (val < 0) { \ 1038 printf("Can't get %s\n", name); \ 1039 return -ENXIO; \ 1040 } \ 1041 } while (0) 1042 1043 FDT_GET_MCU_INT(total_pixel, "mcu-pix-total"); 1044 FDT_GET_MCU_INT(cs_pst, "mcu-cs-pst"); 1045 FDT_GET_MCU_INT(cs_pend, "mcu-cs-pend"); 1046 FDT_GET_MCU_INT(rw_pst, "mcu-rw-pst"); 1047 FDT_GET_MCU_INT(rw_pend, "mcu-rw-pend"); 1048 1049 crtc_state->mcu_timing.mcu_pix_total = total_pixel; 1050 crtc_state->mcu_timing.mcu_cs_pst = cs_pst; 1051 crtc_state->mcu_timing.mcu_cs_pend = cs_pend; 1052 crtc_state->mcu_timing.mcu_rw_pst = rw_pst; 1053 crtc_state->mcu_timing.mcu_rw_pend = rw_pend; 1054 1055 return 0; 1056 } 1057 1058 struct rockchip_logo_cache *find_or_alloc_logo_cache(const char *bmp) 1059 { 1060 struct rockchip_logo_cache *tmp, *logo_cache = NULL; 1061 1062 list_for_each_entry(tmp, &logo_cache_list, head) { 1063 if (!strcmp(tmp->name, bmp)) { 1064 logo_cache = tmp; 1065 break; 1066 } 1067 } 1068 1069 if (!logo_cache) { 1070 logo_cache = malloc(sizeof(*logo_cache)); 1071 if (!logo_cache) { 1072 printf("failed to alloc memory for logo cache\n"); 1073 return NULL; 1074 } 1075 memset(logo_cache, 0, sizeof(*logo_cache)); 1076 strcpy(logo_cache->name, bmp); 1077 INIT_LIST_HEAD(&logo_cache->head); 1078 list_add_tail(&logo_cache->head, &logo_cache_list); 1079 } 1080 1081 return logo_cache; 1082 } 1083 1084 /* Note: used only for rkfb kernel driver */ 1085 static int load_kernel_bmp_logo(struct logo_info *logo, const char *bmp_name) 1086 { 1087 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 1088 void *dst = NULL; 1089 int len, size; 1090 struct bmp_header *header; 1091 1092 if (!logo || !bmp_name) 1093 return -EINVAL; 1094 1095 header = malloc(RK_BLK_SIZE); 1096 if (!header) 1097 return -ENOMEM; 1098 1099 len = rockchip_read_resource_file(header, bmp_name, 0, RK_BLK_SIZE); 1100 if (len != RK_BLK_SIZE) { 1101 free(header); 1102 return -EINVAL; 1103 } 1104 size = get_unaligned_le32(&header->file_size); 1105 dst = (void *)(memory_start + MEMORY_POOL_SIZE / 2); 1106 len = rockchip_read_resource_file(dst, bmp_name, 0, size); 1107 if (len != size) { 1108 printf("failed to load bmp %s\n", bmp_name); 1109 free(header); 1110 return -ENOENT; 1111 } 1112 1113 logo->mem = dst; 1114 #endif 1115 1116 return 0; 1117 } 1118 1119 static int load_bmp_logo(struct logo_info *logo, const char *bmp_name) 1120 { 1121 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 1122 struct rockchip_logo_cache *logo_cache; 1123 struct bmp_header *header; 1124 void *dst = NULL, *pdst; 1125 int size, len; 1126 int ret = 0; 1127 int reserved = 0; 1128 int dst_size; 1129 1130 if (!logo || !bmp_name) 1131 return -EINVAL; 1132 logo_cache = find_or_alloc_logo_cache(bmp_name); 1133 if (!logo_cache) 1134 return -ENOMEM; 1135 1136 if (logo_cache->logo.mem) { 1137 memcpy(logo, &logo_cache->logo, sizeof(*logo)); 1138 return 0; 1139 } 1140 1141 header = malloc(RK_BLK_SIZE); 1142 if (!header) 1143 return -ENOMEM; 1144 1145 len = rockchip_read_resource_file(header, bmp_name, 0, RK_BLK_SIZE); 1146 if (len != RK_BLK_SIZE) { 1147 ret = -EINVAL; 1148 goto free_header; 1149 } 1150 1151 logo->bpp = get_unaligned_le16(&header->bit_count); 1152 logo->width = get_unaligned_le32(&header->width); 1153 logo->height = get_unaligned_le32(&header->height); 1154 dst_size = logo->width * logo->height * logo->bpp >> 3; 1155 reserved = get_unaligned_le32(&header->reserved); 1156 if (logo->height < 0) 1157 logo->height = -logo->height; 1158 size = get_unaligned_le32(&header->file_size); 1159 if (!can_direct_logo(logo->bpp)) { 1160 if (size > MEMORY_POOL_SIZE) { 1161 printf("failed to use boot buf as temp bmp buffer\n"); 1162 ret = -ENOMEM; 1163 goto free_header; 1164 } 1165 pdst = get_display_buffer(size); 1166 1167 } else { 1168 pdst = get_display_buffer(size); 1169 dst = pdst; 1170 } 1171 1172 len = rockchip_read_resource_file(pdst, bmp_name, 0, size); 1173 if (len != size) { 1174 printf("failed to load bmp %s\n", bmp_name); 1175 ret = -ENOENT; 1176 goto free_header; 1177 } 1178 1179 if (!can_direct_logo(logo->bpp)) { 1180 /* 1181 * TODO: force use 16bpp if bpp less than 16; 1182 */ 1183 logo->bpp = (logo->bpp <= 16) ? 16 : logo->bpp; 1184 dst_size = logo->width * logo->height * logo->bpp >> 3; 1185 dst = get_display_buffer(dst_size); 1186 if (!dst) { 1187 ret = -ENOMEM; 1188 goto free_header; 1189 } 1190 if (bmpdecoder(pdst, dst, logo->bpp)) { 1191 printf("failed to decode bmp %s\n", bmp_name); 1192 ret = -EINVAL; 1193 goto free_header; 1194 } 1195 1196 logo->offset = 0; 1197 logo->ymirror = 0; 1198 } else { 1199 logo->offset = get_unaligned_le32(&header->data_offset); 1200 if (reserved == BMP_PROCESSED_FLAG) 1201 logo->ymirror = 0; 1202 else 1203 logo->ymirror = 1; 1204 } 1205 logo->mem = dst; 1206 1207 memcpy(&logo_cache->logo, logo, sizeof(*logo)); 1208 1209 flush_dcache_range((ulong)dst, ALIGN((ulong)dst + dst_size, CONFIG_SYS_CACHELINE_SIZE)); 1210 1211 free_header: 1212 1213 free(header); 1214 1215 return ret; 1216 #else 1217 return -EINVAL; 1218 #endif 1219 } 1220 1221 void rockchip_show_fbbase(ulong fbbase) 1222 { 1223 struct display_state *s; 1224 1225 list_for_each_entry(s, &rockchip_display_list, head) { 1226 s->logo.mode = ROCKCHIP_DISPLAY_FULLSCREEN; 1227 s->logo.mem = (char *)fbbase; 1228 s->logo.width = DRM_ROCKCHIP_FB_WIDTH; 1229 s->logo.height = DRM_ROCKCHIP_FB_HEIGHT; 1230 s->logo.bpp = 32; 1231 s->logo.ymirror = 0; 1232 1233 display_logo(s); 1234 } 1235 } 1236 1237 int rockchip_show_bmp(const char *bmp) 1238 { 1239 struct display_state *s; 1240 int ret = 0; 1241 1242 if (!bmp) { 1243 list_for_each_entry(s, &rockchip_display_list, head) 1244 display_disable(s); 1245 return -ENOENT; 1246 } 1247 1248 list_for_each_entry(s, &rockchip_display_list, head) { 1249 s->logo.mode = s->charge_logo_mode; 1250 if (load_bmp_logo(&s->logo, bmp)) 1251 continue; 1252 ret = display_logo(s); 1253 } 1254 1255 return ret; 1256 } 1257 1258 int rockchip_show_logo(void) 1259 { 1260 struct display_state *s; 1261 int ret = 0; 1262 1263 list_for_each_entry(s, &rockchip_display_list, head) { 1264 s->logo.mode = s->logo_mode; 1265 if (load_bmp_logo(&s->logo, s->ulogo_name)) 1266 printf("failed to display uboot logo\n"); 1267 else 1268 ret = display_logo(s); 1269 1270 /* Load kernel bmp in rockchip_display_fixup() later */ 1271 } 1272 1273 return ret; 1274 } 1275 1276 int rockchip_vop_dump(const char *cmd) 1277 { 1278 struct display_state *state; 1279 struct crtc_state *crtc_state; 1280 struct rockchip_crtc *crtc; 1281 const struct rockchip_crtc_funcs *crtc_funcs; 1282 int ret = -EINVAL; 1283 1284 list_for_each_entry(state, &rockchip_display_list, head) { 1285 if (!state->is_init) 1286 continue; 1287 crtc_state = &state->crtc_state; 1288 crtc = crtc_state->crtc; 1289 crtc_funcs = crtc->funcs; 1290 1291 if (!cmd) 1292 ret = crtc_funcs->active_regs_dump(state); 1293 else if (!strcmp(cmd, "a") || !strcmp(cmd, "all")) 1294 ret = crtc_funcs->regs_dump(state); 1295 if (!ret) 1296 break; 1297 } 1298 1299 if (ret) 1300 ret = CMD_RET_USAGE; 1301 1302 return ret; 1303 } 1304 1305 enum { 1306 PORT_DIR_IN, 1307 PORT_DIR_OUT, 1308 }; 1309 1310 static const struct device_node *rockchip_of_graph_get_port_by_id(ofnode node, int id) 1311 { 1312 ofnode ports, port; 1313 u32 reg; 1314 1315 ports = ofnode_find_subnode(node, "ports"); 1316 if (!ofnode_valid(ports)) 1317 return NULL; 1318 1319 ofnode_for_each_subnode(port, ports) { 1320 if (ofnode_read_u32(port, "reg", ®)) 1321 continue; 1322 1323 if (reg == id) 1324 break; 1325 } 1326 1327 if (reg == id) 1328 return ofnode_to_np(port); 1329 1330 return NULL; 1331 } 1332 1333 static const struct device_node *rockchip_of_graph_get_port_parent(ofnode port) 1334 { 1335 ofnode parent; 1336 int is_ports_node; 1337 1338 parent = ofnode_get_parent(port); 1339 is_ports_node = strstr(ofnode_to_np(parent)->full_name, "ports") ? 1 : 0; 1340 if (is_ports_node) 1341 parent = ofnode_get_parent(parent); 1342 1343 return ofnode_to_np(parent); 1344 } 1345 1346 const struct device_node * 1347 rockchip_of_graph_get_endpoint_by_regs(ofnode node, int port, int endpoint) 1348 { 1349 const struct device_node *port_node; 1350 ofnode ep; 1351 u32 reg; 1352 1353 port_node = rockchip_of_graph_get_port_by_id(node, port); 1354 if (!port_node) 1355 return NULL; 1356 1357 ofnode_for_each_subnode(ep, np_to_ofnode(port_node)) { 1358 if (ofnode_read_u32(ep, "reg", ®)) 1359 break; 1360 if (reg == endpoint) 1361 break; 1362 } 1363 1364 if (!ofnode_valid(ep)) 1365 return NULL; 1366 1367 return ofnode_to_np(ep); 1368 } 1369 1370 static const struct device_node * 1371 rockchip_of_graph_get_remote_node(ofnode node, int port, int endpoint) 1372 { 1373 const struct device_node *ep_node; 1374 ofnode ep; 1375 uint phandle; 1376 1377 ep_node = rockchip_of_graph_get_endpoint_by_regs(node, port, endpoint); 1378 if (!ep_node) 1379 return NULL; 1380 1381 if (ofnode_read_u32(np_to_ofnode(ep_node), "remote-endpoint", &phandle)) 1382 return NULL; 1383 1384 ep = ofnode_get_by_phandle(phandle); 1385 if (!ofnode_valid(ep)) 1386 return NULL; 1387 1388 return ofnode_to_np(ep); 1389 } 1390 1391 static int rockchip_of_find_panel(struct udevice *dev, struct rockchip_panel **panel) 1392 { 1393 const struct device_node *ep_node, *panel_node; 1394 ofnode panel_ofnode, port; 1395 struct udevice *panel_dev; 1396 int ret = 0; 1397 1398 *panel = NULL; 1399 panel_ofnode = dev_read_subnode(dev, "panel"); 1400 if (ofnode_valid(panel_ofnode) && ofnode_is_available(panel_ofnode)) { 1401 ret = uclass_get_device_by_ofnode(UCLASS_PANEL, panel_ofnode, 1402 &panel_dev); 1403 if (!ret) 1404 goto found; 1405 } 1406 1407 ep_node = rockchip_of_graph_get_remote_node(dev->node, PORT_DIR_OUT, 0); 1408 if (!ep_node) 1409 return -ENODEV; 1410 1411 port = ofnode_get_parent(np_to_ofnode(ep_node)); 1412 if (!ofnode_valid(port)) 1413 return -ENODEV; 1414 1415 panel_node = rockchip_of_graph_get_port_parent(port); 1416 if (!panel_node) 1417 return -ENODEV; 1418 1419 ret = uclass_get_device_by_ofnode(UCLASS_PANEL, np_to_ofnode(panel_node), &panel_dev); 1420 if (!ret) 1421 goto found; 1422 1423 return -ENODEV; 1424 1425 found: 1426 *panel = (struct rockchip_panel *)dev_get_driver_data(panel_dev); 1427 return 0; 1428 } 1429 1430 static int rockchip_of_find_bridge(struct udevice *dev, struct rockchip_bridge **bridge) 1431 { 1432 const struct device_node *ep_node, *bridge_node; 1433 ofnode port; 1434 struct udevice *bridge_dev; 1435 int ret = 0; 1436 1437 ep_node = rockchip_of_graph_get_remote_node(dev->node, PORT_DIR_OUT, 0); 1438 if (!ep_node) 1439 return -ENODEV; 1440 1441 port = ofnode_get_parent(np_to_ofnode(ep_node)); 1442 if (!ofnode_valid(port)) 1443 return -ENODEV; 1444 1445 bridge_node = rockchip_of_graph_get_port_parent(port); 1446 if (!bridge_node) 1447 return -ENODEV; 1448 1449 ret = uclass_get_device_by_ofnode(UCLASS_VIDEO_BRIDGE, np_to_ofnode(bridge_node), 1450 &bridge_dev); 1451 if (!ret) 1452 goto found; 1453 1454 return -ENODEV; 1455 1456 found: 1457 *bridge = (struct rockchip_bridge *)dev_get_driver_data(bridge_dev); 1458 return 0; 1459 } 1460 1461 static int rockchip_of_find_panel_or_bridge(struct udevice *dev, struct rockchip_panel **panel, 1462 struct rockchip_bridge **bridge) 1463 { 1464 int ret = 0; 1465 1466 if (*panel) 1467 return 0; 1468 1469 *panel = NULL; 1470 *bridge = NULL; 1471 1472 if (panel) { 1473 ret = rockchip_of_find_panel(dev, panel); 1474 if (!ret) 1475 return 0; 1476 } 1477 1478 if (ret) { 1479 ret = rockchip_of_find_bridge(dev, bridge); 1480 if (!ret) 1481 ret = rockchip_of_find_panel_or_bridge((*bridge)->dev, panel, 1482 &(*bridge)->next_bridge); 1483 } 1484 1485 return ret; 1486 } 1487 1488 static struct rockchip_phy *rockchip_of_find_phy(struct udevice *dev) 1489 { 1490 struct udevice *phy_dev; 1491 int ret; 1492 1493 ret = uclass_get_device_by_phandle(UCLASS_PHY, dev, "phys", &phy_dev); 1494 if (ret) 1495 return NULL; 1496 1497 return (struct rockchip_phy *)dev_get_driver_data(phy_dev); 1498 } 1499 1500 static struct udevice *rockchip_of_find_connector_device(ofnode endpoint) 1501 { 1502 ofnode ep, port, ports, conn; 1503 uint phandle; 1504 struct udevice *dev; 1505 int ret; 1506 1507 if (ofnode_read_u32(endpoint, "remote-endpoint", &phandle)) 1508 return NULL; 1509 1510 ep = ofnode_get_by_phandle(phandle); 1511 if (!ofnode_valid(ep) || !ofnode_is_available(ep)) 1512 return NULL; 1513 1514 port = ofnode_get_parent(ep); 1515 if (!ofnode_valid(port)) 1516 return NULL; 1517 1518 ports = ofnode_get_parent(port); 1519 if (!ofnode_valid(ports)) 1520 return NULL; 1521 1522 conn = ofnode_get_parent(ports); 1523 if (!ofnode_valid(conn) || !ofnode_is_available(conn)) 1524 return NULL; 1525 1526 ret = uclass_get_device_by_ofnode(UCLASS_DISPLAY, conn, &dev); 1527 if (ret) 1528 return NULL; 1529 1530 return dev; 1531 } 1532 1533 static struct rockchip_connector *rockchip_of_get_connector(ofnode endpoint) 1534 { 1535 struct rockchip_connector *conn; 1536 struct udevice *dev; 1537 int ret; 1538 1539 dev = rockchip_of_find_connector_device(endpoint); 1540 if (!dev) { 1541 printf("Warn: can't find connect driver\n"); 1542 return NULL; 1543 } 1544 1545 conn = get_rockchip_connector_by_device(dev); 1546 if (!conn) 1547 return NULL; 1548 ret = rockchip_of_find_panel_or_bridge(dev, &conn->panel, &conn->bridge); 1549 if (ret) 1550 debug("Warn: no find panel or bridge\n"); 1551 1552 conn->phy = rockchip_of_find_phy(dev); 1553 1554 return conn; 1555 } 1556 1557 static struct rockchip_connector *rockchip_get_split_connector(struct rockchip_connector *conn) 1558 { 1559 char *conn_name; 1560 struct device_node *split_node; 1561 struct udevice *split_dev; 1562 struct rockchip_connector *split_conn; 1563 bool split_mode; 1564 int ret; 1565 1566 split_mode = ofnode_read_bool(conn->dev->node, "split-mode"); 1567 if (!split_mode) 1568 return NULL; 1569 1570 switch (conn->type) { 1571 case DRM_MODE_CONNECTOR_DisplayPort: 1572 conn_name = "dp"; 1573 break; 1574 case DRM_MODE_CONNECTOR_eDP: 1575 conn_name = "edp"; 1576 break; 1577 case DRM_MODE_CONNECTOR_HDMIA: 1578 conn_name = "hdmi"; 1579 break; 1580 default: 1581 return NULL; 1582 } 1583 1584 split_node = of_alias_get_dev(conn_name, !conn->id); 1585 if (!split_node || !of_device_is_available(split_node)) 1586 return NULL; 1587 1588 ret = uclass_get_device_by_ofnode(UCLASS_DISPLAY, np_to_ofnode(split_node), &split_dev); 1589 if (ret) 1590 return NULL; 1591 1592 split_conn = get_rockchip_connector_by_device(split_dev); 1593 if (!split_conn) 1594 return NULL; 1595 ret = rockchip_of_find_panel_or_bridge(split_dev, &split_conn->panel, &split_conn->bridge); 1596 if (ret) 1597 debug("Warn: no find panel or bridge\n"); 1598 1599 split_conn->phy = rockchip_of_find_phy(split_dev); 1600 1601 return split_conn; 1602 } 1603 1604 static bool rockchip_get_display_path_status(ofnode endpoint) 1605 { 1606 ofnode ep; 1607 uint phandle; 1608 1609 if (ofnode_read_u32(endpoint, "remote-endpoint", &phandle)) 1610 return false; 1611 1612 ep = ofnode_get_by_phandle(phandle); 1613 if (!ofnode_valid(ep) || !ofnode_is_available(ep)) 1614 return false; 1615 1616 return true; 1617 } 1618 1619 #if defined(CONFIG_ROCKCHIP_RK3568) 1620 static int rockchip_display_fixup_dts(void *blob) 1621 { 1622 ofnode route_node, route_subnode, conn_ep, conn_port; 1623 const struct device_node *route_sub_devnode; 1624 const struct device_node *ep_node, *conn_ep_dev_node; 1625 u32 phandle; 1626 int conn_ep_offset; 1627 const char *route_sub_path, *path; 1628 1629 /* Don't go further if new variant after 1630 * reading PMUGRF_SOC_CON15 1631 */ 1632 if ((readl(0xfdc20100) & GENMASK(15, 14))) 1633 return 0; 1634 1635 route_node = ofnode_path("/display-subsystem/route"); 1636 if (!ofnode_valid(route_node)) 1637 return -EINVAL; 1638 1639 ofnode_for_each_subnode(route_subnode, route_node) { 1640 if (!ofnode_is_available(route_subnode)) 1641 continue; 1642 1643 route_sub_devnode = ofnode_to_np(route_subnode); 1644 route_sub_path = route_sub_devnode->full_name; 1645 if (!strstr(ofnode_get_name(route_subnode), "dsi") && 1646 !strstr(ofnode_get_name(route_subnode), "edp")) 1647 return 0; 1648 1649 phandle = ofnode_read_u32_default(route_subnode, "connect", -1); 1650 if (phandle < 0) { 1651 printf("Warn: can't find connect node's handle\n"); 1652 continue; 1653 } 1654 1655 ep_node = of_find_node_by_phandle(phandle); 1656 if (!ofnode_valid(np_to_ofnode(ep_node))) { 1657 printf("Warn: can't find endpoint node from phandle\n"); 1658 continue; 1659 } 1660 1661 ofnode_read_u32(np_to_ofnode(ep_node), "remote-endpoint", &phandle); 1662 conn_ep = ofnode_get_by_phandle(phandle); 1663 if (!ofnode_valid(conn_ep) || !ofnode_is_available(conn_ep)) 1664 return -ENODEV; 1665 1666 conn_port = ofnode_get_parent(conn_ep); 1667 if (!ofnode_valid(conn_port)) 1668 return -ENODEV; 1669 1670 ofnode_for_each_subnode(conn_ep, conn_port) { 1671 conn_ep_dev_node = ofnode_to_np(conn_ep); 1672 path = conn_ep_dev_node->full_name; 1673 ofnode_read_u32(conn_ep, "remote-endpoint", &phandle); 1674 conn_ep_offset = fdt_path_offset(blob, path); 1675 1676 if (!ofnode_is_available(conn_ep) && 1677 strstr(ofnode_get_name(conn_ep), "endpoint@0")) { 1678 do_fixup_by_path_u32(blob, route_sub_path, 1679 "connect", phandle, 1); 1680 fdt_status_okay(blob, conn_ep_offset); 1681 1682 } else if (ofnode_is_available(conn_ep) && 1683 strstr(ofnode_get_name(conn_ep), "endpoint@1")) { 1684 fdt_status_disabled(blob, conn_ep_offset); 1685 } 1686 } 1687 } 1688 1689 return 0; 1690 } 1691 #endif 1692 1693 static int rockchip_display_probe(struct udevice *dev) 1694 { 1695 struct video_priv *uc_priv = dev_get_uclass_priv(dev); 1696 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 1697 const void *blob = gd->fdt_blob; 1698 int phandle; 1699 struct udevice *crtc_dev; 1700 struct rockchip_crtc *crtc; 1701 struct rockchip_connector *conn, *split_conn; 1702 struct display_state *s; 1703 const char *name; 1704 int ret; 1705 ofnode node, route_node, timing_node; 1706 struct device_node *port_node, *vop_node, *ep_node, *port_parent_node; 1707 struct public_phy_data *data; 1708 bool is_ports_node = false; 1709 1710 #if defined(CONFIG_ROCKCHIP_RK3568) 1711 rockchip_display_fixup_dts((void *)blob); 1712 #endif 1713 /* Before relocation we don't need to do anything */ 1714 if (!(gd->flags & GD_FLG_RELOC)) 1715 return 0; 1716 1717 data = malloc(sizeof(struct public_phy_data)); 1718 if (!data) { 1719 printf("failed to alloc phy data\n"); 1720 return -ENOMEM; 1721 } 1722 data->phy_init = false; 1723 1724 init_display_buffer(plat->base); 1725 1726 route_node = dev_read_subnode(dev, "route"); 1727 if (!ofnode_valid(route_node)) 1728 return -ENODEV; 1729 1730 ofnode_for_each_subnode(node, route_node) { 1731 if (!ofnode_is_available(node)) 1732 continue; 1733 phandle = ofnode_read_u32_default(node, "connect", -1); 1734 if (phandle < 0) { 1735 printf("Warn: can't find connect node's handle\n"); 1736 continue; 1737 } 1738 ep_node = of_find_node_by_phandle(phandle); 1739 if (!ofnode_valid(np_to_ofnode(ep_node))) { 1740 printf("Warn: can't find endpoint node from phandle\n"); 1741 continue; 1742 } 1743 port_node = of_get_parent(ep_node); 1744 if (!ofnode_valid(np_to_ofnode(port_node))) { 1745 printf("Warn: can't find port node from phandle\n"); 1746 continue; 1747 } 1748 1749 port_parent_node = of_get_parent(port_node); 1750 if (!ofnode_valid(np_to_ofnode(port_parent_node))) { 1751 printf("Warn: can't find port parent node from phandle\n"); 1752 continue; 1753 } 1754 1755 is_ports_node = strstr(port_parent_node->full_name, "ports") ? 1 : 0; 1756 if (is_ports_node) { 1757 vop_node = of_get_parent(port_parent_node); 1758 if (!ofnode_valid(np_to_ofnode(vop_node))) { 1759 printf("Warn: can't find crtc node from phandle\n"); 1760 continue; 1761 } 1762 } else { 1763 vop_node = port_parent_node; 1764 } 1765 1766 ret = uclass_get_device_by_ofnode(UCLASS_VIDEO_CRTC, 1767 np_to_ofnode(vop_node), 1768 &crtc_dev); 1769 if (ret) { 1770 printf("Warn: can't find crtc driver %d\n", ret); 1771 continue; 1772 } 1773 crtc = (struct rockchip_crtc *)dev_get_driver_data(crtc_dev); 1774 1775 conn = rockchip_of_get_connector(np_to_ofnode(ep_node)); 1776 if (!conn) { 1777 printf("Warn: can't get connect driver\n"); 1778 continue; 1779 } 1780 split_conn = rockchip_get_split_connector(conn); 1781 1782 s = malloc(sizeof(*s)); 1783 if (!s) 1784 continue; 1785 1786 memset(s, 0, sizeof(*s)); 1787 1788 INIT_LIST_HEAD(&s->head); 1789 ret = ofnode_read_string_index(node, "logo,uboot", 0, &name); 1790 if (!ret) 1791 memcpy(s->ulogo_name, name, strlen(name)); 1792 ret = ofnode_read_string_index(node, "logo,kernel", 0, &name); 1793 if (!ret) 1794 memcpy(s->klogo_name, name, strlen(name)); 1795 ret = ofnode_read_string_index(node, "logo,mode", 0, &name); 1796 if (!strcmp(name, "fullscreen")) 1797 s->logo_mode = ROCKCHIP_DISPLAY_FULLSCREEN; 1798 else 1799 s->logo_mode = ROCKCHIP_DISPLAY_CENTER; 1800 ret = ofnode_read_string_index(node, "charge_logo,mode", 0, &name); 1801 if (!strcmp(name, "fullscreen")) 1802 s->charge_logo_mode = ROCKCHIP_DISPLAY_FULLSCREEN; 1803 else 1804 s->charge_logo_mode = ROCKCHIP_DISPLAY_CENTER; 1805 1806 s->force_output = ofnode_read_bool(node, "force-output"); 1807 1808 if (s->force_output) { 1809 timing_node = ofnode_find_subnode(node, "force_timing"); 1810 ret = display_get_force_timing_from_dts(timing_node, 1811 &s->force_mode, 1812 &s->conn_state.bus_flags); 1813 if (ofnode_read_u32(node, "force-bus-format", &s->force_bus_format)) 1814 s->force_bus_format = MEDIA_BUS_FMT_RGB888_1X24; 1815 } 1816 1817 s->blob = blob; 1818 s->conn_state.connector = conn; 1819 s->conn_state.secondary = NULL; 1820 s->conn_state.type = conn->type; 1821 if (split_conn) { 1822 s->conn_state.secondary = split_conn; 1823 s->conn_state.output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE; 1824 s->conn_state.output_flags |= conn->id ? ROCKCHIP_OUTPUT_DATA_SWAP : 0; 1825 } 1826 s->conn_state.overscan.left_margin = 100; 1827 s->conn_state.overscan.right_margin = 100; 1828 s->conn_state.overscan.top_margin = 100; 1829 s->conn_state.overscan.bottom_margin = 100; 1830 s->crtc_state.node = np_to_ofnode(vop_node); 1831 s->crtc_state.dev = crtc_dev; 1832 s->crtc_state.crtc = crtc; 1833 s->crtc_state.crtc_id = get_crtc_id(np_to_ofnode(ep_node), is_ports_node); 1834 s->node = node; 1835 1836 if (is_ports_node) { /* only vop2 will get into here */ 1837 ofnode vp_node = np_to_ofnode(port_node); 1838 static bool get_plane_mask_from_dts; 1839 1840 s->crtc_state.ports_node = port_parent_node; 1841 if (!get_plane_mask_from_dts) { 1842 ofnode vp_sub_node; 1843 int vp_id = 0; 1844 bool vp_enable = false; 1845 1846 ofnode_for_each_subnode(vp_node, np_to_ofnode(port_parent_node)) { 1847 int cursor_plane = -1; 1848 1849 vp_id = ofnode_read_u32_default(vp_node, "reg", 0); 1850 1851 s->crtc_state.crtc->vps[vp_id].xmirror_en = 1852 ofnode_read_bool(vp_node, "xmirror-enable"); 1853 1854 ret = ofnode_read_u32_default(vp_node, "rockchip,plane-mask", 0); 1855 1856 cursor_plane = ofnode_read_u32_default(vp_node, "cursor-win-id", -1); 1857 s->crtc_state.crtc->vps[vp_id].cursor_plane = cursor_plane; 1858 if (ret) { 1859 s->crtc_state.crtc->vps[vp_id].plane_mask = ret; 1860 s->crtc_state.crtc->assign_plane |= true; 1861 s->crtc_state.crtc->vps[vp_id].primary_plane_id = 1862 ofnode_read_u32_default(vp_node, "rockchip,primary-plane", U8_MAX); 1863 printf("get vp%d plane mask:0x%x, primary id:%d, cursor_plane:%d, from dts\n", 1864 vp_id, 1865 s->crtc_state.crtc->vps[vp_id].plane_mask, 1866 s->crtc_state.crtc->vps[vp_id].primary_plane_id == U8_MAX ? -1 : 1867 s->crtc_state.crtc->vps[vp_id].primary_plane_id, 1868 cursor_plane); 1869 } 1870 1871 /* To check current vp status */ 1872 vp_enable = false; 1873 ofnode_for_each_subnode(vp_sub_node, vp_node) 1874 vp_enable |= rockchip_get_display_path_status(vp_sub_node); 1875 s->crtc_state.crtc->vps[vp_id].enable = vp_enable; 1876 } 1877 get_plane_mask_from_dts = true; 1878 } 1879 } 1880 1881 get_crtc_mcu_mode(&s->crtc_state); 1882 1883 ret = ofnode_read_u32_default(s->crtc_state.node, 1884 "rockchip,dual-channel-swap", 0); 1885 s->crtc_state.dual_channel_swap = ret; 1886 1887 if (connector_phy_init(conn, data)) { 1888 printf("Warn: Failed to init phy drivers\n"); 1889 free(s); 1890 continue; 1891 } 1892 list_add_tail(&s->head, &rockchip_display_list); 1893 } 1894 1895 if (list_empty(&rockchip_display_list)) { 1896 debug("Failed to found available display route\n"); 1897 return -ENODEV; 1898 } 1899 rockchip_get_baseparameter(); 1900 display_pre_init(); 1901 1902 uc_priv->xsize = DRM_ROCKCHIP_FB_WIDTH; 1903 uc_priv->ysize = DRM_ROCKCHIP_FB_HEIGHT; 1904 uc_priv->bpix = VIDEO_BPP32; 1905 1906 #ifdef CONFIG_DRM_ROCKCHIP_VIDEO_FRAMEBUFFER 1907 rockchip_show_fbbase(plat->base); 1908 video_set_flush_dcache(dev, true); 1909 #endif 1910 1911 return 0; 1912 } 1913 1914 void rockchip_display_fixup(void *blob) 1915 { 1916 const struct rockchip_connector_funcs *conn_funcs; 1917 const struct rockchip_crtc_funcs *crtc_funcs; 1918 struct rockchip_connector *conn; 1919 const struct rockchip_crtc *crtc; 1920 struct display_state *s; 1921 int offset; 1922 int ret; 1923 const struct device_node *np; 1924 const char *path; 1925 const char *cacm_header; 1926 u64 aligned_memory_size; 1927 1928 if (fdt_node_offset_by_compatible(blob, 0, "rockchip,drm-logo") >= 0) { 1929 list_for_each_entry(s, &rockchip_display_list, head) { 1930 ret = load_bmp_logo(&s->logo, s->klogo_name); 1931 if (ret < 0) { 1932 s->is_klogo_valid = false; 1933 printf("VP%d fail to load kernel logo\n", s->crtc_state.crtc_id); 1934 } else { 1935 s->is_klogo_valid = true; 1936 } 1937 } 1938 1939 if (!get_display_size()) 1940 return; 1941 1942 aligned_memory_size = (u64)ALIGN(get_display_size(), align_size); 1943 offset = fdt_update_reserved_memory(blob, "rockchip,drm-logo", 1944 (u64)memory_start, 1945 aligned_memory_size); 1946 if (offset < 0) 1947 printf("failed to reserve drm-loader-logo memory\n"); 1948 1949 if (get_cubic_memory_size()) { 1950 aligned_memory_size = (u64)ALIGN(get_cubic_memory_size(), align_size); 1951 offset = fdt_update_reserved_memory(blob, "rockchip,drm-cubic-lut", 1952 (u64)cubic_lut_memory_start, 1953 aligned_memory_size); 1954 if (offset < 0) 1955 printf("failed to reserve drm-cubic-lut memory\n"); 1956 } 1957 } else { 1958 printf("can't found rockchip,drm-logo, use rockchip,fb-logo\n"); 1959 /* Compatible with rkfb display, only need reserve memory */ 1960 offset = fdt_update_reserved_memory(blob, "rockchip,fb-logo", 1961 (u64)memory_start, 1962 MEMORY_POOL_SIZE); 1963 if (offset < 0) 1964 printf("failed to reserve fb-loader-logo memory\n"); 1965 else 1966 list_for_each_entry(s, &rockchip_display_list, head) 1967 load_kernel_bmp_logo(&s->logo, s->klogo_name); 1968 return; 1969 } 1970 1971 list_for_each_entry(s, &rockchip_display_list, head) { 1972 /* 1973 * If plane mask is not set in dts, fixup dts to assign it 1974 * whether crtc is initialized or not. 1975 */ 1976 if (s->crtc_state.crtc->funcs->fixup_dts && !s->crtc_state.crtc->assign_plane) 1977 s->crtc_state.crtc->funcs->fixup_dts(s, blob); 1978 1979 if (!s->is_init || !s->is_klogo_valid) 1980 continue; 1981 1982 conn = s->conn_state.connector; 1983 if (!conn) 1984 continue; 1985 conn_funcs = conn->funcs; 1986 if (!conn_funcs) { 1987 printf("failed to get exist connector\n"); 1988 continue; 1989 } 1990 1991 if (s->conn_state.secondary) { 1992 s->conn_state.mode.clock *= 2; 1993 s->conn_state.mode.hdisplay *= 2; 1994 } 1995 1996 crtc = s->crtc_state.crtc; 1997 if (!crtc) 1998 continue; 1999 2000 crtc_funcs = crtc->funcs; 2001 if (!crtc_funcs) { 2002 printf("failed to get exist crtc\n"); 2003 continue; 2004 } 2005 2006 np = ofnode_to_np(s->node); 2007 path = np->full_name; 2008 fdt_increase_size(blob, 0x400); 2009 #define FDT_SET_U32(name, val) \ 2010 do_fixup_by_path_u32(blob, path, name, val, 1); 2011 2012 offset = s->logo.offset + (u32)(unsigned long)s->logo.mem 2013 - memory_start; 2014 FDT_SET_U32("logo,offset", offset); 2015 FDT_SET_U32("logo,width", s->logo.width); 2016 FDT_SET_U32("logo,height", s->logo.height); 2017 FDT_SET_U32("logo,bpp", s->logo.bpp); 2018 FDT_SET_U32("logo,ymirror", s->logo.ymirror); 2019 FDT_SET_U32("video,clock", s->conn_state.mode.clock); 2020 FDT_SET_U32("video,hdisplay", s->conn_state.mode.hdisplay); 2021 FDT_SET_U32("video,vdisplay", s->conn_state.mode.vdisplay); 2022 FDT_SET_U32("video,crtc_hsync_end", s->conn_state.mode.crtc_hsync_end); 2023 FDT_SET_U32("video,crtc_vsync_end", s->conn_state.mode.crtc_vsync_end); 2024 FDT_SET_U32("video,vrefresh", 2025 drm_mode_vrefresh(&s->conn_state.mode)); 2026 FDT_SET_U32("video,flags", s->conn_state.mode.flags); 2027 FDT_SET_U32("video,aspect_ratio", s->conn_state.mode.picture_aspect_ratio); 2028 FDT_SET_U32("overscan,left_margin", s->conn_state.overscan.left_margin); 2029 FDT_SET_U32("overscan,right_margin", s->conn_state.overscan.right_margin); 2030 FDT_SET_U32("overscan,top_margin", s->conn_state.overscan.top_margin); 2031 FDT_SET_U32("overscan,bottom_margin", s->conn_state.overscan.bottom_margin); 2032 2033 if (s->conn_state.disp_info) { 2034 cacm_header = (const char*)&s->conn_state.disp_info->cacm_header; 2035 2036 FDT_SET_U32("bcsh,brightness", s->conn_state.disp_info->bcsh_info.brightness); 2037 FDT_SET_U32("bcsh,contrast", s->conn_state.disp_info->bcsh_info.contrast); 2038 FDT_SET_U32("bcsh,saturation", s->conn_state.disp_info->bcsh_info.saturation); 2039 FDT_SET_U32("bcsh,hue", s->conn_state.disp_info->bcsh_info.hue); 2040 2041 if (!strncasecmp(cacm_header, "CACM", 4)) { 2042 FDT_SET_U32("post_csc,hue", 2043 s->conn_state.disp_info->csc_info.hue); 2044 FDT_SET_U32("post_csc,saturation", 2045 s->conn_state.disp_info->csc_info.saturation); 2046 FDT_SET_U32("post_csc,contrast", 2047 s->conn_state.disp_info->csc_info.contrast); 2048 FDT_SET_U32("post_csc,brightness", 2049 s->conn_state.disp_info->csc_info.brightness); 2050 FDT_SET_U32("post_csc,r_gain", 2051 s->conn_state.disp_info->csc_info.r_gain); 2052 FDT_SET_U32("post_csc,g_gain", 2053 s->conn_state.disp_info->csc_info.g_gain); 2054 FDT_SET_U32("post_csc,b_gain", 2055 s->conn_state.disp_info->csc_info.b_gain); 2056 FDT_SET_U32("post_csc,r_offset", 2057 s->conn_state.disp_info->csc_info.r_offset); 2058 FDT_SET_U32("post_csc,g_offset", 2059 s->conn_state.disp_info->csc_info.g_offset); 2060 FDT_SET_U32("post_csc,b_offset", 2061 s->conn_state.disp_info->csc_info.b_offset); 2062 FDT_SET_U32("post_csc,csc_enable", 2063 s->conn_state.disp_info->csc_info.csc_enable); 2064 } 2065 } 2066 2067 if (s->conn_state.disp_info->cubic_lut_data.size && 2068 CONFIG_ROCKCHIP_CUBIC_LUT_SIZE) 2069 FDT_SET_U32("cubic_lut,offset", get_cubic_lut_offset(s->crtc_state.crtc_id)); 2070 2071 #undef FDT_SET_U32 2072 } 2073 } 2074 2075 int rockchip_display_bind(struct udevice *dev) 2076 { 2077 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 2078 2079 plat->size = DRM_ROCKCHIP_FB_SIZE + MEMORY_POOL_SIZE; 2080 2081 return 0; 2082 } 2083 2084 static const struct udevice_id rockchip_display_ids[] = { 2085 { .compatible = "rockchip,display-subsystem" }, 2086 { } 2087 }; 2088 2089 U_BOOT_DRIVER(rockchip_display) = { 2090 .name = "rockchip_display", 2091 .id = UCLASS_VIDEO, 2092 .of_match = rockchip_display_ids, 2093 .bind = rockchip_display_bind, 2094 .probe = rockchip_display_probe, 2095 }; 2096 2097 static int do_rockchip_logo_show(cmd_tbl_t *cmdtp, int flag, int argc, 2098 char *const argv[]) 2099 { 2100 if (argc != 1) 2101 return CMD_RET_USAGE; 2102 2103 rockchip_show_logo(); 2104 2105 return 0; 2106 } 2107 2108 static int do_rockchip_show_bmp(cmd_tbl_t *cmdtp, int flag, int argc, 2109 char *const argv[]) 2110 { 2111 if (argc != 2) 2112 return CMD_RET_USAGE; 2113 2114 rockchip_show_bmp(argv[1]); 2115 2116 return 0; 2117 } 2118 2119 static int do_rockchip_vop_dump(cmd_tbl_t *cmdtp, int flag, int argc, 2120 char *const argv[]) 2121 { 2122 int ret; 2123 2124 if (argc < 1 || argc > 2) 2125 return CMD_RET_USAGE; 2126 2127 ret = rockchip_vop_dump(argv[1]); 2128 2129 return ret; 2130 } 2131 2132 U_BOOT_CMD( 2133 rockchip_show_logo, 1, 1, do_rockchip_logo_show, 2134 "load and display log from resource partition", 2135 NULL 2136 ); 2137 2138 U_BOOT_CMD( 2139 rockchip_show_bmp, 2, 1, do_rockchip_show_bmp, 2140 "load and display bmp from resource partition", 2141 " <bmp_name>" 2142 ); 2143 2144 U_BOOT_CMD( 2145 vop_dump, 2, 1, do_rockchip_vop_dump, 2146 "dump vop regs", 2147 " [a/all]" 2148 ); 2149