blob: b15309caf1da816418ea447d2f7152f3ac438622 [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. Rodriguezb3950e62010-04-15 17:39:03 -040019#include "ar9003_initvals.h"
20
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
34/* AR9003 2.0 - new INI format (pre, core, post arrays per subsystem) */
Luis R. Rodriguez991312d2010-04-15 17:39:05 -040035/*
36 * XXX: move TX/RX gain INI to its own init_mode_gain_regs after
37 * ensuring it does not affect hardware bring up
38 */
Luis R. Rodriguezb3950e62010-04-15 17:39:03 -040039static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
40{
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_2p0_mac_core,
45 ARRAY_SIZE(ar9300_2p0_mac_core), 2);
46 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
47 ar9300_2p0_mac_postamble,
48 ARRAY_SIZE(ar9300_2p0_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_2p0_baseband_core,
54 ARRAY_SIZE(ar9300_2p0_baseband_core), 2);
55 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
56 ar9300_2p0_baseband_postamble,
57 ARRAY_SIZE(ar9300_2p0_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_2p0_radio_core,
63 ARRAY_SIZE(ar9300_2p0_radio_core), 2);
64 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
65 ar9300_2p0_radio_postamble,
66 ARRAY_SIZE(ar9300_2p0_radio_postamble), 5);
67
68 /* soc */
69 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
70 ar9300_2p0_soc_preamble,
71 ARRAY_SIZE(ar9300_2p0_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_2p0_soc_postamble,
75 ARRAY_SIZE(ar9300_2p0_soc_postamble), 5);
76
77 /* rx/tx gain */
78 INIT_INI_ARRAY(&ah->iniModesRxGain,
79 ar9300Common_rx_gain_table_2p0,
80 ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2);
81 INIT_INI_ARRAY(&ah->iniModesTxGain,
82 ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
83 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
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_2p0,
92 ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0),
93 2);
94
95 /* Sleep Setting */
96
97 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
98 ar9300PciePhy_clkreq_enable_L1_2p0,
99 ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0),
100 2);
101
102 /* Fast clock modal settings */
103 INIT_INI_ARRAY(&ah->iniModesAdditional,
104 ar9300Modes_fast_clock_2p0,
105 ARRAY_SIZE(ar9300Modes_fast_clock_2p0),
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:
114 INIT_INI_ARRAY(&ah->iniModesTxGain,
115 ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
116 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
117 5);
118 break;
119 case 1:
120 INIT_INI_ARRAY(&ah->iniModesTxGain,
121 ar9300Modes_high_ob_db_tx_gain_table_2p0,
122 ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0),
123 5);
124 break;
125 case 2:
126 INIT_INI_ARRAY(&ah->iniModesTxGain,
127 ar9300Modes_low_ob_db_tx_gain_table_2p0,
128 ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0),
129 5);
130 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:
139 INIT_INI_ARRAY(&ah->iniModesRxGain, ar9300Common_rx_gain_table_2p0,
140 ARRAY_SIZE(ar9300Common_rx_gain_table_2p0),
141 2);
142 break;
143 case 1:
144 INIT_INI_ARRAY(&ah->iniModesRxGain,
145 ar9300Common_wo_xlna_rx_gain_table_2p0,
146 ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0),
147 2);
148 break;
149 }
150}
151
152/* set gain table pointers according to values read from the eeprom */
153static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
154{
155 ar9003_tx_gain_table_apply(ah);
156 ar9003_rx_gain_table_apply(ah);
157}
158
Luis R. Rodriguezb3950e62010-04-15 17:39:03 -0400159/*
160 * Helper for ASPM support.
161 *
162 * Disable PLL when in L0s as well as receiver clock when in L1.
163 * This power saving option must be enabled through the SerDes.
164 *
165 * Programming the SerDes must go through the same 288 bit serial shift
166 * register as the other analog registers. Hence the 9 writes.
167 */
168static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
169 int restore,
170 int power_off)
171{
172 if (ah->is_pciexpress != true)
173 return;
174
175 /* Do not touch SerDes registers */
176 if (ah->config.pcie_powersave_enable == 2)
177 return;
178
179 /* Nothing to do on restore for 11N */
180 if (!restore) {
181 /* set bit 19 to allow forcing of pcie core into L1 state */
182 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
183
184 /* Several PCIe massages to ensure proper behaviour */
185 if (ah->config.pcie_waen)
186 REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
187 }
188}
189
190/* Sets up the AR9003 hardware familiy callbacks */
191void ar9003_hw_attach_ops(struct ath_hw *ah)
192{
193 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
194 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
195
196 priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
Luis R. Rodriguezc14a85d2010-04-15 17:39:21 -0400197 priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
Luis R. Rodriguezb3950e62010-04-15 17:39:03 -0400198 priv_ops->macversion_supported = ar9003_hw_macversion_supported;
199
200 ops->config_pci_powersave = ar9003_hw_configpcipowersave;
201
202 ar9003_hw_attach_phy_ops(ah);
203 ar9003_hw_attach_calib_ops(ah);
204 ar9003_hw_attach_mac_ops(ah);
205}