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 if (IS_ENABLED(CONFIG_ROCKCHIP_RK3568) || IS_ENABLED(CONFIG_ROCKCHIP_RK3588)) { 462 if (mode->hdisplay % 4) { 463 int old_hdisplay = mode->hdisplay; 464 int align = 4 - (mode->hdisplay % 4); 465 466 mode->hdisplay += align; 467 mode->hsync_start += align; 468 mode->hsync_end += align; 469 mode->htotal += align; 470 471 ofnode_write_u32_array(timing, "hactive", (u32 *)&mode->hdisplay, 1); 472 473 printf("WARN: hactive need to be aligned with 4-pixel, %d -> %d\n", 474 old_hdisplay, mode->hdisplay); 475 } 476 } 477 478 return 0; 479 } 480 481 static int display_get_timing(struct display_state *state) 482 { 483 struct connector_state *conn_state = &state->conn_state; 484 struct drm_display_mode *mode = &conn_state->mode; 485 const struct drm_display_mode *m; 486 struct rockchip_panel *panel = conn_state->connector->panel; 487 488 if (panel->funcs->get_mode) 489 return panel->funcs->get_mode(panel, mode); 490 491 if (dev_of_valid(panel->dev) && 492 !display_get_timing_from_dts(panel, mode, &conn_state->bus_flags)) { 493 printf("Using display timing dts\n"); 494 return 0; 495 } 496 497 if (panel->data) { 498 m = (const struct drm_display_mode *)panel->data; 499 memcpy(mode, m, sizeof(*m)); 500 printf("Using display timing from compatible panel driver\n"); 501 return 0; 502 } 503 504 return -ENODEV; 505 } 506 507 static int display_pre_init(void) 508 { 509 struct display_state *state; 510 int ret = 0; 511 512 list_for_each_entry(state, &rockchip_display_list, head) { 513 struct connector_state *conn_state = &state->conn_state; 514 struct crtc_state *crtc_state = &state->crtc_state; 515 struct rockchip_crtc *crtc = crtc_state->crtc; 516 517 ret = rockchip_connector_pre_init(state); 518 if (ret) 519 printf("pre init conn error\n"); 520 521 crtc->vps[crtc_state->crtc_id].output_type = conn_state->type; 522 } 523 return ret; 524 } 525 526 static int display_use_force_mode(struct display_state *state) 527 { 528 struct connector_state *conn_state = &state->conn_state; 529 struct drm_display_mode *mode = &conn_state->mode; 530 531 conn_state->bpc = 8; 532 memcpy(mode, &state->force_mode, sizeof(struct drm_display_mode)); 533 conn_state->bus_format = state->force_bus_format; 534 535 return 0; 536 } 537 538 static int display_get_edid_mode(struct display_state *state) 539 { 540 int ret = 0; 541 struct connector_state *conn_state = &state->conn_state; 542 struct drm_display_mode *mode = &conn_state->mode; 543 int bpc; 544 545 ret = edid_get_drm_mode(conn_state->edid, sizeof(conn_state->edid), mode, &bpc); 546 if (!ret) { 547 conn_state->bpc = bpc; 548 edid_print_info((void *)&conn_state->edid); 549 } else { 550 conn_state->bpc = 8; 551 mode->clock = 74250; 552 mode->flags = 0x5; 553 mode->hdisplay = 1280; 554 mode->hsync_start = 1390; 555 mode->hsync_end = 1430; 556 mode->htotal = 1650; 557 mode->hskew = 0; 558 mode->vdisplay = 720; 559 mode->vsync_start = 725; 560 mode->vsync_end = 730; 561 mode->vtotal = 750; 562 mode->vrefresh = 60; 563 mode->picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9; 564 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 565 566 printf("error: %s get mode from edid failed, use 720p60 as default mode\n", 567 state->conn_state.connector->dev->name); 568 } 569 570 return ret; 571 } 572 573 static int display_mode_valid(struct display_state *state) 574 { 575 struct connector_state *conn_state = &state->conn_state; 576 struct rockchip_connector *conn = conn_state->connector; 577 const struct rockchip_connector_funcs *conn_funcs = conn->funcs; 578 struct crtc_state *crtc_state = &state->crtc_state; 579 const struct rockchip_crtc *crtc = crtc_state->crtc; 580 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 581 int ret; 582 583 if (conn_funcs->mode_valid && state->enabled_at_spl == false) { 584 ret = conn_funcs->mode_valid(conn, state); 585 if (ret) 586 return ret; 587 } 588 589 if (crtc_funcs->mode_valid) { 590 ret = crtc_funcs->mode_valid(state); 591 if (ret) 592 return ret; 593 } 594 595 return 0; 596 } 597 598 static int display_mode_fixup(struct display_state *state) 599 { 600 struct crtc_state *crtc_state = &state->crtc_state; 601 const struct rockchip_crtc *crtc = crtc_state->crtc; 602 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 603 int ret; 604 605 if (crtc_funcs->mode_fixup) { 606 ret = crtc_funcs->mode_fixup(state); 607 if (ret) 608 return ret; 609 } 610 611 return 0; 612 } 613 614 static int display_init(struct display_state *state) 615 { 616 struct connector_state *conn_state = &state->conn_state; 617 struct rockchip_connector *conn = conn_state->connector; 618 struct crtc_state *crtc_state = &state->crtc_state; 619 struct rockchip_crtc *crtc = crtc_state->crtc; 620 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 621 struct drm_display_mode *mode = &conn_state->mode; 622 const char *compatible; 623 int ret = 0; 624 static bool __print_once = false; 625 #ifdef CONFIG_SPL_BUILD 626 struct spl_display_info *spl_disp_info = (struct spl_display_info *)CONFIG_SPL_VIDEO_BUF; 627 #endif 628 if (!__print_once) { 629 __print_once = true; 630 printf("Rockchip UBOOT DRM driver version: %s\n", DRIVER_VERSION); 631 } 632 633 if (state->is_init) 634 return 0; 635 636 if (!crtc_funcs) { 637 printf("failed to find crtc functions\n"); 638 return -ENXIO; 639 } 640 641 #ifdef CONFIG_SPL_BUILD 642 if (state->conn_state.type == DRM_MODE_CONNECTOR_HDMIA) 643 state->enabled_at_spl = spl_disp_info->enabled == 1 ? true : false; 644 if (state->enabled_at_spl) 645 printf("HDMI enabled at SPL\n"); 646 #endif 647 if (crtc_state->crtc->active && !crtc_state->ports_node && 648 memcmp(&crtc_state->crtc->active_mode, &conn_state->mode, 649 sizeof(struct drm_display_mode))) { 650 printf("%s has been used for output type: %d, mode: %dx%dp%d\n", 651 crtc_state->dev->name, 652 crtc_state->crtc->active_mode.type, 653 crtc_state->crtc->active_mode.hdisplay, 654 crtc_state->crtc->active_mode.vdisplay, 655 crtc_state->crtc->active_mode.vrefresh); 656 return -ENODEV; 657 } 658 659 if (crtc_funcs->preinit) { 660 ret = crtc_funcs->preinit(state); 661 if (ret) 662 return ret; 663 } 664 665 if (state->enabled_at_spl == false) { 666 ret = rockchip_connector_init(state); 667 if (ret) 668 goto deinit; 669 } 670 671 /* 672 * support hotplug, but not connect; 673 */ 674 #ifdef CONFIG_DRM_ROCKCHIP_TVE 675 if (crtc->hdmi_hpd && conn_state->type == DRM_MODE_CONNECTOR_TV) { 676 printf("hdmi plugin ,skip tve\n"); 677 goto deinit; 678 } 679 #elif defined(CONFIG_DRM_ROCKCHIP_RK1000) 680 if (crtc->hdmi_hpd && conn_state->type == DRM_MODE_CONNECTOR_LVDS) { 681 printf("hdmi plugin ,skip tve\n"); 682 goto deinit; 683 } 684 #endif 685 686 ret = rockchip_connector_detect(state); 687 #if defined(CONFIG_DRM_ROCKCHIP_TVE) || defined(CONFIG_DRM_ROCKCHIP_RK1000) 688 if (conn_state->type == DRM_MODE_CONNECTOR_HDMIA) 689 crtc->hdmi_hpd = ret; 690 if (state->enabled_at_spl) 691 crtc->hdmi_hpd = true; 692 #endif 693 if (!ret && !state->force_output) 694 goto deinit; 695 696 ret = 0; 697 if (state->enabled_at_spl == true) { 698 #ifdef CONFIG_SPL_BUILD 699 struct drm_display_mode *mode = &conn_state->mode; 700 701 memcpy(mode, &spl_disp_info->mode, sizeof(*mode)); 702 conn_state->bus_format = spl_disp_info->bus_format; 703 704 printf("%s get display mode from spl:%dx%d, bus format:0x%x\n", 705 conn->dev->name, mode->hdisplay, mode->vdisplay, conn_state->bus_format); 706 #endif 707 } else if (conn->panel) { 708 ret = display_get_timing(state); 709 if (!ret) 710 conn_state->bpc = conn->panel->bpc; 711 #if defined(CONFIG_I2C_EDID) 712 if (ret < 0 && conn->funcs->get_edid) { 713 rockchip_panel_prepare(conn->panel); 714 ret = conn->funcs->get_edid(conn, state); 715 if (!ret) 716 display_get_edid_mode(state); 717 } 718 #endif 719 } else if (conn->bridge) { 720 ret = video_bridge_read_edid(conn->bridge->dev, 721 conn_state->edid, EDID_SIZE); 722 if (ret > 0) { 723 #if defined(CONFIG_I2C_EDID) 724 display_get_edid_mode(state); 725 #endif 726 } else { 727 ret = video_bridge_get_timing(conn->bridge->dev); 728 } 729 } else if (conn->funcs->get_timing) { 730 ret = conn->funcs->get_timing(conn, state); 731 } else if (conn->funcs->get_edid) { 732 ret = conn->funcs->get_edid(conn, state); 733 #if defined(CONFIG_I2C_EDID) 734 if (!ret) 735 display_get_edid_mode(state); 736 #endif 737 } 738 739 if (!ret && conn_state->secondary) { 740 struct rockchip_connector *connector = conn_state->secondary; 741 742 if (connector->panel) { 743 if (connector->panel->funcs->get_mode) { 744 struct drm_display_mode *_mode = drm_mode_create(); 745 746 ret = connector->panel->funcs->get_mode(connector->panel, _mode); 747 if (!ret && !drm_mode_equal(_mode, mode)) 748 ret = -EINVAL; 749 750 drm_mode_destroy(_mode); 751 } 752 } 753 } 754 755 if (ret && !state->force_output) 756 goto deinit; 757 if (state->force_output) 758 display_use_force_mode(state); 759 760 if (display_mode_valid(state)) 761 goto deinit; 762 763 /* rk356x series drive mipi pixdata on posedge */ 764 compatible = dev_read_string(conn->dev, "compatible"); 765 if (!strcmp(compatible, "rockchip,rk3568-mipi-dsi")) { 766 conn_state->bus_flags &= ~DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE; 767 conn_state->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE; 768 } 769 770 printf("%s: %s detailed mode clock %u kHz, flags[%x]\n" 771 " H: %04d %04d %04d %04d\n" 772 " V: %04d %04d %04d %04d\n" 773 "bus_format: %x\n", 774 conn->dev->name, 775 state->force_output ? "use force output" : "", 776 mode->clock, mode->flags, 777 mode->hdisplay, mode->hsync_start, 778 mode->hsync_end, mode->htotal, 779 mode->vdisplay, mode->vsync_start, 780 mode->vsync_end, mode->vtotal, 781 conn_state->bus_format); 782 783 if (display_mode_fixup(state)) 784 goto deinit; 785 786 if (conn->bridge) 787 rockchip_bridge_mode_set(conn->bridge, &conn_state->mode); 788 789 if (crtc_funcs->init && state->enabled_at_spl == false) { 790 ret = crtc_funcs->init(state); 791 if (ret) 792 goto deinit; 793 } 794 state->is_init = 1; 795 796 crtc_state->crtc->active = true; 797 memcpy(&crtc_state->crtc->active_mode, 798 &conn_state->mode, sizeof(struct drm_display_mode)); 799 800 return 0; 801 802 deinit: 803 rockchip_connector_deinit(state); 804 return ret; 805 } 806 807 int display_send_mcu_cmd(struct display_state *state, u32 type, u32 val) 808 { 809 struct crtc_state *crtc_state = &state->crtc_state; 810 const struct rockchip_crtc *crtc = crtc_state->crtc; 811 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 812 int ret; 813 814 if (!state->is_init) 815 return -EINVAL; 816 817 if (crtc_funcs->send_mcu_cmd) { 818 ret = crtc_funcs->send_mcu_cmd(state, type, val); 819 if (ret) 820 return ret; 821 } 822 823 return 0; 824 } 825 826 static int display_set_plane(struct display_state *state) 827 { 828 struct crtc_state *crtc_state = &state->crtc_state; 829 const struct rockchip_crtc *crtc = crtc_state->crtc; 830 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 831 int ret; 832 833 if (!state->is_init) 834 return -EINVAL; 835 836 if (crtc_funcs->set_plane) { 837 ret = crtc_funcs->set_plane(state); 838 if (ret) 839 return ret; 840 } 841 842 return 0; 843 } 844 845 static int display_enable(struct display_state *state) 846 { 847 struct crtc_state *crtc_state = &state->crtc_state; 848 const struct rockchip_crtc *crtc = crtc_state->crtc; 849 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 850 851 if (!state->is_init) 852 return -EINVAL; 853 854 if (state->is_enable) 855 return 0; 856 857 if (crtc_funcs->prepare) 858 crtc_funcs->prepare(state); 859 860 if (state->enabled_at_spl == false) 861 rockchip_connector_pre_enable(state); 862 863 if (crtc_funcs->enable) 864 crtc_funcs->enable(state); 865 866 if (state->enabled_at_spl == false) 867 rockchip_connector_enable(state); 868 869 if (crtc_state->soft_te) 870 crtc_funcs->apply_soft_te(state); 871 872 state->is_enable = true; 873 874 return 0; 875 } 876 877 static int display_disable(struct display_state *state) 878 { 879 struct crtc_state *crtc_state = &state->crtc_state; 880 const struct rockchip_crtc *crtc = crtc_state->crtc; 881 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 882 883 if (!state->is_init) 884 return 0; 885 886 if (!state->is_enable) 887 return 0; 888 889 rockchip_connector_disable(state); 890 891 if (crtc_funcs->disable) 892 crtc_funcs->disable(state); 893 894 rockchip_connector_post_disable(state); 895 896 state->is_enable = 0; 897 state->is_init = 0; 898 899 return 0; 900 } 901 902 static int display_check(struct display_state *state) 903 { 904 struct connector_state *conn_state = &state->conn_state; 905 struct rockchip_connector *conn = conn_state->connector; 906 const struct rockchip_connector_funcs *conn_funcs = conn->funcs; 907 struct crtc_state *crtc_state = &state->crtc_state; 908 const struct rockchip_crtc *crtc = crtc_state->crtc; 909 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; 910 int ret; 911 912 if (!state->is_init) 913 return 0; 914 915 if (conn_funcs->check) { 916 ret = conn_funcs->check(conn, state); 917 if (ret) 918 goto check_fail; 919 } 920 921 if (crtc_funcs->check) { 922 ret = crtc_funcs->check(state); 923 if (ret) 924 goto check_fail; 925 } 926 927 if (crtc_funcs->plane_check) { 928 ret = crtc_funcs->plane_check(state); 929 if (ret) 930 goto check_fail; 931 } 932 933 return 0; 934 935 check_fail: 936 state->is_init = false; 937 return ret; 938 } 939 940 static int display_logo(struct display_state *state) 941 { 942 struct crtc_state *crtc_state = &state->crtc_state; 943 struct connector_state *conn_state = &state->conn_state; 944 struct logo_info *logo = &state->logo; 945 int hdisplay, vdisplay, ret; 946 947 ret = display_init(state); 948 if (!state->is_init || ret) 949 return -ENODEV; 950 951 switch (logo->bpp) { 952 case 16: 953 crtc_state->format = ROCKCHIP_FMT_RGB565; 954 break; 955 case 24: 956 crtc_state->format = ROCKCHIP_FMT_RGB888; 957 break; 958 case 32: 959 crtc_state->format = ROCKCHIP_FMT_ARGB8888; 960 break; 961 default: 962 printf("can't support bmp bits[%d]\n", logo->bpp); 963 return -EINVAL; 964 } 965 hdisplay = conn_state->mode.crtc_hdisplay; 966 vdisplay = conn_state->mode.vdisplay; 967 crtc_state->src_rect.w = logo->width; 968 crtc_state->src_rect.h = logo->height; 969 crtc_state->src_rect.x = 0; 970 crtc_state->src_rect.y = 0; 971 crtc_state->ymirror = logo->ymirror; 972 crtc_state->rb_swap = 0; 973 974 crtc_state->dma_addr = (u32)(unsigned long)logo->mem + logo->offset; 975 crtc_state->xvir = ALIGN(crtc_state->src_rect.w * logo->bpp, 32) >> 5; 976 977 if (state->logo_mode == ROCKCHIP_DISPLAY_FULLSCREEN) { 978 crtc_state->crtc_rect.x = 0; 979 crtc_state->crtc_rect.y = 0; 980 crtc_state->crtc_rect.w = hdisplay; 981 crtc_state->crtc_rect.h = vdisplay; 982 } else { 983 if (crtc_state->src_rect.w >= hdisplay) { 984 crtc_state->crtc_rect.x = 0; 985 crtc_state->crtc_rect.w = hdisplay; 986 } else { 987 crtc_state->crtc_rect.x = (hdisplay - crtc_state->src_rect.w) / 2; 988 crtc_state->crtc_rect.w = crtc_state->src_rect.w; 989 } 990 991 if (crtc_state->src_rect.h >= vdisplay) { 992 crtc_state->crtc_rect.y = 0; 993 crtc_state->crtc_rect.h = vdisplay; 994 } else { 995 crtc_state->crtc_rect.y = (vdisplay - crtc_state->src_rect.h) / 2; 996 crtc_state->crtc_rect.h = crtc_state->src_rect.h; 997 } 998 } 999 1000 display_check(state); 1001 display_set_plane(state); 1002 display_enable(state); 1003 1004 return 0; 1005 } 1006 1007 static int get_crtc_id(ofnode connect, bool is_ports_node) 1008 { 1009 struct device_node *port_node; 1010 struct device_node *remote; 1011 int phandle; 1012 int val; 1013 1014 if (is_ports_node) { 1015 port_node = of_get_parent(connect.np); 1016 if (!port_node) 1017 goto err; 1018 1019 val = ofnode_read_u32_default(np_to_ofnode(port_node), "reg", -1); 1020 if (val < 0) 1021 goto err; 1022 } else { 1023 phandle = ofnode_read_u32_default(connect, "remote-endpoint", -1); 1024 if (phandle < 0) 1025 goto err; 1026 1027 remote = of_find_node_by_phandle(phandle); 1028 if (!remote) 1029 goto err; 1030 1031 val = ofnode_read_u32_default(np_to_ofnode(remote), "reg", -1); 1032 if (val < 0) 1033 goto err; 1034 } 1035 1036 return val; 1037 err: 1038 printf("Can't get crtc id, default set to id = 0\n"); 1039 return 0; 1040 } 1041 1042 static int get_crtc_mcu_mode(struct crtc_state *crtc_state, struct device_node *port_node, 1043 bool is_ports_node) 1044 { 1045 ofnode mcu_node, vp_node; 1046 int total_pixel, cs_pst, cs_pend, rw_pst, rw_pend; 1047 1048 if (is_ports_node) { 1049 vp_node = np_to_ofnode(port_node); 1050 mcu_node = ofnode_find_subnode(vp_node, "mcu-timing"); 1051 if (!ofnode_valid(mcu_node)) 1052 return -ENODEV; 1053 } else { 1054 mcu_node = dev_read_subnode(crtc_state->dev, "mcu-timing"); 1055 if (!ofnode_valid(mcu_node)) 1056 return -ENODEV; 1057 } 1058 1059 #define FDT_GET_MCU_INT(val, name) \ 1060 do { \ 1061 val = ofnode_read_s32_default(mcu_node, name, -1); \ 1062 if (val < 0) { \ 1063 printf("Can't get %s\n", name); \ 1064 return -ENXIO; \ 1065 } \ 1066 } while (0) 1067 1068 FDT_GET_MCU_INT(total_pixel, "mcu-pix-total"); 1069 FDT_GET_MCU_INT(cs_pst, "mcu-cs-pst"); 1070 FDT_GET_MCU_INT(cs_pend, "mcu-cs-pend"); 1071 FDT_GET_MCU_INT(rw_pst, "mcu-rw-pst"); 1072 FDT_GET_MCU_INT(rw_pend, "mcu-rw-pend"); 1073 1074 crtc_state->mcu_timing.mcu_pix_total = total_pixel; 1075 crtc_state->mcu_timing.mcu_cs_pst = cs_pst; 1076 crtc_state->mcu_timing.mcu_cs_pend = cs_pend; 1077 crtc_state->mcu_timing.mcu_rw_pst = rw_pst; 1078 crtc_state->mcu_timing.mcu_rw_pend = rw_pend; 1079 1080 return 0; 1081 } 1082 1083 struct rockchip_logo_cache *find_or_alloc_logo_cache(const char *bmp) 1084 { 1085 struct rockchip_logo_cache *tmp, *logo_cache = NULL; 1086 1087 list_for_each_entry(tmp, &logo_cache_list, head) { 1088 if (!strcmp(tmp->name, bmp)) { 1089 logo_cache = tmp; 1090 break; 1091 } 1092 } 1093 1094 if (!logo_cache) { 1095 logo_cache = malloc(sizeof(*logo_cache)); 1096 if (!logo_cache) { 1097 printf("failed to alloc memory for logo cache\n"); 1098 return NULL; 1099 } 1100 memset(logo_cache, 0, sizeof(*logo_cache)); 1101 strcpy(logo_cache->name, bmp); 1102 INIT_LIST_HEAD(&logo_cache->head); 1103 list_add_tail(&logo_cache->head, &logo_cache_list); 1104 } 1105 1106 return logo_cache; 1107 } 1108 1109 /* Note: used only for rkfb kernel driver */ 1110 static int load_kernel_bmp_logo(struct logo_info *logo, const char *bmp_name) 1111 { 1112 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 1113 void *dst = NULL; 1114 int len, size; 1115 struct bmp_header *header; 1116 1117 if (!logo || !bmp_name) 1118 return -EINVAL; 1119 1120 header = malloc(RK_BLK_SIZE); 1121 if (!header) 1122 return -ENOMEM; 1123 1124 len = rockchip_read_resource_file(header, bmp_name, 0, RK_BLK_SIZE); 1125 if (len != RK_BLK_SIZE) { 1126 free(header); 1127 return -EINVAL; 1128 } 1129 size = get_unaligned_le32(&header->file_size); 1130 dst = (void *)(memory_start + MEMORY_POOL_SIZE / 2); 1131 len = rockchip_read_resource_file(dst, bmp_name, 0, size); 1132 if (len != size) { 1133 printf("failed to load bmp %s\n", bmp_name); 1134 free(header); 1135 return -ENOENT; 1136 } 1137 1138 logo->mem = dst; 1139 #endif 1140 1141 return 0; 1142 } 1143 1144 static int load_bmp_logo(struct logo_info *logo, const char *bmp_name) 1145 { 1146 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE 1147 struct rockchip_logo_cache *logo_cache; 1148 struct bmp_header *header; 1149 void *dst = NULL, *pdst; 1150 int size, len; 1151 int ret = 0; 1152 int reserved = 0; 1153 int dst_size; 1154 1155 if (!logo || !bmp_name) 1156 return -EINVAL; 1157 logo_cache = find_or_alloc_logo_cache(bmp_name); 1158 if (!logo_cache) 1159 return -ENOMEM; 1160 1161 if (logo_cache->logo.mem) { 1162 memcpy(logo, &logo_cache->logo, sizeof(*logo)); 1163 return 0; 1164 } 1165 1166 header = malloc(RK_BLK_SIZE); 1167 if (!header) 1168 return -ENOMEM; 1169 1170 len = rockchip_read_resource_file(header, bmp_name, 0, RK_BLK_SIZE); 1171 if (len != RK_BLK_SIZE) { 1172 ret = -EINVAL; 1173 goto free_header; 1174 } 1175 1176 logo->bpp = get_unaligned_le16(&header->bit_count); 1177 logo->width = get_unaligned_le32(&header->width); 1178 logo->height = get_unaligned_le32(&header->height); 1179 dst_size = logo->width * logo->height * logo->bpp >> 3; 1180 reserved = get_unaligned_le32(&header->reserved); 1181 if (logo->height < 0) 1182 logo->height = -logo->height; 1183 size = get_unaligned_le32(&header->file_size); 1184 if (!can_direct_logo(logo->bpp)) { 1185 if (size > MEMORY_POOL_SIZE) { 1186 printf("failed to use boot buf as temp bmp buffer\n"); 1187 ret = -ENOMEM; 1188 goto free_header; 1189 } 1190 pdst = get_display_buffer(size); 1191 1192 } else { 1193 pdst = get_display_buffer(size); 1194 dst = pdst; 1195 } 1196 1197 len = rockchip_read_resource_file(pdst, bmp_name, 0, size); 1198 if (len != size) { 1199 printf("failed to load bmp %s\n", bmp_name); 1200 ret = -ENOENT; 1201 goto free_header; 1202 } 1203 1204 if (!can_direct_logo(logo->bpp)) { 1205 /* 1206 * TODO: force use 16bpp if bpp less than 16; 1207 */ 1208 logo->bpp = (logo->bpp <= 16) ? 16 : logo->bpp; 1209 dst_size = logo->width * logo->height * logo->bpp >> 3; 1210 dst = get_display_buffer(dst_size); 1211 if (!dst) { 1212 ret = -ENOMEM; 1213 goto free_header; 1214 } 1215 if (bmpdecoder(pdst, dst, logo->bpp)) { 1216 printf("failed to decode bmp %s\n", bmp_name); 1217 ret = -EINVAL; 1218 goto free_header; 1219 } 1220 1221 logo->offset = 0; 1222 logo->ymirror = 0; 1223 } else { 1224 logo->offset = get_unaligned_le32(&header->data_offset); 1225 if (reserved == BMP_PROCESSED_FLAG) 1226 logo->ymirror = 0; 1227 else 1228 logo->ymirror = 1; 1229 } 1230 logo->mem = dst; 1231 1232 memcpy(&logo_cache->logo, logo, sizeof(*logo)); 1233 1234 flush_dcache_range((ulong)dst, ALIGN((ulong)dst + dst_size, CONFIG_SYS_CACHELINE_SIZE)); 1235 1236 free_header: 1237 1238 free(header); 1239 1240 return ret; 1241 #else 1242 return -EINVAL; 1243 #endif 1244 } 1245 1246 void rockchip_show_fbbase(ulong fbbase) 1247 { 1248 struct display_state *s; 1249 1250 list_for_each_entry(s, &rockchip_display_list, head) { 1251 s->logo.mode = ROCKCHIP_DISPLAY_FULLSCREEN; 1252 s->logo.mem = (char *)fbbase; 1253 s->logo.width = DRM_ROCKCHIP_FB_WIDTH; 1254 s->logo.height = DRM_ROCKCHIP_FB_HEIGHT; 1255 s->logo.bpp = 32; 1256 s->logo.ymirror = 0; 1257 1258 display_logo(s); 1259 } 1260 } 1261 1262 int rockchip_show_bmp(const char *bmp) 1263 { 1264 struct display_state *s; 1265 int ret = 0; 1266 1267 if (!bmp) { 1268 list_for_each_entry(s, &rockchip_display_list, head) 1269 display_disable(s); 1270 return -ENOENT; 1271 } 1272 1273 list_for_each_entry(s, &rockchip_display_list, head) { 1274 s->logo.mode = s->charge_logo_mode; 1275 if (load_bmp_logo(&s->logo, bmp)) 1276 continue; 1277 ret = display_logo(s); 1278 } 1279 1280 return ret; 1281 } 1282 1283 int rockchip_show_logo(void) 1284 { 1285 struct display_state *s; 1286 int ret = 0; 1287 1288 list_for_each_entry(s, &rockchip_display_list, head) { 1289 s->logo.mode = s->logo_mode; 1290 if (load_bmp_logo(&s->logo, s->ulogo_name)) 1291 printf("failed to display uboot logo\n"); 1292 else 1293 ret = display_logo(s); 1294 1295 /* Load kernel bmp in rockchip_display_fixup() later */ 1296 } 1297 1298 return ret; 1299 } 1300 1301 int rockchip_vop_dump(const char *cmd) 1302 { 1303 struct display_state *state; 1304 struct crtc_state *crtc_state; 1305 struct rockchip_crtc *crtc; 1306 const struct rockchip_crtc_funcs *crtc_funcs; 1307 int ret = -EINVAL; 1308 1309 list_for_each_entry(state, &rockchip_display_list, head) { 1310 if (!state->is_init) 1311 continue; 1312 crtc_state = &state->crtc_state; 1313 crtc = crtc_state->crtc; 1314 crtc_funcs = crtc->funcs; 1315 1316 if (!cmd) 1317 ret = crtc_funcs->active_regs_dump(state); 1318 else if (!strcmp(cmd, "a") || !strcmp(cmd, "all")) 1319 ret = crtc_funcs->regs_dump(state); 1320 if (!ret) 1321 break; 1322 } 1323 1324 if (ret) 1325 ret = CMD_RET_USAGE; 1326 1327 return ret; 1328 } 1329 1330 enum { 1331 PORT_DIR_IN, 1332 PORT_DIR_OUT, 1333 }; 1334 1335 static const struct device_node *rockchip_of_graph_get_port_by_id(ofnode node, int id) 1336 { 1337 ofnode ports, port; 1338 u32 reg; 1339 1340 ports = ofnode_find_subnode(node, "ports"); 1341 if (!ofnode_valid(ports)) 1342 return NULL; 1343 1344 ofnode_for_each_subnode(port, ports) { 1345 if (ofnode_read_u32(port, "reg", ®)) 1346 continue; 1347 1348 if (reg == id) 1349 break; 1350 } 1351 1352 if (reg == id) 1353 return ofnode_to_np(port); 1354 1355 return NULL; 1356 } 1357 1358 static const struct device_node *rockchip_of_graph_get_port_parent(ofnode port) 1359 { 1360 ofnode parent; 1361 int is_ports_node; 1362 1363 parent = ofnode_get_parent(port); 1364 is_ports_node = strstr(ofnode_to_np(parent)->full_name, "ports") ? 1 : 0; 1365 if (is_ports_node) 1366 parent = ofnode_get_parent(parent); 1367 1368 return ofnode_to_np(parent); 1369 } 1370 1371 const struct device_node * 1372 rockchip_of_graph_get_endpoint_by_regs(ofnode node, int port, int endpoint) 1373 { 1374 const struct device_node *port_node; 1375 ofnode ep; 1376 u32 reg; 1377 1378 port_node = rockchip_of_graph_get_port_by_id(node, port); 1379 if (!port_node) 1380 return NULL; 1381 1382 ofnode_for_each_subnode(ep, np_to_ofnode(port_node)) { 1383 if (ofnode_read_u32(ep, "reg", ®)) 1384 break; 1385 if (reg == endpoint) 1386 break; 1387 } 1388 1389 if (!ofnode_valid(ep)) 1390 return NULL; 1391 1392 return ofnode_to_np(ep); 1393 } 1394 1395 static const struct device_node * 1396 rockchip_of_graph_get_remote_node(ofnode node, int port, int endpoint) 1397 { 1398 const struct device_node *ep_node; 1399 ofnode ep; 1400 uint phandle; 1401 1402 ep_node = rockchip_of_graph_get_endpoint_by_regs(node, port, endpoint); 1403 if (!ep_node) 1404 return NULL; 1405 1406 if (ofnode_read_u32(np_to_ofnode(ep_node), "remote-endpoint", &phandle)) 1407 return NULL; 1408 1409 ep = ofnode_get_by_phandle(phandle); 1410 if (!ofnode_valid(ep)) 1411 return NULL; 1412 1413 return ofnode_to_np(ep); 1414 } 1415 1416 static int rockchip_of_find_panel(struct udevice *dev, struct rockchip_panel **panel) 1417 { 1418 const struct device_node *ep_node, *panel_node; 1419 ofnode panel_ofnode, port; 1420 struct udevice *panel_dev; 1421 int ret = 0; 1422 1423 *panel = NULL; 1424 panel_ofnode = dev_read_subnode(dev, "panel"); 1425 if (ofnode_valid(panel_ofnode) && ofnode_is_available(panel_ofnode)) { 1426 ret = uclass_get_device_by_ofnode(UCLASS_PANEL, panel_ofnode, 1427 &panel_dev); 1428 if (!ret) 1429 goto found; 1430 } 1431 1432 ep_node = rockchip_of_graph_get_remote_node(dev->node, PORT_DIR_OUT, 0); 1433 if (!ep_node) 1434 return -ENODEV; 1435 1436 port = ofnode_get_parent(np_to_ofnode(ep_node)); 1437 if (!ofnode_valid(port)) 1438 return -ENODEV; 1439 1440 panel_node = rockchip_of_graph_get_port_parent(port); 1441 if (!panel_node) 1442 return -ENODEV; 1443 1444 ret = uclass_get_device_by_ofnode(UCLASS_PANEL, np_to_ofnode(panel_node), &panel_dev); 1445 if (!ret) 1446 goto found; 1447 1448 return -ENODEV; 1449 1450 found: 1451 *panel = (struct rockchip_panel *)dev_get_driver_data(panel_dev); 1452 return 0; 1453 } 1454 1455 static int rockchip_of_find_bridge(struct udevice *dev, struct rockchip_bridge **bridge) 1456 { 1457 const struct device_node *ep_node, *bridge_node; 1458 ofnode port; 1459 struct udevice *bridge_dev; 1460 int ret = 0; 1461 1462 ep_node = rockchip_of_graph_get_remote_node(dev->node, PORT_DIR_OUT, 0); 1463 if (!ep_node) 1464 return -ENODEV; 1465 1466 port = ofnode_get_parent(np_to_ofnode(ep_node)); 1467 if (!ofnode_valid(port)) 1468 return -ENODEV; 1469 1470 bridge_node = rockchip_of_graph_get_port_parent(port); 1471 if (!bridge_node) 1472 return -ENODEV; 1473 1474 ret = uclass_get_device_by_ofnode(UCLASS_VIDEO_BRIDGE, np_to_ofnode(bridge_node), 1475 &bridge_dev); 1476 if (!ret) 1477 goto found; 1478 1479 return -ENODEV; 1480 1481 found: 1482 *bridge = (struct rockchip_bridge *)dev_get_driver_data(bridge_dev); 1483 return 0; 1484 } 1485 1486 static int rockchip_of_find_panel_or_bridge(struct udevice *dev, struct rockchip_panel **panel, 1487 struct rockchip_bridge **bridge) 1488 { 1489 int ret = 0; 1490 1491 if (*panel) 1492 return 0; 1493 1494 *panel = NULL; 1495 *bridge = NULL; 1496 1497 if (panel) { 1498 ret = rockchip_of_find_panel(dev, panel); 1499 if (!ret) 1500 return 0; 1501 } 1502 1503 if (ret) { 1504 ret = rockchip_of_find_bridge(dev, bridge); 1505 if (!ret) 1506 ret = rockchip_of_find_panel_or_bridge((*bridge)->dev, panel, 1507 &(*bridge)->next_bridge); 1508 } 1509 1510 return ret; 1511 } 1512 1513 static struct rockchip_phy *rockchip_of_find_phy(struct udevice *dev) 1514 { 1515 struct udevice *phy_dev; 1516 int ret; 1517 1518 ret = uclass_get_device_by_phandle(UCLASS_PHY, dev, "phys", &phy_dev); 1519 if (ret) 1520 return NULL; 1521 1522 return (struct rockchip_phy *)dev_get_driver_data(phy_dev); 1523 } 1524 1525 static struct udevice *rockchip_of_find_connector_device(ofnode endpoint) 1526 { 1527 ofnode ep, port, ports, conn; 1528 uint phandle; 1529 struct udevice *dev; 1530 int ret; 1531 1532 if (ofnode_read_u32(endpoint, "remote-endpoint", &phandle)) 1533 return NULL; 1534 1535 ep = ofnode_get_by_phandle(phandle); 1536 if (!ofnode_valid(ep) || !ofnode_is_available(ep)) 1537 return NULL; 1538 1539 port = ofnode_get_parent(ep); 1540 if (!ofnode_valid(port)) 1541 return NULL; 1542 1543 ports = ofnode_get_parent(port); 1544 if (!ofnode_valid(ports)) 1545 return NULL; 1546 1547 conn = ofnode_get_parent(ports); 1548 if (!ofnode_valid(conn) || !ofnode_is_available(conn)) 1549 return NULL; 1550 1551 ret = uclass_get_device_by_ofnode(UCLASS_DISPLAY, conn, &dev); 1552 if (ret) 1553 return NULL; 1554 1555 return dev; 1556 } 1557 1558 static struct rockchip_connector *rockchip_of_get_connector(ofnode endpoint) 1559 { 1560 struct rockchip_connector *conn; 1561 struct udevice *dev; 1562 int ret; 1563 1564 dev = rockchip_of_find_connector_device(endpoint); 1565 if (!dev) { 1566 printf("Warn: can't find connect driver\n"); 1567 return NULL; 1568 } 1569 1570 conn = get_rockchip_connector_by_device(dev); 1571 if (!conn) 1572 return NULL; 1573 ret = rockchip_of_find_panel_or_bridge(dev, &conn->panel, &conn->bridge); 1574 if (ret) 1575 debug("Warn: no find panel or bridge\n"); 1576 1577 conn->phy = rockchip_of_find_phy(dev); 1578 1579 return conn; 1580 } 1581 1582 static struct rockchip_connector *rockchip_get_split_connector(struct rockchip_connector *conn) 1583 { 1584 char *conn_name; 1585 struct device_node *split_node; 1586 struct udevice *split_dev; 1587 struct rockchip_connector *split_conn; 1588 bool split_mode; 1589 int ret; 1590 1591 split_mode = ofnode_read_bool(conn->dev->node, "split-mode"); 1592 if (!split_mode) 1593 return NULL; 1594 1595 switch (conn->type) { 1596 case DRM_MODE_CONNECTOR_DisplayPort: 1597 conn_name = "dp"; 1598 break; 1599 case DRM_MODE_CONNECTOR_eDP: 1600 conn_name = "edp"; 1601 break; 1602 case DRM_MODE_CONNECTOR_HDMIA: 1603 conn_name = "hdmi"; 1604 break; 1605 default: 1606 return NULL; 1607 } 1608 1609 split_node = of_alias_get_dev(conn_name, !conn->id); 1610 if (!split_node || !of_device_is_available(split_node)) 1611 return NULL; 1612 1613 ret = uclass_get_device_by_ofnode(UCLASS_DISPLAY, np_to_ofnode(split_node), &split_dev); 1614 if (ret) 1615 return NULL; 1616 1617 split_conn = get_rockchip_connector_by_device(split_dev); 1618 if (!split_conn) 1619 return NULL; 1620 ret = rockchip_of_find_panel_or_bridge(split_dev, &split_conn->panel, &split_conn->bridge); 1621 if (ret) 1622 debug("Warn: no find panel or bridge\n"); 1623 1624 split_conn->phy = rockchip_of_find_phy(split_dev); 1625 1626 return split_conn; 1627 } 1628 1629 static bool rockchip_get_display_path_status(ofnode endpoint) 1630 { 1631 ofnode ep; 1632 uint phandle; 1633 1634 if (ofnode_read_u32(endpoint, "remote-endpoint", &phandle)) 1635 return false; 1636 1637 ep = ofnode_get_by_phandle(phandle); 1638 if (!ofnode_valid(ep) || !ofnode_is_available(ep)) 1639 return false; 1640 1641 return true; 1642 } 1643 1644 #if defined(CONFIG_ROCKCHIP_RK3568) 1645 static int rockchip_display_fixup_dts(void *blob) 1646 { 1647 ofnode route_node, route_subnode, conn_ep, conn_port; 1648 const struct device_node *route_sub_devnode; 1649 const struct device_node *ep_node, *conn_ep_dev_node; 1650 u32 phandle; 1651 int conn_ep_offset; 1652 const char *route_sub_path, *path; 1653 1654 /* Don't go further if new variant after 1655 * reading PMUGRF_SOC_CON15 1656 */ 1657 if ((readl(0xfdc20100) & GENMASK(15, 14))) 1658 return 0; 1659 1660 route_node = ofnode_path("/display-subsystem/route"); 1661 if (!ofnode_valid(route_node)) 1662 return -EINVAL; 1663 1664 ofnode_for_each_subnode(route_subnode, route_node) { 1665 if (!ofnode_is_available(route_subnode)) 1666 continue; 1667 1668 route_sub_devnode = ofnode_to_np(route_subnode); 1669 route_sub_path = route_sub_devnode->full_name; 1670 if (!strstr(ofnode_get_name(route_subnode), "dsi") && 1671 !strstr(ofnode_get_name(route_subnode), "edp")) 1672 return 0; 1673 1674 phandle = ofnode_read_u32_default(route_subnode, "connect", -1); 1675 if (phandle < 0) { 1676 printf("Warn: can't find connect node's handle\n"); 1677 continue; 1678 } 1679 1680 ep_node = of_find_node_by_phandle(phandle); 1681 if (!ofnode_valid(np_to_ofnode(ep_node))) { 1682 printf("Warn: can't find endpoint node from phandle\n"); 1683 continue; 1684 } 1685 1686 ofnode_read_u32(np_to_ofnode(ep_node), "remote-endpoint", &phandle); 1687 conn_ep = ofnode_get_by_phandle(phandle); 1688 if (!ofnode_valid(conn_ep) || !ofnode_is_available(conn_ep)) 1689 return -ENODEV; 1690 1691 conn_port = ofnode_get_parent(conn_ep); 1692 if (!ofnode_valid(conn_port)) 1693 return -ENODEV; 1694 1695 ofnode_for_each_subnode(conn_ep, conn_port) { 1696 conn_ep_dev_node = ofnode_to_np(conn_ep); 1697 path = conn_ep_dev_node->full_name; 1698 ofnode_read_u32(conn_ep, "remote-endpoint", &phandle); 1699 conn_ep_offset = fdt_path_offset(blob, path); 1700 1701 if (!ofnode_is_available(conn_ep) && 1702 strstr(ofnode_get_name(conn_ep), "endpoint@0")) { 1703 do_fixup_by_path_u32(blob, route_sub_path, 1704 "connect", phandle, 1); 1705 fdt_status_okay(blob, conn_ep_offset); 1706 1707 } else if (ofnode_is_available(conn_ep) && 1708 strstr(ofnode_get_name(conn_ep), "endpoint@1")) { 1709 fdt_status_disabled(blob, conn_ep_offset); 1710 } 1711 } 1712 } 1713 1714 return 0; 1715 } 1716 #endif 1717 1718 static int rockchip_display_probe(struct udevice *dev) 1719 { 1720 struct video_priv *uc_priv = dev_get_uclass_priv(dev); 1721 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 1722 const void *blob = gd->fdt_blob; 1723 int phandle; 1724 struct udevice *crtc_dev; 1725 struct rockchip_crtc *crtc; 1726 struct rockchip_connector *conn, *split_conn; 1727 struct display_state *s; 1728 const char *name; 1729 int ret; 1730 ofnode node, route_node, timing_node; 1731 struct device_node *port_node, *vop_node, *ep_node, *port_parent_node; 1732 struct public_phy_data *data; 1733 bool is_ports_node = false; 1734 1735 #if defined(CONFIG_ROCKCHIP_RK3568) 1736 rockchip_display_fixup_dts((void *)blob); 1737 #endif 1738 /* Before relocation we don't need to do anything */ 1739 if (!(gd->flags & GD_FLG_RELOC)) 1740 return 0; 1741 1742 data = malloc(sizeof(struct public_phy_data)); 1743 if (!data) { 1744 printf("failed to alloc phy data\n"); 1745 return -ENOMEM; 1746 } 1747 data->phy_init = false; 1748 1749 init_display_buffer(plat->base); 1750 1751 route_node = dev_read_subnode(dev, "route"); 1752 if (!ofnode_valid(route_node)) 1753 return -ENODEV; 1754 1755 ofnode_for_each_subnode(node, route_node) { 1756 if (!ofnode_is_available(node)) 1757 continue; 1758 phandle = ofnode_read_u32_default(node, "connect", -1); 1759 if (phandle < 0) { 1760 printf("Warn: can't find connect node's handle\n"); 1761 continue; 1762 } 1763 ep_node = of_find_node_by_phandle(phandle); 1764 if (!ofnode_valid(np_to_ofnode(ep_node))) { 1765 printf("Warn: can't find endpoint node from phandle\n"); 1766 continue; 1767 } 1768 port_node = of_get_parent(ep_node); 1769 if (!ofnode_valid(np_to_ofnode(port_node))) { 1770 printf("Warn: can't find port node from phandle\n"); 1771 continue; 1772 } 1773 1774 port_parent_node = of_get_parent(port_node); 1775 if (!ofnode_valid(np_to_ofnode(port_parent_node))) { 1776 printf("Warn: can't find port parent node from phandle\n"); 1777 continue; 1778 } 1779 1780 is_ports_node = strstr(port_parent_node->full_name, "ports") ? 1 : 0; 1781 if (is_ports_node) { 1782 vop_node = of_get_parent(port_parent_node); 1783 if (!ofnode_valid(np_to_ofnode(vop_node))) { 1784 printf("Warn: can't find crtc node from phandle\n"); 1785 continue; 1786 } 1787 } else { 1788 vop_node = port_parent_node; 1789 } 1790 1791 ret = uclass_get_device_by_ofnode(UCLASS_VIDEO_CRTC, 1792 np_to_ofnode(vop_node), 1793 &crtc_dev); 1794 if (ret) { 1795 printf("Warn: can't find crtc driver %d\n", ret); 1796 continue; 1797 } 1798 crtc = (struct rockchip_crtc *)dev_get_driver_data(crtc_dev); 1799 1800 conn = rockchip_of_get_connector(np_to_ofnode(ep_node)); 1801 if (!conn) { 1802 printf("Warn: can't get connect driver\n"); 1803 continue; 1804 } 1805 split_conn = rockchip_get_split_connector(conn); 1806 1807 s = malloc(sizeof(*s)); 1808 if (!s) 1809 continue; 1810 1811 memset(s, 0, sizeof(*s)); 1812 1813 INIT_LIST_HEAD(&s->head); 1814 ret = ofnode_read_string_index(node, "logo,uboot", 0, &name); 1815 if (!ret) 1816 memcpy(s->ulogo_name, name, strlen(name)); 1817 ret = ofnode_read_string_index(node, "logo,kernel", 0, &name); 1818 if (!ret) 1819 memcpy(s->klogo_name, name, strlen(name)); 1820 ret = ofnode_read_string_index(node, "logo,mode", 0, &name); 1821 if (!strcmp(name, "fullscreen")) 1822 s->logo_mode = ROCKCHIP_DISPLAY_FULLSCREEN; 1823 else 1824 s->logo_mode = ROCKCHIP_DISPLAY_CENTER; 1825 ret = ofnode_read_string_index(node, "charge_logo,mode", 0, &name); 1826 if (!strcmp(name, "fullscreen")) 1827 s->charge_logo_mode = ROCKCHIP_DISPLAY_FULLSCREEN; 1828 else 1829 s->charge_logo_mode = ROCKCHIP_DISPLAY_CENTER; 1830 1831 s->force_output = ofnode_read_bool(node, "force-output"); 1832 1833 if (s->force_output) { 1834 timing_node = ofnode_find_subnode(node, "force_timing"); 1835 ret = display_get_force_timing_from_dts(timing_node, 1836 &s->force_mode, 1837 &s->conn_state.bus_flags); 1838 if (ofnode_read_u32(node, "force-bus-format", &s->force_bus_format)) 1839 s->force_bus_format = MEDIA_BUS_FMT_RGB888_1X24; 1840 } 1841 1842 s->blob = blob; 1843 s->conn_state.connector = conn; 1844 s->conn_state.secondary = NULL; 1845 s->conn_state.type = conn->type; 1846 if (split_conn) { 1847 s->conn_state.secondary = split_conn; 1848 s->conn_state.output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE; 1849 s->conn_state.output_flags |= conn->id ? ROCKCHIP_OUTPUT_DATA_SWAP : 0; 1850 } 1851 s->conn_state.overscan.left_margin = 100; 1852 s->conn_state.overscan.right_margin = 100; 1853 s->conn_state.overscan.top_margin = 100; 1854 s->conn_state.overscan.bottom_margin = 100; 1855 s->crtc_state.node = np_to_ofnode(vop_node); 1856 s->crtc_state.dev = crtc_dev; 1857 s->crtc_state.crtc = crtc; 1858 s->crtc_state.crtc_id = get_crtc_id(np_to_ofnode(ep_node), is_ports_node); 1859 s->node = node; 1860 1861 if (is_ports_node) { /* only vop2 will get into here */ 1862 ofnode vp_node = np_to_ofnode(port_node); 1863 static bool get_plane_mask_from_dts; 1864 1865 s->crtc_state.ports_node = port_parent_node; 1866 if (!get_plane_mask_from_dts) { 1867 ofnode vp_sub_node; 1868 int vp_id = 0; 1869 bool vp_enable = false; 1870 1871 ofnode_for_each_subnode(vp_node, np_to_ofnode(port_parent_node)) { 1872 int cursor_plane = -1; 1873 1874 vp_id = ofnode_read_u32_default(vp_node, "reg", 0); 1875 1876 s->crtc_state.crtc->vps[vp_id].xmirror_en = 1877 ofnode_read_bool(vp_node, "xmirror-enable"); 1878 1879 ret = ofnode_read_u32_default(vp_node, "rockchip,plane-mask", 0); 1880 1881 cursor_plane = ofnode_read_u32_default(vp_node, "cursor-win-id", -1); 1882 s->crtc_state.crtc->vps[vp_id].cursor_plane = cursor_plane; 1883 if (ret) { 1884 s->crtc_state.crtc->vps[vp_id].plane_mask = ret; 1885 s->crtc_state.crtc->assign_plane |= true; 1886 s->crtc_state.crtc->vps[vp_id].primary_plane_id = 1887 ofnode_read_u32_default(vp_node, "rockchip,primary-plane", U8_MAX); 1888 printf("get vp%d plane mask:0x%x, primary id:%d, cursor_plane:%d, from dts\n", 1889 vp_id, 1890 s->crtc_state.crtc->vps[vp_id].plane_mask, 1891 s->crtc_state.crtc->vps[vp_id].primary_plane_id == U8_MAX ? -1 : 1892 s->crtc_state.crtc->vps[vp_id].primary_plane_id, 1893 cursor_plane); 1894 } 1895 1896 /* To check current vp status */ 1897 vp_enable = false; 1898 ofnode_for_each_subnode(vp_sub_node, vp_node) 1899 vp_enable |= rockchip_get_display_path_status(vp_sub_node); 1900 s->crtc_state.crtc->vps[vp_id].enable = vp_enable; 1901 } 1902 get_plane_mask_from_dts = true; 1903 } 1904 } 1905 1906 get_crtc_mcu_mode(&s->crtc_state, port_node, is_ports_node); 1907 1908 ret = ofnode_read_u32_default(s->crtc_state.node, 1909 "rockchip,dual-channel-swap", 0); 1910 s->crtc_state.dual_channel_swap = ret; 1911 1912 if (connector_phy_init(conn, data)) { 1913 printf("Warn: Failed to init phy drivers\n"); 1914 free(s); 1915 continue; 1916 } 1917 list_add_tail(&s->head, &rockchip_display_list); 1918 } 1919 1920 if (list_empty(&rockchip_display_list)) { 1921 debug("Failed to found available display route\n"); 1922 return -ENODEV; 1923 } 1924 rockchip_get_baseparameter(); 1925 display_pre_init(); 1926 1927 uc_priv->xsize = DRM_ROCKCHIP_FB_WIDTH; 1928 uc_priv->ysize = DRM_ROCKCHIP_FB_HEIGHT; 1929 uc_priv->bpix = VIDEO_BPP32; 1930 1931 #ifdef CONFIG_DRM_ROCKCHIP_VIDEO_FRAMEBUFFER 1932 rockchip_show_fbbase(plat->base); 1933 video_set_flush_dcache(dev, true); 1934 #endif 1935 1936 return 0; 1937 } 1938 1939 void rockchip_display_fixup(void *blob) 1940 { 1941 const struct rockchip_connector_funcs *conn_funcs; 1942 const struct rockchip_crtc_funcs *crtc_funcs; 1943 struct rockchip_connector *conn; 1944 const struct rockchip_crtc *crtc; 1945 struct display_state *s; 1946 int offset; 1947 int ret; 1948 const struct device_node *np; 1949 const char *path; 1950 const char *cacm_header; 1951 u64 aligned_memory_size; 1952 1953 if (fdt_node_offset_by_compatible(blob, 0, "rockchip,drm-logo") >= 0) { 1954 list_for_each_entry(s, &rockchip_display_list, head) { 1955 ret = load_bmp_logo(&s->logo, s->klogo_name); 1956 if (ret < 0) { 1957 s->is_klogo_valid = false; 1958 printf("VP%d fail to load kernel logo\n", s->crtc_state.crtc_id); 1959 } else { 1960 s->is_klogo_valid = true; 1961 } 1962 } 1963 1964 if (!get_display_size()) 1965 return; 1966 1967 aligned_memory_size = (u64)ALIGN(get_display_size(), align_size); 1968 offset = fdt_update_reserved_memory(blob, "rockchip,drm-logo", 1969 (u64)memory_start, 1970 aligned_memory_size); 1971 if (offset < 0) 1972 printf("failed to reserve drm-loader-logo memory\n"); 1973 1974 if (get_cubic_memory_size()) { 1975 aligned_memory_size = (u64)ALIGN(get_cubic_memory_size(), align_size); 1976 offset = fdt_update_reserved_memory(blob, "rockchip,drm-cubic-lut", 1977 (u64)cubic_lut_memory_start, 1978 aligned_memory_size); 1979 if (offset < 0) 1980 printf("failed to reserve drm-cubic-lut memory\n"); 1981 } 1982 } else { 1983 printf("can't found rockchip,drm-logo, use rockchip,fb-logo\n"); 1984 /* Compatible with rkfb display, only need reserve memory */ 1985 offset = fdt_update_reserved_memory(blob, "rockchip,fb-logo", 1986 (u64)memory_start, 1987 MEMORY_POOL_SIZE); 1988 if (offset < 0) 1989 printf("failed to reserve fb-loader-logo memory\n"); 1990 else 1991 list_for_each_entry(s, &rockchip_display_list, head) 1992 load_kernel_bmp_logo(&s->logo, s->klogo_name); 1993 return; 1994 } 1995 1996 list_for_each_entry(s, &rockchip_display_list, head) { 1997 /* 1998 * If plane mask is not set in dts, fixup dts to assign it 1999 * whether crtc is initialized or not. 2000 */ 2001 if (s->crtc_state.crtc->funcs->fixup_dts && !s->crtc_state.crtc->assign_plane) 2002 s->crtc_state.crtc->funcs->fixup_dts(s, blob); 2003 2004 if (!s->is_init || !s->is_klogo_valid) 2005 continue; 2006 2007 conn = s->conn_state.connector; 2008 if (!conn) 2009 continue; 2010 conn_funcs = conn->funcs; 2011 if (!conn_funcs) { 2012 printf("failed to get exist connector\n"); 2013 continue; 2014 } 2015 2016 if (s->conn_state.secondary) { 2017 s->conn_state.mode.clock *= 2; 2018 s->conn_state.mode.hdisplay *= 2; 2019 } 2020 2021 crtc = s->crtc_state.crtc; 2022 if (!crtc) 2023 continue; 2024 2025 crtc_funcs = crtc->funcs; 2026 if (!crtc_funcs) { 2027 printf("failed to get exist crtc\n"); 2028 continue; 2029 } 2030 2031 np = ofnode_to_np(s->node); 2032 path = np->full_name; 2033 fdt_increase_size(blob, 0x400); 2034 #define FDT_SET_U32(name, val) \ 2035 do_fixup_by_path_u32(blob, path, name, val, 1); 2036 2037 offset = s->logo.offset + (u32)(unsigned long)s->logo.mem 2038 - memory_start; 2039 FDT_SET_U32("logo,offset", offset); 2040 FDT_SET_U32("logo,width", s->logo.width); 2041 FDT_SET_U32("logo,height", s->logo.height); 2042 FDT_SET_U32("logo,bpp", s->logo.bpp); 2043 FDT_SET_U32("logo,ymirror", s->logo.ymirror); 2044 FDT_SET_U32("video,clock", s->conn_state.mode.clock); 2045 FDT_SET_U32("video,hdisplay", s->conn_state.mode.hdisplay); 2046 FDT_SET_U32("video,vdisplay", s->conn_state.mode.vdisplay); 2047 FDT_SET_U32("video,crtc_hsync_end", s->conn_state.mode.crtc_hsync_end); 2048 FDT_SET_U32("video,crtc_vsync_end", s->conn_state.mode.crtc_vsync_end); 2049 FDT_SET_U32("video,vrefresh", 2050 drm_mode_vrefresh(&s->conn_state.mode)); 2051 FDT_SET_U32("video,flags", s->conn_state.mode.flags); 2052 FDT_SET_U32("video,aspect_ratio", s->conn_state.mode.picture_aspect_ratio); 2053 FDT_SET_U32("overscan,left_margin", s->conn_state.overscan.left_margin); 2054 FDT_SET_U32("overscan,right_margin", s->conn_state.overscan.right_margin); 2055 FDT_SET_U32("overscan,top_margin", s->conn_state.overscan.top_margin); 2056 FDT_SET_U32("overscan,bottom_margin", s->conn_state.overscan.bottom_margin); 2057 2058 if (s->conn_state.disp_info) { 2059 cacm_header = (const char*)&s->conn_state.disp_info->cacm_header; 2060 2061 FDT_SET_U32("bcsh,brightness", s->conn_state.disp_info->bcsh_info.brightness); 2062 FDT_SET_U32("bcsh,contrast", s->conn_state.disp_info->bcsh_info.contrast); 2063 FDT_SET_U32("bcsh,saturation", s->conn_state.disp_info->bcsh_info.saturation); 2064 FDT_SET_U32("bcsh,hue", s->conn_state.disp_info->bcsh_info.hue); 2065 2066 if (!strncasecmp(cacm_header, "CACM", 4)) { 2067 FDT_SET_U32("post_csc,hue", 2068 s->conn_state.disp_info->csc_info.hue); 2069 FDT_SET_U32("post_csc,saturation", 2070 s->conn_state.disp_info->csc_info.saturation); 2071 FDT_SET_U32("post_csc,contrast", 2072 s->conn_state.disp_info->csc_info.contrast); 2073 FDT_SET_U32("post_csc,brightness", 2074 s->conn_state.disp_info->csc_info.brightness); 2075 FDT_SET_U32("post_csc,r_gain", 2076 s->conn_state.disp_info->csc_info.r_gain); 2077 FDT_SET_U32("post_csc,g_gain", 2078 s->conn_state.disp_info->csc_info.g_gain); 2079 FDT_SET_U32("post_csc,b_gain", 2080 s->conn_state.disp_info->csc_info.b_gain); 2081 FDT_SET_U32("post_csc,r_offset", 2082 s->conn_state.disp_info->csc_info.r_offset); 2083 FDT_SET_U32("post_csc,g_offset", 2084 s->conn_state.disp_info->csc_info.g_offset); 2085 FDT_SET_U32("post_csc,b_offset", 2086 s->conn_state.disp_info->csc_info.b_offset); 2087 FDT_SET_U32("post_csc,csc_enable", 2088 s->conn_state.disp_info->csc_info.csc_enable); 2089 } 2090 } 2091 2092 if (s->conn_state.disp_info->cubic_lut_data.size && 2093 CONFIG_ROCKCHIP_CUBIC_LUT_SIZE) 2094 FDT_SET_U32("cubic_lut,offset", get_cubic_lut_offset(s->crtc_state.crtc_id)); 2095 2096 #undef FDT_SET_U32 2097 } 2098 } 2099 2100 int rockchip_display_bind(struct udevice *dev) 2101 { 2102 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 2103 2104 plat->size = DRM_ROCKCHIP_FB_SIZE + MEMORY_POOL_SIZE; 2105 2106 return 0; 2107 } 2108 2109 static const struct udevice_id rockchip_display_ids[] = { 2110 { .compatible = "rockchip,display-subsystem" }, 2111 { } 2112 }; 2113 2114 U_BOOT_DRIVER(rockchip_display) = { 2115 .name = "rockchip_display", 2116 .id = UCLASS_VIDEO, 2117 .of_match = rockchip_display_ids, 2118 .bind = rockchip_display_bind, 2119 .probe = rockchip_display_probe, 2120 }; 2121 2122 static int do_rockchip_logo_show(cmd_tbl_t *cmdtp, int flag, int argc, 2123 char *const argv[]) 2124 { 2125 if (argc != 1) 2126 return CMD_RET_USAGE; 2127 2128 rockchip_show_logo(); 2129 2130 return 0; 2131 } 2132 2133 static int do_rockchip_show_bmp(cmd_tbl_t *cmdtp, int flag, int argc, 2134 char *const argv[]) 2135 { 2136 if (argc != 2) 2137 return CMD_RET_USAGE; 2138 2139 rockchip_show_bmp(argv[1]); 2140 2141 return 0; 2142 } 2143 2144 static int do_rockchip_vop_dump(cmd_tbl_t *cmdtp, int flag, int argc, 2145 char *const argv[]) 2146 { 2147 int ret; 2148 2149 if (argc < 1 || argc > 2) 2150 return CMD_RET_USAGE; 2151 2152 ret = rockchip_vop_dump(argv[1]); 2153 2154 return ret; 2155 } 2156 2157 U_BOOT_CMD( 2158 rockchip_show_logo, 1, 1, do_rockchip_logo_show, 2159 "load and display log from resource partition", 2160 NULL 2161 ); 2162 2163 U_BOOT_CMD( 2164 rockchip_show_bmp, 2, 1, do_rockchip_show_bmp, 2165 "load and display bmp from resource partition", 2166 " <bmp_name>" 2167 ); 2168 2169 U_BOOT_CMD( 2170 vop_dump, 2, 1, do_rockchip_vop_dump, 2171 "dump vop regs", 2172 " [a/all]" 2173 ); 2174