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"
21 /* General hardware code for the AR9003 hadware family */
23 static bool ar9003_hw_macversion_supported(u32 macversion)
26 case AR_SREV_VERSION_9300:
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.
39 static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
42 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
43 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_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);
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);
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);
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);
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),
86 /* Load PCIE SERDES settings from INI */
90 INIT_INI_ARRAY(&ah->iniPcieSerdes,
91 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
92 ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
97 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
98 ar9300PciePhy_clkreq_enable_L1_2p2,
99 ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p2),
102 /* Fast clock modal settings */
103 INIT_INI_ARRAY(&ah->iniModesAdditional,
104 ar9300Modes_fast_clock_2p2,
105 ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
109 static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
111 switch (ar9003_hw_get_tx_gain_idx(ah)) {
114 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),
120 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),
126 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),
134 static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
136 switch (ar9003_hw_get_rx_gain_idx(ah)) {
139 INIT_INI_ARRAY(&ah->iniModesRxGain,
140 ar9300Common_rx_gain_table_2p2,
141 ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
145 INIT_INI_ARRAY(&ah->iniModesRxGain,
146 ar9300Common_wo_xlna_rx_gain_table_2p2,
147 ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
153 /* set gain table pointers according to values read from the eeprom */
154 static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
156 ar9003_tx_gain_table_apply(ah);
157 ar9003_rx_gain_table_apply(ah);
161 * Helper for ASPM support.
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.
166 * Programming the SerDes must go through the same 288 bit serial shift
167 * register as the other analog registers. Hence the 9 writes.
169 static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
173 if (ah->is_pciexpress != true)
176 /* Do not touch SerDes registers */
177 if (ah->config.pcie_powersave_enable == 2)
180 /* Nothing to do on restore for 11N */
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);
185 /* Several PCIe massages to ensure proper behaviour */
186 if (ah->config.pcie_waen)
187 REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
189 REG_WRITE(ah, AR_WA, ah->WARegVal);
193 * Configire PCIE after Ini init. SERDES values now come from ini file
194 * This enables PCIe low power mode.
196 if (ah->config.pcieSerDesWrite) {
198 struct ar5416IniArray *array;
200 array = power_off ? &ah->iniPcieSerdes :
201 &ah->iniPcieSerdesLowPower;
203 for (i = 0; i < array->ia_rows; i++) {
206 INI_RA(array, i, 1));
211 /* Sets up the AR9003 hardware familiy callbacks */
212 void ar9003_hw_attach_ops(struct ath_hw *ah)
214 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
215 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
217 priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
218 priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
219 priv_ops->macversion_supported = ar9003_hw_macversion_supported;
221 ops->config_pci_powersave = ar9003_hw_configpcipowersave;
223 ar9003_hw_attach_phy_ops(ah);
224 ar9003_hw_attach_calib_ops(ah);
225 ar9003_hw_attach_mac_ops(ah);