diff options
author | Janine Hagemann <j.hagemann@phytec.de> | 2018-08-28 08:25:05 +0200 |
---|---|---|
committer | Philipp Tomsich <philipp.tomsich@theobroma-systems.com> | 2018-10-04 21:15:46 +0200 |
commit | 3d1bd5b5908db002a7d52a43bca744bc33790453 (patch) | |
tree | ea6ce12d9065aceb0d909bece36ac0d7204d1b8f /drivers | |
parent | 04acabd22c2473c7dd65c3a5f900cb80d9619cc0 (diff) | |
download | u-boot-3d1bd5b5908db002a7d52a43bca744bc33790453.tar.gz |
net: gmac_rockchip: Add handling for RGMII_ID/RXID/TXID
Using PHY internal delays in combination with the phy-mode
rgmii-id/rxid/txid was not possible. Only rgmii was supported.
Now we can disable rockchip's gmac delay lines and also use
rgmii-id/rxid/txid.
Based on commit eaf70ad14cbb ("net: stmmac: dwmac-rk: Add
handling for RGMII_ID/RXID/TXID") for mainline linux kernel.
Signed-off-by: Janine Hagemann <j.hagemann@phytec.de>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Reviewed-by: David Wu <david.wu@rock-chips.com>
Reviewed-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/gmac_rockchip.c | 80 |
1 files changed, 63 insertions, 17 deletions
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index 0f91731172..c01ae758c7 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -24,6 +24,11 @@ #include <dt-bindings/clock/rk3288-cru.h> #include "designware.h" +DECLARE_GLOBAL_DATA_PTR; +#define DELAY_ENABLE(soc, tx, rx) \ + (((tx) ? soc##_TXCLK_DLY_ENA_GMAC_ENABLE : soc##_TXCLK_DLY_ENA_GMAC_DISABLE) | \ + ((rx) ? soc##_RXCLK_DLY_ENA_GMAC_ENABLE : soc##_RXCLK_DLY_ENA_GMAC_DISABLE)) + /* * Platform data for the gmac * @@ -286,8 +291,7 @@ static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) RK3228_RXCLK_DLY_ENA_GMAC_MASK | RK3228_TXCLK_DLY_ENA_GMAC_MASK, RK3228_GMAC_PHY_INTF_SEL_RGMII | - RK3228_RXCLK_DLY_ENA_GMAC_ENABLE | - RK3228_TXCLK_DLY_ENA_GMAC_ENABLE); + DELAY_ENABLE(RK3228, pdata->tx_delay, pdata->rx_delay)); rk_clrsetreg(&grf->mac_con[0], RK3228_CLK_RX_DL_CFG_GMAC_MASK | @@ -310,8 +314,7 @@ static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) RK3288_TXCLK_DLY_ENA_GMAC_MASK | RK3288_CLK_RX_DL_CFG_GMAC_MASK | RK3288_CLK_TX_DL_CFG_GMAC_MASK, - RK3288_RXCLK_DLY_ENA_GMAC_ENABLE | - RK3288_TXCLK_DLY_ENA_GMAC_ENABLE | + DELAY_ENABLE(RK3288, pdata->rx_delay, pdata->tx_delay) | pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT | pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT); } @@ -350,8 +353,7 @@ static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) RK3328_RXCLK_DLY_ENA_GMAC_MASK | RK3328_TXCLK_DLY_ENA_GMAC_MASK, RK3328_GMAC_PHY_INTF_SEL_RGMII | - RK3328_RXCLK_DLY_ENA_GMAC_ENABLE | - RK3328_TXCLK_DLY_ENA_GMAC_ENABLE); + DELAY_ENABLE(RK3328, pdata->tx_delay, pdata->rx_delay)); rk_clrsetreg(&grf->mac_con[0], RK3328_CLK_RX_DL_CFG_GMAC_MASK | @@ -392,8 +394,7 @@ static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) RK3368_TXCLK_DLY_ENA_GMAC_MASK | RK3368_CLK_RX_DL_CFG_GMAC_MASK | RK3368_CLK_TX_DL_CFG_GMAC_MASK, - RK3368_RXCLK_DLY_ENA_GMAC_ENABLE | - RK3368_TXCLK_DLY_ENA_GMAC_ENABLE | + DELAY_ENABLE(RK3368, pdata->tx_delay, pdata->rx_delay) | pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT | pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT); } @@ -413,8 +414,7 @@ static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) RK3399_TXCLK_DLY_ENA_GMAC_MASK | RK3399_CLK_RX_DL_CFG_GMAC_MASK | RK3399_CLK_TX_DL_CFG_GMAC_MASK, - RK3399_RXCLK_DLY_ENA_GMAC_ENABLE | - RK3399_TXCLK_DLY_ENA_GMAC_ENABLE | + DELAY_ENABLE(RK3399, pdata->tx_delay, pdata->rx_delay) | pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT | pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT); } @@ -451,40 +451,86 @@ static int gmac_rockchip_probe(struct udevice *dev) switch (eth_pdata->phy_interface) { case PHY_INTERFACE_MODE_RGMII: + /* Set to RGMII mode */ + if (ops->set_to_rgmii) + ops->set_to_rgmii(pdata); + else + return -EPERM; + /* * If the gmac clock is from internal pll, need to set and * check the return value for gmac clock at RGMII mode. If * the gmac clock is from external source, the clock rate * is not set, because of it is bypassed. */ + if (!pdata->clock_input) { rate = clk_set_rate(&clk, 125000000); if (rate != 125000000) return -EINVAL; } + break; + case PHY_INTERFACE_MODE_RGMII_ID: /* Set to RGMII mode */ - if (ops->set_to_rgmii) + if (ops->set_to_rgmii) { + pdata->tx_delay = 0; + pdata->rx_delay = 0; ops->set_to_rgmii(pdata); - else + } else return -EPERM; - break; - case PHY_INTERFACE_MODE_RMII: - /* The commet is the same as RGMII mode */ if (!pdata->clock_input) { - rate = clk_set_rate(&clk, 50000000); - if (rate != 50000000) + rate = clk_set_rate(&clk, 125000000); + if (rate != 125000000) return -EINVAL; } + break; + case PHY_INTERFACE_MODE_RMII: /* Set to RMII mode */ if (ops->set_to_rmii) ops->set_to_rmii(pdata); else return -EPERM; + if (!pdata->clock_input) { + rate = clk_set_rate(&clk, 50000000); + if (rate != 50000000) + return -EINVAL; + } + break; + + case PHY_INTERFACE_MODE_RGMII_RXID: + /* Set to RGMII_RXID mode */ + if (ops->set_to_rgmii) { + pdata->tx_delay = 0; + ops->set_to_rgmii(pdata); + } else + return -EPERM; + + if (!pdata->clock_input) { + rate = clk_set_rate(&clk, 125000000); + if (rate != 125000000) + return -EINVAL; + } break; + + case PHY_INTERFACE_MODE_RGMII_TXID: + /* Set to RGMII_TXID mode */ + if (ops->set_to_rgmii) { + pdata->rx_delay = 0; + ops->set_to_rgmii(pdata); + } else + return -EPERM; + + if (!pdata->clock_input) { + rate = clk_set_rate(&clk, 125000000); + if (rate != 125000000) + return -EINVAL; + } + break; + default: debug("NO interface defined!\n"); return -ENXIO; |