From e3e12f52b214121840b44c91de5b3e5af5d3eb84 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 06 Nov 2023 03:04:41 +0000
Subject: [PATCH] rk3568 rt init

---
 kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c |  244 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 242 insertions(+), 2 deletions(-)

diff --git a/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 870e60a..d945d92 100644
--- a/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -24,6 +24,7 @@
 #include <linux/of_net.h>
 #include <linux/gpio.h>
 #include <linux/module.h>
+#include <linux/nvmem-consumer.h>
 #include <linux/of_gpio.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
@@ -77,6 +78,7 @@
 	struct clk *pclk_mac;
 	struct clk *clk_phy;
 	struct clk *pclk_xpcs;
+	struct clk *clk_xpcs_eee;
 
 	struct reset_control *phy_reset;
 
@@ -85,6 +87,8 @@
 
 	struct regmap *grf;
 	struct regmap *xpcs;
+
+	unsigned char otp_data;
 };
 
 /* XPCS */
@@ -1322,6 +1326,208 @@
 	.set_rmii_speed = rk3399_set_rmii_speed,
 };
 
+#define RK3528_VO_GRF_GMAC_CON		0X60018
+#define RK3528_VPU_GRF_GMAC_CON5	0X40018
+#define RK3528_VPU_GRF_GMAC_CON6	0X4001c
+
+#define RK3528_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
+#define RK3528_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
+#define RK3528_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(14)
+#define RK3528_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(14)
+
+#define RK3528_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0xFF, 8)
+#define RK3528_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0xFF, 0)
+
+#define RK3528_GMAC0_PHY_INTF_SEL_RMII	GRF_BIT(1)
+#define RK3528_GMAC1_PHY_INTF_SEL_RGMII	GRF_CLR_BIT(8)
+#define RK3528_GMAC1_PHY_INTF_SEL_RMII	GRF_BIT(8)
+
+#define RK3528_GMAC1_CLK_SELET_CRU	GRF_CLR_BIT(12)
+#define RK3528_GMAC1_CLK_SELET_IO	GRF_BIT(12)
+
+#define RK3528_GMAC0_CLK_RMII_DIV2	GRF_BIT(3)
+#define RK3528_GMAC0_CLK_RMII_DIV20	GRF_CLR_BIT(3)
+#define RK3528_GMAC1_CLK_RMII_DIV2	GRF_BIT(10)
+#define RK3528_GMAC1_CLK_RMII_DIV20	GRF_CLR_BIT(10)
+
+#define RK3528_GMAC1_CLK_RGMII_DIV1		\
+			(GRF_CLR_BIT(11) | GRF_CLR_BIT(10))
+#define RK3528_GMAC1_CLK_RGMII_DIV5		\
+			(GRF_BIT(11) | GRF_BIT(10))
+#define RK3528_GMAC1_CLK_RGMII_DIV50		\
+			(GRF_BIT(11) | GRF_CLR_BIT(10))
+
+#define RK3528_GMAC0_CLK_RMII_GATE	GRF_BIT(2)
+#define RK3528_GMAC0_CLK_RMII_NOGATE	GRF_CLR_BIT(2)
+#define RK3528_GMAC1_CLK_RMII_GATE	GRF_BIT(9)
+#define RK3528_GMAC1_CLK_RMII_NOGATE	GRF_CLR_BIT(9)
+
+#define RK3528_VO_GRF_MACPHY_CON0		0X6001c
+#define RK3528_VO_GRF_MACPHY_CON1		0X60020
+
+#define RK3528_VO_GRF_MACPHY_SHUTDOWN		GRF_BIT(1)
+#define RK3528_VO_GRF_MACPHY_POWERUP		GRF_CLR_BIT(1)
+#define RK3528_VO_GRF_MACPHY_INTERNAL_RMII_SEL	GRF_BIT(6)
+#define RK3528_VO_GRF_MACPHY_24M_CLK_SEL	(GRF_BIT(8) | GRF_BIT(9))
+#define RK3528_VO_GRF_MACPHY_PHY_ID		GRF_BIT(11)
+
+#define RK3528_VO_GRF_MACPHY_BGS		HIWORD_UPDATE(0x0, 0xf, 0)
+
+static void rk3528_set_to_rgmii(struct rk_priv_data *bsp_priv,
+				int tx_delay, int rx_delay)
+{
+	struct device *dev = &bsp_priv->pdev->dev;
+
+	if (IS_ERR(bsp_priv->grf)) {
+		dev_err(dev, "Missing rockchip,grf property\n");
+		return;
+	}
+
+	regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5,
+		     RK3528_GMAC1_PHY_INTF_SEL_RGMII);
+
+	regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5,
+		     DELAY_ENABLE(RK3528, tx_delay, rx_delay));
+
+	regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON6,
+		     DELAY_VALUE(RK3528, tx_delay, rx_delay));
+}
+
+static void rk3528_set_to_rmii(struct rk_priv_data *bsp_priv)
+{
+	struct device *dev = &bsp_priv->pdev->dev;
+	unsigned int id = bsp_priv->bus_id;
+
+	if (IS_ERR(bsp_priv->grf)) {
+		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
+		return;
+	}
+
+	if (id == 1)
+		regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5,
+			     RK3528_GMAC1_PHY_INTF_SEL_RMII);
+	else
+		regmap_write(bsp_priv->grf, RK3528_VO_GRF_GMAC_CON,
+			     RK3528_GMAC0_PHY_INTF_SEL_RMII);
+}
+
+static void rk3528_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+	struct device *dev = &bsp_priv->pdev->dev;
+	unsigned int val = 0;
+
+	switch (speed) {
+	case 10:
+		val = RK3528_GMAC1_CLK_RGMII_DIV50;
+		break;
+	case 100:
+		val = RK3528_GMAC1_CLK_RGMII_DIV5;
+		break;
+	case 1000:
+		val = RK3528_GMAC1_CLK_RGMII_DIV1;
+		break;
+	default:
+		goto err;
+	}
+
+	regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, val);
+	return;
+err:
+	dev_err(dev, "unknown RGMII speed value for GMAC speed=%d", speed);
+}
+
+static void rk3528_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+	struct device *dev = &bsp_priv->pdev->dev;
+	unsigned int val, offset, id = bsp_priv->bus_id;
+
+	switch (speed) {
+	case 10:
+		val = (id == 1) ? RK3528_GMAC1_CLK_RMII_DIV20 :
+				  RK3528_GMAC0_CLK_RMII_DIV20;
+		break;
+	case 100:
+		val = (id == 1) ? RK3528_GMAC1_CLK_RMII_DIV2 :
+				  RK3528_GMAC0_CLK_RMII_DIV2;
+		break;
+	default:
+		goto err;
+	}
+
+	offset = (id == 1) ? RK3528_VPU_GRF_GMAC_CON5 : RK3528_VO_GRF_GMAC_CON;
+	regmap_write(bsp_priv->grf, offset, val);
+
+	return;
+err:
+	dev_err(dev, "unknown RMII speed value for GMAC speed=%d", speed);
+}
+
+static void rk3528_set_clock_selection(struct rk_priv_data *bsp_priv,
+				       bool input, bool enable)
+{
+	unsigned int value, id = bsp_priv->bus_id;
+
+	if (id == 1) {
+		value = input ? RK3528_GMAC1_CLK_SELET_IO :
+				RK3528_GMAC1_CLK_SELET_CRU;
+		value |= enable ? RK3528_GMAC1_CLK_RMII_NOGATE :
+				  RK3528_GMAC1_CLK_RMII_GATE;
+		regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, value);
+	} else {
+		value = enable ? RK3528_GMAC0_CLK_RMII_NOGATE :
+				 RK3528_GMAC0_CLK_RMII_GATE;
+		regmap_write(bsp_priv->grf, RK3528_VO_GRF_GMAC_CON, value);
+	}
+}
+
+static void rk3528_integrated_sphy_power(struct rk_priv_data *priv, bool up)
+{
+	struct device *dev = &priv->pdev->dev;
+	unsigned int id = priv->bus_id;
+
+	/* Only GMAC0 support integrated phy */
+	if (id > 0)
+		return;
+
+	if (IS_ERR(priv->grf) || !priv->phy_reset) {
+		dev_err(dev, "%s: Missing rockchip,grf or phy_reset property\n",
+			__func__);
+		return;
+	}
+
+	if (up) {
+		unsigned int bgs = RK3528_VO_GRF_MACPHY_BGS;
+
+		reset_control_assert(priv->phy_reset);
+		udelay(20);
+		regmap_write(priv->grf, RK3528_VO_GRF_MACPHY_CON0,
+			     RK3528_VO_GRF_MACPHY_POWERUP |
+			     RK3528_VO_GRF_MACPHY_INTERNAL_RMII_SEL |
+			     RK3528_VO_GRF_MACPHY_24M_CLK_SEL |
+			     RK3528_VO_GRF_MACPHY_PHY_ID);
+
+		if (priv->otp_data > 0)
+			bgs = HIWORD_UPDATE(priv->otp_data, 0xf, 0);
+
+		regmap_write(priv->grf, RK3528_VO_GRF_MACPHY_CON1, bgs);
+		usleep_range(10 * 1000, 12 * 1000);
+		reset_control_deassert(priv->phy_reset);
+		usleep_range(50 * 1000, 60 * 1000);
+	} else {
+		regmap_write(priv->grf, RK3528_VO_GRF_MACPHY_CON0,
+			     RK3528_VO_GRF_MACPHY_SHUTDOWN);
+	}
+}
+
+static const struct rk_gmac_ops rk3528_ops = {
+	.set_to_rgmii = rk3528_set_to_rgmii,
+	.set_to_rmii = rk3528_set_to_rmii,
+	.set_rgmii_speed = rk3528_set_rgmii_speed,
+	.set_rmii_speed = rk3528_set_rmii_speed,
+	.set_clock_selection = rk3528_set_clock_selection,
+	.integrated_phy_power = rk3528_integrated_sphy_power,
+};
+
 #define RK3568_GRF_GMAC0_CON0		0X0380
 #define RK3568_GRF_GMAC0_CON1		0X0384
 #define RK3568_GRF_GMAC1_CON0		0X0388
