diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c index bee65b49c810..62a1dcc8de53 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c @@ -1609,7 +1609,20 @@ static const struct rk_gmac_ops rk3588_ops = { #define RV1106_VOGRF_MACPHY_CON1 0X6002C -#define RV1106_VOGRF_MACPHY_BGS GRF_BIT(2) +#define RV1106_VOGRF_MACPHY_BGS HIWORD_UPDATE(0xd, 0xf, 0) + +static void rv1106_set_to_rmii(struct rk_priv_data *bsp_priv) +{ + struct device *dev = &bsp_priv->pdev->dev; + + if (IS_ERR(bsp_priv->grf)) { + dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); + return; + } + + regmap_write(bsp_priv->grf, RV1106_VOGRF_GMAC_CLK_CON, + RV1106_VOGRF_MACPHY_RMII_MODE); +} static void rv1106_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) { @@ -1644,8 +1657,6 @@ static void rv1106_integrated_sphy_power(struct rk_priv_data *priv, bool up) } if (up) { - regmap_write(priv->grf, RV1106_VOGRF_GMAC_CLK_CON, - RV1106_VOGRF_MACPHY_RMII_MODE); reset_control_assert(priv->phy_reset); udelay(20); regmap_write(priv->grf, RV1106_VOGRF_MACPHY_CON0, @@ -1655,7 +1666,9 @@ static void rv1106_integrated_sphy_power(struct rk_priv_data *priv, bool up) RV1106_VOGRF_MACPHY_PHY_ID); regmap_write(priv->grf, RV1106_VOGRF_MACPHY_CON1, RV1106_VOGRF_MACPHY_BGS); + usleep_range(10 * 1000, 12 * 1000); reset_control_deassert(priv->phy_reset); + usleep_range(50 * 1000, 60 * 1000); } else { regmap_write(priv->grf, RV1106_VOGRF_MACPHY_CON0, RV1106_VOGRF_MACPHY_SHUTDOWN); @@ -1663,6 +1676,7 @@ static void rv1106_integrated_sphy_power(struct rk_priv_data *priv, bool up) } static const struct rk_gmac_ops rv1106_ops = { + .set_to_rmii = rv1106_set_to_rmii, .set_rmii_speed = rv1106_set_rmii_speed, .integrated_phy_power = rv1106_integrated_sphy_power, }; @@ -2183,10 +2197,6 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) pm_runtime_enable(dev); pm_runtime_get_sync(dev); - if (bsp_priv->integrated_phy && bsp_priv->ops && - bsp_priv->ops->integrated_phy_power) - bsp_priv->ops->integrated_phy_power(bsp_priv, true); - return 0; } @@ -2194,10 +2204,6 @@ static void rk_gmac_powerdown(struct rk_priv_data *gmac) { struct device *dev = &gmac->pdev->dev; - if (gmac->integrated_phy && gmac->ops && - gmac->ops->integrated_phy_power) - gmac->ops->integrated_phy_power(gmac, false); - pm_runtime_put_sync(dev); pm_runtime_disable(dev); @@ -2230,6 +2236,19 @@ static void rk_fix_speed(void *priv, unsigned int speed) } } +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, int tx_delay, int rx_delay) { @@ -2332,6 +2351,7 @@ static int rk_gmac_probe(struct platform_device *pdev) plat_dat->sph_disable = true; 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)) { diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 7f42033c403c..b79ab5fc66a8 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1059,6 +1059,9 @@ static int stmmac_init_phy(struct net_device *dev) struct device_node *node; int ret; + if (priv->plat->integrated_phy_power) + ret = priv->plat->integrated_phy_power(priv->plat->bsp_priv, true); + node = priv->plat->phylink_node; if (node) @@ -2946,6 +2949,9 @@ static int stmmac_release(struct net_device *dev) phylink_stop(priv->phylink); phylink_disconnect_phy(priv->phylink); + if (priv->plat->integrated_phy_power) + priv->plat->integrated_phy_power(priv->plat->bsp_priv, false); + stmmac_disable_all_queues(priv); for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) @@ -5231,6 +5237,9 @@ int stmmac_suspend(struct device *dev) rtnl_lock(); if (device_may_wakeup(priv->device)) phylink_speed_down(priv->phylink, false); + if (priv->plat->integrated_phy_power) + priv->plat->integrated_phy_power(priv->plat->bsp_priv, + false); phylink_stop(priv->phylink); rtnl_unlock(); mutex_lock(&priv->lock); @@ -5314,6 +5323,9 @@ int stmmac_resume(struct device *dev) /* reset the phy so that it's ready */ if (priv->mii) stmmac_mdio_reset(priv->mii); + if (priv->plat->integrated_phy_power) + priv->plat->integrated_phy_power(priv->plat->bsp_priv, + true); } if (priv->plat->serdes_powerup) { diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 25f738478092..1f4a7c840f02 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -182,6 +182,7 @@ struct plat_stmmacenet_data { void (*fix_mac_speed)(void *priv, unsigned int speed); int (*serdes_powerup)(struct net_device *ndev, void *priv); void (*serdes_powerdown)(struct net_device *ndev, void *priv); + int (*integrated_phy_power)(void *priv, bool up); int (*init)(struct platform_device *pdev, void *priv); void (*exit)(struct platform_device *pdev, void *priv); void (*get_eth_addr)(void *priv, unsigned char *addr);