Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'bcmgenet-next'

Florian Fainelli says:

====================
net: bcmgenet: integrated GPHY power up/down

This patch series implements integrated Gigabit PHY power up/down, which allows
us to save close to 300mW on some designs when the Gigabit PHY is known to be
unused (e.g: during bcmgenet_close or bcmgenet_suspend not doing Wake-on-LAN).

Changes in v2:

- drop an extra bcmgenet_ext_readl in bcmgenet_phy_power_set
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+47 -18
+25 -9
drivers/net/ethernet/broadcom/genet/bcmgenet.c
··· 847 847 }; 848 848 849 849 /* Power down the unimac, based on mode. */ 850 - static void bcmgenet_power_down(struct bcmgenet_priv *priv, 850 + static int bcmgenet_power_down(struct bcmgenet_priv *priv, 851 851 enum bcmgenet_power_mode mode) 852 852 { 853 + int ret = 0; 853 854 u32 reg; 854 855 855 856 switch (mode) { ··· 859 858 break; 860 859 861 860 case GENET_POWER_WOL_MAGIC: 862 - bcmgenet_wol_power_down_cfg(priv, mode); 861 + ret = bcmgenet_wol_power_down_cfg(priv, mode); 863 862 break; 864 863 865 864 case GENET_POWER_PASSIVE: ··· 869 868 reg |= (EXT_PWR_DOWN_PHY | 870 869 EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS); 871 870 bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); 871 + 872 + bcmgenet_phy_power_set(priv->dev, false); 872 873 } 873 874 break; 874 875 default: 875 876 break; 876 877 } 878 + 879 + return 0; 877 880 } 878 881 879 882 static void bcmgenet_power_up(struct bcmgenet_priv *priv, ··· 2467 2462 2468 2463 umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true); 2469 2464 2470 - if (phy_is_internal(priv->phydev)) 2471 - bcmgenet_power_up(priv, GENET_POWER_PASSIVE); 2472 - 2473 2465 netif_tx_start_all_queues(dev); 2474 2466 2475 2467 phy_start(priv->phydev); ··· 2484 2482 /* Turn on the clock */ 2485 2483 if (!IS_ERR(priv->clk)) 2486 2484 clk_prepare_enable(priv->clk); 2485 + 2486 + /* If this is an internal GPHY, power it back on now, before UniMAC is 2487 + * brought out of reset as absolutely no UniMAC activity is allowed 2488 + */ 2489 + if (phy_is_internal(priv->phydev)) 2490 + bcmgenet_power_up(priv, GENET_POWER_PASSIVE); 2487 2491 2488 2492 /* take MAC out of reset */ 2489 2493 bcmgenet_umac_reset(priv); ··· 2614 2606 free_irq(priv->irq1, priv); 2615 2607 2616 2608 if (phy_is_internal(priv->phydev)) 2617 - bcmgenet_power_down(priv, GENET_POWER_PASSIVE); 2609 + ret = bcmgenet_power_down(priv, GENET_POWER_PASSIVE); 2618 2610 2619 2611 if (!IS_ERR(priv->clk)) 2620 2612 clk_disable_unprepare(priv->clk); 2621 2613 2622 - return 0; 2614 + return ret; 2623 2615 } 2624 2616 2625 2617 static void bcmgenet_timeout(struct net_device *dev) ··· 3105 3097 3106 3098 /* Prepare the device for Wake-on-LAN and switch to the slow clock */ 3107 3099 if (device_may_wakeup(d) && priv->wolopts) { 3108 - bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC); 3100 + ret = bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC); 3109 3101 clk_prepare_enable(priv->clk_wol); 3102 + } else if (phy_is_internal(priv->phydev)) { 3103 + ret = bcmgenet_power_down(priv, GENET_POWER_PASSIVE); 3110 3104 } 3111 3105 3112 3106 /* Turn off the clocks */ 3113 3107 clk_disable_unprepare(priv->clk); 3114 3108 3115 - return 0; 3109 + return ret; 3116 3110 } 3117 3111 3118 3112 static int bcmgenet_resume(struct device *d) ··· 3132 3122 ret = clk_prepare_enable(priv->clk); 3133 3123 if (ret) 3134 3124 return ret; 3125 + 3126 + /* If this is an internal GPHY, power it back on now, before UniMAC is 3127 + * brought out of reset as absolutely no UniMAC activity is allowed 3128 + */ 3129 + if (phy_is_internal(priv->phydev)) 3130 + bcmgenet_power_up(priv, GENET_POWER_PASSIVE); 3135 3131 3136 3132 bcmgenet_umac_reset(priv); 3137 3133
+2
drivers/net/ethernet/broadcom/genet/bcmgenet.h
··· 354 354 #define EXT_GPHY_CTRL 0x1C 355 355 #define EXT_CFG_IDDQ_BIAS (1 << 0) 356 356 #define EXT_CFG_PWR_DOWN (1 << 1) 357 + #define EXT_CK25_DIS (1 << 4) 357 358 #define EXT_GPHY_RESET (1 << 5) 358 359 359 360 /* DMA rings size */ ··· 664 663 int bcmgenet_mii_config(struct net_device *dev, bool init); 665 664 void bcmgenet_mii_exit(struct net_device *dev); 666 665 void bcmgenet_mii_reset(struct net_device *dev); 666 + void bcmgenet_phy_power_set(struct net_device *dev, bool enable); 667 667 void bcmgenet_mii_setup(struct net_device *dev); 668 668 669 669 /* Wake-on-LAN routines */
+20 -9
drivers/net/ethernet/broadcom/genet/bcmmii.c
··· 168 168 } 169 169 } 170 170 171 - static void bcmgenet_ephy_power_up(struct net_device *dev) 171 + void bcmgenet_phy_power_set(struct net_device *dev, bool enable) 172 172 { 173 173 struct bcmgenet_priv *priv = netdev_priv(dev); 174 174 u32 reg = 0; ··· 178 178 return; 179 179 180 180 reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL); 181 - reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN); 182 - reg |= EXT_GPHY_RESET; 183 - bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); 184 - mdelay(2); 181 + if (enable) { 182 + reg &= ~EXT_CK25_DIS; 183 + bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); 184 + mdelay(1); 185 185 186 - reg &= ~EXT_GPHY_RESET; 186 + reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN); 187 + reg |= EXT_GPHY_RESET; 188 + bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); 189 + mdelay(1); 190 + 191 + reg &= ~EXT_GPHY_RESET; 192 + } else { 193 + reg |= EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN | EXT_GPHY_RESET; 194 + bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); 195 + mdelay(1); 196 + reg |= EXT_CK25_DIS; 197 + } 187 198 bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL); 188 - udelay(20); 199 + udelay(60); 189 200 } 190 201 191 202 static void bcmgenet_internal_phy_setup(struct net_device *dev) ··· 204 193 struct bcmgenet_priv *priv = netdev_priv(dev); 205 194 u32 reg; 206 195 207 - /* Power up EPHY */ 208 - bcmgenet_ephy_power_up(dev); 196 + /* Power up PHY */ 197 + bcmgenet_phy_power_set(dev, true); 209 198 /* enable APD */ 210 199 reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); 211 200 reg |= EXT_PWR_DN_EN_LD;