2 * Copyright (c) 2008-2010 Atheros Communications Inc.
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.
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.
18 #include "ar9003_mac.h"
19 #include "ar9003_2p2_initvals.h"
20 #include "ar9485_initvals.h"
21 #include "ar9340_initvals.h"
23 /* General hardware code for the AR9003 hadware family */
26 * The AR9003 family uses a new INI format (pre, core, post
27 * arrays per subsystem). This provides support for the
28 * AR9003 2.2 chipsets.
30 static void ar9003_hw_init_mode_regs(struct ath_hw
*ah
)
32 if (AR_SREV_9340(ah
)) {
34 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_PRE
], NULL
, 0, 0);
35 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_CORE
],
37 ARRAY_SIZE(ar9340_1p0_mac_core
), 2);
38 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_POST
],
39 ar9340_1p0_mac_postamble
,
40 ARRAY_SIZE(ar9340_1p0_mac_postamble
), 5);
43 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_PRE
], NULL
, 0, 0);
44 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_CORE
],
45 ar9340_1p0_baseband_core
,
46 ARRAY_SIZE(ar9340_1p0_baseband_core
), 2);
47 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_POST
],
48 ar9340_1p0_baseband_postamble
,
49 ARRAY_SIZE(ar9340_1p0_baseband_postamble
), 5);
52 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_PRE
], NULL
, 0, 0);
53 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_CORE
],
54 ar9340_1p0_radio_core
,
55 ARRAY_SIZE(ar9340_1p0_radio_core
), 2);
56 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_POST
],
57 ar9340_1p0_radio_postamble
,
58 ARRAY_SIZE(ar9340_1p0_radio_postamble
), 5);
61 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_PRE
],
62 ar9340_1p0_soc_preamble
,
63 ARRAY_SIZE(ar9340_1p0_soc_preamble
), 2);
64 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_CORE
], NULL
, 0, 0);
65 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_POST
],
66 ar9340_1p0_soc_postamble
,
67 ARRAY_SIZE(ar9340_1p0_soc_postamble
), 5);
70 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
71 ar9340Common_wo_xlna_rx_gain_table_1p0
,
72 ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0
),
74 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
75 ar9340Modes_high_ob_db_tx_gain_table_1p0
,
76 ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0
),
79 INIT_INI_ARRAY(&ah
->iniModesAdditional
,
80 ar9340Modes_fast_clock_1p0
,
81 ARRAY_SIZE(ar9340Modes_fast_clock_1p0
),
84 INIT_INI_ARRAY(&ah
->iniModesAdditional_40M
,
85 ar9340_1p0_radio_core_40M
,
86 ARRAY_SIZE(ar9340_1p0_radio_core_40M
),
88 } else if (AR_SREV_9485_11(ah
)) {
90 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_PRE
], NULL
, 0, 0);
91 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_CORE
],
93 ARRAY_SIZE(ar9485_1_1_mac_core
), 2);
94 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_POST
],
95 ar9485_1_1_mac_postamble
,
96 ARRAY_SIZE(ar9485_1_1_mac_postamble
), 5);
99 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_PRE
], ar9485_1_1
,
100 ARRAY_SIZE(ar9485_1_1
), 2);
101 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_CORE
],
102 ar9485_1_1_baseband_core
,
103 ARRAY_SIZE(ar9485_1_1_baseband_core
), 2);
104 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_POST
],
105 ar9485_1_1_baseband_postamble
,
106 ARRAY_SIZE(ar9485_1_1_baseband_postamble
), 5);
109 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_PRE
], NULL
, 0, 0);
110 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_CORE
],
111 ar9485_1_1_radio_core
,
112 ARRAY_SIZE(ar9485_1_1_radio_core
), 2);
113 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_POST
],
114 ar9485_1_1_radio_postamble
,
115 ARRAY_SIZE(ar9485_1_1_radio_postamble
), 2);
118 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_PRE
],
119 ar9485_1_1_soc_preamble
,
120 ARRAY_SIZE(ar9485_1_1_soc_preamble
), 2);
121 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_CORE
], NULL
, 0, 0);
122 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_POST
], NULL
, 0, 0);
125 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
126 ar9485Common_wo_xlna_rx_gain_1_1
,
127 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1
), 2);
128 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
129 ar9485_modes_lowest_ob_db_tx_gain_1_1
,
130 ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1
),
133 /* Load PCIE SERDES settings from INI */
137 INIT_INI_ARRAY(&ah
->iniPcieSerdes
,
138 ar9485_1_1_pcie_phy_clkreq_disable_L1
,
139 ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1
),
144 INIT_INI_ARRAY(&ah
->iniPcieSerdesLowPower
,
145 ar9485_1_1_pcie_phy_clkreq_disable_L1
,
146 ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1
),
150 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_PRE
], NULL
, 0, 0);
151 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_CORE
],
153 ARRAY_SIZE(ar9300_2p2_mac_core
), 2);
154 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_POST
],
155 ar9300_2p2_mac_postamble
,
156 ARRAY_SIZE(ar9300_2p2_mac_postamble
), 5);
159 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_PRE
], NULL
, 0, 0);
160 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_CORE
],
161 ar9300_2p2_baseband_core
,
162 ARRAY_SIZE(ar9300_2p2_baseband_core
), 2);
163 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_POST
],
164 ar9300_2p2_baseband_postamble
,
165 ARRAY_SIZE(ar9300_2p2_baseband_postamble
), 5);
168 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_PRE
], NULL
, 0, 0);
169 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_CORE
],
170 ar9300_2p2_radio_core
,
171 ARRAY_SIZE(ar9300_2p2_radio_core
), 2);
172 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_POST
],
173 ar9300_2p2_radio_postamble
,
174 ARRAY_SIZE(ar9300_2p2_radio_postamble
), 5);
177 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_PRE
],
178 ar9300_2p2_soc_preamble
,
179 ARRAY_SIZE(ar9300_2p2_soc_preamble
), 2);
180 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_CORE
], NULL
, 0, 0);
181 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_POST
],
182 ar9300_2p2_soc_postamble
,
183 ARRAY_SIZE(ar9300_2p2_soc_postamble
), 5);
186 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
187 ar9300Common_rx_gain_table_2p2
,
188 ARRAY_SIZE(ar9300Common_rx_gain_table_2p2
), 2);
189 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
190 ar9300Modes_lowest_ob_db_tx_gain_table_2p2
,
191 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2
),
194 /* Load PCIE SERDES settings from INI */
198 INIT_INI_ARRAY(&ah
->iniPcieSerdes
,
199 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2
,
200 ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2
),
205 INIT_INI_ARRAY(&ah
->iniPcieSerdesLowPower
,
206 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2
,
207 ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2
),
210 /* Fast clock modal settings */
211 INIT_INI_ARRAY(&ah
->iniModesAdditional
,
212 ar9300Modes_fast_clock_2p2
,
213 ARRAY_SIZE(ar9300Modes_fast_clock_2p2
),
218 static void ar9003_tx_gain_table_apply(struct ath_hw
*ah
)
220 switch (ar9003_hw_get_tx_gain_idx(ah
)) {
223 if (AR_SREV_9340(ah
))
224 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
225 ar9340Modes_lowest_ob_db_tx_gain_table_1p0
,
226 ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0
),
228 else if (AR_SREV_9485_11(ah
))
229 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
230 ar9485_modes_lowest_ob_db_tx_gain_1_1
,
231 ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1
),
234 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
235 ar9300Modes_lowest_ob_db_tx_gain_table_2p2
,
236 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2
),
240 if (AR_SREV_9340(ah
))
241 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
242 ar9340Modes_lowest_ob_db_tx_gain_table_1p0
,
243 ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0
),
245 else if (AR_SREV_9485_11(ah
))
246 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
247 ar9485Modes_high_ob_db_tx_gain_1_1
,
248 ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1
),
251 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
252 ar9300Modes_high_ob_db_tx_gain_table_2p2
,
253 ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2
),
257 if (AR_SREV_9340(ah
))
258 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
259 ar9340Modes_lowest_ob_db_tx_gain_table_1p0
,
260 ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0
),
262 else if (AR_SREV_9485_11(ah
))
263 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
264 ar9485Modes_low_ob_db_tx_gain_1_1
,
265 ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1
),
268 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
269 ar9300Modes_low_ob_db_tx_gain_table_2p2
,
270 ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2
),
274 if (AR_SREV_9340(ah
))
275 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
276 ar9340Modes_lowest_ob_db_tx_gain_table_1p0
,
277 ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0
),
279 else if (AR_SREV_9485_11(ah
))
280 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
281 ar9485Modes_high_power_tx_gain_1_1
,
282 ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1
),
285 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
286 ar9300Modes_high_power_tx_gain_table_2p2
,
287 ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2
),
293 static void ar9003_rx_gain_table_apply(struct ath_hw
*ah
)
295 switch (ar9003_hw_get_rx_gain_idx(ah
)) {
298 if (AR_SREV_9340(ah
))
299 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
300 ar9340Common_rx_gain_table_1p0
,
301 ARRAY_SIZE(ar9340Common_rx_gain_table_1p0
),
303 else if (AR_SREV_9485_11(ah
))
304 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
305 ar9485Common_wo_xlna_rx_gain_1_1
,
306 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1
),
309 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
310 ar9300Common_rx_gain_table_2p2
,
311 ARRAY_SIZE(ar9300Common_rx_gain_table_2p2
),
315 if (AR_SREV_9340(ah
))
316 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
317 ar9340Common_wo_xlna_rx_gain_table_1p0
,
318 ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0
),
320 else if (AR_SREV_9485_11(ah
))
321 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
322 ar9485Common_wo_xlna_rx_gain_1_1
,
323 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1
),
326 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
327 ar9300Common_wo_xlna_rx_gain_table_2p2
,
328 ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2
),
334 /* set gain table pointers according to values read from the eeprom */
335 static void ar9003_hw_init_mode_gain_regs(struct ath_hw
*ah
)
337 ar9003_tx_gain_table_apply(ah
);
338 ar9003_rx_gain_table_apply(ah
);
342 * Helper for ASPM support.
344 * Disable PLL when in L0s as well as receiver clock when in L1.
345 * This power saving option must be enabled through the SerDes.
347 * Programming the SerDes must go through the same 288 bit serial shift
348 * register as the other analog registers. Hence the 9 writes.
350 static void ar9003_hw_configpcipowersave(struct ath_hw
*ah
,
354 if (ah
->is_pciexpress
!= true)
357 /* Do not touch SerDes registers */
358 if (ah
->config
.pcie_powersave_enable
== 2)
361 /* Nothing to do on restore for 11N */
363 /* set bit 19 to allow forcing of pcie core into L1 state */
364 REG_SET_BIT(ah
, AR_PCIE_PM_CTRL
, AR_PCIE_PM_CTRL_ENA
);
366 /* Several PCIe massages to ensure proper behaviour */
367 if (ah
->config
.pcie_waen
)
368 REG_WRITE(ah
, AR_WA
, ah
->config
.pcie_waen
);
370 REG_WRITE(ah
, AR_WA
, ah
->WARegVal
);
374 * Configire PCIE after Ini init. SERDES values now come from ini file
375 * This enables PCIe low power mode.
377 if (ah
->config
.pcieSerDesWrite
) {
379 struct ar5416IniArray
*array
;
381 array
= power_off
? &ah
->iniPcieSerdes
:
382 &ah
->iniPcieSerdesLowPower
;
384 for (i
= 0; i
< array
->ia_rows
; i
++) {
387 INI_RA(array
, i
, 1));
392 /* Sets up the AR9003 hardware familiy callbacks */
393 void ar9003_hw_attach_ops(struct ath_hw
*ah
)
395 struct ath_hw_private_ops
*priv_ops
= ath9k_hw_private_ops(ah
);
396 struct ath_hw_ops
*ops
= ath9k_hw_ops(ah
);
398 priv_ops
->init_mode_regs
= ar9003_hw_init_mode_regs
;
399 priv_ops
->init_mode_gain_regs
= ar9003_hw_init_mode_gain_regs
;
401 ops
->config_pci_powersave
= ar9003_hw_configpcipowersave
;
403 ar9003_hw_attach_phy_ops(ah
);
404 ar9003_hw_attach_calib_ops(ah
);
405 ar9003_hw_attach_mac_ops(ah
);