|
@@ -575,14 +575,8 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
|
|
* This enables PCIe low power mode.
|
|
|
*/
|
|
|
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
|
|
- u32 regval;
|
|
|
unsigned int i;
|
|
|
|
|
|
- /* Set Bits 16 and 17 in the AR_WA register. */
|
|
|
- regval = REG_READ(ah, AR_WA);
|
|
|
- regval |= 0x00030000;
|
|
|
- REG_WRITE(ah, AR_WA, regval);
|
|
|
-
|
|
|
for (i = 0; i < ah->iniPcieSerdesLowPower.ia_rows; i++) {
|
|
|
REG_WRITE(ah,
|
|
|
INI_RA(&ah->iniPcieSerdesLowPower, i, 0),
|
|
@@ -590,6 +584,15 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Read back AR_WA into a permanent copy and set bits 14 and 17.
|
|
|
+ * We need to do this to avoid RMW of this register. We cannot
|
|
|
+ * read the reg when chip is asleep.
|
|
|
+ */
|
|
|
+ ah->WARegVal = REG_READ(ah, AR_WA);
|
|
|
+ ah->WARegVal |= (AR_WA_D3_L1_DISABLE |
|
|
|
+ AR_WA_ASPM_TIMER_BASED_DISABLE);
|
|
|
+
|
|
|
if (ah->is_pciexpress)
|
|
|
ath9k_hw_configpcipowersave(ah, 0, 0);
|
|
|
else
|
|
@@ -1009,6 +1012,11 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
|
|
|
|
|
|
ENABLE_REGWRITE_BUFFER(ah);
|
|
|
|
|
|
+ if (AR_SREV_9300_20_OR_LATER(ah)) {
|
|
|
+ REG_WRITE(ah, AR_WA, ah->WARegVal);
|
|
|
+ udelay(10);
|
|
|
+ }
|
|
|
+
|
|
|
REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
|
|
|
AR_RTC_FORCE_WAKE_ON_INT);
|
|
|
|
|
@@ -1063,6 +1071,11 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
|
|
|
{
|
|
|
ENABLE_REGWRITE_BUFFER(ah);
|
|
|
|
|
|
+ if (AR_SREV_9300_20_OR_LATER(ah)) {
|
|
|
+ REG_WRITE(ah, AR_WA, ah->WARegVal);
|
|
|
+ udelay(10);
|
|
|
+ }
|
|
|
+
|
|
|
REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
|
|
|
AR_RTC_FORCE_WAKE_ON_INT);
|
|
|
|
|
@@ -1099,6 +1112,11 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
|
|
|
|
|
|
static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
|
|
|
{
|
|
|
+ if (AR_SREV_9300_20_OR_LATER(ah)) {
|
|
|
+ REG_WRITE(ah, AR_WA, ah->WARegVal);
|
|
|
+ udelay(10);
|
|
|
+ }
|
|
|
+
|
|
|
REG_WRITE(ah, AR_RTC_FORCE_WAKE,
|
|
|
AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
|
|
|
|
|
@@ -1768,6 +1786,11 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
|
|
|
REG_CLR_BIT(ah, (AR_RTC_RESET),
|
|
|
AR_RTC_RESET_EN);
|
|
|
}
|
|
|
+
|
|
|
+ /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */
|
|
|
+ if (AR_SREV_9300_20_OR_LATER(ah))
|
|
|
+ REG_WRITE(ah, AR_WA,
|
|
|
+ ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1794,6 +1817,10 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
|
|
|
AR_RTC_FORCE_WAKE_EN);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /* Clear Bit 14 of AR_WA after putting chip into Net Sleep mode. */
|
|
|
+ if (AR_SREV_9300_20_OR_LATER(ah))
|
|
|
+ REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
|
|
|
}
|
|
|
|
|
|
static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
|
|
@@ -1801,6 +1828,12 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
|
|
|
u32 val;
|
|
|
int i;
|
|
|
|
|
|
+ /* Set Bits 14 and 17 of AR_WA before powering on the chip. */
|
|
|
+ if (AR_SREV_9300_20_OR_LATER(ah)) {
|
|
|
+ REG_WRITE(ah, AR_WA, ah->WARegVal);
|
|
|
+ udelay(10);
|
|
|
+ }
|
|
|
+
|
|
|
if (setChip) {
|
|
|
if ((REG_READ(ah, AR_RTC_STATUS) &
|
|
|
AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) {
|