Commit | Line | Data |
---|---|---|
b3950e6a LR |
1 | /* |
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | |
3 | * | |
4 | * Permission to use, copy, modify, and/or distribute this software for any | |
5 | * purpose with or without fee is hereby granted, provided that the above | |
6 | * copyright notice and this permission notice appear in all copies. | |
7 | * | |
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | */ | |
16 | ||
17 | #include "hw.h" | |
b622a720 | 18 | #include "ar9003_mac.h" |
7284635d | 19 | #include "ar9003_2p2_initvals.h" |
b3950e6a LR |
20 | |
21 | /* General hardware code for the AR9003 hadware family */ | |
22 | ||
23 | static bool ar9003_hw_macversion_supported(u32 macversion) | |
24 | { | |
25 | switch (macversion) { | |
26 | case AR_SREV_VERSION_9300: | |
27 | return true; | |
28 | default: | |
29 | break; | |
30 | } | |
31 | return false; | |
32 | } | |
33 | ||
886b42bf LR |
34 | /* |
35 | * The AR9003 family uses a new INI format (pre, core, post | |
36 | * arrays per subsystem). This provides support for the | |
37 | * AR9003 2.2 chipsets. | |
38 | */ | |
39 | static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |
7284635d LR |
40 | { |
41 | /* mac */ | |
42 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | |
43 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | |
44 | ar9300_2p2_mac_core, | |
45 | ARRAY_SIZE(ar9300_2p2_mac_core), 2); | |
46 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | |
47 | ar9300_2p2_mac_postamble, | |
48 | ARRAY_SIZE(ar9300_2p2_mac_postamble), 5); | |
49 | ||
50 | /* bb */ | |
51 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); | |
52 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | |
53 | ar9300_2p2_baseband_core, | |
54 | ARRAY_SIZE(ar9300_2p2_baseband_core), 2); | |
55 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | |
56 | ar9300_2p2_baseband_postamble, | |
57 | ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5); | |
58 | ||
59 | /* radio */ | |
60 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | |
61 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | |
62 | ar9300_2p2_radio_core, | |
63 | ARRAY_SIZE(ar9300_2p2_radio_core), 2); | |
64 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | |
65 | ar9300_2p2_radio_postamble, | |
66 | ARRAY_SIZE(ar9300_2p2_radio_postamble), 5); | |
67 | ||
68 | /* soc */ | |
69 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | |
70 | ar9300_2p2_soc_preamble, | |
71 | ARRAY_SIZE(ar9300_2p2_soc_preamble), 2); | |
72 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | |
73 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | |
74 | ar9300_2p2_soc_postamble, | |
75 | ARRAY_SIZE(ar9300_2p2_soc_postamble), 5); | |
76 | ||
77 | /* rx/tx gain */ | |
78 | INIT_INI_ARRAY(&ah->iniModesRxGain, | |
79 | ar9300Common_rx_gain_table_2p2, | |
80 | ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2); | |
81 | INIT_INI_ARRAY(&ah->iniModesTxGain, | |
82 | ar9300Modes_lowest_ob_db_tx_gain_table_2p2, | |
83 | ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), | |
84 | 5); | |
85 | ||
86 | /* Load PCIE SERDES settings from INI */ | |
87 | ||
88 | /* Awake Setting */ | |
89 | ||
90 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | |
91 | ar9300PciePhy_pll_on_clkreq_disable_L1_2p2, | |
92 | ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2), | |
93 | 2); | |
94 | ||
95 | /* Sleep Setting */ | |
96 | ||
97 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, | |
98 | ar9300PciePhy_clkreq_enable_L1_2p2, | |
99 | ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2), | |
100 | 2); | |
101 | ||
102 | /* Fast clock modal settings */ | |
103 | INIT_INI_ARRAY(&ah->iniModesAdditional, | |
104 | ar9300Modes_fast_clock_2p2, | |
105 | ARRAY_SIZE(ar9300Modes_fast_clock_2p2), | |
106 | 3); | |
107 | } | |
108 | ||
c14a85da LR |
109 | static void ar9003_tx_gain_table_apply(struct ath_hw *ah) |
110 | { | |
111 | switch (ar9003_hw_get_tx_gain_idx(ah)) { | |
112 | case 0: | |
113 | default: | |
886b42bf LR |
114 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
115 | ar9300Modes_lowest_ob_db_tx_gain_table_2p2, | |
116 | ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), | |
117 | 5); | |
c14a85da LR |
118 | break; |
119 | case 1: | |
886b42bf LR |
120 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
121 | ar9300Modes_high_ob_db_tx_gain_table_2p2, | |
122 | ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2), | |
123 | 5); | |
c14a85da LR |
124 | break; |
125 | case 2: | |
886b42bf LR |
126 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
127 | ar9300Modes_low_ob_db_tx_gain_table_2p2, | |
128 | ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2), | |
129 | 5); | |
c14a85da LR |
130 | break; |
131 | } | |
132 | } | |
133 | ||
134 | static void ar9003_rx_gain_table_apply(struct ath_hw *ah) | |
135 | { | |
136 | switch (ar9003_hw_get_rx_gain_idx(ah)) { | |
137 | case 0: | |
138 | default: | |
886b42bf LR |
139 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
140 | ar9300Common_rx_gain_table_2p2, | |
141 | ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), | |
142 | 2); | |
c14a85da LR |
143 | break; |
144 | case 1: | |
886b42bf LR |
145 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
146 | ar9300Common_wo_xlna_rx_gain_table_2p2, | |
147 | ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2), | |
148 | 2); | |
c14a85da LR |
149 | break; |
150 | } | |
151 | } | |
152 | ||
153 | /* set gain table pointers according to values read from the eeprom */ | |
154 | static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah) | |
155 | { | |
156 | ar9003_tx_gain_table_apply(ah); | |
157 | ar9003_rx_gain_table_apply(ah); | |
158 | } | |
159 | ||
b3950e6a LR |
160 | /* |
161 | * Helper for ASPM support. | |
162 | * | |
163 | * Disable PLL when in L0s as well as receiver clock when in L1. | |
164 | * This power saving option must be enabled through the SerDes. | |
165 | * | |
166 | * Programming the SerDes must go through the same 288 bit serial shift | |
167 | * register as the other analog registers. Hence the 9 writes. | |
168 | */ | |
169 | static void ar9003_hw_configpcipowersave(struct ath_hw *ah, | |
170 | int restore, | |
171 | int power_off) | |
172 | { | |
173 | if (ah->is_pciexpress != true) | |
174 | return; | |
175 | ||
176 | /* Do not touch SerDes registers */ | |
177 | if (ah->config.pcie_powersave_enable == 2) | |
178 | return; | |
179 | ||
180 | /* Nothing to do on restore for 11N */ | |
181 | if (!restore) { | |
182 | /* set bit 19 to allow forcing of pcie core into L1 state */ | |
183 | REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); | |
184 | ||
185 | /* Several PCIe massages to ensure proper behaviour */ | |
186 | if (ah->config.pcie_waen) | |
187 | REG_WRITE(ah, AR_WA, ah->config.pcie_waen); | |
9a658d2b LR |
188 | else |
189 | REG_WRITE(ah, AR_WA, ah->WARegVal); | |
b3950e6a | 190 | } |
653fe371 LR |
191 | |
192 | /* | |
193 | * Configire PCIE after Ini init. SERDES values now come from ini file | |
194 | * This enables PCIe low power mode. | |
195 | */ | |
6a0ec30a | 196 | if (ah->config.pcieSerDesWrite) { |
653fe371 | 197 | unsigned int i; |
d5c4d193 | 198 | struct ar5416IniArray *array; |
653fe371 | 199 | |
d5c4d193 LR |
200 | array = power_off ? &ah->iniPcieSerdes : |
201 | &ah->iniPcieSerdesLowPower; | |
202 | ||
203 | for (i = 0; i < array->ia_rows; i++) { | |
653fe371 | 204 | REG_WRITE(ah, |
d5c4d193 LR |
205 | INI_RA(array, i, 0), |
206 | INI_RA(array, i, 1)); | |
653fe371 LR |
207 | } |
208 | } | |
b3950e6a LR |
209 | } |
210 | ||
211 | /* Sets up the AR9003 hardware familiy callbacks */ | |
212 | void ar9003_hw_attach_ops(struct ath_hw *ah) | |
213 | { | |
214 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | |
215 | struct ath_hw_ops *ops = ath9k_hw_ops(ah); | |
216 | ||
217 | priv_ops->init_mode_regs = ar9003_hw_init_mode_regs; | |
c14a85da | 218 | priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs; |
b3950e6a LR |
219 | priv_ops->macversion_supported = ar9003_hw_macversion_supported; |
220 | ||
221 | ops->config_pci_powersave = ar9003_hw_configpcipowersave; | |
222 | ||
223 | ar9003_hw_attach_phy_ops(ah); | |
224 | ar9003_hw_attach_calib_ops(ah); | |
225 | ar9003_hw_attach_mac_ops(ah); | |
226 | } |