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