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