blob: aa52fd7b630c976ec3c881dd3f28244a3dd80b31 [file] [log] [blame]
Luis R. Rodriguezb3950e62010-04-15 17:39:03 -04001/*
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"
18#include "ar5008_initvals.h"
19#include "ar9001_initvals.h"
20#include "ar9002_initvals.h"
21
22/* General hardware code for the A5008/AR9001/AR9002 hadware families */
23
24static bool ar9002_hw_macversion_supported(u32 macversion)
25{
26 switch (macversion) {
27 case AR_SREV_VERSION_5416_PCI:
28 case AR_SREV_VERSION_5416_PCIE:
29 case AR_SREV_VERSION_9160:
30 case AR_SREV_VERSION_9100:
31 case AR_SREV_VERSION_9280:
32 case AR_SREV_VERSION_9285:
33 case AR_SREV_VERSION_9287:
34 case AR_SREV_VERSION_9271:
35 return true;
36 default:
37 break;
38 }
39 return false;
40}
41
42static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
43{
44 if (AR_SREV_9271(ah)) {
45 INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
46 ARRAY_SIZE(ar9271Modes_9271), 6);
47 INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
48 ARRAY_SIZE(ar9271Common_9271), 2);
49 INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
50 ar9271Common_normal_cck_fir_coeff_9271,
51 ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2);
52 INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
53 ar9271Common_japan_2484_cck_fir_coeff_9271,
54 ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
55 INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
56 ar9271Modes_9271_1_0_only,
57 ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
58 INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
59 ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6);
60 INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
61 ar9271Modes_high_power_tx_gain_9271,
62 ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6);
63 INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
64 ar9271Modes_normal_power_tx_gain_9271,
65 ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6);
66 return;
67 }
68
69 if (AR_SREV_9287_11_OR_LATER(ah)) {
70 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
71 ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
72 INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
73 ARRAY_SIZE(ar9287Common_9287_1_1), 2);
74 if (ah->config.pcie_clock_req)
75 INIT_INI_ARRAY(&ah->iniPcieSerdes,
76 ar9287PciePhy_clkreq_off_L1_9287_1_1,
77 ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
78 else
79 INIT_INI_ARRAY(&ah->iniPcieSerdes,
80 ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
81 ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
82 2);
83 } else if (AR_SREV_9287_10_OR_LATER(ah)) {
84 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0,
85 ARRAY_SIZE(ar9287Modes_9287_1_0), 6);
86 INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0,
87 ARRAY_SIZE(ar9287Common_9287_1_0), 2);
88
89 if (ah->config.pcie_clock_req)
90 INIT_INI_ARRAY(&ah->iniPcieSerdes,
91 ar9287PciePhy_clkreq_off_L1_9287_1_0,
92 ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2);
93 else
94 INIT_INI_ARRAY(&ah->iniPcieSerdes,
95 ar9287PciePhy_clkreq_always_on_L1_9287_1_0,
96 ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0),
97 2);
98 } else if (AR_SREV_9285_12_OR_LATER(ah)) {
99
100
101 INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
102 ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
103 INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
104 ARRAY_SIZE(ar9285Common_9285_1_2), 2);
105
106 if (ah->config.pcie_clock_req) {
107 INIT_INI_ARRAY(&ah->iniPcieSerdes,
108 ar9285PciePhy_clkreq_off_L1_9285_1_2,
109 ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
110 } else {
111 INIT_INI_ARRAY(&ah->iniPcieSerdes,
112 ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
113 ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
114 2);
115 }
116 } else if (AR_SREV_9285_10_OR_LATER(ah)) {
117 INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
118 ARRAY_SIZE(ar9285Modes_9285), 6);
119 INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
120 ARRAY_SIZE(ar9285Common_9285), 2);
121
122 if (ah->config.pcie_clock_req) {
123 INIT_INI_ARRAY(&ah->iniPcieSerdes,
124 ar9285PciePhy_clkreq_off_L1_9285,
125 ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
126 } else {
127 INIT_INI_ARRAY(&ah->iniPcieSerdes,
128 ar9285PciePhy_clkreq_always_on_L1_9285,
129 ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
130 }
131 } else if (AR_SREV_9280_20_OR_LATER(ah)) {
132 INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
133 ARRAY_SIZE(ar9280Modes_9280_2), 6);
134 INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
135 ARRAY_SIZE(ar9280Common_9280_2), 2);
136
137 if (ah->config.pcie_clock_req) {
138 INIT_INI_ARRAY(&ah->iniPcieSerdes,
139 ar9280PciePhy_clkreq_off_L1_9280,
140 ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2);
141 } else {
142 INIT_INI_ARRAY(&ah->iniPcieSerdes,
143 ar9280PciePhy_clkreq_always_on_L1_9280,
144 ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
145 }
146 INIT_INI_ARRAY(&ah->iniModesAdditional,
147 ar9280Modes_fast_clock_9280_2,
148 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
149 } else if (AR_SREV_9280_10_OR_LATER(ah)) {
150 INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
151 ARRAY_SIZE(ar9280Modes_9280), 6);
152 INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
153 ARRAY_SIZE(ar9280Common_9280), 2);
154 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
155 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
156 ARRAY_SIZE(ar5416Modes_9160), 6);
157 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
158 ARRAY_SIZE(ar5416Common_9160), 2);
159 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
160 ARRAY_SIZE(ar5416Bank0_9160), 2);
161 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
162 ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
163 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
164 ARRAY_SIZE(ar5416Bank1_9160), 2);
165 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
166 ARRAY_SIZE(ar5416Bank2_9160), 2);
167 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
168 ARRAY_SIZE(ar5416Bank3_9160), 3);
169 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
170 ARRAY_SIZE(ar5416Bank6_9160), 3);
171 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
172 ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
173 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
174 ARRAY_SIZE(ar5416Bank7_9160), 2);
175 if (AR_SREV_9160_11(ah)) {
176 INIT_INI_ARRAY(&ah->iniAddac,
177 ar5416Addac_91601_1,
178 ARRAY_SIZE(ar5416Addac_91601_1), 2);
179 } else {
180 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
181 ARRAY_SIZE(ar5416Addac_9160), 2);
182 }
183 } else if (AR_SREV_9100_OR_LATER(ah)) {
184 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
185 ARRAY_SIZE(ar5416Modes_9100), 6);
186 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
187 ARRAY_SIZE(ar5416Common_9100), 2);
188 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
189 ARRAY_SIZE(ar5416Bank0_9100), 2);
190 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
191 ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
192 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
193 ARRAY_SIZE(ar5416Bank1_9100), 2);
194 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
195 ARRAY_SIZE(ar5416Bank2_9100), 2);
196 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
197 ARRAY_SIZE(ar5416Bank3_9100), 3);
198 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
199 ARRAY_SIZE(ar5416Bank6_9100), 3);
200 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
201 ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
202 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
203 ARRAY_SIZE(ar5416Bank7_9100), 2);
204 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
205 ARRAY_SIZE(ar5416Addac_9100), 2);
206 } else {
207 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
208 ARRAY_SIZE(ar5416Modes), 6);
209 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
210 ARRAY_SIZE(ar5416Common), 2);
211 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
212 ARRAY_SIZE(ar5416Bank0), 2);
213 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
214 ARRAY_SIZE(ar5416BB_RfGain), 3);
215 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
216 ARRAY_SIZE(ar5416Bank1), 2);
217 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
218 ARRAY_SIZE(ar5416Bank2), 2);
219 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
220 ARRAY_SIZE(ar5416Bank3), 3);
221 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
222 ARRAY_SIZE(ar5416Bank6), 3);
223 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
224 ARRAY_SIZE(ar5416Bank6TPC), 3);
225 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
226 ARRAY_SIZE(ar5416Bank7), 2);
227 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
228 ARRAY_SIZE(ar5416Addac), 2);
229 }
230}
231
232/*
233 * Helper for ASPM support.
234 *
235 * Disable PLL when in L0s as well as receiver clock when in L1.
236 * This power saving option must be enabled through the SerDes.
237 *
238 * Programming the SerDes must go through the same 288 bit serial shift
239 * register as the other analog registers. Hence the 9 writes.
240 */
241static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
242 int restore,
243 int power_off)
244{
245 u8 i;
246 u32 val;
247
248 if (ah->is_pciexpress != true)
249 return;
250
251 /* Do not touch SerDes registers */
252 if (ah->config.pcie_powersave_enable == 2)
253 return;
254
255 /* Nothing to do on restore for 11N */
256 if (!restore) {
257 if (AR_SREV_9280_20_OR_LATER(ah)) {
258 /*
259 * AR9280 2.0 or later chips use SerDes values from the
260 * initvals.h initialized depending on chipset during
261 * __ath9k_hw_init()
262 */
263 for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
264 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
265 INI_RA(&ah->iniPcieSerdes, i, 1));
266 }
267 } else if (AR_SREV_9280(ah) &&
268 (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
269 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
270 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
271
272 /* RX shut off when elecidle is asserted */
273 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
274 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
275 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
276
277 /* Shut off CLKREQ active in L1 */
278 if (ah->config.pcie_clock_req)
279 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
280 else
281 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
282
283 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
284 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
285 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
286
287 /* Load the new settings */
288 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
289
290 } else {
291 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
292 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
293
294 /* RX shut off when elecidle is asserted */
295 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
296 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
297 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
298
299 /*
300 * Ignore ah->ah_config.pcie_clock_req setting for
301 * pre-AR9280 11n
302 */
303 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
304
305 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
306 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
307 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
308
309 /* Load the new settings */
310 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
311 }
312
313 udelay(1000);
314
315 /* set bit 19 to allow forcing of pcie core into L1 state */
316 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
317
318 /* Several PCIe massages to ensure proper behaviour */
319 if (ah->config.pcie_waen) {
320 val = ah->config.pcie_waen;
321 if (!power_off)
322 val &= (~AR_WA_D3_L1_DISABLE);
323 } else {
324 if (AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
325 AR_SREV_9287(ah)) {
326 val = AR9285_WA_DEFAULT;
327 if (!power_off)
328 val &= (~AR_WA_D3_L1_DISABLE);
329 } else if (AR_SREV_9280(ah)) {
330 /*
331 * On AR9280 chips bit 22 of 0x4004 needs to be
332 * set otherwise card may disappear.
333 */
334 val = AR9280_WA_DEFAULT;
335 if (!power_off)
336 val &= (~AR_WA_D3_L1_DISABLE);
337 } else
338 val = AR_WA_DEFAULT;
339 }
340
341 REG_WRITE(ah, AR_WA, val);
342 }
343
344 if (power_off) {
345 /*
346 * Set PCIe workaround bits
347 * bit 14 in WA register (disable L1) should only
348 * be set when device enters D3 and be cleared
349 * when device comes back to D0.
350 */
351 if (ah->config.pcie_waen) {
352 if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
353 REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
354 } else {
355 if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
356 AR_SREV_9287(ah)) &&
357 (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
358 (AR_SREV_9280(ah) &&
359 (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
360 REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
361 }
362 }
363 }
364}
365
366/* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
367void ar9002_hw_attach_ops(struct ath_hw *ah)
368{
369 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
370 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
371
372 priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
373 priv_ops->macversion_supported = ar9002_hw_macversion_supported;
374
375 ops->config_pci_powersave = ar9002_hw_configpcipowersave;
376
377 ar5008_hw_attach_phy_ops(ah);
378 if (AR_SREV_9280_10_OR_LATER(ah))
379 ar9002_hw_attach_phy_ops(ah);
380
381 ar9002_hw_attach_calib_ops(ah);
382 ar9002_hw_attach_mac_ops(ah);
383}