hc
2023-11-06 9df731a176aab8e03b984b681b1bea01ccff6644
u-boot/drivers/video/drm/rockchip_dw_hdmi.c
....@@ -7,6 +7,7 @@
77 #include <common.h>
88 #include <boot_rkimg.h>
99 #include <asm/io.h>
10
+#include <asm/gpio.h>
1011 #include <dm/of_access.h>
1112 #include <dm/device.h>
1213 #include <linux/dw_hdmi.h>
....@@ -35,6 +36,19 @@
3536 #define RK3328_GRF_SOC_CON2 0x0408
3637 #define RK3328_GRF_SOC_CON3 0x040c
3738 #define RK3328_GRF_SOC_CON4 0x0410
39
+
40
+#define RK3528_GPIO0A_IOMUX_SEL_H 0x4
41
+#define RK3528_GPIO0A_PULL 0x200
42
+#define RK3528_DDC_PULL (0xf00 << 16)
43
+#define RK3528_VO_GRF_HDMI_MASK 0x60014
44
+#define RK3528_HDMI_SNKDET_SEL ((BIT(6) << 16) | BIT(6))
45
+#define RK3528_HDMI_SNKDET BIT(21)
46
+#define RK3528_HDMI_CECIN_MSK ((BIT(2) << 16) | BIT(2))
47
+#define RK3528_HDMI_SDAIN_MSK ((BIT(1) << 16) | BIT(1))
48
+#define RK3528_HDMI_SCLIN_MSK ((BIT(0) << 16) | BIT(0))
49
+
50
+#define RK3528_GPIO_SWPORT_DR_L 0x0000
51
+#define RK3528_GPIO0_A2_DR ((BIT(2) << 16) | BIT(2))
3852
3953 #define RK3568_GRF_VO_CON1 0x0364
4054 #define RK3568_HDMI_SDAIN_MSK ((1 << 15) | (1 << (15 + 16)))
....@@ -177,7 +191,7 @@
177191 }
178192 };
179193
180
-static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
194
+static struct dw_hdmi_phy_config rockchip_phy_config[] = {
181195 /*pixelclk symbol term vlev*/
182196 { 74250000, 0x8009, 0x0004, 0x0272},
183197 { 165000000, 0x802b, 0x0004, 0x0209},
....@@ -334,19 +348,23 @@
334348 enum dw_hdmi_devtype dev_type,
335349 bool output_bus_format_rgb)
336350 {
337
- int ret, i, screen_size;
338
- struct base_disp_info base_parameter;
339351 struct base2_disp_info *base2_parameter = conn_state->disp_info;
340352 const struct base_overscan *scan;
341353 struct base_screen_info *screen_info = NULL;
342354 struct base2_screen_info *screen_info2 = NULL;
343355 int max_scan = 100;
344356 int min_scan = 51;
357
+#ifdef CONFIG_SPL_BUILD
358
+ int i, screen_size;
359
+#else
360
+ int ret, i, screen_size;
345361 int offset = 0;
346362 bool found = false;
347363 struct blk_desc *dev_desc;
348364 disk_partition_t part_info;
349365 char baseparameter_buf[8 * RK_BLK_SIZE] __aligned(ARCH_DMA_MINALIGN);
366
+ struct base_disp_info base_parameter;
367
+#endif
350368
351369 overscan->left_margin = max_scan;
352370 overscan->right_margin = max_scan;
....@@ -358,6 +376,27 @@
358376 else
359377 *bus_format = MEDIA_BUS_FMT_YUV8_1X24;
360378
379
+#ifdef CONFIG_SPL_BUILD
380
+ scan = &base2_parameter->overscan_info;
381
+ screen_size = sizeof(base2_parameter->screen_info) /
382
+ sizeof(base2_parameter->screen_info[0]);
383
+
384
+ for (i = 0; i < screen_size; i++) {
385
+ if (base2_parameter->screen_info[i].type ==
386
+ DRM_MODE_CONNECTOR_HDMIA) {
387
+ screen_info2 =
388
+ &base2_parameter->screen_info[i];
389
+ break;
390
+ }
391
+ }
392
+ screen_info = malloc(sizeof(*screen_info));
393
+
394
+ screen_info->type = screen_info2->type;
395
+ screen_info->mode = screen_info2->resolution;
396
+ screen_info->format = screen_info2->format;
397
+ screen_info->depth = screen_info2->depthc;
398
+ screen_info->feature = screen_info2->feature;
399
+#else
361400 if (!base2_parameter) {
362401 dev_desc = rockchip_get_bootdev();
363402 if (!dev_desc) {
....@@ -422,6 +461,7 @@
422461 screen_info->depth = screen_info2->depthc;
423462 screen_info->feature = screen_info2->feature;
424463 }
464
+#endif
425465
426466 if (scan->leftscale < min_scan && scan->leftscale > 0)
427467 overscan->left_margin = min_scan;
....@@ -443,7 +483,9 @@
443483 else if (scan->bottomscale < max_scan && scan->bottomscale > 0)
444484 overscan->bottom_margin = scan->bottomscale;
445485
486
+#ifndef CONFIG_SPL_BUILD
446487 null_basep:
488
+#endif
447489
448490 if (screen_info)
449491 printf("base_parameter.mode:%dx%d\n",
....@@ -463,8 +505,15 @@
463505 writel(RK3328_IO_3V_DOMAIN, grf + RK3328_GRF_SOC_CON4);
464506 }
465507
466
-void dw_hdmi_set_iomux(void *grf, int dev_type)
508
+void dw_hdmi_set_iomux(void *grf, void *gpio_base, struct gpio_desc *hpd_gpiod,
509
+ int dev_type)
467510 {
511
+ u32 val = 0;
512
+ int i = 400;
513
+#ifdef CONFIG_SPL_BUILD
514
+ void *gpio0_ioc = (void *)RK3528_GPIO0_IOC_BASE;
515
+#endif
516
+
468517 switch (dev_type) {
469518 case RK3328_HDMI:
470519 writel(RK3328_IO_DDC_IN_MSK, grf + RK3328_GRF_SOC_CON2);
....@@ -473,6 +522,49 @@
473522 case RK3228_HDMI:
474523 writel(RK3228_IO_3V_DOMAIN, grf + RK3228_GRF_SOC_CON6);
475524 writel(RK3228_IO_DDC_IN_MSK, grf + RK3228_GRF_SOC_CON2);
525
+ break;
526
+ case RK3528_HDMI:
527
+ writel(RK3528_HDMI_SDAIN_MSK | RK3528_HDMI_SCLIN_MSK |
528
+ RK3528_HDMI_SNKDET_SEL,
529
+ grf + RK3528_VO_GRF_HDMI_MASK);
530
+
531
+#ifdef CONFIG_SPL_BUILD
532
+ val = (0x11 << 16) | 0x11;
533
+ writel(val, gpio0_ioc + RK3528_GPIO0A_IOMUX_SEL_H);
534
+
535
+ writel(RK3528_DDC_PULL, gpio0_ioc + RK3528_GPIO0A_PULL);
536
+
537
+ /* gpio0_a2's input enable is controlled by gpio output data bit */
538
+ writel(RK3528_GPIO0_A2_DR, gpio_base + RK3528_GPIO_SWPORT_DR_L);
539
+
540
+ while (i--) {
541
+ val = readl(gpio_base + 0x70) & BIT(2);
542
+ if (val)
543
+ break;
544
+ mdelay(5);
545
+ }
546
+#else
547
+ writel(val, grf + RK3528_VO_GRF_HDMI_MASK);
548
+
549
+ /* gpio0_a2's input enable is controlled by gpio output data bit */
550
+ writel(RK3528_GPIO0_A2_DR, gpio_base + RK3528_GPIO_SWPORT_DR_L);
551
+
552
+ if (dm_gpio_is_valid(hpd_gpiod)) {
553
+ while (i--) {
554
+ val = dm_gpio_get_value(hpd_gpiod);
555
+ if (val)
556
+ break;
557
+ mdelay(5);
558
+ }
559
+ }
560
+#endif
561
+
562
+ if (val)
563
+ val = RK3528_HDMI_SNKDET | BIT(5);
564
+ else
565
+ val = RK3528_HDMI_SNKDET;
566
+ writel(val, grf + RK3528_VO_GRF_HDMI_MASK);
567
+
476568 break;
477569 case RK3568_HDMI:
478570 writel(RK3568_HDMI_SDAIN_MSK | RK3568_HDMI_SCLIN_MSK,
....@@ -544,6 +636,14 @@
544636 .dev_type = RK3399_HDMI,
545637 };
546638
639
+const struct dw_hdmi_plat_data rk3528_hdmi_drv_data = {
640
+ .vop_sel_bit = 0,
641
+ .grf_vop_sel_reg = 0,
642
+ .phy_ops = &inno_dw_hdmi_phy_ops,
643
+ .phy_name = "inno_dw_hdmi_phy2",
644
+ .dev_type = RK3528_HDMI,
645
+};
646
+
547647 const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = {
548648 .vop_sel_bit = 0,
549649 .grf_vop_sel_reg = 0,
....@@ -554,6 +654,19 @@
554654 .dev_type = RK3568_HDMI,
555655 };
556656
657
+#ifdef CONFIG_SPL_BUILD
658
+int rockchip_spl_dw_hdmi_probe(struct connector_state *conn_state)
659
+{
660
+ conn_state->connector = malloc(sizeof(struct rockchip_connector));
661
+
662
+ memset(conn_state->connector, 0, sizeof(*conn_state->connector));
663
+ rockchip_connector_bind(conn_state->connector, NULL, 0, &rockchip_dw_hdmi_funcs,
664
+ (void *)&rk3528_hdmi_drv_data,
665
+ DRM_MODE_CONNECTOR_HDMIA);
666
+
667
+ return 0;
668
+}
669
+#else
557670 static int rockchip_dw_hdmi_probe(struct udevice *dev)
558671 {
559672 int id;
....@@ -568,9 +681,13 @@
568681
569682 return 0;
570683 }
684
+#endif
571685
572686 static const struct udevice_id rockchip_dw_hdmi_ids[] = {
573687 {
688
+ .compatible = "rockchip,rk3528-dw-hdmi",
689
+ .data = (ulong)&rk3528_hdmi_drv_data,
690
+ }, {
574691 .compatible = "rockchip,rk3568-dw-hdmi",
575692 .data = (ulong)&rk3568_hdmi_drv_data,
576693 }, {
....@@ -598,6 +715,8 @@
598715 .name = "rockchip_dw_hdmi",
599716 .id = UCLASS_DISPLAY,
600717 .of_match = rockchip_dw_hdmi_ids,
718
+#ifndef CONFIG_SPL_BUILD
601719 .probe = rockchip_dw_hdmi_probe,
720
+#endif
602721 .priv_auto_alloc_size = sizeof(struct rockchip_connector),
603722 };