From ee930fffee469d076998274a2ca55e13dc1efb67 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 10 May 2024 08:50:54 +0000
Subject: [PATCH] enable tun/tap/iptables

---
 u-boot/drivers/video/drm/rockchip_dw_hdmi.c |  127 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 123 insertions(+), 4 deletions(-)

diff --git a/u-boot/drivers/video/drm/rockchip_dw_hdmi.c b/u-boot/drivers/video/drm/rockchip_dw_hdmi.c
index 3a3169c..6e6139f 100644
--- a/u-boot/drivers/video/drm/rockchip_dw_hdmi.c
+++ b/u-boot/drivers/video/drm/rockchip_dw_hdmi.c
@@ -7,6 +7,7 @@
 #include <common.h>
 #include <boot_rkimg.h>
 #include <asm/io.h>
+#include <asm/gpio.h>
 #include <dm/of_access.h>
 #include <dm/device.h>
 #include <linux/dw_hdmi.h>
@@ -35,6 +36,19 @@
 #define RK3328_GRF_SOC_CON2              0x0408
 #define RK3328_GRF_SOC_CON3              0x040c
 #define RK3328_GRF_SOC_CON4              0x0410
+
+#define RK3528_GPIO0A_IOMUX_SEL_H	0x4
+#define RK3528_GPIO0A_PULL 		0x200
+#define RK3528_DDC_PULL			(0xf00 << 16)
+#define RK3528_VO_GRF_HDMI_MASK		0x60014
+#define RK3528_HDMI_SNKDET_SEL		((BIT(6) << 16) | BIT(6))
+#define RK3528_HDMI_SNKDET		BIT(21)
+#define RK3528_HDMI_CECIN_MSK		((BIT(2) << 16) | BIT(2))
+#define RK3528_HDMI_SDAIN_MSK		((BIT(1) << 16) | BIT(1))
+#define RK3528_HDMI_SCLIN_MSK		((BIT(0) << 16) | BIT(0))
+
+#define RK3528_GPIO_SWPORT_DR_L		0x0000
+#define RK3528_GPIO0_A2_DR		((BIT(2) << 16) | BIT(2))
 
 #define RK3568_GRF_VO_CON1               0x0364
 #define RK3568_HDMI_SDAIN_MSK            ((1 << 15) | (1 << (15 + 16)))
@@ -177,7 +191,7 @@
 	}
 };
 
-static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
+static struct dw_hdmi_phy_config rockchip_phy_config[] = {
 	/*pixelclk   symbol   term   vlev*/
 	{ 74250000,  0x8009, 0x0004, 0x0272},
 	{ 165000000, 0x802b, 0x0004, 0x0209},
@@ -334,19 +348,23 @@
 			  enum dw_hdmi_devtype dev_type,
 			  bool output_bus_format_rgb)
 {
-	int ret, i, screen_size;
-	struct base_disp_info base_parameter;
 	struct base2_disp_info *base2_parameter = conn_state->disp_info;
 	const struct base_overscan *scan;
 	struct base_screen_info *screen_info = NULL;
 	struct base2_screen_info *screen_info2 = NULL;
 	int max_scan = 100;
 	int min_scan = 51;
+#ifdef CONFIG_SPL_BUILD
+	int i, screen_size;
+#else
+	int ret, i, screen_size;
 	int offset = 0;
 	bool found = false;
 	struct blk_desc *dev_desc;
 	disk_partition_t part_info;
 	char baseparameter_buf[8 * RK_BLK_SIZE] __aligned(ARCH_DMA_MINALIGN);
+	struct base_disp_info base_parameter;
+#endif
 
 	overscan->left_margin = max_scan;
 	overscan->right_margin = max_scan;
@@ -358,6 +376,27 @@
 	else
 		*bus_format = MEDIA_BUS_FMT_YUV8_1X24;
 
+#ifdef CONFIG_SPL_BUILD
+	scan = &base2_parameter->overscan_info;
+	screen_size = sizeof(base2_parameter->screen_info) /
+		sizeof(base2_parameter->screen_info[0]);
+
+	for (i = 0; i < screen_size; i++) {
+		if (base2_parameter->screen_info[i].type ==
+		    DRM_MODE_CONNECTOR_HDMIA) {
+			screen_info2 =
+				&base2_parameter->screen_info[i];
+			break;
+		}
+	}
+	screen_info = malloc(sizeof(*screen_info));
+
+	screen_info->type = screen_info2->type;
+	screen_info->mode = screen_info2->resolution;
+	screen_info->format = screen_info2->format;
+	screen_info->depth = screen_info2->depthc;
+	screen_info->feature = screen_info2->feature;
+#else
 	if (!base2_parameter) {
 		dev_desc = rockchip_get_bootdev();
 		if (!dev_desc) {
@@ -422,6 +461,7 @@
 		screen_info->depth = screen_info2->depthc;
 		screen_info->feature = screen_info2->feature;
 	}
+#endif
 
 	if (scan->leftscale < min_scan && scan->leftscale > 0)
 		overscan->left_margin = min_scan;
@@ -443,7 +483,9 @@
 	else if (scan->bottomscale < max_scan && scan->bottomscale > 0)
 		overscan->bottom_margin = scan->bottomscale;
 
+#ifndef CONFIG_SPL_BUILD
 null_basep:
+#endif
 
 	if (screen_info)
 		printf("base_parameter.mode:%dx%d\n",
@@ -463,8 +505,15 @@
 		writel(RK3328_IO_3V_DOMAIN, grf + RK3328_GRF_SOC_CON4);
 }
 
-void dw_hdmi_set_iomux(void *grf, int dev_type)
+void dw_hdmi_set_iomux(void *grf, void *gpio_base, struct gpio_desc *hpd_gpiod,
+		       int dev_type)
 {
+	u32 val = 0;
+	int i = 400;
+#ifdef CONFIG_SPL_BUILD
+	void *gpio0_ioc = (void *)RK3528_GPIO0_IOC_BASE;
+#endif
+
 	switch (dev_type) {
 	case RK3328_HDMI:
 		writel(RK3328_IO_DDC_IN_MSK, grf + RK3328_GRF_SOC_CON2);
@@ -473,6 +522,49 @@
 	case RK3228_HDMI:
 		writel(RK3228_IO_3V_DOMAIN, grf + RK3228_GRF_SOC_CON6);
 		writel(RK3228_IO_DDC_IN_MSK, grf + RK3228_GRF_SOC_CON2);
+		break;
+	case RK3528_HDMI:
+		writel(RK3528_HDMI_SDAIN_MSK | RK3528_HDMI_SCLIN_MSK |
+		       RK3528_HDMI_SNKDET_SEL,
+		       grf + RK3528_VO_GRF_HDMI_MASK);
+
+#ifdef CONFIG_SPL_BUILD
+		val = (0x11 << 16) | 0x11;
+		writel(val, gpio0_ioc + RK3528_GPIO0A_IOMUX_SEL_H);
+
+		writel(RK3528_DDC_PULL, gpio0_ioc + RK3528_GPIO0A_PULL);
+
+		/* gpio0_a2's input enable is controlled by gpio output data bit */
+		writel(RK3528_GPIO0_A2_DR, gpio_base + RK3528_GPIO_SWPORT_DR_L);
+
+		while (i--) {
+			val = readl(gpio_base + 0x70) & BIT(2);
+			if (val)
+				break;
+			mdelay(5);
+		}
+#else
+		writel(val, grf + RK3528_VO_GRF_HDMI_MASK);
+
+		/* gpio0_a2's input enable is controlled by gpio output data bit */
+		writel(RK3528_GPIO0_A2_DR, gpio_base + RK3528_GPIO_SWPORT_DR_L);
+
+		if (dm_gpio_is_valid(hpd_gpiod)) {
+			while (i--) {
+				val = dm_gpio_get_value(hpd_gpiod);
+				if (val)
+					break;
+				mdelay(5);
+			}
+		}
+#endif
+
+		if (val)
+			val = RK3528_HDMI_SNKDET | BIT(5);
+		else
+			val = RK3528_HDMI_SNKDET;
+		writel(val, grf + RK3528_VO_GRF_HDMI_MASK);
+
 		break;
 	case RK3568_HDMI:
 		writel(RK3568_HDMI_SDAIN_MSK | RK3568_HDMI_SCLIN_MSK,
@@ -544,6 +636,14 @@
 	.dev_type   = RK3399_HDMI,
 };
 
+const struct dw_hdmi_plat_data rk3528_hdmi_drv_data = {
+	.vop_sel_bit = 0,
+	.grf_vop_sel_reg = 0,
+	.phy_ops    = &inno_dw_hdmi_phy_ops,
+	.phy_name   = "inno_dw_hdmi_phy2",
+	.dev_type   = RK3528_HDMI,
+};
+
 const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = {
 	.vop_sel_bit = 0,
 	.grf_vop_sel_reg = 0,
@@ -554,6 +654,19 @@
 	.dev_type   = RK3568_HDMI,
 };
 
+#ifdef CONFIG_SPL_BUILD
+int rockchip_spl_dw_hdmi_probe(struct connector_state *conn_state)
+{
+	conn_state->connector = malloc(sizeof(struct rockchip_connector));
+
+	memset(conn_state->connector, 0, sizeof(*conn_state->connector));
+	rockchip_connector_bind(conn_state->connector, NULL, 0, &rockchip_dw_hdmi_funcs,
+				(void *)&rk3528_hdmi_drv_data,
+				DRM_MODE_CONNECTOR_HDMIA);
+
+	return 0;
+}
+#else
 static int rockchip_dw_hdmi_probe(struct udevice *dev)
 {
 	int id;
@@ -568,9 +681,13 @@
 
 	return 0;
 }
+#endif
 
 static const struct udevice_id rockchip_dw_hdmi_ids[] = {
 	{
+	 .compatible = "rockchip,rk3528-dw-hdmi",
+	 .data = (ulong)&rk3528_hdmi_drv_data,
+	}, {
 	 .compatible = "rockchip,rk3568-dw-hdmi",
 	 .data = (ulong)&rk3568_hdmi_drv_data,
 	}, {
@@ -598,6 +715,8 @@
 	.name = "rockchip_dw_hdmi",
 	.id = UCLASS_DISPLAY,
 	.of_match = rockchip_dw_hdmi_ids,
+#ifndef CONFIG_SPL_BUILD
 	.probe	= rockchip_dw_hdmi_probe,
+#endif
 	.priv_auto_alloc_size = sizeof(struct rockchip_connector),
 };

--
Gitblit v1.6.2