hc
2023-11-06 9df731a176aab8e03b984b681b1bea01ccff6644
u-boot/drivers/video/drm/rockchip_display.c
....@@ -57,7 +57,7 @@
5757 static unsigned long cubic_lut_memory_start;
5858 static unsigned long memory_end;
5959 static struct base2_info base_parameter;
60
-static uint32_t crc32_table[256];
60
+static u32 align_size = PAGE_SIZE;
6161
6262 /*
6363 * the phy types are used by different connectors in public.
....@@ -75,41 +75,6 @@
7575 int public_phy_type;
7676 bool phy_init;
7777 };
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
-}
11378
11479 int rockchip_get_baseparameter(void)
11580 {
....@@ -152,6 +117,7 @@
152117 struct base2_disp_header *disp_header;
153118 int i = 0, offset = -1;
154119 u32 crc_val;
120
+ u32 base2_length;
155121 void *base_parameter_addr = (void *)&base_parameter;
156122
157123 for (i = 0; i < 8; i++) {
....@@ -178,11 +144,23 @@
178144 if (strncasecmp(disp_info->disp_head_flag, "DISP", 4))
179145 return NULL;
180146
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
+ }
186164 }
187165
188166 return disp_info;
....@@ -253,9 +231,9 @@
253231
254232 static void init_display_buffer(ulong base)
255233 {
256
- memory_start = base + DRM_ROCKCHIP_FB_SIZE;
234
+ memory_start = ALIGN(base + DRM_ROCKCHIP_FB_SIZE, align_size);
257235 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);
259237 }
260238
261239 void *get_display_buffer(int size)
....@@ -340,38 +318,15 @@
340318 return 0;
341319 }
342320
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)
370322 {
371323 int hactive, vactive, pixelclock;
372324 int hfront_porch, hback_porch, hsync_len;
373325 int vfront_porch, vback_porch, vsync_len;
374326 int val, flags = 0;
327
+
328
+#define FDT_GET_BOOL(val, name) \
329
+ val = ofnode_read_bool(node, name);
375330
376331 #define FDT_GET_INT(val, name) \
377332 val = ofnode_read_s32_default(node, name, -1); \
....@@ -396,8 +351,18 @@
396351 flags |= val ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
397352 FDT_GET_INT(val, "vsync-active");
398353 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;
399364 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;
401366
402367 FDT_GET_INT_DEFAULT(val, "screen-rotate", 0);
403368 if (val == DRM_MODE_FLAG_XMIRROR) {
....@@ -425,11 +390,13 @@
425390 return 0;
426391 }
427392
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)
429396 {
430397 int ret = 0;
431398
432
- ret = rockchip_ofnode_get_display_mode(node, mode);
399
+ ret = rockchip_ofnode_get_display_mode(node, mode, bus_flags);
433400
434401 if (ret) {
435402 mode->clock = 74250;
....@@ -456,14 +423,24 @@
456423 }
457424
458425 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)
460428 {
461429 struct ofnode_phandle_args args;
462
- ofnode dt, timing;
430
+ ofnode dt, timing, mcu_panel;
463431 int ret;
464432
433
+ mcu_panel = dev_read_subnode(panel->dev, "mcu-panel");
465434 dt = dev_read_subnode(panel->dev, "display-timings");
466435 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");
467444 ret = ofnode_parse_phandle_with_args(dt, "native-mode", NULL,
468445 0, 0, &args);
469446 if (ret)
....@@ -479,163 +456,26 @@
479456 return -ENXIO;
480457 }
481458
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
+ }
483477
484478 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);
639479 }
640480
641481 static int display_get_timing(struct display_state *state)
....@@ -649,7 +489,7 @@
649489 return panel->funcs->get_mode(panel, mode);
650490
651491 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)) {
653493 printf("Using display timing dts\n");
654494 return 0;
655495 }
....@@ -730,6 +570,47 @@
730570 return ret;
731571 }
732572
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
+
733614 static int display_init(struct display_state *state)
734615 {
735616 struct connector_state *conn_state = &state->conn_state;
....@@ -741,7 +622,9 @@
741622 const char *compatible;
742623 int ret = 0;
743624 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
745628 if (!__print_once) {
746629 __print_once = true;
747630 printf("Rockchip UBOOT DRM driver version: %s\n", DRIVER_VERSION);
....@@ -755,6 +638,12 @@
755638 return -ENXIO;
756639 }
757640
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
758647 if (crtc_state->crtc->active && !crtc_state->ports_node &&
759648 memcmp(&crtc_state->crtc->active_mode, &conn_state->mode,
760649 sizeof(struct drm_display_mode))) {
....@@ -773,14 +662,16 @@
773662 return ret;
774663 }
775664
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
+ }
779670
780671 /*
781672 * support hotplug, but not connect;
782673 */
783
-#ifdef CONFIG_ROCKCHIP_DRM_TVE
674
+#ifdef CONFIG_DRM_ROCKCHIP_TVE
784675 if (crtc->hdmi_hpd && conn_state->type == DRM_MODE_CONNECTOR_TV) {
785676 printf("hdmi plugin ,skip tve\n");
786677 goto deinit;
....@@ -793,14 +684,27 @@
793684 #endif
794685
795686 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)
797688 if (conn_state->type == DRM_MODE_CONNECTOR_HDMIA)
798689 crtc->hdmi_hpd = ret;
690
+ if (state->enabled_at_spl)
691
+ crtc->hdmi_hpd = true;
799692 #endif
800693 if (!ret && !state->force_output)
801694 goto deinit;
802695
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) {
804708 ret = display_get_timing(state);
805709 if (!ret)
806710 conn_state->bpc = conn->panel->bpc;
....@@ -853,10 +757,15 @@
853757 if (state->force_output)
854758 display_use_force_mode(state);
855759
760
+ if (display_mode_valid(state))
761
+ goto deinit;
762
+
856763 /* rk356x series drive mipi pixdata on posedge */
857764 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
+ }
860769
861770 printf("%s: %s detailed mode clock %u kHz, flags[%x]\n"
862771 " H: %04d %04d %04d %04d\n"
....@@ -871,20 +780,13 @@
871780 mode->vsync_end, mode->vtotal,
872781 conn_state->bus_format);
873782
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;
883785
884786 if (conn->bridge)
885787 rockchip_bridge_mode_set(conn->bridge, &conn_state->mode);
886788
887
- if (crtc_funcs->init) {
789
+ if (crtc_funcs->init && state->enabled_at_spl == false) {
888790 ret = crtc_funcs->init(state);
889791 if (ret)
890792 goto deinit;
....@@ -955,12 +857,17 @@
955857 if (crtc_funcs->prepare)
956858 crtc_funcs->prepare(state);
957859
958
- rockchip_connector_pre_enable(state);
860
+ if (state->enabled_at_spl == false)
861
+ rockchip_connector_pre_enable(state);
959862
960863 if (crtc_funcs->enable)
961864 crtc_funcs->enable(state);
962865
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);
964871
965872 state->is_enable = true;
966873
....@@ -990,54 +897,6 @@
990897 state->is_init = 0;
991898
992899 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;
1041900 }
1042901
1043902 static int display_check(struct display_state *state)
....@@ -1074,38 +933,6 @@
1074933 return 0;
1075934
1076935 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:
1109936 state->is_init = false;
1110937 return ret;
1111938 }
....@@ -1170,7 +997,6 @@
1170997 }
1171998 }
1172999
1173
- display_mode_valid(state);
11741000 display_check(state);
11751001 display_set_plane(state);
11761002 display_enable(state);
....@@ -1213,14 +1039,22 @@
12131039 return 0;
12141040 }
12151041
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)
12171044 {
1218
- ofnode mcu_node;
1045
+ ofnode mcu_node, vp_node;
12191046 int total_pixel, cs_pst, cs_pend, rw_pst, rw_pend;
12201047
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
+ }
12241058
12251059 #define FDT_GET_MCU_INT(val, name) \
12261060 do { \
....@@ -1464,6 +1298,35 @@
14641298 return ret;
14651299 }
14661300
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
+
14671330 enum {
14681331 PORT_DIR_IN,
14691332 PORT_DIR_OUT,
....@@ -1505,13 +1368,12 @@
15051368 return ofnode_to_np(parent);
15061369 }
15071370
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)
15101373 {
15111374 const struct device_node *port_node;
15121375 ofnode ep;
15131376 u32 reg;
1514
- uint phandle;
15151377
15161378 port_node = rockchip_of_graph_get_port_by_id(node, port);
15171379 if (!port_node)
....@@ -1527,7 +1389,21 @@
15271389 if (!ofnode_valid(ep))
15281390 return NULL;
15291391
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))
15311407 return NULL;
15321408
15331409 ep = ofnode_get_by_phandle(phandle);
....@@ -1611,6 +1487,10 @@
16111487 struct rockchip_bridge **bridge)
16121488 {
16131489 int ret = 0;
1490
+
1491
+ if (*panel)
1492
+ return 0;
1493
+
16141494 *panel = NULL;
16151495 *bridge = NULL;
16161496
....@@ -1952,7 +1832,9 @@
19521832
19531833 if (s->force_output) {
19541834 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);
19561838 if (ofnode_read_u32(node, "force-bus-format", &s->force_bus_format))
19571839 s->force_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
19581840 }
....@@ -2002,10 +1884,11 @@
20021884 s->crtc_state.crtc->vps[vp_id].plane_mask = ret;
20031885 s->crtc_state.crtc->assign_plane |= true;
20041886 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);
20061888 printf("get vp%d plane mask:0x%x, primary id:%d, cursor_plane:%d, from dts\n",
20071889 vp_id,
20081890 s->crtc_state.crtc->vps[vp_id].plane_mask,
1891
+ s->crtc_state.crtc->vps[vp_id].primary_plane_id == U8_MAX ? -1 :
20091892 s->crtc_state.crtc->vps[vp_id].primary_plane_id,
20101893 cursor_plane);
20111894 }
....@@ -2020,7 +1903,7 @@
20201903 }
20211904 }
20221905
2023
- get_crtc_mcu_mode(&s->crtc_state);
1906
+ get_crtc_mcu_mode(&s->crtc_state, port_node, is_ports_node);
20241907
20251908 ret = ofnode_read_u32_default(s->crtc_state.node,
20261909 "rockchip,dual-channel-swap", 0);
....@@ -2061,27 +1944,41 @@
20611944 const struct rockchip_crtc *crtc;
20621945 struct display_state *s;
20631946 int offset;
1947
+ int ret;
20641948 const struct device_node *np;
20651949 const char *path;
1950
+ const char *cacm_header;
1951
+ u64 aligned_memory_size;
20661952
20671953 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
+ }
20701963
20711964 if (!get_display_size())
20721965 return;
20731966
1967
+ aligned_memory_size = (u64)ALIGN(get_display_size(), align_size);
20741968 offset = fdt_update_reserved_memory(blob, "rockchip,drm-logo",
20751969 (u64)memory_start,
2076
- (u64)get_display_size());
1970
+ aligned_memory_size);
20771971 if (offset < 0)
20781972 printf("failed to reserve drm-loader-logo memory\n");
20791973
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
+ }
20851982 } else {
20861983 printf("can't found rockchip,drm-logo, use rockchip,fb-logo\n");
20871984 /* Compatible with rkfb display, only need reserve memory */
....@@ -2097,7 +1994,14 @@
20971994 }
20981995
20991996 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)
21012005 continue;
21022006
21032007 conn = s->conn_state.connector;
....@@ -2123,9 +2027,6 @@
21232027 printf("failed to get exist crtc\n");
21242028 continue;
21252029 }
2126
-
2127
- if (crtc_funcs->fixup_dts)
2128
- crtc_funcs->fixup_dts(s, blob);
21292030
21302031 np = ofnode_to_np(s->node);
21312032 path = np->full_name;
....@@ -2155,10 +2056,37 @@
21552056 FDT_SET_U32("overscan,bottom_margin", s->conn_state.overscan.bottom_margin);
21562057
21572058 if (s->conn_state.disp_info) {
2059
+ cacm_header = (const char*)&s->conn_state.disp_info->cacm_header;
2060
+
21582061 FDT_SET_U32("bcsh,brightness", s->conn_state.disp_info->bcsh_info.brightness);
21592062 FDT_SET_U32("bcsh,contrast", s->conn_state.disp_info->bcsh_info.contrast);
21602063 FDT_SET_U32("bcsh,saturation", s->conn_state.disp_info->bcsh_info.saturation);
21612064 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
+ }
21622090 }
21632091
21642092 if (s->conn_state.disp_info->cubic_lut_data.size &&
....@@ -2213,6 +2141,19 @@
22132141 return 0;
22142142 }
22152143
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
+
22162157 U_BOOT_CMD(
22172158 rockchip_show_logo, 1, 1, do_rockchip_logo_show,
22182159 "load and display log from resource partition",
....@@ -2224,3 +2165,9 @@
22242165 "load and display bmp from resource partition",
22252166 " <bmp_name>"
22262167 );
2168
+
2169
+U_BOOT_CMD(
2170
+ vop_dump, 2, 1, do_rockchip_vop_dump,
2171
+ "dump vop regs",
2172
+ " [a/all]"
2173
+);