diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2010-06-21 18:38:47 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-06-23 15:14:00 -0400 |
commit | 9a658d2b5c222b62919ab47b11c907c731ac180a (patch) | |
tree | 80d12299df8955d526c1103f2e3a7f6d9882c1c2 | |
parent | 1047d5edd4838f27dc86f24676178f2249c446ea (diff) |
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>
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_hw.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 45 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/reg.h | 5 |
4 files changed, 52 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 82c3ab756cd0..b4a9441a5ac7 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -295,6 +295,8 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah, | |||
295 | /* Several PCIe massages to ensure proper behaviour */ | 295 | /* Several PCIe massages to ensure proper behaviour */ |
296 | if (ah->config.pcie_waen) | 296 | if (ah->config.pcie_waen) |
297 | REG_WRITE(ah, AR_WA, ah->config.pcie_waen); | 297 | REG_WRITE(ah, AR_WA, ah->config.pcie_waen); |
298 | else | ||
299 | REG_WRITE(ah, AR_WA, ah->WARegVal); | ||
298 | } | 300 | } |
299 | } | 301 | } |
300 | 302 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 62597f4ca319..fb09042e2889 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -575,14 +575,8 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
575 | * This enables PCIe low power mode. | 575 | * This enables PCIe low power mode. |
576 | */ | 576 | */ |
577 | if (AR_SREV_9300_20_OR_LATER(ah)) { | 577 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
578 | u32 regval; | ||
579 | unsigned int i; | 578 | unsigned int i; |
580 | 579 | ||
581 | /* Set Bits 16 and 17 in the AR_WA register. */ | ||
582 | regval = REG_READ(ah, AR_WA); | ||
583 | regval |= 0x00030000; | ||
584 | REG_WRITE(ah, AR_WA, regval); | ||
585 | |||
586 | for (i = 0; i < ah->iniPcieSerdesLowPower.ia_rows; i++) { | 580 | for (i = 0; i < ah->iniPcieSerdesLowPower.ia_rows; i++) { |
587 | REG_WRITE(ah, | 581 | REG_WRITE(ah, |
588 | INI_RA(&ah->iniPcieSerdesLowPower, i, 0), | 582 | INI_RA(&ah->iniPcieSerdesLowPower, i, 0), |
@@ -590,6 +584,15 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
590 | } | 584 | } |
591 | } | 585 | } |
592 | 586 | ||
587 | /* | ||
588 | * Read back AR_WA into a permanent copy and set bits 14 and 17. | ||
589 | * We need to do this to avoid RMW of this register. We cannot | ||
590 | * read the reg when chip is asleep. | ||
591 | */ | ||
592 | ah->WARegVal = REG_READ(ah, AR_WA); | ||
593 | ah->WARegVal |= (AR_WA_D3_L1_DISABLE | | ||
594 | AR_WA_ASPM_TIMER_BASED_DISABLE); | ||
595 | |||
593 | if (ah->is_pciexpress) | 596 | if (ah->is_pciexpress) |
594 | ath9k_hw_configpcipowersave(ah, 0, 0); | 597 | ath9k_hw_configpcipowersave(ah, 0, 0); |
595 | else | 598 | else |
@@ -1009,6 +1012,11 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
1009 | 1012 | ||
1010 | ENABLE_REGWRITE_BUFFER(ah); | 1013 | ENABLE_REGWRITE_BUFFER(ah); |
1011 | 1014 | ||
1015 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
1016 | REG_WRITE(ah, AR_WA, ah->WARegVal); | ||
1017 | udelay(10); | ||
1018 | } | ||
1019 | |||
1012 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | | 1020 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | |
1013 | AR_RTC_FORCE_WAKE_ON_INT); | 1021 | AR_RTC_FORCE_WAKE_ON_INT); |
1014 | 1022 | ||
@@ -1063,6 +1071,11 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) | |||
1063 | { | 1071 | { |
1064 | ENABLE_REGWRITE_BUFFER(ah); | 1072 | ENABLE_REGWRITE_BUFFER(ah); |
1065 | 1073 | ||
1074 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
1075 | REG_WRITE(ah, AR_WA, ah->WARegVal); | ||
1076 | udelay(10); | ||
1077 | } | ||
1078 | |||
1066 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | | 1079 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | |
1067 | AR_RTC_FORCE_WAKE_ON_INT); | 1080 | AR_RTC_FORCE_WAKE_ON_INT); |
1068 | 1081 | ||
@@ -1099,6 +1112,11 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) | |||
1099 | 1112 | ||
1100 | static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) | 1113 | static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) |
1101 | { | 1114 | { |
1115 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
1116 | REG_WRITE(ah, AR_WA, ah->WARegVal); | ||
1117 | udelay(10); | ||
1118 | } | ||
1119 | |||
1102 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, | 1120 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, |
1103 | AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); | 1121 | AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); |
1104 | 1122 | ||
@@ -1768,6 +1786,11 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) | |||
1768 | REG_CLR_BIT(ah, (AR_RTC_RESET), | 1786 | REG_CLR_BIT(ah, (AR_RTC_RESET), |
1769 | AR_RTC_RESET_EN); | 1787 | AR_RTC_RESET_EN); |
1770 | } | 1788 | } |
1789 | |||
1790 | /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ | ||
1791 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
1792 | REG_WRITE(ah, AR_WA, | ||
1793 | ah->WARegVal & ~AR_WA_D3_L1_DISABLE); | ||
1771 | } | 1794 | } |
1772 | 1795 | ||
1773 | /* | 1796 | /* |
@@ -1794,6 +1817,10 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) | |||
1794 | AR_RTC_FORCE_WAKE_EN); | 1817 | AR_RTC_FORCE_WAKE_EN); |
1795 | } | 1818 | } |
1796 | } | 1819 | } |
1820 | |||
1821 | /* Clear Bit 14 of AR_WA after putting chip into Net Sleep mode. */ | ||
1822 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
1823 | REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); | ||
1797 | } | 1824 | } |
1798 | 1825 | ||
1799 | static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) | 1826 | 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) | |||
1801 | u32 val; | 1828 | u32 val; |
1802 | int i; | 1829 | int i; |
1803 | 1830 | ||
1831 | /* Set Bits 14 and 17 of AR_WA before powering on the chip. */ | ||
1832 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
1833 | REG_WRITE(ah, AR_WA, ah->WARegVal); | ||
1834 | udelay(10); | ||
1835 | } | ||
1836 | |||
1804 | if (setChip) { | 1837 | if (setChip) { |
1805 | if ((REG_READ(ah, AR_RTC_STATUS) & | 1838 | if ((REG_READ(ah, AR_RTC_STATUS) & |
1806 | AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { | 1839 | AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 5ecbfcf7470a..6c6d47b0ed1b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -819,6 +819,12 @@ struct ath_hw { | |||
819 | 819 | ||
820 | u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES]; | 820 | u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES]; |
821 | u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES]; | 821 | u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES]; |
822 | /* | ||
823 | * Store the permanent value of Reg 0x4004in WARegVal | ||
824 | * so we dont have to R/M/W. We should not be reading | ||
825 | * this register when in sleep states. | ||
826 | */ | ||
827 | u32 WARegVal; | ||
822 | }; | 828 | }; |
823 | 829 | ||
824 | static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) | 830 | static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 3e3ccef438db..47be667fe4ff 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -704,6 +704,11 @@ | |||
704 | #define AR_WA_BIT7 (1 << 7) | 704 | #define AR_WA_BIT7 (1 << 7) |
705 | #define AR_WA_BIT23 (1 << 23) | 705 | #define AR_WA_BIT23 (1 << 23) |
706 | #define AR_WA_D3_L1_DISABLE (1 << 14) | 706 | #define AR_WA_D3_L1_DISABLE (1 << 14) |
707 | #define AR_WA_D3_TO_L1_DISABLE_REAL (1 << 16) | ||
708 | #define AR_WA_ASPM_TIMER_BASED_DISABLE (1 << 17) | ||
709 | #define AR_WA_RESET_EN (1 << 18) /* Sw Control to enable PCI-Reset to POR (bit 15) */ | ||
710 | #define AR_WA_ANALOG_SHIFT (1 << 20) | ||
711 | #define AR_WA_POR_SHORT (1 << 21) /* PCI-E Phy reset control */ | ||
707 | #define AR9285_WA_DEFAULT 0x004a050b | 712 | #define AR9285_WA_DEFAULT 0x004a050b |
708 | #define AR9280_WA_DEFAULT 0x0040073b | 713 | #define AR9280_WA_DEFAULT 0x0040073b |
709 | #define AR_WA_DEFAULT 0x0000073f | 714 | #define AR_WA_DEFAULT 0x0000073f |