@@ -1708,8 +1914,10 @@
 		   bsp_priv->phy_iface == PHY_INTERFACE_MODE_QSGMII) {
 		bsp_priv->pclk_xpcs = devm_clk_get(dev, "pclk_xpcs");
 		if (IS_ERR(bsp_priv->pclk_xpcs))
-			dev_err(dev, "cannot get clock %s\n",
-				"pclk_xpcs");
+			dev_err(dev, "cannot get clock %s\n", "pclk_xpcs");
+		bsp_priv->clk_xpcs_eee = devm_clk_get(dev, "clk_xpcs_eee");
+		if (IS_ERR(bsp_priv->clk_xpcs_eee))
+			dev_err(dev, "cannot get clock %s\n", "clk_xpcs_eee");
 	}
 
 	bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed");
@@ -1777,6 +1985,9 @@
 			if (!IS_ERR(bsp_priv->pclk_xpcs))
 				clk_prepare_enable(bsp_priv->pclk_xpcs);
 
+			if (!IS_ERR(bsp_priv->clk_xpcs_eee))
+				clk_prepare_enable(bsp_priv->clk_xpcs_eee);
+
 			if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
 				bsp_priv->ops->set_clock_selection(bsp_priv, bsp_priv->clock_input,
 								   true);
@@ -1813,6 +2024,8 @@
 			clk_disable_unprepare(bsp_priv->clk_mac_speed);
 
 			clk_disable_unprepare(bsp_priv->pclk_xpcs);
+
+			clk_disable_unprepare(bsp_priv->clk_xpcs_eee);
 
 			/**
 			 * if (!IS_ERR(bsp_priv->clk_mac))
@@ -1926,10 +2139,34 @@
 		bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node,
 								 "phy-is-integrated");
 		if (bsp_priv->integrated_phy) {
+			unsigned char *efuse_buf;
+			struct nvmem_cell *cell;
+			size_t len;
+
 			bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL);
 			if (IS_ERR(bsp_priv->phy_reset)) {
 				dev_err(&pdev->dev, "No PHY reset control found.\n");
 				bsp_priv->phy_reset = NULL;
+			}
+
+			/* Read bgs from OTP if it exists */
+			cell = nvmem_cell_get(dev, "bgs");
+			if (IS_ERR(cell)) {
+				if (PTR_ERR(cell) != -EPROBE_DEFER)
+					dev_info(dev, "failed to get bgs cell: %ld, use default\n",
+						 PTR_ERR(cell));
+				else
+					return ERR_CAST(cell);
+			} else {
+				efuse_buf = nvmem_cell_read(cell, &len);
+				nvmem_cell_put(cell);
+				if (!IS_ERR(efuse_buf)) {
+					if (len == 1)
+						bsp_priv->otp_data = efuse_buf[0];
+					kfree(efuse_buf);
+				} else {
+					dev_err(dev, "failed to get efuse buf, use default\n");
+				}
 			}
 		}
 	}
@@ -2284,6 +2521,9 @@
 #ifdef CONFIG_CPU_RK3399
 	{ .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops },
 #endif
+#ifdef CONFIG_CPU_RK3528
+	{ .compatible = "rockchip,rk3528-gmac", .data = &rk3528_ops },
+#endif
 #ifdef CONFIG_CPU_RK3568
 	{ .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops },
 #endif

--
Gitblit v1.6.2