Commit 520b2756 authored by Matt Carlson's avatar Matt Carlson Committed by David S. Miller

tg3: Create funcs for power source switching

The power source switching code is about to get a little more complex.
This patch seeks to simplify future power source switching patches by
clarifying the existing code.
Signed-off-by: default avatarMatt Carlson <mcarlson@broadcom.com>
Reviewed-by: default avatarMichael Chan <mchan@broadcom.com>
Reviewed-by: default avatarBenjamin Li <benli@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@conan.davemloft.net>
parent 221c5637
...@@ -107,6 +107,8 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) ...@@ -107,6 +107,8 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
NETIF_MSG_RX_ERR | \ NETIF_MSG_RX_ERR | \
NETIF_MSG_TX_ERR) NETIF_MSG_TX_ERR)
#define TG3_GRC_LCLCTL_PWRSW_DELAY 100
/* length of time before we decide the hardware is borked, /* length of time before we decide the hardware is borked,
* and dev->tx_timeout() should be called to fix the problem * and dev->tx_timeout() should be called to fix the problem
*/ */
...@@ -2165,42 +2167,46 @@ static int tg3_phy_reset(struct tg3 *tp) ...@@ -2165,42 +2167,46 @@ static int tg3_phy_reset(struct tg3 *tp)
return 0; return 0;
} }
static void tg3_frob_aux_power(struct tg3 *tp) static inline int tg3_pwrsrc_switch_to_vmain(struct tg3 *tp)
{ {
bool need_vaux = false; if (!tg3_flag(tp, IS_NIC))
return 0;
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl,
TG3_GRC_LCLCTL_PWRSW_DELAY);
return 0;
}
static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp)
{
u32 grc_local_ctrl;
/* The GPIOs do something completely different on 57765. */
if (!tg3_flag(tp, IS_NIC) || if (!tg3_flag(tp, IS_NIC) ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)
return; return;
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || grc_local_ctrl = tp->grc_local_ctrl | GRC_LCLCTRL_GPIO_OE1;
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) &&
tp->pdev_peer != tp->pdev) {
struct net_device *dev_peer;
dev_peer = pci_get_drvdata(tp->pdev_peer);
/* remove_one() may have been run on the peer. */ tw32_wait_f(GRC_LOCAL_CTRL,
if (dev_peer) { grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1,
struct tg3 *tp_peer = netdev_priv(dev_peer); TG3_GRC_LCLCTL_PWRSW_DELAY);
if (tg3_flag(tp_peer, INIT_COMPLETE)) tw32_wait_f(GRC_LOCAL_CTRL,
return; grc_local_ctrl,
TG3_GRC_LCLCTL_PWRSW_DELAY);
if (tg3_flag(tp_peer, WOL_ENABLE) || tw32_wait_f(GRC_LOCAL_CTRL,
tg3_flag(tp_peer, ENABLE_ASF)) grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1,
need_vaux = true; TG3_GRC_LCLCTL_PWRSW_DELAY);
} }
}
if (tg3_flag(tp, WOL_ENABLE) || tg3_flag(tp, ENABLE_ASF)) static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
need_vaux = true; {
if (!tg3_flag(tp, IS_NIC))
return;
if (need_vaux) {
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
...@@ -2209,7 +2215,7 @@ static void tg3_frob_aux_power(struct tg3 *tp) ...@@ -2209,7 +2215,7 @@ static void tg3_frob_aux_power(struct tg3 *tp)
GRC_LCLCTRL_GPIO_OE2 | GRC_LCLCTRL_GPIO_OE2 |
GRC_LCLCTRL_GPIO_OUTPUT0 | GRC_LCLCTRL_GPIO_OUTPUT0 |
GRC_LCLCTRL_GPIO_OUTPUT1), GRC_LCLCTRL_GPIO_OUTPUT1),
100); TG3_GRC_LCLCTL_PWRSW_DELAY);
} else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 || } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) { tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
/* The 5761 non-e device swaps GPIO 0 and GPIO 2. */ /* The 5761 non-e device swaps GPIO 0 and GPIO 2. */
...@@ -2219,23 +2225,26 @@ static void tg3_frob_aux_power(struct tg3 *tp) ...@@ -2219,23 +2225,26 @@ static void tg3_frob_aux_power(struct tg3 *tp)
GRC_LCLCTRL_GPIO_OUTPUT0 | GRC_LCLCTRL_GPIO_OUTPUT0 |
GRC_LCLCTRL_GPIO_OUTPUT1 | GRC_LCLCTRL_GPIO_OUTPUT1 |
tp->grc_local_ctrl; tp->grc_local_ctrl;
tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100); tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl,
TG3_GRC_LCLCTL_PWRSW_DELAY);
grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT2; grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT2;
tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100); tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl,
TG3_GRC_LCLCTL_PWRSW_DELAY);
grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT0; grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT0;
tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl, 100); tw32_wait_f(GRC_LOCAL_CTRL, grc_local_ctrl,
TG3_GRC_LCLCTL_PWRSW_DELAY);
} else { } else {
u32 no_gpio2; u32 no_gpio2;
u32 grc_local_ctrl = 0; u32 grc_local_ctrl = 0;
/* Workaround to prevent overdrawing Amps. */ /* Workaround to prevent overdrawing Amps. */
if (GET_ASIC_REV(tp->pci_chip_rev_id) == if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
ASIC_REV_5714) {
grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3; grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
grc_local_ctrl, 100); grc_local_ctrl,
TG3_GRC_LCLCTL_PWRSW_DELAY);
} }
/* On 5753 and variants, GPIO2 cannot be used. */ /* On 5753 and variants, GPIO2 cannot be used. */
...@@ -2251,35 +2260,64 @@ static void tg3_frob_aux_power(struct tg3 *tp) ...@@ -2251,35 +2260,64 @@ static void tg3_frob_aux_power(struct tg3 *tp)
grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 | grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 |
GRC_LCLCTRL_GPIO_OUTPUT2); GRC_LCLCTRL_GPIO_OUTPUT2);
} }
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | tw32_wait_f(GRC_LOCAL_CTRL,
grc_local_ctrl, 100); tp->grc_local_ctrl | grc_local_ctrl,
TG3_GRC_LCLCTL_PWRSW_DELAY);
grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0; grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0;
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | tw32_wait_f(GRC_LOCAL_CTRL,
grc_local_ctrl, 100); tp->grc_local_ctrl | grc_local_ctrl,
TG3_GRC_LCLCTL_PWRSW_DELAY);
if (!no_gpio2) { if (!no_gpio2) {
grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2; grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2;
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | tw32_wait_f(GRC_LOCAL_CTRL,
grc_local_ctrl, 100); tp->grc_local_ctrl | grc_local_ctrl,
TG3_GRC_LCLCTL_PWRSW_DELAY);
} }
} }
} else { }
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
(GRC_LCLCTRL_GPIO_OE1 |
GRC_LCLCTRL_GPIO_OUTPUT1), 100);
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | static void tg3_frob_aux_power(struct tg3 *tp)
GRC_LCLCTRL_GPIO_OE1, 100); {
bool need_vaux = false;
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | /* The GPIOs do something completely different on 57765. */
(GRC_LCLCTRL_GPIO_OE1 | if (!tg3_flag(tp, IS_NIC) ||
GRC_LCLCTRL_GPIO_OUTPUT1), 100); GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
return;
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) &&
tp->pdev_peer != tp->pdev) {
struct net_device *dev_peer;
dev_peer = pci_get_drvdata(tp->pdev_peer);
/* remove_one() may have been run on the peer. */
if (dev_peer) {
struct tg3 *tp_peer = netdev_priv(dev_peer);
if (tg3_flag(tp_peer, INIT_COMPLETE))
return;
if (tg3_flag(tp_peer, WOL_ENABLE) ||
tg3_flag(tp_peer, ENABLE_ASF))
need_vaux = true;
} }
} }
if (tg3_flag(tp, WOL_ENABLE) || tg3_flag(tp, ENABLE_ASF))
need_vaux = true;
if (need_vaux)
tg3_pwrsrc_switch_to_vaux(tp);
else
tg3_pwrsrc_die_with_vmain(tp);
} }
static int tg3_5700_link_polarity(struct tg3 *tp, u32 speed) static int tg3_5700_link_polarity(struct tg3 *tp, u32 speed)
...@@ -2624,8 +2662,7 @@ static int tg3_power_up(struct tg3 *tp) ...@@ -2624,8 +2662,7 @@ static int tg3_power_up(struct tg3 *tp)
pci_set_power_state(tp->pdev, PCI_D0); pci_set_power_state(tp->pdev, PCI_D0);
/* Switch out of Vaux if it is a NIC */ /* Switch out of Vaux if it is a NIC */
if (tg3_flag(tp, IS_NIC)) tg3_pwrsrc_switch_to_vmain(tp);
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment