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 | 624 +++++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 456 insertions(+), 168 deletions(-) diff --git a/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c index c6b6cae..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> @@ -47,7 +48,10 @@ void (*set_to_qsgmii)(struct rk_priv_data *bsp_priv); void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed); void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed); - void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv); + void (*set_sgmii_speed)(struct rk_priv_data *bsp_priv, int speed); + void (*set_clock_selection)(struct rk_priv_data *bsp_priv, bool input, + bool enable); + void (*integrated_phy_power)(struct rk_priv_data *bsp_priv, bool up); }; struct rk_priv_data { @@ -61,6 +65,7 @@ bool clk_enabled; bool clock_input; bool integrated_phy; + struct phy *comphy; struct clk *clk_mac; struct clk *gmac_clkin; @@ -73,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; @@ -81,6 +87,8 @@ struct regmap *grf; struct regmap *xpcs; + + unsigned char otp_data; }; /* XPCS */ @@ -165,10 +173,10 @@ int ret, i, id = bsp_priv->bus_id; u32 val; - if (mode == PHY_INTERFACE_MODE_QSGMII && id > 0) + if (mode == PHY_INTERFACE_MODE_QSGMII && !id) return 0; - ret = xpcs_soft_reset(bsp_priv, id); + ret = xpcs_soft_reset(bsp_priv, 0); if (ret) { dev_err(&bsp_priv->pdev->dev, "xpcs_soft_reset fail %d\n", ret); return ret; @@ -195,10 +203,10 @@ SR_MII_CTRL_AN_ENABLE); } } else { - val = xpcs_read(bsp_priv, SR_MII_OFFSET(id) + VR_MII_DIG_CTRL1); - xpcs_write(bsp_priv, SR_MII_OFFSET(id) + VR_MII_DIG_CTRL1, + val = xpcs_read(bsp_priv, SR_MII_OFFSET(0) + VR_MII_DIG_CTRL1); + xpcs_write(bsp_priv, SR_MII_OFFSET(0) + VR_MII_DIG_CTRL1, val | MII_MAC_AUTO_SW); - xpcs_write(bsp_priv, SR_MII_OFFSET(id) + MII_BMCR, + xpcs_write(bsp_priv, SR_MII_OFFSET(0) + MII_BMCR, SR_MII_CTRL_AN_ENABLE); } @@ -212,8 +220,55 @@ #define GRF_CLR_BIT(nr) (BIT(nr+16)) #define DELAY_ENABLE(soc, tx, rx) \ - (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \ - ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE)) + ((((tx) >= 0) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \ + (((rx) >= 0) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE)) + +#define DELAY_VALUE(soc, tx, rx) \ + ((((tx) >= 0) ? soc##_GMAC_CLK_TX_DL_CFG(tx) : 0) | \ + (((rx) >= 0) ? soc##_GMAC_CLK_RX_DL_CFG(rx) : 0)) + +/* Integrated EPHY */ + +#define RK_GRF_MACPHY_CON0 0xb00 +#define RK_GRF_MACPHY_CON1 0xb04 +#define RK_GRF_MACPHY_CON2 0xb08 +#define RK_GRF_MACPHY_CON3 0xb0c + +#define RK_MACPHY_ENABLE GRF_BIT(0) +#define RK_MACPHY_DISABLE GRF_CLR_BIT(0) +#define RK_MACPHY_CFG_CLK_50M GRF_BIT(14) +#define RK_GMAC2PHY_RMII_MODE (GRF_BIT(6) | GRF_CLR_BIT(7)) +#define RK_GRF_CON2_MACPHY_ID HIWORD_UPDATE(0x1234, 0xffff, 0) +#define RK_GRF_CON3_MACPHY_ID HIWORD_UPDATE(0x35, 0x3f, 0) + +static void rk_gmac_integrated_ephy_powerup(struct rk_priv_data *priv) +{ + regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M); + regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE); + + regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID); + regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID); + + if (priv->phy_reset) { + /* PHY needs to be disabled before trying to reset it */ + regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); + if (priv->phy_reset) + reset_control_assert(priv->phy_reset); + usleep_range(10, 20); + if (priv->phy_reset) + reset_control_deassert(priv->phy_reset); + usleep_range(10, 20); + regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE); + msleep(30); + } +} + +static void rk_gmac_integrated_ephy_powerdown(struct rk_priv_data *priv) +{ + regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); + if (priv->phy_reset) + reset_control_assert(priv->phy_reset); +} #define PX30_GRF_GMAC_CON1 0x0904 @@ -306,12 +361,10 @@ regmap_write(bsp_priv->grf, RK1808_GRF_GMAC_CON1, RK1808_GMAC_PHY_INTF_SEL_RGMII | - RK1808_GMAC_RXCLK_DLY_ENABLE | - RK1808_GMAC_TXCLK_DLY_ENABLE); + DELAY_ENABLE(RK1808, tx_delay, rx_delay)); regmap_write(bsp_priv->grf, RK1808_GRF_GMAC_CON0, - RK1808_GMAC_CLK_RX_DL_CFG(rx_delay) | - RK1808_GMAC_CLK_TX_DL_CFG(tx_delay)); + DELAY_VALUE(RK1808, tx_delay, rx_delay)); } static void rk1808_set_to_rmii(struct rk_priv_data *bsp_priv) @@ -439,8 +492,7 @@ RK3128_GMAC_RMII_MODE_CLR); regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0, DELAY_ENABLE(RK3128, tx_delay, rx_delay) | - RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) | - RK3128_GMAC_CLK_TX_DL_CFG(tx_delay)); + DELAY_VALUE(RK3128, tx_delay, rx_delay)); } static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv) @@ -556,8 +608,7 @@ DELAY_ENABLE(RK3228, tx_delay, rx_delay)); regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0, - RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) | - RK3228_GMAC_CLK_TX_DL_CFG(tx_delay)); + DELAY_VALUE(RK3128, tx_delay, rx_delay)); } static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv) @@ -620,10 +671,16 @@ dev_err(dev, "unknown speed value for RMII! speed=%d", speed); } -static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv) +static void rk3228_integrated_phy_power(struct rk_priv_data *priv, bool up) { - regmap_write(priv->grf, RK3228_GRF_CON_MUX, - RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY); + if (up) { + regmap_write(priv->grf, RK3228_GRF_CON_MUX, + RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY); + + rk_gmac_integrated_ephy_powerup(priv); + } else { + rk_gmac_integrated_ephy_powerdown(priv); + } } static const struct rk_gmac_ops rk3228_ops = { @@ -631,7 +688,7 @@ .set_to_rmii = rk3228_set_to_rmii, .set_rgmii_speed = rk3228_set_rgmii_speed, .set_rmii_speed = rk3228_set_rmii_speed, - .integrated_phy_powerup = rk3228_integrated_phy_powerup, + .integrated_phy_power = rk3228_integrated_phy_power, }; #define RK3288_GRF_SOC_CON1 0x0248 @@ -677,8 +734,7 @@ RK3288_GMAC_RMII_MODE_CLR); regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3, DELAY_ENABLE(RK3288, tx_delay, rx_delay) | - RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) | - RK3288_GMAC_CLK_TX_DL_CFG(tx_delay)); + DELAY_VALUE(RK3288, tx_delay, rx_delay)); } static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv) @@ -849,12 +905,10 @@ regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, RK3328_GMAC_PHY_INTF_SEL_RGMII | RK3328_GMAC_RMII_MODE_CLR | - RK3328_GMAC_RXCLK_DLY_ENABLE | - RK3328_GMAC_TXCLK_DLY_ENABLE); + DELAY_ENABLE(RK3328, tx_delay, rx_delay)); regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0, - RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) | - RK3328_GMAC_CLK_TX_DL_CFG(tx_delay)); + DELAY_VALUE(RK3328, tx_delay, rx_delay)); } static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv) @@ -922,10 +976,16 @@ dev_err(dev, "unknown speed value for RMII! speed=%d", speed); } -static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv) +static void rk3328_integrated_phy_power(struct rk_priv_data *priv, bool up) { - regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1, - RK3328_MACPHY_RMII_MODE); + if (up) { + regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1, + RK3328_MACPHY_RMII_MODE); + + rk_gmac_integrated_ephy_powerup(priv); + } else { + rk_gmac_integrated_ephy_powerdown(priv); + } } static const struct rk_gmac_ops rk3328_ops = { @@ -933,7 +993,7 @@ .set_to_rmii = rk3328_set_to_rmii, .set_rgmii_speed = rk3328_set_rgmii_speed, .set_rmii_speed = rk3328_set_rmii_speed, - .integrated_phy_powerup = rk3328_integrated_phy_powerup, + .integrated_phy_power = rk3328_integrated_phy_power, }; #define RK3366_GRF_SOC_CON6 0x0418 @@ -979,8 +1039,7 @@ RK3366_GMAC_RMII_MODE_CLR); regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7, DELAY_ENABLE(RK3366, tx_delay, rx_delay) | - RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) | - RK3366_GMAC_CLK_TX_DL_CFG(tx_delay)); + DELAY_VALUE(RK3366, tx_delay, rx_delay)); } static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv) @@ -1090,8 +1149,7 @@ RK3368_GMAC_RMII_MODE_CLR); regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16, DELAY_ENABLE(RK3368, tx_delay, rx_delay) | - RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) | - RK3368_GMAC_CLK_TX_DL_CFG(tx_delay)); + DELAY_VALUE(RK3368, tx_delay, rx_delay)); } static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv) @@ -1201,8 +1259,7 @@ RK3399_GMAC_RMII_MODE_CLR); regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6, DELAY_ENABLE(RK3399, tx_delay, rx_delay) | - RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) | - RK3399_GMAC_CLK_TX_DL_CFG(tx_delay)); + DELAY_VALUE(RK3399, tx_delay, rx_delay)); } static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv) @@ -1267,6 +1324,208 @@ .set_to_rmii = rk3399_set_to_rmii, .set_rgmii_speed = rk3399_set_rgmii_speed, .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 @@ -1349,12 +1608,10 @@ regmap_write(bsp_priv->grf, offset_con1, RK3568_GMAC_PHY_INTF_SEL_RGMII | - RK3568_GMAC_RXCLK_DLY_ENABLE | - RK3568_GMAC_TXCLK_DLY_ENABLE); + DELAY_ENABLE(RK3568, tx_delay, rx_delay)); regmap_write(bsp_priv->grf, offset_con0, - RK3568_GMAC_CLK_RX_DL_CFG(rx_delay) | - RK3568_GMAC_CLK_TX_DL_CFG(tx_delay)); + DELAY_VALUE(RK3568, tx_delay, rx_delay)); } static void rk3568_set_to_rmii(struct rk_priv_data *bsp_priv) @@ -1400,6 +1657,34 @@ __func__, rate, ret); } +static void rk3568_set_gmac_sgmii_speed(struct rk_priv_data *bsp_priv, int speed) +{ + struct device *dev = &bsp_priv->pdev->dev; + unsigned int ctrl; + + /* Only gmac1 set the speed for port1 */ + if (!bsp_priv->bus_id) + return; + + switch (speed) { + case 10: + ctrl = BMCR_SPEED10; + break; + case 100: + ctrl = BMCR_SPEED100; + break; + case 1000: + ctrl = BMCR_SPEED1000; + break; + default: + dev_err(dev, "unknown speed value for GMAC speed=%d", speed); + return; + } + + xpcs_write(bsp_priv, SR_MII_OFFSET(bsp_priv->bus_id) + MII_BMCR, + ctrl | BMCR_FULLDPLX); +} + static const struct rk_gmac_ops rk3568_ops = { .set_to_rgmii = rk3568_set_to_rgmii, .set_to_rmii = rk3568_set_to_rmii, @@ -1407,6 +1692,7 @@ .set_to_qsgmii = rk3568_set_to_qsgmii, .set_rgmii_speed = rk3568_set_gmac_speed, .set_rmii_speed = rk3568_set_gmac_speed, + .set_sgmii_speed = rk3568_set_gmac_sgmii_speed, }; #define RV1108_GRF_GMAC_CON0 0X0900 @@ -1472,21 +1758,18 @@ (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) #define RV1126_GMAC_FLOW_CTRL GRF_BIT(7) #define RV1126_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(7) -#define RV1126_GMAC_M0_RXCLK_DLY_ENABLE GRF_BIT(1) -#define RV1126_GMAC_M0_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) -#define RV1126_GMAC_M0_TXCLK_DLY_ENABLE GRF_BIT(0) -#define RV1126_GMAC_M0_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) -#define RV1126_GMAC_M1_RXCLK_DLY_ENABLE GRF_BIT(3) -#define RV1126_GMAC_M1_RXCLK_DLY_DISABLE GRF_CLR_BIT(3) -#define RV1126_GMAC_M1_TXCLK_DLY_ENABLE GRF_BIT(2) -#define RV1126_GMAC_M1_TXCLK_DLY_DISABLE GRF_CLR_BIT(2) +#define RV1126_M0_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) +#define RV1126_M0_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) +#define RV1126_M0_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) +#define RV1126_M0_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) +#define RV1126_M1_GMAC_RXCLK_DLY_ENABLE GRF_BIT(3) +#define RV1126_M1_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(3) +#define RV1126_M1_GMAC_TXCLK_DLY_ENABLE GRF_BIT(2) +#define RV1126_M1_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(2) -/* RV1126_GRF_GMAC_CON1 */ -#define RV1126_GMAC_M0_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) -#define RV1126_GMAC_M0_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) -/* RV1126_GRF_GMAC_CON2 */ -#define RV1126_GMAC_M1_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) -#define RV1126_GMAC_M1_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) +/* RV1126_GRF_GMAC_CON1 && RV1126_GRF_GMAC_CON2 */ +#define RV1126_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) +#define RV1126_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) static void rv1126_set_to_rgmii(struct rk_priv_data *bsp_priv, int tx_delay, int rx_delay) @@ -1500,18 +1783,14 @@ regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0, RV1126_GMAC_PHY_INTF_SEL_RGMII | - RV1126_GMAC_M0_RXCLK_DLY_ENABLE | - RV1126_GMAC_M0_TXCLK_DLY_ENABLE | - RV1126_GMAC_M1_RXCLK_DLY_ENABLE | - RV1126_GMAC_M1_TXCLK_DLY_ENABLE); + DELAY_ENABLE(RV1126_M0, tx_delay, rx_delay) | + DELAY_ENABLE(RV1126_M1, tx_delay, rx_delay)); regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON1, - RV1126_GMAC_M0_CLK_RX_DL_CFG(rx_delay) | - RV1126_GMAC_M0_CLK_TX_DL_CFG(tx_delay)); + DELAY_VALUE(RV1126, tx_delay, rx_delay)); regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON2, - RV1126_GMAC_M1_CLK_RX_DL_CFG(rx_delay) | - RV1126_GMAC_M1_CLK_TX_DL_CFG(tx_delay)); + DELAY_VALUE(RV1126, tx_delay, rx_delay)); } static void rv1126_set_to_rmii(struct rk_priv_data *bsp_priv) @@ -1585,50 +1864,6 @@ .set_rmii_speed = rv1126_set_rmii_speed, }; -#define RK_GRF_MACPHY_CON0 0xb00 -#define RK_GRF_MACPHY_CON1 0xb04 -#define RK_GRF_MACPHY_CON2 0xb08 -#define RK_GRF_MACPHY_CON3 0xb0c - -#define RK_MACPHY_ENABLE GRF_BIT(0) -#define RK_MACPHY_DISABLE GRF_CLR_BIT(0) -#define RK_MACPHY_CFG_CLK_50M GRF_BIT(14) -#define RK_GMAC2PHY_RMII_MODE (GRF_BIT(6) | GRF_CLR_BIT(7)) -#define RK_GRF_CON2_MACPHY_ID HIWORD_UPDATE(0x1234, 0xffff, 0) -#define RK_GRF_CON3_MACPHY_ID HIWORD_UPDATE(0x35, 0x3f, 0) - -static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv) -{ - if (priv->ops->integrated_phy_powerup) - priv->ops->integrated_phy_powerup(priv); - - regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M); - regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE); - - regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID); - regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID); - - if (priv->phy_reset) { - /* PHY needs to be disabled before trying to reset it */ - regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); - if (priv->phy_reset) - reset_control_assert(priv->phy_reset); - usleep_range(10, 20); - if (priv->phy_reset) - reset_control_deassert(priv->phy_reset); - usleep_range(10, 20); - regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE); - msleep(30); - } -} - -static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv) -{ - regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); - if (priv->phy_reset) - reset_control_assert(priv->phy_reset); -} - static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat) { struct rk_priv_data *bsp_priv = plat->bsp_priv; @@ -1679,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"); @@ -1748,15 +1985,26 @@ 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); + /** * if (!IS_ERR(bsp_priv->clk_mac)) * clk_prepare_enable(bsp_priv->clk_mac); */ - mdelay(5); + usleep_range(100, 200); bsp_priv->clk_enabled = true; } } else { if (bsp_priv->clk_enabled) { + if (bsp_priv->ops && bsp_priv->ops->set_clock_selection) + bsp_priv->ops->set_clock_selection(bsp_priv, bsp_priv->clock_input, + false); + if (phy_iface == PHY_INTERFACE_MODE_RMII) { clk_disable_unprepare(bsp_priv->mac_clk_rx); @@ -1776,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)) @@ -1853,7 +2103,7 @@ ret = of_property_read_u32(dev->of_node, "tx_delay", &value); if (ret) { - bsp_priv->tx_delay = 0x30; + bsp_priv->tx_delay = -1; dev_err(dev, "Can not read property: tx_delay."); dev_err(dev, "set tx_delay to 0x%x\n", bsp_priv->tx_delay); @@ -1864,7 +2114,7 @@ ret = of_property_read_u32(dev->of_node, "rx_delay", &value); if (ret) { - bsp_priv->rx_delay = 0x10; + bsp_priv->rx_delay = -1; dev_err(dev, "Can not read property: rx_delay."); dev_err(dev, "set rx_delay to 0x%x\n", bsp_priv->rx_delay); @@ -1878,24 +2128,45 @@ bsp_priv->xpcs = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,xpcs"); if (!IS_ERR(bsp_priv->xpcs)) { - struct phy *comphy; - - comphy = devm_of_phy_get(&pdev->dev, dev->of_node, NULL); - if (IS_ERR(comphy)) + bsp_priv->comphy = devm_of_phy_get(&pdev->dev, dev->of_node, NULL); + if (IS_ERR(bsp_priv->comphy)) { + bsp_priv->comphy = NULL; dev_err(dev, "devm_of_phy_get error\n"); - ret = phy_init(comphy); - if (ret) - dev_err(dev, "phy_init error\n"); + } } if (plat->phy_node) { 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"); + } } } } @@ -1927,17 +2198,17 @@ case PHY_INTERFACE_MODE_RGMII_ID: dev_info(dev, "init for RGMII_ID\n"); if (bsp_priv->ops && bsp_priv->ops->set_to_rgmii) - bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0); + bsp_priv->ops->set_to_rgmii(bsp_priv, -1, -1); break; case PHY_INTERFACE_MODE_RGMII_RXID: dev_info(dev, "init for RGMII_RXID\n"); if (bsp_priv->ops && bsp_priv->ops->set_to_rgmii) - bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0); + bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, -1); break; case PHY_INTERFACE_MODE_RGMII_TXID: dev_info(dev, "init for RGMII_TXID\n"); if (bsp_priv->ops && bsp_priv->ops->set_to_rgmii) - bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay); + bsp_priv->ops->set_to_rgmii(bsp_priv, -1, bsp_priv->rx_delay); break; case PHY_INTERFACE_MODE_RMII: dev_info(dev, "init for RMII\n"); @@ -1946,11 +2217,23 @@ break; case PHY_INTERFACE_MODE_SGMII: dev_info(dev, "init for SGMII\n"); + ret = phy_init(bsp_priv->comphy); + if (ret) { + dev_err(dev, "phy_init error: %d\n", ret); + return ret; + } + if (bsp_priv->ops && bsp_priv->ops->set_to_sgmii) bsp_priv->ops->set_to_sgmii(bsp_priv); break; case PHY_INTERFACE_MODE_QSGMII: dev_info(dev, "init for QSGMII\n"); + ret = phy_init(bsp_priv->comphy); + if (ret) { + dev_err(dev, "phy_init error: %d\n", ret); + return ret; + } + if (bsp_priv->ops && bsp_priv->ops->set_to_qsgmii) bsp_priv->ops->set_to_qsgmii(bsp_priv); break; @@ -1967,9 +2250,6 @@ pm_runtime_enable(dev); pm_runtime_get_sync(dev); - if (bsp_priv->integrated_phy) - rk_gmac_integrated_phy_powerup(bsp_priv); - return 0; } @@ -1977,8 +2257,9 @@ { struct device *dev = &gmac->pdev->dev; - if (gmac->integrated_phy) - rk_gmac_integrated_phy_powerdown(gmac); + if (gmac->phy_iface == PHY_INTERFACE_MODE_SGMII || + gmac->phy_iface == PHY_INTERFACE_MODE_QSGMII) + phy_exit(gmac->comphy); pm_runtime_put_sync(dev); pm_runtime_disable(dev); @@ -2005,11 +2286,26 @@ bsp_priv->ops->set_rmii_speed(bsp_priv, speed); break; case PHY_INTERFACE_MODE_SGMII: + if (bsp_priv->ops && bsp_priv->ops->set_sgmii_speed) + bsp_priv->ops->set_sgmii_speed(bsp_priv, speed); case PHY_INTERFACE_MODE_QSGMII: break; default: dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); } +} + +static int rk_integrated_phy_power(void *priv, bool up) +{ + struct rk_priv_data *bsp_priv = priv; + + if (!bsp_priv->integrated_phy || !bsp_priv->ops || + !bsp_priv->ops->integrated_phy_power) + return 0; + + bsp_priv->ops->integrated_phy_power(bsp_priv, up); + + return 0; } void dwmac_rk_set_rgmii_delayline(struct stmmac_priv *priv, @@ -2050,24 +2346,17 @@ { } -static unsigned char macaddr[6]; -extern ssize_t at24_mac_read(unsigned char* addr); void rk_get_eth_addr(void *priv, unsigned char *addr) { struct rk_priv_data *bsp_priv = priv; struct device *dev = &bsp_priv->pdev->dev; - int i; - //unsigned char ethaddr[ETH_ALEN * MAX_ETH] = {0}; - //int ret, id = bsp_priv->bus_id; + unsigned char ethaddr[ETH_ALEN * MAX_ETH] = {0}; + int ret, id = bsp_priv->bus_id; - //ben - printk("nk-debug:enter rk_get_eth_addr.. \n"); - - #if 0 rk_devinfo_get_eth_mac(addr); if (is_valid_ether_addr(addr)) goto out; - + if (id < 0 || id >= MAX_ETH) { dev_err(dev, "%s: Invalid ethernet bus id %d\n", __func__, id); return; @@ -2094,35 +2383,7 @@ } else { memcpy(addr, ðaddr[id * ETH_ALEN], ETH_ALEN); } - #endif - - #if 0 - macaddr[0] = 0xee; - macaddr[1] = 0x31; - macaddr[2] = 0x32; - macaddr[3] = 0x33; - macaddr[4] = 0x34; - macaddr[5] = 0x35; - - memcpy(addr, macaddr, 6); - #endif - - #if 1 - if (at24_mac_read(macaddr) > 0) { - printk("ben %s: at24_mac_read Success!! \n", __func__); - memcpy(addr, macaddr, 6); - printk("Read the Ethernet MAC address from :"); - for (i = 0; i < 5; i++) - printk("%2.2x:", addr[i]); - - printk("%2.2x\n", addr[i]); - } else { - printk("ben %s: at24_mac_read Failed!! \n", __func__); - goto out; - } - #endif - out: dev_err(dev, "%s: mac address: %pM\n", __func__, addr); } @@ -2134,7 +2395,6 @@ const struct rk_gmac_ops *data; int ret; - printk("nk-debug:enter rk_gmac_probe 1.. \n"); data = of_device_get_match_data(&pdev->dev); if (!data) { dev_err(&pdev->dev, "no of match data provided\n"); @@ -2154,6 +2414,7 @@ plat_dat->fix_mac_speed = rk_fix_speed; plat_dat->get_eth_addr = rk_get_eth_addr; + plat_dat->integrated_phy_power = rk_integrated_phy_power; plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data); if (IS_ERR(plat_dat->bsp_priv)) { @@ -2161,7 +2422,6 @@ goto err_remove_config_dt; } - printk("nk-debug:enter rk_gmac_probe 2.. \n"); ret = rk_gmac_clk_init(plat_dat); if (ret) goto err_remove_config_dt; @@ -2231,19 +2491,48 @@ static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume); static const struct of_device_id rk_gmac_dwmac_match[] = { +#ifdef CONFIG_CPU_PX30 { .compatible = "rockchip,px30-gmac", .data = &px30_ops }, +#endif +#ifdef CONFIG_CPU_RK1808 { .compatible = "rockchip,rk1808-gmac", .data = &rk1808_ops }, +#endif +#ifdef CONFIG_CPU_RK312X { .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops }, +#endif +#ifdef CONFIG_CPU_RK322X { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops }, +#endif +#ifdef CONFIG_CPU_RK3288 { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, +#endif +#ifdef CONFIG_CPU_RK3308 { .compatible = "rockchip,rk3308-mac", .data = &rk3308_ops }, +#endif +#ifdef CONFIG_CPU_RK3328 { .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops }, +#endif +#ifdef CONFIG_CPU_RK3366 { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops }, +#endif +#ifdef CONFIG_CPU_RK3368 { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, +#endif +#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 +#ifdef CONFIG_CPU_RV110X { .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops }, +#endif +#ifdef CONFIG_CPU_RV1126 { .compatible = "rockchip,rv1126-gmac", .data = &rv1126_ops }, +#endif { } }; MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match); @@ -2257,8 +2546,7 @@ .of_match_table = rk_gmac_dwmac_match, }, }; -//module_platform_driver(rk_gmac_dwmac_driver); - module_platform_driver1(rk_gmac_dwmac_driver); +module_platform_driver(rk_gmac_dwmac_driver); MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>"); MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer"); -- Gitblit v1.6.2