blob: c2a057156bfa19c7c9db6862bb3233254fb0d452 [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"
Luis R. Rodriguezb622a722010-04-15 17:39:28 -040018#include "ar9003_mac.h"
Luis R. Rodriguez72846352010-05-12 21:15:05 -040019#include "ar9003_2p2_initvals.h"
Luis R. Rodriguezb3950e62010-04-15 17:39:03 -040020
21/* General hardware code for the AR9003 hadware family */
22
23static 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
Luis R. Rodriguez886b42b2010-10-14 11:44:27 -070034/*
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 */
39static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
Luis R. Rodriguez72846352010-05-12 21:15:05 -040040{
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
Luis R. Rodriguezc14a85d2010-04-15 17:39:21 -0400109static 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:
Luis R. Rodriguez886b42b2010-10-14 11:44:27 -0700114 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);
Luis R. Rodriguezc14a85d2010-04-15 17:39:21 -0400118 break;
119 case 1:
Luis R. Rodriguez886b42b2010-10-14 11:44:27 -0700120 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);
Luis R. Rodriguezc14a85d2010-04-15 17:39:21 -0400124 break;
125 case 2:
Luis R. Rodriguez886b42b2010-10-14 11:44:27 -0700126 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);
Luis R. Rodriguezc14a85d2010-04-15 17:39:21 -0400130 break;
131 }
132}
133
134static 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:
Luis R. Rodriguez886b42b2010-10-14 11:44:27 -0700139 INIT_INI_ARRAY(&ah->iniModesRxGain,
140 ar9300Common_rx_gain_table_2p2,
141 ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
142 2);
Luis R. Rodriguezc14a85d2010-04-15 17:39:21 -0400143 break;
144 case 1:
Luis R. Rodriguez886b42b2010-10-14 11:44:27 -0700145 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);
Luis R. Rodriguezc14a85d2010-04-15 17:39:21 -0400149 break;
150 }
151}
152
153/* set gain table pointers according to values read from the eeprom */
154static 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
Luis R. Rodriguezb3950e62010-04-15 17:39:03 -0400160/*
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 */
169static 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);
Luis R. Rodriguez9a658d22010-06-21 18:38:47 -0400188 else
189 REG_WRITE(ah, AR_WA, ah->WARegVal);
Luis R. Rodriguezb3950e62010-04-15 17:39:03 -0400190 }
Luis R. Rodriguez653fe372010-06-21 18:38:48 -0400191
192 /*
193 * Configire PCIE after Ini init. SERDES values now come from ini file
194 * This enables PCIe low power mode.
195 */
Luis R. Rodriguez6a0ec302010-06-21 18:38:49 -0400196 if (ah->config.pcieSerDesWrite) {
Luis R. Rodriguez653fe372010-06-21 18:38:48 -0400197 unsigned int i;
Luis R. Rodriguezd5c4d192010-06-21 18:38:50 -0400198 struct ar5416IniArray *array;
Luis R. Rodriguez653fe372010-06-21 18:38:48 -0400199
Luis R. Rodriguezd5c4d192010-06-21 18:38:50 -0400200 array = power_off ? &ah->iniPcieSerdes :
201 &ah->iniPcieSerdesLowPower;
202
203 for (i = 0; i < array->ia_rows; i++) {
Luis R. Rodriguez653fe372010-06-21 18:38:48 -0400204 REG_WRITE(ah,
Luis R. Rodriguezd5c4d192010-06-21 18:38:50 -0400205 INI_RA(array, i, 0),
206 INI_RA(array, i, 1));
Luis R. Rodriguez653fe372010-06-21 18:38:48 -0400207 }
208 }
Luis R. Rodriguezb3950e62010-04-15 17:39:03 -0400209}
210
211/* Sets up the AR9003 hardware familiy callbacks */
212void 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;
Luis R. Rodriguezc14a85d2010-04-15 17:39:21 -0400218 priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
Luis R. Rodriguezb3950e62010-04-15 17:39:03 -0400219 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);
Luis R. Rodriguezb3950e62010-04-15 17:39:03 -0400226}