diff options
author | Guo-Fu Tseng <cooldavid@cooldavid.org> | 2011-02-13 13:27:35 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-02-13 23:43:20 -0500 |
commit | 4872b11fdbbf78665230b2bb5864b1611dcb4a25 (patch) | |
tree | daa51591b2f7f2b515a549d98ed92d61f66475fb /drivers/net/jme.c | |
parent | 19d96017d1b5b1c9b709bc21a398ea793256644c (diff) |
jme: PHY Power control for new chip
After main chip rev 5, the hardware support more power saving
control registers.
Some Non-Linux drivers might turn off the phy power with new
interfaces, this patch makes it possible for Linux to turn it
on again.
Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/jme.c')
-rw-r--r-- | drivers/net/jme.c | 68 |
1 files changed, 54 insertions, 14 deletions
diff --git a/drivers/net/jme.c b/drivers/net/jme.c index d44716e804b6..d446fdb89f68 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c | |||
@@ -1577,6 +1577,38 @@ jme_free_irq(struct jme_adapter *jme) | |||
1577 | } | 1577 | } |
1578 | 1578 | ||
1579 | static inline void | 1579 | static inline void |
1580 | jme_new_phy_on(struct jme_adapter *jme) | ||
1581 | { | ||
1582 | u32 reg; | ||
1583 | |||
1584 | reg = jread32(jme, JME_PHY_PWR); | ||
1585 | reg &= ~(PHY_PWR_DWN1SEL | PHY_PWR_DWN1SW | | ||
1586 | PHY_PWR_DWN2 | PHY_PWR_CLKSEL); | ||
1587 | jwrite32(jme, JME_PHY_PWR, reg); | ||
1588 | |||
1589 | pci_read_config_dword(jme->pdev, PCI_PRIV_PE1, ®); | ||
1590 | reg &= ~PE1_GPREG0_PBG; | ||
1591 | reg |= PE1_GPREG0_ENBG; | ||
1592 | pci_write_config_dword(jme->pdev, PCI_PRIV_PE1, reg); | ||
1593 | } | ||
1594 | |||
1595 | static inline void | ||
1596 | jme_new_phy_off(struct jme_adapter *jme) | ||
1597 | { | ||
1598 | u32 reg; | ||
1599 | |||
1600 | reg = jread32(jme, JME_PHY_PWR); | ||
1601 | reg |= PHY_PWR_DWN1SEL | PHY_PWR_DWN1SW | | ||
1602 | PHY_PWR_DWN2 | PHY_PWR_CLKSEL; | ||
1603 | jwrite32(jme, JME_PHY_PWR, reg); | ||
1604 | |||
1605 | pci_read_config_dword(jme->pdev, PCI_PRIV_PE1, ®); | ||
1606 | reg &= ~PE1_GPREG0_PBG; | ||
1607 | reg |= PE1_GPREG0_PDD3COLD; | ||
1608 | pci_write_config_dword(jme->pdev, PCI_PRIV_PE1, reg); | ||
1609 | } | ||
1610 | |||
1611 | static inline void | ||
1580 | jme_phy_on(struct jme_adapter *jme) | 1612 | jme_phy_on(struct jme_adapter *jme) |
1581 | { | 1613 | { |
1582 | u32 bmcr; | 1614 | u32 bmcr; |
@@ -1584,6 +1616,22 @@ jme_phy_on(struct jme_adapter *jme) | |||
1584 | bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR); | 1616 | bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR); |
1585 | bmcr &= ~BMCR_PDOWN; | 1617 | bmcr &= ~BMCR_PDOWN; |
1586 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr); | 1618 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr); |
1619 | |||
1620 | if (new_phy_power_ctrl(jme->chip_main_rev)) | ||
1621 | jme_new_phy_on(jme); | ||
1622 | } | ||
1623 | |||
1624 | static inline void | ||
1625 | jme_phy_off(struct jme_adapter *jme) | ||
1626 | { | ||
1627 | u32 bmcr; | ||
1628 | |||
1629 | bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR); | ||
1630 | bmcr |= BMCR_PDOWN; | ||
1631 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr); | ||
1632 | |||
1633 | if (new_phy_power_ctrl(jme->chip_main_rev)) | ||
1634 | jme_new_phy_off(jme); | ||
1587 | } | 1635 | } |
1588 | 1636 | ||
1589 | static int | 1637 | static int |
@@ -1606,12 +1654,11 @@ jme_open(struct net_device *netdev) | |||
1606 | 1654 | ||
1607 | jme_start_irq(jme); | 1655 | jme_start_irq(jme); |
1608 | 1656 | ||
1609 | if (test_bit(JME_FLAG_SSET, &jme->flags)) { | 1657 | jme_phy_on(jme); |
1610 | jme_phy_on(jme); | 1658 | if (test_bit(JME_FLAG_SSET, &jme->flags)) |
1611 | jme_set_settings(netdev, &jme->old_ecmd); | 1659 | jme_set_settings(netdev, &jme->old_ecmd); |
1612 | } else { | 1660 | else |
1613 | jme_reset_phy_processor(jme); | 1661 | jme_reset_phy_processor(jme); |
1614 | } | ||
1615 | 1662 | ||
1616 | jme_reset_link(jme); | 1663 | jme_reset_link(jme); |
1617 | 1664 | ||
@@ -1657,12 +1704,6 @@ jme_wait_link(struct jme_adapter *jme) | |||
1657 | } | 1704 | } |
1658 | } | 1705 | } |
1659 | 1706 | ||
1660 | static inline void | ||
1661 | jme_phy_off(struct jme_adapter *jme) | ||
1662 | { | ||
1663 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, BMCR_PDOWN); | ||
1664 | } | ||
1665 | |||
1666 | static void | 1707 | static void |
1667 | jme_powersave_phy(struct jme_adapter *jme) | 1708 | jme_powersave_phy(struct jme_adapter *jme) |
1668 | { | 1709 | { |
@@ -3068,12 +3109,11 @@ jme_resume(struct pci_dev *pdev) | |||
3068 | jme_clear_pm(jme); | 3109 | jme_clear_pm(jme); |
3069 | pci_restore_state(pdev); | 3110 | pci_restore_state(pdev); |
3070 | 3111 | ||
3071 | if (test_bit(JME_FLAG_SSET, &jme->flags)) { | 3112 | jme_phy_on(jme); |
3072 | jme_phy_on(jme); | 3113 | if (test_bit(JME_FLAG_SSET, &jme->flags)) |
3073 | jme_set_settings(netdev, &jme->old_ecmd); | 3114 | jme_set_settings(netdev, &jme->old_ecmd); |
3074 | } else { | 3115 | else |
3075 | jme_reset_phy_processor(jme); | 3116 | jme_reset_phy_processor(jme); |
3076 | } | ||
3077 | 3117 | ||
3078 | jme_start_irq(jme); | 3118 | jme_start_irq(jme); |
3079 | netif_device_attach(netdev); | 3119 | netif_device_attach(netdev); |