mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 06:25:52 +02:00
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:
parent
c002048f4f
commit
931b12539b
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user