From 97e4dc4a4f27dc5f68797a9e1b26cb3e208c7fa3 Mon Sep 17 00:00:00 2001 From: Wadim Egorov Date: Wed, 29 Mar 2017 14:12:19 +0200 Subject: [PATCH] UPSTREAM: net: stmmac: dwmac-rk: Add handling for RGMII_ID/RXID/TXID ATM dwmac-rk will always set and enable it's internal delay lines. 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. Tested only with a RK3288 based board. Signed-off-by: Wadim Egorov Signed-off-by: David S. Miller (cherry picked from commit eaf70ad14cbbb99d46b78b1307628a16a3f6075d) Change-Id: Id0152a9f048cbc810b62c252d4105594ed1895df Signed-off-by: Jacob Chen --- .../net/ethernet/stmicro/stmmac/dwmac-rk.c | 53 +++++++++++++------ 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c index 70538ae2be2f..3080502e79de 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c @@ -73,6 +73,10 @@ struct rk_priv_data { #define GRF_BIT(nr) (BIT(nr) | BIT(nr+16)) #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)) + #define RK3228_GRF_MAC_CON0 0x0900 #define RK3228_GRF_MAC_CON1 0x0904 @@ -114,8 +118,7 @@ static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv, regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, RK3228_GMAC_PHY_INTF_SEL_RGMII | RK3228_GMAC_RMII_MODE_CLR | - RK3228_GMAC_RXCLK_DLY_ENABLE | - RK3228_GMAC_TXCLK_DLY_ENABLE); + DELAY_ENABLE(RK3228, tx_delay, rx_delay)); regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0, RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) | @@ -231,8 +234,7 @@ static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv, RK3288_GMAC_PHY_INTF_SEL_RGMII | RK3288_GMAC_RMII_MODE_CLR); regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3, - RK3288_GMAC_RXCLK_DLY_ENABLE | - RK3288_GMAC_TXCLK_DLY_ENABLE | + DELAY_ENABLE(RK3288, tx_delay, rx_delay) | RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) | RK3288_GMAC_CLK_TX_DL_CFG(tx_delay)); } @@ -459,8 +461,7 @@ static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv, RK3366_GMAC_PHY_INTF_SEL_RGMII | RK3366_GMAC_RMII_MODE_CLR); regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7, - RK3366_GMAC_RXCLK_DLY_ENABLE | - RK3366_GMAC_TXCLK_DLY_ENABLE | + DELAY_ENABLE(RK3366, tx_delay, rx_delay) | RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) | RK3366_GMAC_CLK_TX_DL_CFG(tx_delay)); } @@ -571,8 +572,7 @@ static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv, RK3368_GMAC_PHY_INTF_SEL_RGMII | RK3368_GMAC_RMII_MODE_CLR); regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16, - RK3368_GMAC_RXCLK_DLY_ENABLE | - RK3368_GMAC_TXCLK_DLY_ENABLE | + DELAY_ENABLE(RK3368, tx_delay, rx_delay) | RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) | RK3368_GMAC_CLK_TX_DL_CFG(tx_delay)); } @@ -683,8 +683,7 @@ static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv, RK3399_GMAC_PHY_INTF_SEL_RGMII | RK3399_GMAC_RMII_MODE_CLR); regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6, - RK3399_GMAC_RXCLK_DLY_ENABLE | - RK3399_GMAC_TXCLK_DLY_ENABLE | + DELAY_ENABLE(RK3399, tx_delay, rx_delay) | RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) | RK3399_GMAC_CLK_TX_DL_CFG(tx_delay)); } @@ -981,14 +980,29 @@ static int rk_gmac_init(struct platform_device *pdev, void *priv) struct device *dev = &pdev->dev; /*rmii or rgmii*/ - if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) { + switch (bsp_priv->phy_iface) { + case PHY_INTERFACE_MODE_RGMII: dev_info(dev, "init for RGMII\n"); bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, bsp_priv->rx_delay); - } else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) { + break; + case PHY_INTERFACE_MODE_RGMII_ID: + dev_info(dev, "init for RGMII_ID\n"); + bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0); + break; + case PHY_INTERFACE_MODE_RGMII_RXID: + dev_info(dev, "init for RGMII_RXID\n"); + bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0); + break; + case PHY_INTERFACE_MODE_RGMII_TXID: + dev_info(dev, "init for RGMII_TXID\n"); + bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay); + break; + case PHY_INTERFACE_MODE_RMII: dev_info(dev, "init for RMII\n"); bsp_priv->ops->set_to_rmii(bsp_priv); - } else { + break; + default: dev_err(dev, "NO interface defined!\n"); } @@ -1022,12 +1036,19 @@ static void rk_fix_speed(void *priv, unsigned int speed) struct rk_priv_data *bsp_priv = priv; struct device *dev = &bsp_priv->pdev->dev; - if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) + switch (bsp_priv->phy_iface) { + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: bsp_priv->ops->set_rgmii_speed(bsp_priv, speed); - else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) + break; + case PHY_INTERFACE_MODE_RMII: bsp_priv->ops->set_rmii_speed(bsp_priv, speed); - else + break; + default: dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); + } } void __weak rk_devinfo_get_eth_mac(u8 *mac) -- 2.34.1