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