mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 22:02:28 +00:00
ath9k_hw: fix ASPM setting for AR9003
The AR_WA register should not be read when in sleep state so add a variable we can stash its value into for when we need to set it. Additionally the AR_WA_D3_TO_L1_DISABLE_REAL (bit 16) needs to be removed. Cc: Aeolus Yang <aeolus.yang@atheros.com> Cc: Madhan Jaganathan <madhan.jaganathan@atheros.com> signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
1047d5edd4
commit
9a658d2b5c
@ -295,6 +295,8 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
|
||||
/* Several PCIe massages to ensure proper behaviour */
|
||||
if (ah->config.pcie_waen)
|
||||
REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
|
||||
else
|
||||
REG_WRITE(ah, AR_WA, ah->WARegVal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -819,6 +819,12 @@ struct ath_hw {
|
||||
|
||||
u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
|
||||
u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
|
||||
/*
|
||||
* Store the permanent value of Reg 0x4004in WARegVal
|
||||
* so we dont have to R/M/W. We should not be reading
|
||||
* this register when in sleep states.
|
||||
*/
|
||||
u32 WARegVal;
|
||||
};
|
||||
|
||||
static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
|
||||
|
@ -704,6 +704,11 @@
|
||||
#define AR_WA_BIT7 (1 << 7)
|
||||
#define AR_WA_BIT23 (1 << 23)
|
||||
#define AR_WA_D3_L1_DISABLE (1 << 14)
|
||||
#define AR_WA_D3_TO_L1_DISABLE_REAL (1 << 16)
|
||||
#define AR_WA_ASPM_TIMER_BASED_DISABLE (1 << 17)
|
||||
#define AR_WA_RESET_EN (1 << 18) /* Sw Control to enable PCI-Reset to POR (bit 15) */
|
||||
#define AR_WA_ANALOG_SHIFT (1 << 20)
|
||||
#define AR_WA_POR_SHORT (1 << 21) /* PCI-E Phy reset control */
|
||||
#define AR9285_WA_DEFAULT 0x004a050b
|
||||
#define AR9280_WA_DEFAULT 0x0040073b
|
||||
#define AR_WA_DEFAULT 0x0000073f
|
||||
|
Loading…
Reference in New Issue
Block a user