ath9k_hw: Initialize mode registers from initvals.h for AR9340
[linux-2.6.git] / drivers / net / wireless / ath / ath9k / ar9003_hw.c
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"
18 #include "ar9003_mac.h"
19 #include "ar9003_2p2_initvals.h"
20 #include "ar9485_initvals.h"
21 #include "ar9340_initvals.h"
22
23 /* General hardware code for the AR9003 hadware family */
24
25 /*
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.
29  */
30 static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
31 {
32         if (AR_SREV_9340(ah)) {
33                 /* mac */
34                 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
35                 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
36                                 ar9340_1p0_mac_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);
41
42                 /* bb */
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);
50
51                 /* radio */
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);
59
60                 /* soc */
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);
68
69                 /* rx/tx gain */
70                 INIT_INI_ARRAY(&ah->iniModesRxGain,
71                                 ar9340Common_wo_xlna_rx_gain_table_1p0,
72                                 ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
73                                 5);
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),
77                                 5);
78
79                 INIT_INI_ARRAY(&ah->iniModesAdditional,
80                                 ar9340Modes_fast_clock_1p0,
81                                 ARRAY_SIZE(ar9340Modes_fast_clock_1p0),
82                                 3);
83
84                 INIT_INI_ARRAY(&ah->iniModesAdditional_40M,
85                                 ar9340_1p0_radio_core_40M,
86                                 ARRAY_SIZE(ar9340_1p0_radio_core_40M),
87                                 2);
88         } else if (AR_SREV_9485_11(ah)) {
89                 /* mac */
90                 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
91                 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
92                                 ar9485_1_1_mac_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);
97
98                 /* bb */
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);
107
108                 /* radio */
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);
116
117                 /* soc */
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);
123
124                 /* rx/tx gain */
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),
131                                 5);
132
133                 /* Load PCIE SERDES settings from INI */
134
135                 /* Awake Setting */
136
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),
140                                 2);
141
142                 /* Sleep Setting */
143
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),
147                                 2);
148         } else {
149                 /* mac */
150                 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
151                 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
152                                 ar9300_2p2_mac_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);
157
158                 /* bb */
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);
166
167                 /* radio */
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);
175
176                 /* soc */
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);
184
185                 /* rx/tx gain */
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),
192                                 5);
193
194                 /* Load PCIE SERDES settings from INI */
195
196                 /* Awake Setting */
197
198                 INIT_INI_ARRAY(&ah->iniPcieSerdes,
199                                 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
200                                 ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
201                                 2);
202
203                 /* Sleep Setting */
204
205                 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
206                                 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
207                                 ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
208                                 2);
209
210                 /* Fast clock modal settings */
211                 INIT_INI_ARRAY(&ah->iniModesAdditional,
212                                 ar9300Modes_fast_clock_2p2,
213                                 ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
214                                 3);
215         }
216 }
217
218 static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
219 {
220         switch (ar9003_hw_get_tx_gain_idx(ah)) {
221         case 0:
222         default:
223                 if (AR_SREV_9485_11(ah))
224                         INIT_INI_ARRAY(&ah->iniModesTxGain,
225                                        ar9485_modes_lowest_ob_db_tx_gain_1_1,
226                                        ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
227                                        5);
228                 else
229                         INIT_INI_ARRAY(&ah->iniModesTxGain,
230                                        ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
231                                        ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
232                                        5);
233                 break;
234         case 1:
235                 if (AR_SREV_9485_11(ah))
236                         INIT_INI_ARRAY(&ah->iniModesTxGain,
237                                        ar9485Modes_high_ob_db_tx_gain_1_1,
238                                        ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
239                                        5);
240                 else
241                         INIT_INI_ARRAY(&ah->iniModesTxGain,
242                                        ar9300Modes_high_ob_db_tx_gain_table_2p2,
243                                        ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
244                                        5);
245                 break;
246         case 2:
247                 if (AR_SREV_9485_11(ah))
248                         INIT_INI_ARRAY(&ah->iniModesTxGain,
249                                        ar9485Modes_low_ob_db_tx_gain_1_1,
250                                        ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
251                                        5);
252                 else
253                         INIT_INI_ARRAY(&ah->iniModesTxGain,
254                                        ar9300Modes_low_ob_db_tx_gain_table_2p2,
255                                        ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
256                                        5);
257                 break;
258         case 3:
259                 if (AR_SREV_9485_11(ah))
260                         INIT_INI_ARRAY(&ah->iniModesTxGain,
261                                        ar9485Modes_high_power_tx_gain_1_1,
262                                        ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
263                                        5);
264                 else
265                         INIT_INI_ARRAY(&ah->iniModesTxGain,
266                                        ar9300Modes_high_power_tx_gain_table_2p2,
267                                        ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2),
268                                        5);
269                 break;
270         }
271 }
272
273 static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
274 {
275         switch (ar9003_hw_get_rx_gain_idx(ah)) {
276         case 0:
277         default:
278                 if (AR_SREV_9485_11(ah))
279                         INIT_INI_ARRAY(&ah->iniModesRxGain,
280                                        ar9485Common_wo_xlna_rx_gain_1_1,
281                                        ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
282                                        2);
283                 else
284                         INIT_INI_ARRAY(&ah->iniModesRxGain,
285                                        ar9300Common_rx_gain_table_2p2,
286                                        ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
287                                        2);
288                 break;
289         case 1:
290                 if (AR_SREV_9485_11(ah))
291                         INIT_INI_ARRAY(&ah->iniModesRxGain,
292                                        ar9485Common_wo_xlna_rx_gain_1_1,
293                                        ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
294                                        2);
295                 else
296                         INIT_INI_ARRAY(&ah->iniModesRxGain,
297                                        ar9300Common_wo_xlna_rx_gain_table_2p2,
298                                        ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
299                                        2);
300                 break;
301         }
302 }
303
304 /* set gain table pointers according to values read from the eeprom */
305 static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
306 {
307         ar9003_tx_gain_table_apply(ah);
308         ar9003_rx_gain_table_apply(ah);
309 }
310
311 /*
312  * Helper for ASPM support.
313  *
314  * Disable PLL when in L0s as well as receiver clock when in L1.
315  * This power saving option must be enabled through the SerDes.
316  *
317  * Programming the SerDes must go through the same 288 bit serial shift
318  * register as the other analog registers.  Hence the 9 writes.
319  */
320 static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
321                                          int restore,
322                                          int power_off)
323 {
324         if (ah->is_pciexpress != true)
325                 return;
326
327         /* Do not touch SerDes registers */
328         if (ah->config.pcie_powersave_enable == 2)
329                 return;
330
331         /* Nothing to do on restore for 11N */
332         if (!restore) {
333                 /* set bit 19 to allow forcing of pcie core into L1 state */
334                 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
335
336                 /* Several PCIe massages to ensure proper behaviour */
337                 if (ah->config.pcie_waen)
338                         REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
339                 else
340                         REG_WRITE(ah, AR_WA, ah->WARegVal);
341         }
342
343         /*
344          * Configire PCIE after Ini init. SERDES values now come from ini file
345          * This enables PCIe low power mode.
346          */
347         if (ah->config.pcieSerDesWrite) {
348                 unsigned int i;
349                 struct ar5416IniArray *array;
350
351                 array = power_off ? &ah->iniPcieSerdes :
352                                     &ah->iniPcieSerdesLowPower;
353
354                 for (i = 0; i < array->ia_rows; i++) {
355                         REG_WRITE(ah,
356                                   INI_RA(array, i, 0),
357                                   INI_RA(array, i, 1));
358                 }
359         }
360 }
361
362 /* Sets up the AR9003 hardware familiy callbacks */
363 void ar9003_hw_attach_ops(struct ath_hw *ah)
364 {
365         struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
366         struct ath_hw_ops *ops = ath9k_hw_ops(ah);
367
368         priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
369         priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
370
371         ops->config_pci_powersave = ar9003_hw_configpcipowersave;
372
373         ar9003_hw_attach_phy_ops(ah);
374         ar9003_hw_attach_calib_ops(ah);
375         ar9003_hw_attach_mac_ops(ah);
376 }