From 9df731a176aab8e03b984b681b1bea01ccff6644 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 06 Nov 2023 07:23:06 +0000
Subject: [PATCH] rk3568 rt uboot init

---
 u-boot/drivers/video/drm/max96745.c |  105 +++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 87 insertions(+), 18 deletions(-)

diff --git a/u-boot/drivers/video/drm/max96745.c b/u-boot/drivers/video/drm/max96745.c
index c824e01..3750f4d 100644
--- a/u-boot/drivers/video/drm/max96745.c
+++ b/u-boot/drivers/video/drm/max96745.c
@@ -9,41 +9,111 @@
 #include <i2c.h>
 #include <max96745.h>
 #include <video_bridge.h>
+#include <linux/iopoll.h>
 
 #include "rockchip_bridge.h"
 #include "rockchip_display.h"
 #include "rockchip_panel.h"
 
-struct max96745_bridge_priv {
-	struct gpio_desc lock_gpio;
-};
-
-static bool max96745_bridge_detect(struct rockchip_bridge *bridge)
+static bool max96745_bridge_link_locked(struct udevice *dev)
 {
-	struct max96745_bridge_priv *priv = dev_get_priv(bridge->dev);
+	int ret;
 
-	if (!dm_gpio_get_value(&priv->lock_gpio))
+	ret = dm_i2c_reg_read(dev->parent, 0x002a);
+	if (ret < 0)
+		return false;
+
+	if (!FIELD_GET(LINK_LOCKED, ret))
 		return false;
 
 	return true;
 }
 
+static bool max96745_bridge_detect(struct rockchip_bridge *bridge)
+{
+	return max96745_bridge_link_locked(bridge->dev);
+}
+
+static void max96745_bridge_enable(struct rockchip_bridge *bridge)
+{
+	struct udevice *dev = bridge->dev;
+	struct drm_display_mode *mode = &bridge->state->conn_state.mode;
+	u8 cxtp, tx_rate;
+	int ret;
+
+	ret = dm_i2c_reg_read(dev->parent, 0x0011);
+	if (ret < 0)
+		return;
+
+	cxtp = FIELD_GET(CXTP_A, ret);
+
+	ret = dm_i2c_reg_read(dev->parent, 0x0028);
+	if (ret < 0)
+		return;
+
+	tx_rate = FIELD_GET(TX_RATE, ret);
+
+	if (!cxtp && mode->clock > 95000 && tx_rate == 1) {
+		ret = dm_i2c_reg_clrset(dev->parent, 0x0028, TX_RATE,
+					FIELD_PREP(TX_RATE, 2));
+		if (ret < 0)
+			return;
+
+		ret = dm_i2c_reg_clrset(dev->parent, 0x0029, RESET_ONESHOT,
+					FIELD_PREP(RESET_ONESHOT, 1));
+		if (ret < 0)
+			return;
+
+		if (readx_poll_timeout(max96745_bridge_link_locked, dev, ret,
+				       ret, 200000))
+			dev_err(dev, "%s: GMSL link not locked\n", __func__);
+	}
+}
+
+static void max96745_bridge_post_disable(struct rockchip_bridge *bridge)
+{
+	struct udevice *dev = bridge->dev;
+	u8 cxtp, tx_rate;
+	int ret;
+
+	ret = dm_i2c_reg_read(dev->parent, 0x0011);
+	if (ret < 0)
+		return;
+
+	cxtp = FIELD_GET(CXTP_A, ret);
+
+	ret = dm_i2c_reg_read(dev->parent, 0x0028);
+	if (ret < 0)
+		return;
+
+	tx_rate = FIELD_GET(TX_RATE, ret);
+
+	if (!cxtp && tx_rate == 2) {
+		ret = dm_i2c_reg_clrset(dev->parent, 0x0028, TX_RATE,
+					FIELD_PREP(TX_RATE, 1));
+		if (ret < 0)
+			return;
+
+		ret = dm_i2c_reg_clrset(dev->parent, 0x0029, RESET_ONESHOT,
+					FIELD_PREP(RESET_ONESHOT, 1));
+		if (ret < 0)
+			return;
+
+		if (readx_poll_timeout(max96745_bridge_link_locked, dev, ret,
+				       ret, 200000))
+			dev_err(dev, "%s: GMSL link not locked\n", __func__);
+	}
+}
+
 static const struct rockchip_bridge_funcs max96745_bridge_funcs = {
-	.detect = max96745_bridge_detect,
+	.detect		= max96745_bridge_detect,
+	.enable		= max96745_bridge_enable,
+	.post_disable	= max96745_bridge_post_disable,
 };
 
 static int max96745_bridge_probe(struct udevice *dev)
 {
-	struct max96745_bridge_priv *priv = dev_get_priv(dev);
 	struct rockchip_bridge *bridge;
-	int ret;
-
-	ret = gpio_request_by_name(dev, "lock-gpios", 0, &priv->lock_gpio,
-				   GPIOD_IS_IN);
-	if (ret) {
-		dev_err(dev, "failed to get lock GPIO: %d\n", ret);
-		return ret;
-	}
 
 	bridge = calloc(1, sizeof(*bridge));
 	if (!bridge)
@@ -66,5 +136,4 @@
 	.id = UCLASS_VIDEO_BRIDGE,
 	.of_match = max96745_bridge_of_match,
 	.probe = max96745_bridge_probe,
-	.priv_auto_alloc_size = sizeof(struct max96745_bridge_priv),
 };

--
Gitblit v1.6.2