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