|
@@ -608,7 +608,7 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
|
|
static void tg3_ape_lock_init(struct tg3 *tp)
|
|
static void tg3_ape_lock_init(struct tg3 *tp)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|
|
- u32 regbase;
|
|
|
|
|
|
+ u32 regbase, bit;
|
|
|
|
|
|
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
|
|
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
|
|
regbase = TG3_APE_LOCK_GRANT;
|
|
regbase = TG3_APE_LOCK_GRANT;
|
|
@@ -616,20 +616,34 @@ static void tg3_ape_lock_init(struct tg3 *tp)
|
|
regbase = TG3_APE_PER_LOCK_GRANT;
|
|
regbase = TG3_APE_PER_LOCK_GRANT;
|
|
|
|
|
|
/* Make sure the driver hasn't any stale locks. */
|
|
/* Make sure the driver hasn't any stale locks. */
|
|
- for (i = 0; i < 8; i++)
|
|
|
|
|
|
+ for (i = 0; i < 8; i++) {
|
|
|
|
+ if (i == TG3_APE_LOCK_GPIO)
|
|
|
|
+ continue;
|
|
tg3_ape_write32(tp, regbase + 4 * i, APE_LOCK_GRANT_DRIVER);
|
|
tg3_ape_write32(tp, regbase + 4 * i, APE_LOCK_GRANT_DRIVER);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Clear the correct bit of the GPIO lock too. */
|
|
|
|
+ if (!tp->pci_fn)
|
|
|
|
+ bit = APE_LOCK_GRANT_DRIVER;
|
|
|
|
+ else
|
|
|
|
+ bit = 1 << tp->pci_fn;
|
|
|
|
+
|
|
|
|
+ tg3_ape_write32(tp, regbase + 4 * TG3_APE_LOCK_GPIO, bit);
|
|
}
|
|
}
|
|
|
|
|
|
static int tg3_ape_lock(struct tg3 *tp, int locknum)
|
|
static int tg3_ape_lock(struct tg3 *tp, int locknum)
|
|
{
|
|
{
|
|
int i, off;
|
|
int i, off;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
- u32 status, req, gnt;
|
|
|
|
|
|
+ u32 status, req, gnt, bit;
|
|
|
|
|
|
if (!tg3_flag(tp, ENABLE_APE))
|
|
if (!tg3_flag(tp, ENABLE_APE))
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
switch (locknum) {
|
|
switch (locknum) {
|
|
|
|
+ case TG3_APE_LOCK_GPIO:
|
|
|
|
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
|
|
|
|
+ return 0;
|
|
case TG3_APE_LOCK_GRC:
|
|
case TG3_APE_LOCK_GRC:
|
|
case TG3_APE_LOCK_MEM:
|
|
case TG3_APE_LOCK_MEM:
|
|
break;
|
|
break;
|
|
@@ -647,21 +661,24 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
|
|
|
|
|
|
off = 4 * locknum;
|
|
off = 4 * locknum;
|
|
|
|
|
|
- tg3_ape_write32(tp, req + off, APE_LOCK_REQ_DRIVER);
|
|
|
|
|
|
+ if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn)
|
|
|
|
+ bit = APE_LOCK_REQ_DRIVER;
|
|
|
|
+ else
|
|
|
|
+ bit = 1 << tp->pci_fn;
|
|
|
|
+
|
|
|
|
+ tg3_ape_write32(tp, req + off, bit);
|
|
|
|
|
|
/* Wait for up to 1 millisecond to acquire lock. */
|
|
/* Wait for up to 1 millisecond to acquire lock. */
|
|
for (i = 0; i < 100; i++) {
|
|
for (i = 0; i < 100; i++) {
|
|
status = tg3_ape_read32(tp, gnt + off);
|
|
status = tg3_ape_read32(tp, gnt + off);
|
|
- if (status == APE_LOCK_GRANT_DRIVER)
|
|
|
|
|
|
+ if (status == bit)
|
|
break;
|
|
break;
|
|
udelay(10);
|
|
udelay(10);
|
|
}
|
|
}
|
|
|
|
|
|
- if (status != APE_LOCK_GRANT_DRIVER) {
|
|
|
|
|
|
+ if (status != bit) {
|
|
/* Revoke the lock request. */
|
|
/* Revoke the lock request. */
|
|
- tg3_ape_write32(tp, gnt + off,
|
|
|
|
- APE_LOCK_GRANT_DRIVER);
|
|
|
|
-
|
|
|
|
|
|
+ tg3_ape_write32(tp, gnt + off, bit);
|
|
ret = -EBUSY;
|
|
ret = -EBUSY;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -670,12 +687,15 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
|
|
|
|
|
|
static void tg3_ape_unlock(struct tg3 *tp, int locknum)
|
|
static void tg3_ape_unlock(struct tg3 *tp, int locknum)
|
|
{
|
|
{
|
|
- u32 gnt;
|
|
|
|
|
|
+ u32 gnt, bit;
|
|
|
|
|
|
if (!tg3_flag(tp, ENABLE_APE))
|
|
if (!tg3_flag(tp, ENABLE_APE))
|
|
return;
|
|
return;
|
|
|
|
|
|
switch (locknum) {
|
|
switch (locknum) {
|
|
|
|
+ case TG3_APE_LOCK_GPIO:
|
|
|
|
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
|
|
|
|
+ return;
|
|
case TG3_APE_LOCK_GRC:
|
|
case TG3_APE_LOCK_GRC:
|
|
case TG3_APE_LOCK_MEM:
|
|
case TG3_APE_LOCK_MEM:
|
|
break;
|
|
break;
|
|
@@ -688,7 +708,12 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
|
|
else
|
|
else
|
|
gnt = TG3_APE_PER_LOCK_GRANT;
|
|
gnt = TG3_APE_PER_LOCK_GRANT;
|
|
|
|
|
|
- tg3_ape_write32(tp, gnt + 4 * locknum, APE_LOCK_GRANT_DRIVER);
|
|
|
|
|
|
+ if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn)
|
|
|
|
+ bit = APE_LOCK_GRANT_DRIVER;
|
|
|
|
+ else
|
|
|
|
+ bit = 1 << tp->pci_fn;
|
|
|
|
+
|
|
|
|
+ tg3_ape_write32(tp, gnt + 4 * locknum, bit);
|
|
}
|
|
}
|
|
|
|
|
|
static void tg3_disable_ints(struct tg3 *tp)
|
|
static void tg3_disable_ints(struct tg3 *tp)
|
|
@@ -2170,11 +2195,16 @@ out:
|
|
static inline int tg3_pwrsrc_switch_to_vmain(struct tg3 *tp)
|
|
static inline int tg3_pwrsrc_switch_to_vmain(struct tg3 *tp)
|
|
{
|
|
{
|
|
if (!tg3_flag(tp, IS_NIC))
|
|
if (!tg3_flag(tp, IS_NIC))
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl,
|
|
tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl,
|
|
TG3_GRC_LCLCTL_PWRSW_DELAY);
|
|
TG3_GRC_LCLCTL_PWRSW_DELAY);
|
|
|
|
|
|
|
|
+ tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2187,6 +2217,10 @@ static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp)
|
|
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)
|
|
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
+
|
|
|
|
+ if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
|
|
|
|
+ return;
|
|
|
|
+
|
|
grc_local_ctrl = tp->grc_local_ctrl | GRC_LCLCTRL_GPIO_OE1;
|
|
grc_local_ctrl = tp->grc_local_ctrl | GRC_LCLCTRL_GPIO_OE1;
|
|
|
|
|
|
tw32_wait_f(GRC_LOCAL_CTRL,
|
|
tw32_wait_f(GRC_LOCAL_CTRL,
|
|
@@ -2200,6 +2234,8 @@ static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp)
|
|
tw32_wait_f(GRC_LOCAL_CTRL,
|
|
tw32_wait_f(GRC_LOCAL_CTRL,
|
|
grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1,
|
|
grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1,
|
|
TG3_GRC_LCLCTL_PWRSW_DELAY);
|
|
TG3_GRC_LCLCTL_PWRSW_DELAY);
|
|
|
|
+
|
|
|
|
+ tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
|
|
}
|
|
}
|
|
|
|
|
|
static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
|
|
static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
|
|
@@ -2207,6 +2243,9 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
|
|
if (!tg3_flag(tp, IS_NIC))
|
|
if (!tg3_flag(tp, IS_NIC))
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
+ if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
|
|
|
|
+ return;
|
|
|
|
+
|
|
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 |
|
|
@@ -2277,6 +2316,8 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
|
|
TG3_GRC_LCLCTL_PWRSW_DELAY);
|
|
TG3_GRC_LCLCTL_PWRSW_DELAY);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
|
|
}
|
|
}
|
|
|
|
|
|
static void tg3_frob_aux_power(struct tg3 *tp)
|
|
static void tg3_frob_aux_power(struct tg3 *tp)
|