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"
22 /* General hardware code for the AR9003 hadware family */
25 * The AR9003 family uses a new INI format (pre, core, post
26 * arrays per subsystem). This provides support for the
27 * AR9003 2.2 chipsets.
29 static void ar9003_hw_init_mode_regs(struct ath_hw
*ah
)
31 if (AR_SREV_9485_11(ah
)) {
33 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_PRE
], NULL
, 0, 0);
34 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_CORE
],
36 ARRAY_SIZE(ar9485_1_1_mac_core
), 2);
37 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_POST
],
38 ar9485_1_1_mac_postamble
,
39 ARRAY_SIZE(ar9485_1_1_mac_postamble
), 5);
42 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_PRE
], ar9485_1_1
,
43 ARRAY_SIZE(ar9485_1_1
), 2);
44 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_CORE
],
45 ar9485_1_1_baseband_core
,
46 ARRAY_SIZE(ar9485_1_1_baseband_core
), 2);
47 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_POST
],
48 ar9485_1_1_baseband_postamble
,
49 ARRAY_SIZE(ar9485_1_1_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 ar9485_1_1_radio_core
,
55 ARRAY_SIZE(ar9485_1_1_radio_core
), 2);
56 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_POST
],
57 ar9485_1_1_radio_postamble
,
58 ARRAY_SIZE(ar9485_1_1_radio_postamble
), 2);
61 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_PRE
],
62 ar9485_1_1_soc_preamble
,
63 ARRAY_SIZE(ar9485_1_1_soc_preamble
), 2);
64 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_CORE
], NULL
, 0, 0);
65 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_POST
], NULL
, 0, 0);
68 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
69 ar9485_common_rx_gain_1_1
,
70 ARRAY_SIZE(ar9485_common_rx_gain_1_1
), 2);
71 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
72 ar9485_modes_lowest_ob_db_tx_gain_1_1
,
73 ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1
),
76 /* Load PCIE SERDES settings from INI */
80 INIT_INI_ARRAY(&ah
->iniPcieSerdes
,
81 ar9485_1_1_pcie_phy_clkreq_disable_L1
,
82 ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1
),
87 INIT_INI_ARRAY(&ah
->iniPcieSerdesLowPower
,
88 ar9485_1_1_pcie_phy_clkreq_disable_L1
,
89 ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1
),
91 } else if (AR_SREV_9485(ah
)) {
93 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_PRE
], NULL
, 0, 0);
94 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_CORE
],
96 ARRAY_SIZE(ar9485_1_0_mac_core
), 2);
97 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_POST
],
98 ar9485_1_0_mac_postamble
,
99 ARRAY_SIZE(ar9485_1_0_mac_postamble
), 5);
102 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_PRE
], ar9485_1_0
,
103 ARRAY_SIZE(ar9485_1_0
), 2);
104 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_CORE
],
105 ar9485_1_0_baseband_core
,
106 ARRAY_SIZE(ar9485_1_0_baseband_core
), 2);
107 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_POST
],
108 ar9485_1_0_baseband_postamble
,
109 ARRAY_SIZE(ar9485_1_0_baseband_postamble
), 5);
112 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_PRE
], NULL
, 0, 0);
113 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_CORE
],
114 ar9485_1_0_radio_core
,
115 ARRAY_SIZE(ar9485_1_0_radio_core
), 2);
116 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_POST
],
117 ar9485_1_0_radio_postamble
,
118 ARRAY_SIZE(ar9485_1_0_radio_postamble
), 2);
121 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_PRE
],
122 ar9485_1_0_soc_preamble
,
123 ARRAY_SIZE(ar9485_1_0_soc_preamble
), 2);
124 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_CORE
], NULL
, 0, 0);
125 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_POST
], NULL
, 0, 0);
128 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
129 ar9485Common_rx_gain_1_0
,
130 ARRAY_SIZE(ar9485Common_rx_gain_1_0
), 2);
131 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
132 ar9485Modes_lowest_ob_db_tx_gain_1_0
,
133 ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0
),
136 /* Load PCIE SERDES settings from INI */
140 INIT_INI_ARRAY(&ah
->iniPcieSerdes
,
141 ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1
,
142 ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1
),
147 INIT_INI_ARRAY(&ah
->iniPcieSerdesLowPower
,
148 ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1
,
149 ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1
),
153 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_PRE
], NULL
, 0, 0);
154 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_CORE
],
156 ARRAY_SIZE(ar9300_2p2_mac_core
), 2);
157 INIT_INI_ARRAY(&ah
->iniMac
[ATH_INI_POST
],
158 ar9300_2p2_mac_postamble
,
159 ARRAY_SIZE(ar9300_2p2_mac_postamble
), 5);
162 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_PRE
], NULL
, 0, 0);
163 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_CORE
],
164 ar9300_2p2_baseband_core
,
165 ARRAY_SIZE(ar9300_2p2_baseband_core
), 2);
166 INIT_INI_ARRAY(&ah
->iniBB
[ATH_INI_POST
],
167 ar9300_2p2_baseband_postamble
,
168 ARRAY_SIZE(ar9300_2p2_baseband_postamble
), 5);
171 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_PRE
], NULL
, 0, 0);
172 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_CORE
],
173 ar9300_2p2_radio_core
,
174 ARRAY_SIZE(ar9300_2p2_radio_core
), 2);
175 INIT_INI_ARRAY(&ah
->iniRadio
[ATH_INI_POST
],
176 ar9300_2p2_radio_postamble
,
177 ARRAY_SIZE(ar9300_2p2_radio_postamble
), 5);
180 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_PRE
],
181 ar9300_2p2_soc_preamble
,
182 ARRAY_SIZE(ar9300_2p2_soc_preamble
), 2);
183 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_CORE
], NULL
, 0, 0);
184 INIT_INI_ARRAY(&ah
->iniSOC
[ATH_INI_POST
],
185 ar9300_2p2_soc_postamble
,
186 ARRAY_SIZE(ar9300_2p2_soc_postamble
), 5);
189 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
190 ar9300Common_rx_gain_table_2p2
,
191 ARRAY_SIZE(ar9300Common_rx_gain_table_2p2
), 2);
192 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
193 ar9300Modes_lowest_ob_db_tx_gain_table_2p2
,
194 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2
),
197 /* Load PCIE SERDES settings from INI */
201 INIT_INI_ARRAY(&ah
->iniPcieSerdes
,
202 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2
,
203 ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2
),
208 INIT_INI_ARRAY(&ah
->iniPcieSerdesLowPower
,
209 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2
,
210 ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2
),
213 /* Fast clock modal settings */
214 INIT_INI_ARRAY(&ah
->iniModesAdditional
,
215 ar9300Modes_fast_clock_2p2
,
216 ARRAY_SIZE(ar9300Modes_fast_clock_2p2
),
221 static void ar9003_tx_gain_table_apply(struct ath_hw
*ah
)
223 switch (ar9003_hw_get_tx_gain_idx(ah
)) {
226 if (AR_SREV_9485_11(ah
))
227 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
228 ar9485_modes_lowest_ob_db_tx_gain_1_1
,
229 ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1
),
231 else if (AR_SREV_9485(ah
))
232 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
233 ar9485Modes_lowest_ob_db_tx_gain_1_0
,
234 ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0
),
237 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
238 ar9300Modes_lowest_ob_db_tx_gain_table_2p2
,
239 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2
),
243 if (AR_SREV_9485_11(ah
))
244 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
245 ar9485Modes_high_ob_db_tx_gain_1_1
,
246 ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1
),
248 else if (AR_SREV_9485(ah
))
249 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
250 ar9485Modes_high_ob_db_tx_gain_1_0
,
251 ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_0
),
254 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
255 ar9300Modes_high_ob_db_tx_gain_table_2p2
,
256 ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2
),
260 if (AR_SREV_9485_11(ah
))
261 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
262 ar9485Modes_low_ob_db_tx_gain_1_1
,
263 ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1
),
265 else if (AR_SREV_9485(ah
))
266 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
267 ar9485Modes_low_ob_db_tx_gain_1_0
,
268 ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_0
),
271 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
272 ar9300Modes_low_ob_db_tx_gain_table_2p2
,
273 ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2
),
277 if (AR_SREV_9485_11(ah
))
278 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
279 ar9485Modes_high_power_tx_gain_1_1
,
280 ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1
),
282 else if (AR_SREV_9485(ah
))
283 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
284 ar9485Modes_high_power_tx_gain_1_0
,
285 ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_0
),
288 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
289 ar9300Modes_high_power_tx_gain_table_2p2
,
290 ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2
),
296 static void ar9003_rx_gain_table_apply(struct ath_hw
*ah
)
298 switch (ar9003_hw_get_rx_gain_idx(ah
)) {
301 if (AR_SREV_9485_11(ah
))
302 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
303 ar9485_common_rx_gain_1_1
,
304 ARRAY_SIZE(ar9485_common_rx_gain_1_1
),
306 else if (AR_SREV_9485(ah
))
307 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
308 ar9485Common_rx_gain_1_0
,
309 ARRAY_SIZE(ar9485Common_rx_gain_1_0
),
312 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
313 ar9300Common_rx_gain_table_2p2
,
314 ARRAY_SIZE(ar9300Common_rx_gain_table_2p2
),
318 if (AR_SREV_9485_11(ah
))
319 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
320 ar9485Common_wo_xlna_rx_gain_1_1
,
321 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1
),
323 else if (AR_SREV_9485(ah
))
324 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
325 ar9485Common_wo_xlna_rx_gain_1_0
,
326 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_0
),
329 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
330 ar9300Common_wo_xlna_rx_gain_table_2p2
,
331 ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2
),
337 /* set gain table pointers according to values read from the eeprom */
338 static void ar9003_hw_init_mode_gain_regs(struct ath_hw
*ah
)
340 ar9003_tx_gain_table_apply(ah
);
341 ar9003_rx_gain_table_apply(ah
);
345 * Helper for ASPM support.
347 * Disable PLL when in L0s as well as receiver clock when in L1.
348 * This power saving option must be enabled through the SerDes.
350 * Programming the SerDes must go through the same 288 bit serial shift
351 * register as the other analog registers. Hence the 9 writes.
353 static void ar9003_hw_configpcipowersave(struct ath_hw
*ah
,
357 if (ah
->is_pciexpress
!= true)
360 /* Do not touch SerDes registers */
361 if (ah
->config
.pcie_powersave_enable
== 2)
364 /* Nothing to do on restore for 11N */
366 /* set bit 19 to allow forcing of pcie core into L1 state */
367 REG_SET_BIT(ah
, AR_PCIE_PM_CTRL
, AR_PCIE_PM_CTRL_ENA
);
369 /* Several PCIe massages to ensure proper behaviour */
370 if (ah
->config
.pcie_waen
)
371 REG_WRITE(ah
, AR_WA
, ah
->config
.pcie_waen
);
373 REG_WRITE(ah
, AR_WA
, ah
->WARegVal
);
377 * Configire PCIE after Ini init. SERDES values now come from ini file
378 * This enables PCIe low power mode.
380 if (ah
->config
.pcieSerDesWrite
) {
382 struct ar5416IniArray
*array
;
384 array
= power_off
? &ah
->iniPcieSerdes
:
385 &ah
->iniPcieSerdesLowPower
;
387 for (i
= 0; i
< array
->ia_rows
; i
++) {
390 INI_RA(array
, i
, 1));
395 /* Sets up the AR9003 hardware familiy callbacks */
396 void ar9003_hw_attach_ops(struct ath_hw
*ah
)
398 struct ath_hw_private_ops
*priv_ops
= ath9k_hw_private_ops(ah
);
399 struct ath_hw_ops
*ops
= ath9k_hw_ops(ah
);
401 priv_ops
->init_mode_regs
= ar9003_hw_init_mode_regs
;
402 priv_ops
->init_mode_gain_regs
= ar9003_hw_init_mode_gain_regs
;
404 ops
->config_pci_powersave
= ar9003_hw_configpcipowersave
;
406 ar9003_hw_attach_phy_ops(ah
);
407 ar9003_hw_attach_calib_ops(ah
);
408 ar9003_hw_attach_mac_ops(ah
);