net: stmmac: Add integrated phy powe up/down for ethernet up/down

For integrated PHY, there is no stmmac_mdio_reset(), so add callback for
the PHY power control during ethernet interface up/down, and suspend/resume.

Signed-off-by: David Wu <david.wu@rock-chips.com>
Change-Id: Ib8ae375ee885aecefc7f5b9a6617523186a3f0e1
This commit is contained in:
David Wu 2022-03-26 19:20:50 +08:00 committed by Tao Huang
parent c002048f4f
commit 931b12539b
3 changed files with 44 additions and 11 deletions

View File

@ -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)) {

View File

@ -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) {

View File

@ -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);