| .. | .. |
|---|
| 57 | 57 | static unsigned long cubic_lut_memory_start; |
|---|
| 58 | 58 | static unsigned long memory_end; |
|---|
| 59 | 59 | static struct base2_info base_parameter; |
|---|
| 60 | | -static uint32_t crc32_table[256]; |
|---|
| 60 | +static u32 align_size = PAGE_SIZE; |
|---|
| 61 | 61 | |
|---|
| 62 | 62 | /* |
|---|
| 63 | 63 | * the phy types are used by different connectors in public. |
|---|
| .. | .. |
|---|
| 75 | 75 | int public_phy_type; |
|---|
| 76 | 76 | bool phy_init; |
|---|
| 77 | 77 | }; |
|---|
| 78 | | - |
|---|
| 79 | | -void rockchip_display_make_crc32_table(void) |
|---|
| 80 | | -{ |
|---|
| 81 | | - uint32_t c; |
|---|
| 82 | | - int n, k; |
|---|
| 83 | | - unsigned long poly; /* polynomial exclusive-or pattern */ |
|---|
| 84 | | - /* terms of polynomial defining this crc (except x^32): */ |
|---|
| 85 | | - static const char p[] = {0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26}; |
|---|
| 86 | | - |
|---|
| 87 | | - /* make exclusive-or pattern from polynomial (0xedb88320L) */ |
|---|
| 88 | | - poly = 0L; |
|---|
| 89 | | - for (n = 0; n < sizeof(p) / sizeof(char); n++) |
|---|
| 90 | | - poly |= 1L << (31 - p[n]); |
|---|
| 91 | | - |
|---|
| 92 | | - for (n = 0; n < 256; n++) { |
|---|
| 93 | | - c = (unsigned long)n; |
|---|
| 94 | | - for (k = 0; k < 8; k++) |
|---|
| 95 | | - c = c & 1 ? poly ^ (c >> 1) : c >> 1; |
|---|
| 96 | | - crc32_table[n] = cpu_to_le32(c); |
|---|
| 97 | | - } |
|---|
| 98 | | -} |
|---|
| 99 | | - |
|---|
| 100 | | -uint32_t rockchip_display_crc32c_cal(unsigned char *data, int length) |
|---|
| 101 | | -{ |
|---|
| 102 | | - int i; |
|---|
| 103 | | - uint32_t crc; |
|---|
| 104 | | - crc = 0xFFFFFFFF; |
|---|
| 105 | | - |
|---|
| 106 | | - for (i = 0; i < length; i++) { |
|---|
| 107 | | - crc = crc32_table[(crc ^ *data) & 0xff] ^ (crc >> 8); |
|---|
| 108 | | - data++; |
|---|
| 109 | | - } |
|---|
| 110 | | - |
|---|
| 111 | | - return crc ^ 0xffffffff; |
|---|
| 112 | | -} |
|---|
| 113 | 78 | |
|---|
| 114 | 79 | int rockchip_get_baseparameter(void) |
|---|
| 115 | 80 | { |
|---|
| .. | .. |
|---|
| 152 | 117 | struct base2_disp_header *disp_header; |
|---|
| 153 | 118 | int i = 0, offset = -1; |
|---|
| 154 | 119 | u32 crc_val; |
|---|
| 120 | + u32 base2_length; |
|---|
| 155 | 121 | void *base_parameter_addr = (void *)&base_parameter; |
|---|
| 156 | 122 | |
|---|
| 157 | 123 | for (i = 0; i < 8; i++) { |
|---|
| .. | .. |
|---|
| 178 | 144 | if (strncasecmp(disp_info->disp_head_flag, "DISP", 4)) |
|---|
| 179 | 145 | return NULL; |
|---|
| 180 | 146 | |
|---|
| 181 | | - crc_val = rockchip_display_crc32c_cal((unsigned char *)disp_info, sizeof(struct base2_disp_info) - 4); |
|---|
| 182 | | - |
|---|
| 183 | | - if (crc_val != disp_info->crc) { |
|---|
| 184 | | - printf("error: connector type[%d], id[%d] disp info crc check error\n", type, id); |
|---|
| 185 | | - return NULL; |
|---|
| 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 | + } |
|---|
| 186 | 164 | } |
|---|
| 187 | 165 | |
|---|
| 188 | 166 | return disp_info; |
|---|
| .. | .. |
|---|
| 253 | 231 | |
|---|
| 254 | 232 | static void init_display_buffer(ulong base) |
|---|
| 255 | 233 | { |
|---|
| 256 | | - memory_start = base + DRM_ROCKCHIP_FB_SIZE; |
|---|
| 234 | + memory_start = ALIGN(base + DRM_ROCKCHIP_FB_SIZE, align_size); |
|---|
| 257 | 235 | memory_end = memory_start; |
|---|
| 258 | | - cubic_lut_memory_start = memory_start + MEMORY_POOL_SIZE; |
|---|
| 236 | + cubic_lut_memory_start = ALIGN(memory_start + MEMORY_POOL_SIZE, align_size); |
|---|
| 259 | 237 | } |
|---|
| 260 | 238 | |
|---|
| 261 | 239 | void *get_display_buffer(int size) |
|---|
| .. | .. |
|---|
| 340 | 318 | return 0; |
|---|
| 341 | 319 | } |
|---|
| 342 | 320 | |
|---|
| 343 | | -int drm_mode_vrefresh(const struct drm_display_mode *mode) |
|---|
| 344 | | -{ |
|---|
| 345 | | - int refresh = 0; |
|---|
| 346 | | - unsigned int calc_val; |
|---|
| 347 | | - |
|---|
| 348 | | - if (mode->vrefresh > 0) { |
|---|
| 349 | | - refresh = mode->vrefresh; |
|---|
| 350 | | - } else if (mode->htotal > 0 && mode->vtotal > 0) { |
|---|
| 351 | | - int vtotal; |
|---|
| 352 | | - |
|---|
| 353 | | - vtotal = mode->vtotal; |
|---|
| 354 | | - /* work out vrefresh the value will be x1000 */ |
|---|
| 355 | | - calc_val = (mode->clock * 1000); |
|---|
| 356 | | - calc_val /= mode->htotal; |
|---|
| 357 | | - refresh = (calc_val + vtotal / 2) / vtotal; |
|---|
| 358 | | - |
|---|
| 359 | | - if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
|---|
| 360 | | - refresh *= 2; |
|---|
| 361 | | - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
|---|
| 362 | | - refresh /= 2; |
|---|
| 363 | | - if (mode->vscan > 1) |
|---|
| 364 | | - refresh /= mode->vscan; |
|---|
| 365 | | - } |
|---|
| 366 | | - return refresh; |
|---|
| 367 | | -} |
|---|
| 368 | | - |
|---|
| 369 | | -int rockchip_ofnode_get_display_mode(ofnode node, struct drm_display_mode *mode) |
|---|
| 321 | +int rockchip_ofnode_get_display_mode(ofnode node, struct drm_display_mode *mode, u32 *bus_flags) |
|---|
| 370 | 322 | { |
|---|
| 371 | 323 | int hactive, vactive, pixelclock; |
|---|
| 372 | 324 | int hfront_porch, hback_porch, hsync_len; |
|---|
| 373 | 325 | int vfront_porch, vback_porch, vsync_len; |
|---|
| 374 | 326 | int val, flags = 0; |
|---|
| 327 | + |
|---|
| 328 | +#define FDT_GET_BOOL(val, name) \ |
|---|
| 329 | + val = ofnode_read_bool(node, name); |
|---|
| 375 | 330 | |
|---|
| 376 | 331 | #define FDT_GET_INT(val, name) \ |
|---|
| 377 | 332 | val = ofnode_read_s32_default(node, name, -1); \ |
|---|
| .. | .. |
|---|
| 396 | 351 | flags |= val ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; |
|---|
| 397 | 352 | FDT_GET_INT(val, "vsync-active"); |
|---|
| 398 | 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; |
|---|
| 399 | 364 | FDT_GET_INT(val, "pixelclk-active"); |
|---|
| 400 | | - flags |= val ? DRM_MODE_FLAG_PPIXDATA : 0; |
|---|
| 365 | + *bus_flags |= val ? DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE : DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE; |
|---|
| 401 | 366 | |
|---|
| 402 | 367 | FDT_GET_INT_DEFAULT(val, "screen-rotate", 0); |
|---|
| 403 | 368 | if (val == DRM_MODE_FLAG_XMIRROR) { |
|---|
| .. | .. |
|---|
| 425 | 390 | return 0; |
|---|
| 426 | 391 | } |
|---|
| 427 | 392 | |
|---|
| 428 | | -static int display_get_force_timing_from_dts(ofnode node, struct drm_display_mode *mode) |
|---|
| 393 | +static int display_get_force_timing_from_dts(ofnode node, |
|---|
| 394 | + struct drm_display_mode *mode, |
|---|
| 395 | + u32 *bus_flags) |
|---|
| 429 | 396 | { |
|---|
| 430 | 397 | int ret = 0; |
|---|
| 431 | 398 | |
|---|
| 432 | | - ret = rockchip_ofnode_get_display_mode(node, mode); |
|---|
| 399 | + ret = rockchip_ofnode_get_display_mode(node, mode, bus_flags); |
|---|
| 433 | 400 | |
|---|
| 434 | 401 | if (ret) { |
|---|
| 435 | 402 | mode->clock = 74250; |
|---|
| .. | .. |
|---|
| 456 | 423 | } |
|---|
| 457 | 424 | |
|---|
| 458 | 425 | static int display_get_timing_from_dts(struct rockchip_panel *panel, |
|---|
| 459 | | - struct drm_display_mode *mode) |
|---|
| 426 | + struct drm_display_mode *mode, |
|---|
| 427 | + u32 *bus_flags) |
|---|
| 460 | 428 | { |
|---|
| 461 | 429 | struct ofnode_phandle_args args; |
|---|
| 462 | | - ofnode dt, timing; |
|---|
| 430 | + ofnode dt, timing, mcu_panel; |
|---|
| 463 | 431 | int ret; |
|---|
| 464 | 432 | |
|---|
| 433 | + mcu_panel = dev_read_subnode(panel->dev, "mcu-panel"); |
|---|
| 465 | 434 | dt = dev_read_subnode(panel->dev, "display-timings"); |
|---|
| 466 | 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"); |
|---|
| 467 | 444 | ret = ofnode_parse_phandle_with_args(dt, "native-mode", NULL, |
|---|
| 468 | 445 | 0, 0, &args); |
|---|
| 469 | 446 | if (ret) |
|---|
| .. | .. |
|---|
| 479 | 456 | return -ENXIO; |
|---|
| 480 | 457 | } |
|---|
| 481 | 458 | |
|---|
| 482 | | - rockchip_ofnode_get_display_mode(timing, mode); |
|---|
| 459 | + rockchip_ofnode_get_display_mode(timing, mode, bus_flags); |
|---|
| 460 | + |
|---|
| 461 | + if (IS_ENABLED(CONFIG_ROCKCHIP_RK3568) || IS_ENABLED(CONFIG_ROCKCHIP_RK3588)) { |
|---|
| 462 | + if (mode->hdisplay % 4) { |
|---|
| 463 | + int old_hdisplay = mode->hdisplay; |
|---|
| 464 | + int align = 4 - (mode->hdisplay % 4); |
|---|
| 465 | + |
|---|
| 466 | + mode->hdisplay += align; |
|---|
| 467 | + mode->hsync_start += align; |
|---|
| 468 | + mode->hsync_end += align; |
|---|
| 469 | + mode->htotal += align; |
|---|
| 470 | + |
|---|
| 471 | + ofnode_write_u32_array(timing, "hactive", (u32 *)&mode->hdisplay, 1); |
|---|
| 472 | + |
|---|
| 473 | + printf("WARN: hactive need to be aligned with 4-pixel, %d -> %d\n", |
|---|
| 474 | + old_hdisplay, mode->hdisplay); |
|---|
| 475 | + } |
|---|
| 476 | + } |
|---|
| 483 | 477 | |
|---|
| 484 | 478 | return 0; |
|---|
| 485 | | -} |
|---|
| 486 | | - |
|---|
| 487 | | -/** |
|---|
| 488 | | - * drm_mode_max_resolution_filter - mark modes out of vop max resolution |
|---|
| 489 | | - * @edid_data: structure store mode list |
|---|
| 490 | | - * @max_output: vop max output resolution |
|---|
| 491 | | - */ |
|---|
| 492 | | -void drm_mode_max_resolution_filter(struct hdmi_edid_data *edid_data, |
|---|
| 493 | | - struct vop_rect *max_output) |
|---|
| 494 | | -{ |
|---|
| 495 | | - int i; |
|---|
| 496 | | - |
|---|
| 497 | | - for (i = 0; i < edid_data->modes; i++) { |
|---|
| 498 | | - if (edid_data->mode_buf[i].hdisplay > max_output->width || |
|---|
| 499 | | - edid_data->mode_buf[i].vdisplay > max_output->height) |
|---|
| 500 | | - edid_data->mode_buf[i].invalid = true; |
|---|
| 501 | | - } |
|---|
| 502 | | -} |
|---|
| 503 | | - |
|---|
| 504 | | -/** |
|---|
| 505 | | - * drm_mode_set_crtcinfo - set CRTC modesetting timing parameters |
|---|
| 506 | | - * @p: mode |
|---|
| 507 | | - * @adjust_flags: a combination of adjustment flags |
|---|
| 508 | | - * |
|---|
| 509 | | - * Setup the CRTC modesetting timing parameters for @p, adjusting if necessary. |
|---|
| 510 | | - * |
|---|
| 511 | | - * - The CRTC_INTERLACE_HALVE_V flag can be used to halve vertical timings of |
|---|
| 512 | | - * interlaced modes. |
|---|
| 513 | | - * - The CRTC_STEREO_DOUBLE flag can be used to compute the timings for |
|---|
| 514 | | - * buffers containing two eyes (only adjust the timings when needed, eg. for |
|---|
| 515 | | - * "frame packing" or "side by side full"). |
|---|
| 516 | | - * - The CRTC_NO_DBLSCAN and CRTC_NO_VSCAN flags request that adjustment *not* |
|---|
| 517 | | - * be performed for doublescan and vscan > 1 modes respectively. |
|---|
| 518 | | - */ |
|---|
| 519 | | -void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) |
|---|
| 520 | | -{ |
|---|
| 521 | | - if ((p == NULL) || ((p->type & DRM_MODE_TYPE_CRTC_C) == DRM_MODE_TYPE_BUILTIN)) |
|---|
| 522 | | - return; |
|---|
| 523 | | - |
|---|
| 524 | | - if (p->flags & DRM_MODE_FLAG_DBLCLK) |
|---|
| 525 | | - p->crtc_clock = 2 * p->clock; |
|---|
| 526 | | - else |
|---|
| 527 | | - p->crtc_clock = p->clock; |
|---|
| 528 | | - p->crtc_hdisplay = p->hdisplay; |
|---|
| 529 | | - p->crtc_hsync_start = p->hsync_start; |
|---|
| 530 | | - p->crtc_hsync_end = p->hsync_end; |
|---|
| 531 | | - p->crtc_htotal = p->htotal; |
|---|
| 532 | | - p->crtc_hskew = p->hskew; |
|---|
| 533 | | - p->crtc_vdisplay = p->vdisplay; |
|---|
| 534 | | - p->crtc_vsync_start = p->vsync_start; |
|---|
| 535 | | - p->crtc_vsync_end = p->vsync_end; |
|---|
| 536 | | - p->crtc_vtotal = p->vtotal; |
|---|
| 537 | | - |
|---|
| 538 | | - if (p->flags & DRM_MODE_FLAG_INTERLACE) { |
|---|
| 539 | | - if (adjust_flags & CRTC_INTERLACE_HALVE_V) { |
|---|
| 540 | | - p->crtc_vdisplay /= 2; |
|---|
| 541 | | - p->crtc_vsync_start /= 2; |
|---|
| 542 | | - p->crtc_vsync_end /= 2; |
|---|
| 543 | | - p->crtc_vtotal /= 2; |
|---|
| 544 | | - } |
|---|
| 545 | | - } |
|---|
| 546 | | - |
|---|
| 547 | | - if (!(adjust_flags & CRTC_NO_DBLSCAN)) { |
|---|
| 548 | | - if (p->flags & DRM_MODE_FLAG_DBLSCAN) { |
|---|
| 549 | | - p->crtc_vdisplay *= 2; |
|---|
| 550 | | - p->crtc_vsync_start *= 2; |
|---|
| 551 | | - p->crtc_vsync_end *= 2; |
|---|
| 552 | | - p->crtc_vtotal *= 2; |
|---|
| 553 | | - } |
|---|
| 554 | | - } |
|---|
| 555 | | - |
|---|
| 556 | | - if (!(adjust_flags & CRTC_NO_VSCAN)) { |
|---|
| 557 | | - if (p->vscan > 1) { |
|---|
| 558 | | - p->crtc_vdisplay *= p->vscan; |
|---|
| 559 | | - p->crtc_vsync_start *= p->vscan; |
|---|
| 560 | | - p->crtc_vsync_end *= p->vscan; |
|---|
| 561 | | - p->crtc_vtotal *= p->vscan; |
|---|
| 562 | | - } |
|---|
| 563 | | - } |
|---|
| 564 | | - |
|---|
| 565 | | - if (adjust_flags & CRTC_STEREO_DOUBLE) { |
|---|
| 566 | | - unsigned int layout = p->flags & DRM_MODE_FLAG_3D_MASK; |
|---|
| 567 | | - |
|---|
| 568 | | - switch (layout) { |
|---|
| 569 | | - case DRM_MODE_FLAG_3D_FRAME_PACKING: |
|---|
| 570 | | - p->crtc_clock *= 2; |
|---|
| 571 | | - p->crtc_vdisplay += p->crtc_vtotal; |
|---|
| 572 | | - p->crtc_vsync_start += p->crtc_vtotal; |
|---|
| 573 | | - p->crtc_vsync_end += p->crtc_vtotal; |
|---|
| 574 | | - p->crtc_vtotal += p->crtc_vtotal; |
|---|
| 575 | | - break; |
|---|
| 576 | | - } |
|---|
| 577 | | - } |
|---|
| 578 | | - |
|---|
| 579 | | - p->crtc_vblank_start = min(p->crtc_vsync_start, p->crtc_vdisplay); |
|---|
| 580 | | - p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal); |
|---|
| 581 | | - p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay); |
|---|
| 582 | | - p->crtc_hblank_end = max(p->crtc_hsync_end, p->crtc_htotal); |
|---|
| 583 | | -} |
|---|
| 584 | | - |
|---|
| 585 | | -/** |
|---|
| 586 | | - * drm_mode_is_420_only - if a given videomode can be only supported in YCBCR420 |
|---|
| 587 | | - * output format |
|---|
| 588 | | - * |
|---|
| 589 | | - * @connector: drm connector under action. |
|---|
| 590 | | - * @mode: video mode to be tested. |
|---|
| 591 | | - * |
|---|
| 592 | | - * Returns: |
|---|
| 593 | | - * true if the mode can be supported in YCBCR420 format |
|---|
| 594 | | - * false if not. |
|---|
| 595 | | - */ |
|---|
| 596 | | -bool drm_mode_is_420_only(const struct drm_display_info *display, |
|---|
| 597 | | - struct drm_display_mode *mode) |
|---|
| 598 | | -{ |
|---|
| 599 | | - u8 vic = drm_match_cea_mode(mode); |
|---|
| 600 | | - |
|---|
| 601 | | - return test_bit(vic, display->hdmi.y420_vdb_modes); |
|---|
| 602 | | -} |
|---|
| 603 | | - |
|---|
| 604 | | -/** |
|---|
| 605 | | - * drm_mode_is_420_also - if a given videomode can be supported in YCBCR420 |
|---|
| 606 | | - * output format also (along with RGB/YCBCR444/422) |
|---|
| 607 | | - * |
|---|
| 608 | | - * @display: display under action. |
|---|
| 609 | | - * @mode: video mode to be tested. |
|---|
| 610 | | - * |
|---|
| 611 | | - * Returns: |
|---|
| 612 | | - * true if the mode can be support YCBCR420 format |
|---|
| 613 | | - * false if not. |
|---|
| 614 | | - */ |
|---|
| 615 | | -bool drm_mode_is_420_also(const struct drm_display_info *display, |
|---|
| 616 | | - struct drm_display_mode *mode) |
|---|
| 617 | | -{ |
|---|
| 618 | | - u8 vic = drm_match_cea_mode(mode); |
|---|
| 619 | | - |
|---|
| 620 | | - return test_bit(vic, display->hdmi.y420_cmdb_modes); |
|---|
| 621 | | -} |
|---|
| 622 | | - |
|---|
| 623 | | -/** |
|---|
| 624 | | - * drm_mode_is_420 - if a given videomode can be supported in YCBCR420 |
|---|
| 625 | | - * output format |
|---|
| 626 | | - * |
|---|
| 627 | | - * @display: display under action. |
|---|
| 628 | | - * @mode: video mode to be tested. |
|---|
| 629 | | - * |
|---|
| 630 | | - * Returns: |
|---|
| 631 | | - * true if the mode can be supported in YCBCR420 format |
|---|
| 632 | | - * false if not. |
|---|
| 633 | | - */ |
|---|
| 634 | | -bool drm_mode_is_420(const struct drm_display_info *display, |
|---|
| 635 | | - struct drm_display_mode *mode) |
|---|
| 636 | | -{ |
|---|
| 637 | | - return drm_mode_is_420_only(display, mode) || |
|---|
| 638 | | - drm_mode_is_420_also(display, mode); |
|---|
| 639 | 479 | } |
|---|
| 640 | 480 | |
|---|
| 641 | 481 | static int display_get_timing(struct display_state *state) |
|---|
| .. | .. |
|---|
| 649 | 489 | return panel->funcs->get_mode(panel, mode); |
|---|
| 650 | 490 | |
|---|
| 651 | 491 | if (dev_of_valid(panel->dev) && |
|---|
| 652 | | - !display_get_timing_from_dts(panel, mode)) { |
|---|
| 492 | + !display_get_timing_from_dts(panel, mode, &conn_state->bus_flags)) { |
|---|
| 653 | 493 | printf("Using display timing dts\n"); |
|---|
| 654 | 494 | return 0; |
|---|
| 655 | 495 | } |
|---|
| .. | .. |
|---|
| 730 | 570 | return ret; |
|---|
| 731 | 571 | } |
|---|
| 732 | 572 | |
|---|
| 573 | +static int display_mode_valid(struct display_state *state) |
|---|
| 574 | +{ |
|---|
| 575 | + struct connector_state *conn_state = &state->conn_state; |
|---|
| 576 | + struct rockchip_connector *conn = conn_state->connector; |
|---|
| 577 | + const struct rockchip_connector_funcs *conn_funcs = conn->funcs; |
|---|
| 578 | + struct crtc_state *crtc_state = &state->crtc_state; |
|---|
| 579 | + const struct rockchip_crtc *crtc = crtc_state->crtc; |
|---|
| 580 | + const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; |
|---|
| 581 | + int ret; |
|---|
| 582 | + |
|---|
| 583 | + if (conn_funcs->mode_valid && state->enabled_at_spl == false) { |
|---|
| 584 | + ret = conn_funcs->mode_valid(conn, state); |
|---|
| 585 | + if (ret) |
|---|
| 586 | + return ret; |
|---|
| 587 | + } |
|---|
| 588 | + |
|---|
| 589 | + if (crtc_funcs->mode_valid) { |
|---|
| 590 | + ret = crtc_funcs->mode_valid(state); |
|---|
| 591 | + if (ret) |
|---|
| 592 | + return ret; |
|---|
| 593 | + } |
|---|
| 594 | + |
|---|
| 595 | + return 0; |
|---|
| 596 | +} |
|---|
| 597 | + |
|---|
| 598 | +static int display_mode_fixup(struct display_state *state) |
|---|
| 599 | +{ |
|---|
| 600 | + struct crtc_state *crtc_state = &state->crtc_state; |
|---|
| 601 | + const struct rockchip_crtc *crtc = crtc_state->crtc; |
|---|
| 602 | + const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; |
|---|
| 603 | + int ret; |
|---|
| 604 | + |
|---|
| 605 | + if (crtc_funcs->mode_fixup) { |
|---|
| 606 | + ret = crtc_funcs->mode_fixup(state); |
|---|
| 607 | + if (ret) |
|---|
| 608 | + return ret; |
|---|
| 609 | + } |
|---|
| 610 | + |
|---|
| 611 | + return 0; |
|---|
| 612 | +} |
|---|
| 613 | + |
|---|
| 733 | 614 | static int display_init(struct display_state *state) |
|---|
| 734 | 615 | { |
|---|
| 735 | 616 | struct connector_state *conn_state = &state->conn_state; |
|---|
| .. | .. |
|---|
| 741 | 622 | const char *compatible; |
|---|
| 742 | 623 | int ret = 0; |
|---|
| 743 | 624 | static bool __print_once = false; |
|---|
| 744 | | - |
|---|
| 625 | +#ifdef CONFIG_SPL_BUILD |
|---|
| 626 | + struct spl_display_info *spl_disp_info = (struct spl_display_info *)CONFIG_SPL_VIDEO_BUF; |
|---|
| 627 | +#endif |
|---|
| 745 | 628 | if (!__print_once) { |
|---|
| 746 | 629 | __print_once = true; |
|---|
| 747 | 630 | printf("Rockchip UBOOT DRM driver version: %s\n", DRIVER_VERSION); |
|---|
| .. | .. |
|---|
| 755 | 638 | return -ENXIO; |
|---|
| 756 | 639 | } |
|---|
| 757 | 640 | |
|---|
| 641 | +#ifdef CONFIG_SPL_BUILD |
|---|
| 642 | + if (state->conn_state.type == DRM_MODE_CONNECTOR_HDMIA) |
|---|
| 643 | + state->enabled_at_spl = spl_disp_info->enabled == 1 ? true : false; |
|---|
| 644 | + if (state->enabled_at_spl) |
|---|
| 645 | + printf("HDMI enabled at SPL\n"); |
|---|
| 646 | +#endif |
|---|
| 758 | 647 | if (crtc_state->crtc->active && !crtc_state->ports_node && |
|---|
| 759 | 648 | memcmp(&crtc_state->crtc->active_mode, &conn_state->mode, |
|---|
| 760 | 649 | sizeof(struct drm_display_mode))) { |
|---|
| .. | .. |
|---|
| 773 | 662 | return ret; |
|---|
| 774 | 663 | } |
|---|
| 775 | 664 | |
|---|
| 776 | | - ret = rockchip_connector_init(state); |
|---|
| 777 | | - if (ret) |
|---|
| 778 | | - goto deinit; |
|---|
| 665 | + if (state->enabled_at_spl == false) { |
|---|
| 666 | + ret = rockchip_connector_init(state); |
|---|
| 667 | + if (ret) |
|---|
| 668 | + goto deinit; |
|---|
| 669 | + } |
|---|
| 779 | 670 | |
|---|
| 780 | 671 | /* |
|---|
| 781 | 672 | * support hotplug, but not connect; |
|---|
| 782 | 673 | */ |
|---|
| 783 | | -#ifdef CONFIG_ROCKCHIP_DRM_TVE |
|---|
| 674 | +#ifdef CONFIG_DRM_ROCKCHIP_TVE |
|---|
| 784 | 675 | if (crtc->hdmi_hpd && conn_state->type == DRM_MODE_CONNECTOR_TV) { |
|---|
| 785 | 676 | printf("hdmi plugin ,skip tve\n"); |
|---|
| 786 | 677 | goto deinit; |
|---|
| .. | .. |
|---|
| 793 | 684 | #endif |
|---|
| 794 | 685 | |
|---|
| 795 | 686 | ret = rockchip_connector_detect(state); |
|---|
| 796 | | -#if defined(CONFIG_ROCKCHIP_DRM_TVE) || defined(CONFIG_DRM_ROCKCHIP_RK1000) |
|---|
| 687 | +#if defined(CONFIG_DRM_ROCKCHIP_TVE) || defined(CONFIG_DRM_ROCKCHIP_RK1000) |
|---|
| 797 | 688 | if (conn_state->type == DRM_MODE_CONNECTOR_HDMIA) |
|---|
| 798 | 689 | crtc->hdmi_hpd = ret; |
|---|
| 690 | + if (state->enabled_at_spl) |
|---|
| 691 | + crtc->hdmi_hpd = true; |
|---|
| 799 | 692 | #endif |
|---|
| 800 | 693 | if (!ret && !state->force_output) |
|---|
| 801 | 694 | goto deinit; |
|---|
| 802 | 695 | |
|---|
| 803 | | - if (conn->panel) { |
|---|
| 696 | + ret = 0; |
|---|
| 697 | + if (state->enabled_at_spl == true) { |
|---|
| 698 | +#ifdef CONFIG_SPL_BUILD |
|---|
| 699 | + struct drm_display_mode *mode = &conn_state->mode; |
|---|
| 700 | + |
|---|
| 701 | + memcpy(mode, &spl_disp_info->mode, sizeof(*mode)); |
|---|
| 702 | + conn_state->bus_format = spl_disp_info->bus_format; |
|---|
| 703 | + |
|---|
| 704 | + printf("%s get display mode from spl:%dx%d, bus format:0x%x\n", |
|---|
| 705 | + conn->dev->name, mode->hdisplay, mode->vdisplay, conn_state->bus_format); |
|---|
| 706 | +#endif |
|---|
| 707 | + } else if (conn->panel) { |
|---|
| 804 | 708 | ret = display_get_timing(state); |
|---|
| 805 | 709 | if (!ret) |
|---|
| 806 | 710 | conn_state->bpc = conn->panel->bpc; |
|---|
| .. | .. |
|---|
| 853 | 757 | if (state->force_output) |
|---|
| 854 | 758 | display_use_force_mode(state); |
|---|
| 855 | 759 | |
|---|
| 760 | + if (display_mode_valid(state)) |
|---|
| 761 | + goto deinit; |
|---|
| 762 | + |
|---|
| 856 | 763 | /* rk356x series drive mipi pixdata on posedge */ |
|---|
| 857 | 764 | compatible = dev_read_string(conn->dev, "compatible"); |
|---|
| 858 | | - if (!strcmp(compatible, "rockchip,rk3568-mipi-dsi")) |
|---|
| 859 | | - conn_state->mode.flags |= DRM_MODE_FLAG_PPIXDATA; |
|---|
| 765 | + if (!strcmp(compatible, "rockchip,rk3568-mipi-dsi")) { |
|---|
| 766 | + conn_state->bus_flags &= ~DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE; |
|---|
| 767 | + conn_state->bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE; |
|---|
| 768 | + } |
|---|
| 860 | 769 | |
|---|
| 861 | 770 | printf("%s: %s detailed mode clock %u kHz, flags[%x]\n" |
|---|
| 862 | 771 | " H: %04d %04d %04d %04d\n" |
|---|
| .. | .. |
|---|
| 871 | 780 | mode->vsync_end, mode->vtotal, |
|---|
| 872 | 781 | conn_state->bus_format); |
|---|
| 873 | 782 | |
|---|
| 874 | | - drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); |
|---|
| 875 | | - |
|---|
| 876 | | - if (conn_state->secondary) { |
|---|
| 877 | | - mode->crtc_clock *= 2; |
|---|
| 878 | | - mode->crtc_hdisplay *= 2; |
|---|
| 879 | | - mode->crtc_hsync_start *= 2; |
|---|
| 880 | | - mode->crtc_hsync_end *= 2; |
|---|
| 881 | | - mode->crtc_htotal *= 2; |
|---|
| 882 | | - } |
|---|
| 783 | + if (display_mode_fixup(state)) |
|---|
| 784 | + goto deinit; |
|---|
| 883 | 785 | |
|---|
| 884 | 786 | if (conn->bridge) |
|---|
| 885 | 787 | rockchip_bridge_mode_set(conn->bridge, &conn_state->mode); |
|---|
| 886 | 788 | |
|---|
| 887 | | - if (crtc_funcs->init) { |
|---|
| 789 | + if (crtc_funcs->init && state->enabled_at_spl == false) { |
|---|
| 888 | 790 | ret = crtc_funcs->init(state); |
|---|
| 889 | 791 | if (ret) |
|---|
| 890 | 792 | goto deinit; |
|---|
| .. | .. |
|---|
| 955 | 857 | if (crtc_funcs->prepare) |
|---|
| 956 | 858 | crtc_funcs->prepare(state); |
|---|
| 957 | 859 | |
|---|
| 958 | | - rockchip_connector_pre_enable(state); |
|---|
| 860 | + if (state->enabled_at_spl == false) |
|---|
| 861 | + rockchip_connector_pre_enable(state); |
|---|
| 959 | 862 | |
|---|
| 960 | 863 | if (crtc_funcs->enable) |
|---|
| 961 | 864 | crtc_funcs->enable(state); |
|---|
| 962 | 865 | |
|---|
| 963 | | - rockchip_connector_enable(state); |
|---|
| 866 | + if (state->enabled_at_spl == false) |
|---|
| 867 | + rockchip_connector_enable(state); |
|---|
| 868 | + |
|---|
| 869 | + if (crtc_state->soft_te) |
|---|
| 870 | + crtc_funcs->apply_soft_te(state); |
|---|
| 964 | 871 | |
|---|
| 965 | 872 | state->is_enable = true; |
|---|
| 966 | 873 | |
|---|
| .. | .. |
|---|
| 990 | 897 | state->is_init = 0; |
|---|
| 991 | 898 | |
|---|
| 992 | 899 | return 0; |
|---|
| 993 | | -} |
|---|
| 994 | | - |
|---|
| 995 | | -static int display_rect_calc_scale(int src, int dst) |
|---|
| 996 | | -{ |
|---|
| 997 | | - int scale = 0; |
|---|
| 998 | | - |
|---|
| 999 | | - if (WARN_ON(src < 0 || dst < 0)) |
|---|
| 1000 | | - return -EINVAL; |
|---|
| 1001 | | - |
|---|
| 1002 | | - if (dst == 0) |
|---|
| 1003 | | - return 0; |
|---|
| 1004 | | - |
|---|
| 1005 | | - src <<= 16; |
|---|
| 1006 | | - |
|---|
| 1007 | | - if (src > (dst << 16)) |
|---|
| 1008 | | - return DIV_ROUND_UP(src, dst); |
|---|
| 1009 | | - else |
|---|
| 1010 | | - scale = src / dst; |
|---|
| 1011 | | - |
|---|
| 1012 | | - return scale; |
|---|
| 1013 | | -} |
|---|
| 1014 | | - |
|---|
| 1015 | | -int display_rect_calc_hscale(struct display_rect *src, struct display_rect *dst, |
|---|
| 1016 | | - int min_hscale, int max_hscale) |
|---|
| 1017 | | -{ |
|---|
| 1018 | | - int hscale = display_rect_calc_scale(src->w, dst->w); |
|---|
| 1019 | | - |
|---|
| 1020 | | - if (hscale < 0 || dst->w == 0) |
|---|
| 1021 | | - return hscale; |
|---|
| 1022 | | - |
|---|
| 1023 | | - if (hscale < min_hscale || hscale > max_hscale) |
|---|
| 1024 | | - return -ERANGE; |
|---|
| 1025 | | - |
|---|
| 1026 | | - return hscale; |
|---|
| 1027 | | -} |
|---|
| 1028 | | - |
|---|
| 1029 | | -int display_rect_calc_vscale(struct display_rect *src, struct display_rect *dst, |
|---|
| 1030 | | - int min_vscale, int max_vscale) |
|---|
| 1031 | | -{ |
|---|
| 1032 | | - int vscale = display_rect_calc_scale(src->h, dst->h); |
|---|
| 1033 | | - |
|---|
| 1034 | | - if (vscale < 0 || dst->h == 0) |
|---|
| 1035 | | - return vscale; |
|---|
| 1036 | | - |
|---|
| 1037 | | - if (vscale < min_vscale || vscale > max_vscale) |
|---|
| 1038 | | - return -ERANGE; |
|---|
| 1039 | | - |
|---|
| 1040 | | - return vscale; |
|---|
| 1041 | 900 | } |
|---|
| 1042 | 901 | |
|---|
| 1043 | 902 | static int display_check(struct display_state *state) |
|---|
| .. | .. |
|---|
| 1074 | 933 | return 0; |
|---|
| 1075 | 934 | |
|---|
| 1076 | 935 | check_fail: |
|---|
| 1077 | | - state->is_init = false; |
|---|
| 1078 | | - return ret; |
|---|
| 1079 | | -} |
|---|
| 1080 | | - |
|---|
| 1081 | | -static int display_mode_valid(struct display_state *state) |
|---|
| 1082 | | -{ |
|---|
| 1083 | | - struct connector_state *conn_state = &state->conn_state; |
|---|
| 1084 | | - struct rockchip_connector *conn = conn_state->connector; |
|---|
| 1085 | | - const struct rockchip_connector_funcs *conn_funcs = conn->funcs; |
|---|
| 1086 | | - struct crtc_state *crtc_state = &state->crtc_state; |
|---|
| 1087 | | - const struct rockchip_crtc *crtc = crtc_state->crtc; |
|---|
| 1088 | | - const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs; |
|---|
| 1089 | | - int ret; |
|---|
| 1090 | | - |
|---|
| 1091 | | - if (!state->is_init) |
|---|
| 1092 | | - return 0; |
|---|
| 1093 | | - |
|---|
| 1094 | | - if (conn_funcs->mode_valid) { |
|---|
| 1095 | | - ret = conn_funcs->mode_valid(conn, state); |
|---|
| 1096 | | - if (ret) |
|---|
| 1097 | | - goto invalid_mode; |
|---|
| 1098 | | - } |
|---|
| 1099 | | - |
|---|
| 1100 | | - if (crtc_funcs->mode_valid) { |
|---|
| 1101 | | - ret = crtc_funcs->mode_valid(state); |
|---|
| 1102 | | - if (ret) |
|---|
| 1103 | | - goto invalid_mode; |
|---|
| 1104 | | - } |
|---|
| 1105 | | - |
|---|
| 1106 | | - return 0; |
|---|
| 1107 | | - |
|---|
| 1108 | | -invalid_mode: |
|---|
| 1109 | 936 | state->is_init = false; |
|---|
| 1110 | 937 | return ret; |
|---|
| 1111 | 938 | } |
|---|
| .. | .. |
|---|
| 1170 | 997 | } |
|---|
| 1171 | 998 | } |
|---|
| 1172 | 999 | |
|---|
| 1173 | | - display_mode_valid(state); |
|---|
| 1174 | 1000 | display_check(state); |
|---|
| 1175 | 1001 | display_set_plane(state); |
|---|
| 1176 | 1002 | display_enable(state); |
|---|
| .. | .. |
|---|
| 1213 | 1039 | return 0; |
|---|
| 1214 | 1040 | } |
|---|
| 1215 | 1041 | |
|---|
| 1216 | | -static int get_crtc_mcu_mode(struct crtc_state *crtc_state) |
|---|
| 1042 | +static int get_crtc_mcu_mode(struct crtc_state *crtc_state, struct device_node *port_node, |
|---|
| 1043 | + bool is_ports_node) |
|---|
| 1217 | 1044 | { |
|---|
| 1218 | | - ofnode mcu_node; |
|---|
| 1045 | + ofnode mcu_node, vp_node; |
|---|
| 1219 | 1046 | int total_pixel, cs_pst, cs_pend, rw_pst, rw_pend; |
|---|
| 1220 | 1047 | |
|---|
| 1221 | | - mcu_node = dev_read_subnode(crtc_state->dev, "mcu-timing"); |
|---|
| 1222 | | - if (!ofnode_valid(mcu_node)) |
|---|
| 1223 | | - return -ENODEV; |
|---|
| 1048 | + if (is_ports_node) { |
|---|
| 1049 | + vp_node = np_to_ofnode(port_node); |
|---|
| 1050 | + mcu_node = ofnode_find_subnode(vp_node, "mcu-timing"); |
|---|
| 1051 | + if (!ofnode_valid(mcu_node)) |
|---|
| 1052 | + return -ENODEV; |
|---|
| 1053 | + } else { |
|---|
| 1054 | + mcu_node = dev_read_subnode(crtc_state->dev, "mcu-timing"); |
|---|
| 1055 | + if (!ofnode_valid(mcu_node)) |
|---|
| 1056 | + return -ENODEV; |
|---|
| 1057 | + } |
|---|
| 1224 | 1058 | |
|---|
| 1225 | 1059 | #define FDT_GET_MCU_INT(val, name) \ |
|---|
| 1226 | 1060 | do { \ |
|---|
| .. | .. |
|---|
| 1464 | 1298 | return ret; |
|---|
| 1465 | 1299 | } |
|---|
| 1466 | 1300 | |
|---|
| 1301 | +int rockchip_vop_dump(const char *cmd) |
|---|
| 1302 | +{ |
|---|
| 1303 | + struct display_state *state; |
|---|
| 1304 | + struct crtc_state *crtc_state; |
|---|
| 1305 | + struct rockchip_crtc *crtc; |
|---|
| 1306 | + const struct rockchip_crtc_funcs *crtc_funcs; |
|---|
| 1307 | + int ret = -EINVAL; |
|---|
| 1308 | + |
|---|
| 1309 | + list_for_each_entry(state, &rockchip_display_list, head) { |
|---|
| 1310 | + if (!state->is_init) |
|---|
| 1311 | + continue; |
|---|
| 1312 | + crtc_state = &state->crtc_state; |
|---|
| 1313 | + crtc = crtc_state->crtc; |
|---|
| 1314 | + crtc_funcs = crtc->funcs; |
|---|
| 1315 | + |
|---|
| 1316 | + if (!cmd) |
|---|
| 1317 | + ret = crtc_funcs->active_regs_dump(state); |
|---|
| 1318 | + else if (!strcmp(cmd, "a") || !strcmp(cmd, "all")) |
|---|
| 1319 | + ret = crtc_funcs->regs_dump(state); |
|---|
| 1320 | + if (!ret) |
|---|
| 1321 | + break; |
|---|
| 1322 | + } |
|---|
| 1323 | + |
|---|
| 1324 | + if (ret) |
|---|
| 1325 | + ret = CMD_RET_USAGE; |
|---|
| 1326 | + |
|---|
| 1327 | + return ret; |
|---|
| 1328 | +} |
|---|
| 1329 | + |
|---|
| 1467 | 1330 | enum { |
|---|
| 1468 | 1331 | PORT_DIR_IN, |
|---|
| 1469 | 1332 | PORT_DIR_OUT, |
|---|
| .. | .. |
|---|
| 1505 | 1368 | return ofnode_to_np(parent); |
|---|
| 1506 | 1369 | } |
|---|
| 1507 | 1370 | |
|---|
| 1508 | | -static const struct device_node *rockchip_of_graph_get_remote_node(ofnode node, int port, |
|---|
| 1509 | | - int endpoint) |
|---|
| 1371 | +const struct device_node * |
|---|
| 1372 | +rockchip_of_graph_get_endpoint_by_regs(ofnode node, int port, int endpoint) |
|---|
| 1510 | 1373 | { |
|---|
| 1511 | 1374 | const struct device_node *port_node; |
|---|
| 1512 | 1375 | ofnode ep; |
|---|
| 1513 | 1376 | u32 reg; |
|---|
| 1514 | | - uint phandle; |
|---|
| 1515 | 1377 | |
|---|
| 1516 | 1378 | port_node = rockchip_of_graph_get_port_by_id(node, port); |
|---|
| 1517 | 1379 | if (!port_node) |
|---|
| .. | .. |
|---|
| 1527 | 1389 | if (!ofnode_valid(ep)) |
|---|
| 1528 | 1390 | return NULL; |
|---|
| 1529 | 1391 | |
|---|
| 1530 | | - if (ofnode_read_u32(ep, "remote-endpoint", &phandle)) |
|---|
| 1392 | + return ofnode_to_np(ep); |
|---|
| 1393 | +} |
|---|
| 1394 | + |
|---|
| 1395 | +static const struct device_node * |
|---|
| 1396 | +rockchip_of_graph_get_remote_node(ofnode node, int port, int endpoint) |
|---|
| 1397 | +{ |
|---|
| 1398 | + const struct device_node *ep_node; |
|---|
| 1399 | + ofnode ep; |
|---|
| 1400 | + uint phandle; |
|---|
| 1401 | + |
|---|
| 1402 | + ep_node = rockchip_of_graph_get_endpoint_by_regs(node, port, endpoint); |
|---|
| 1403 | + if (!ep_node) |
|---|
| 1404 | + return NULL; |
|---|
| 1405 | + |
|---|
| 1406 | + if (ofnode_read_u32(np_to_ofnode(ep_node), "remote-endpoint", &phandle)) |
|---|
| 1531 | 1407 | return NULL; |
|---|
| 1532 | 1408 | |
|---|
| 1533 | 1409 | ep = ofnode_get_by_phandle(phandle); |
|---|
| .. | .. |
|---|
| 1611 | 1487 | struct rockchip_bridge **bridge) |
|---|
| 1612 | 1488 | { |
|---|
| 1613 | 1489 | int ret = 0; |
|---|
| 1490 | + |
|---|
| 1491 | + if (*panel) |
|---|
| 1492 | + return 0; |
|---|
| 1493 | + |
|---|
| 1614 | 1494 | *panel = NULL; |
|---|
| 1615 | 1495 | *bridge = NULL; |
|---|
| 1616 | 1496 | |
|---|
| .. | .. |
|---|
| 1952 | 1832 | |
|---|
| 1953 | 1833 | if (s->force_output) { |
|---|
| 1954 | 1834 | timing_node = ofnode_find_subnode(node, "force_timing"); |
|---|
| 1955 | | - ret = display_get_force_timing_from_dts(timing_node, &s->force_mode); |
|---|
| 1835 | + ret = display_get_force_timing_from_dts(timing_node, |
|---|
| 1836 | + &s->force_mode, |
|---|
| 1837 | + &s->conn_state.bus_flags); |
|---|
| 1956 | 1838 | if (ofnode_read_u32(node, "force-bus-format", &s->force_bus_format)) |
|---|
| 1957 | 1839 | s->force_bus_format = MEDIA_BUS_FMT_RGB888_1X24; |
|---|
| 1958 | 1840 | } |
|---|
| .. | .. |
|---|
| 2002 | 1884 | s->crtc_state.crtc->vps[vp_id].plane_mask = ret; |
|---|
| 2003 | 1885 | s->crtc_state.crtc->assign_plane |= true; |
|---|
| 2004 | 1886 | s->crtc_state.crtc->vps[vp_id].primary_plane_id = |
|---|
| 2005 | | - ofnode_read_u32_default(vp_node, "rockchip,primary-plane", -1); |
|---|
| 1887 | + ofnode_read_u32_default(vp_node, "rockchip,primary-plane", U8_MAX); |
|---|
| 2006 | 1888 | printf("get vp%d plane mask:0x%x, primary id:%d, cursor_plane:%d, from dts\n", |
|---|
| 2007 | 1889 | vp_id, |
|---|
| 2008 | 1890 | s->crtc_state.crtc->vps[vp_id].plane_mask, |
|---|
| 1891 | + s->crtc_state.crtc->vps[vp_id].primary_plane_id == U8_MAX ? -1 : |
|---|
| 2009 | 1892 | s->crtc_state.crtc->vps[vp_id].primary_plane_id, |
|---|
| 2010 | 1893 | cursor_plane); |
|---|
| 2011 | 1894 | } |
|---|
| .. | .. |
|---|
| 2020 | 1903 | } |
|---|
| 2021 | 1904 | } |
|---|
| 2022 | 1905 | |
|---|
| 2023 | | - get_crtc_mcu_mode(&s->crtc_state); |
|---|
| 1906 | + get_crtc_mcu_mode(&s->crtc_state, port_node, is_ports_node); |
|---|
| 2024 | 1907 | |
|---|
| 2025 | 1908 | ret = ofnode_read_u32_default(s->crtc_state.node, |
|---|
| 2026 | 1909 | "rockchip,dual-channel-swap", 0); |
|---|
| .. | .. |
|---|
| 2061 | 1944 | const struct rockchip_crtc *crtc; |
|---|
| 2062 | 1945 | struct display_state *s; |
|---|
| 2063 | 1946 | int offset; |
|---|
| 1947 | + int ret; |
|---|
| 2064 | 1948 | const struct device_node *np; |
|---|
| 2065 | 1949 | const char *path; |
|---|
| 1950 | + const char *cacm_header; |
|---|
| 1951 | + u64 aligned_memory_size; |
|---|
| 2066 | 1952 | |
|---|
| 2067 | 1953 | if (fdt_node_offset_by_compatible(blob, 0, "rockchip,drm-logo") >= 0) { |
|---|
| 2068 | | - list_for_each_entry(s, &rockchip_display_list, head) |
|---|
| 2069 | | - load_bmp_logo(&s->logo, s->klogo_name); |
|---|
| 1954 | + list_for_each_entry(s, &rockchip_display_list, head) { |
|---|
| 1955 | + ret = load_bmp_logo(&s->logo, s->klogo_name); |
|---|
| 1956 | + if (ret < 0) { |
|---|
| 1957 | + s->is_klogo_valid = false; |
|---|
| 1958 | + printf("VP%d fail to load kernel logo\n", s->crtc_state.crtc_id); |
|---|
| 1959 | + } else { |
|---|
| 1960 | + s->is_klogo_valid = true; |
|---|
| 1961 | + } |
|---|
| 1962 | + } |
|---|
| 2070 | 1963 | |
|---|
| 2071 | 1964 | if (!get_display_size()) |
|---|
| 2072 | 1965 | return; |
|---|
| 2073 | 1966 | |
|---|
| 1967 | + aligned_memory_size = (u64)ALIGN(get_display_size(), align_size); |
|---|
| 2074 | 1968 | offset = fdt_update_reserved_memory(blob, "rockchip,drm-logo", |
|---|
| 2075 | 1969 | (u64)memory_start, |
|---|
| 2076 | | - (u64)get_display_size()); |
|---|
| 1970 | + aligned_memory_size); |
|---|
| 2077 | 1971 | if (offset < 0) |
|---|
| 2078 | 1972 | printf("failed to reserve drm-loader-logo memory\n"); |
|---|
| 2079 | 1973 | |
|---|
| 2080 | | - offset = fdt_update_reserved_memory(blob, "rockchip,drm-cubic-lut", |
|---|
| 2081 | | - (u64)cubic_lut_memory_start, |
|---|
| 2082 | | - (u64)get_cubic_memory_size()); |
|---|
| 2083 | | - if (offset < 0) |
|---|
| 2084 | | - printf("failed to reserve drm-cubic-lut memory\n"); |
|---|
| 1974 | + if (get_cubic_memory_size()) { |
|---|
| 1975 | + aligned_memory_size = (u64)ALIGN(get_cubic_memory_size(), align_size); |
|---|
| 1976 | + offset = fdt_update_reserved_memory(blob, "rockchip,drm-cubic-lut", |
|---|
| 1977 | + (u64)cubic_lut_memory_start, |
|---|
| 1978 | + aligned_memory_size); |
|---|
| 1979 | + if (offset < 0) |
|---|
| 1980 | + printf("failed to reserve drm-cubic-lut memory\n"); |
|---|
| 1981 | + } |
|---|
| 2085 | 1982 | } else { |
|---|
| 2086 | 1983 | printf("can't found rockchip,drm-logo, use rockchip,fb-logo\n"); |
|---|
| 2087 | 1984 | /* Compatible with rkfb display, only need reserve memory */ |
|---|
| .. | .. |
|---|
| 2097 | 1994 | } |
|---|
| 2098 | 1995 | |
|---|
| 2099 | 1996 | list_for_each_entry(s, &rockchip_display_list, head) { |
|---|
| 2100 | | - if (!s->is_init) |
|---|
| 1997 | + /* |
|---|
| 1998 | + * If plane mask is not set in dts, fixup dts to assign it |
|---|
| 1999 | + * whether crtc is initialized or not. |
|---|
| 2000 | + */ |
|---|
| 2001 | + if (s->crtc_state.crtc->funcs->fixup_dts && !s->crtc_state.crtc->assign_plane) |
|---|
| 2002 | + s->crtc_state.crtc->funcs->fixup_dts(s, blob); |
|---|
| 2003 | + |
|---|
| 2004 | + if (!s->is_init || !s->is_klogo_valid) |
|---|
| 2101 | 2005 | continue; |
|---|
| 2102 | 2006 | |
|---|
| 2103 | 2007 | conn = s->conn_state.connector; |
|---|
| .. | .. |
|---|
| 2123 | 2027 | printf("failed to get exist crtc\n"); |
|---|
| 2124 | 2028 | continue; |
|---|
| 2125 | 2029 | } |
|---|
| 2126 | | - |
|---|
| 2127 | | - if (crtc_funcs->fixup_dts) |
|---|
| 2128 | | - crtc_funcs->fixup_dts(s, blob); |
|---|
| 2129 | 2030 | |
|---|
| 2130 | 2031 | np = ofnode_to_np(s->node); |
|---|
| 2131 | 2032 | path = np->full_name; |
|---|
| .. | .. |
|---|
| 2155 | 2056 | FDT_SET_U32("overscan,bottom_margin", s->conn_state.overscan.bottom_margin); |
|---|
| 2156 | 2057 | |
|---|
| 2157 | 2058 | if (s->conn_state.disp_info) { |
|---|
| 2059 | + cacm_header = (const char*)&s->conn_state.disp_info->cacm_header; |
|---|
| 2060 | + |
|---|
| 2158 | 2061 | FDT_SET_U32("bcsh,brightness", s->conn_state.disp_info->bcsh_info.brightness); |
|---|
| 2159 | 2062 | FDT_SET_U32("bcsh,contrast", s->conn_state.disp_info->bcsh_info.contrast); |
|---|
| 2160 | 2063 | FDT_SET_U32("bcsh,saturation", s->conn_state.disp_info->bcsh_info.saturation); |
|---|
| 2161 | 2064 | FDT_SET_U32("bcsh,hue", s->conn_state.disp_info->bcsh_info.hue); |
|---|
| 2065 | + |
|---|
| 2066 | + if (!strncasecmp(cacm_header, "CACM", 4)) { |
|---|
| 2067 | + FDT_SET_U32("post_csc,hue", |
|---|
| 2068 | + s->conn_state.disp_info->csc_info.hue); |
|---|
| 2069 | + FDT_SET_U32("post_csc,saturation", |
|---|
| 2070 | + s->conn_state.disp_info->csc_info.saturation); |
|---|
| 2071 | + FDT_SET_U32("post_csc,contrast", |
|---|
| 2072 | + s->conn_state.disp_info->csc_info.contrast); |
|---|
| 2073 | + FDT_SET_U32("post_csc,brightness", |
|---|
| 2074 | + s->conn_state.disp_info->csc_info.brightness); |
|---|
| 2075 | + FDT_SET_U32("post_csc,r_gain", |
|---|
| 2076 | + s->conn_state.disp_info->csc_info.r_gain); |
|---|
| 2077 | + FDT_SET_U32("post_csc,g_gain", |
|---|
| 2078 | + s->conn_state.disp_info->csc_info.g_gain); |
|---|
| 2079 | + FDT_SET_U32("post_csc,b_gain", |
|---|
| 2080 | + s->conn_state.disp_info->csc_info.b_gain); |
|---|
| 2081 | + FDT_SET_U32("post_csc,r_offset", |
|---|
| 2082 | + s->conn_state.disp_info->csc_info.r_offset); |
|---|
| 2083 | + FDT_SET_U32("post_csc,g_offset", |
|---|
| 2084 | + s->conn_state.disp_info->csc_info.g_offset); |
|---|
| 2085 | + FDT_SET_U32("post_csc,b_offset", |
|---|
| 2086 | + s->conn_state.disp_info->csc_info.b_offset); |
|---|
| 2087 | + FDT_SET_U32("post_csc,csc_enable", |
|---|
| 2088 | + s->conn_state.disp_info->csc_info.csc_enable); |
|---|
| 2089 | + } |
|---|
| 2162 | 2090 | } |
|---|
| 2163 | 2091 | |
|---|
| 2164 | 2092 | if (s->conn_state.disp_info->cubic_lut_data.size && |
|---|
| .. | .. |
|---|
| 2213 | 2141 | return 0; |
|---|
| 2214 | 2142 | } |
|---|
| 2215 | 2143 | |
|---|
| 2144 | +static int do_rockchip_vop_dump(cmd_tbl_t *cmdtp, int flag, int argc, |
|---|
| 2145 | + char *const argv[]) |
|---|
| 2146 | +{ |
|---|
| 2147 | + int ret; |
|---|
| 2148 | + |
|---|
| 2149 | + if (argc < 1 || argc > 2) |
|---|
| 2150 | + return CMD_RET_USAGE; |
|---|
| 2151 | + |
|---|
| 2152 | + ret = rockchip_vop_dump(argv[1]); |
|---|
| 2153 | + |
|---|
| 2154 | + return ret; |
|---|
| 2155 | +} |
|---|
| 2156 | + |
|---|
| 2216 | 2157 | U_BOOT_CMD( |
|---|
| 2217 | 2158 | rockchip_show_logo, 1, 1, do_rockchip_logo_show, |
|---|
| 2218 | 2159 | "load and display log from resource partition", |
|---|
| .. | .. |
|---|
| 2224 | 2165 | "load and display bmp from resource partition", |
|---|
| 2225 | 2166 | " <bmp_name>" |
|---|
| 2226 | 2167 | ); |
|---|
| 2168 | + |
|---|
| 2169 | +U_BOOT_CMD( |
|---|
| 2170 | + vop_dump, 2, 1, do_rockchip_vop_dump, |
|---|
| 2171 | + "dump vop regs", |
|---|
| 2172 | + " [a/all]" |
|---|
| 2173 | +); |
|---|