mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 15:41:40 +00:00
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>
This commit is contained in:
parent
04acabd22c
commit
3d1bd5b590
1 changed files with 73 additions and 27 deletions
|
@ -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:
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/* Set to RGMII mode */
|
||||
if (ops->set_to_rgmii)
|
||||
ops->set_to_rgmii(pdata);
|
||||
else
|
||||
return -EPERM;
|
||||
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_RMII:
|
||||
/* The commet is the same as RGMII mode */
|
||||
/*
|
||||
* 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, 50000000);
|
||||
if (rate != 50000000)
|
||||
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) {
|
||||
pdata->tx_delay = 0;
|
||||
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;
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue