Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ar9003_rtt.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2011 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 "hw-ops.h"
19 #include "ar9003_phy.h"
20 #include "ar9003_rtt.h"
21 
22 #define RTT_RESTORE_TIMEOUT 1000
23 #define RTT_ACCESS_TIMEOUT 100
24 #define RTT_BAD_VALUE 0x0bad0bad
25 
26 /*
27  * RTT (Radio Retention Table) hardware implementation information
28  *
29  * There is an internal table (i.e. the rtt) for each chain (or bank).
30  * Each table contains 6 entries and each entry is corresponding to
31  * a specific calibration parameter as depicted below.
32  * 0~2 - DC offset DAC calibration: loop, low, high (offsetI/Q_...)
33  * 3 - Filter cal (filterfc)
34  * 4 - RX gain settings
35  * 5 - Peak detector offset calibration (agc_caldac)
36  */
37 
39 {
40  REG_WRITE(ah, AR_PHY_RTT_CTRL, 1);
41 }
42 
44 {
45  REG_WRITE(ah, AR_PHY_RTT_CTRL, 0);
46 }
47 
48 void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask)
49 {
52 }
53 
55 {
59  return false;
60 
63 
67  return false;
68 
69  return true;
70 }
71 
72 static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain,
73  u32 index, u32 data28)
74 {
75  u32 val;
76 
77  val = SM(data28, AR_PHY_RTT_SW_RTT_TABLE_DATA);
78  REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain), val);
79 
83  REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
84  udelay(1);
85 
87  REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
88  udelay(1);
89 
93  return;
94 
96  REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
97  udelay(1);
98 
102 }
103 
105 {
106  int chain, i;
107 
108  for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
109  if (!(ah->rxchainmask & (1 << chain)))
110  continue;
111  for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
112  ar9003_hw_rtt_load_hist_entry(ah, chain, i,
113  ah->caldata->rtt_table[chain][i]);
114  ath_dbg(ath9k_hw_common(ah), CALIBRATE,
115  "Load RTT value at idx %d, chain %d: 0x%x\n",
116  i, chain, ah->caldata->rtt_table[chain][i]);
117  }
118  }
119 }
120 
121 static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index)
122 {
123  u32 val;
124 
128 
129  REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
130  udelay(1);
131 
133  REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
134  udelay(1);
135 
139  return RTT_BAD_VALUE;
140 
141  val = MS(REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)),
143 
144 
145  return val;
146 }
147 
149 {
150  int chain, i;
151 
152  for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
153  if (!(ah->rxchainmask & (1 << chain)))
154  continue;
155  for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
156  ah->caldata->rtt_table[chain][i] =
157  ar9003_hw_rtt_fill_hist_entry(ah, chain, i);
158  ath_dbg(ath9k_hw_common(ah), CALIBRATE,
159  "RTT value at idx %d, chain %d is: 0x%x\n",
160  i, chain, ah->caldata->rtt_table[chain][i]);
161  }
162  }
163 
164  ah->caldata->rtt_done = true;
165 }
166 
168 {
169  int chain, i;
170 
171  for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
172  if (!(ah->rxchainmask & (1 << chain)))
173  continue;
174  for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
175  ar9003_hw_rtt_load_hist_entry(ah, chain, i, 0);
176  }
177 
178  if (ah->caldata)
179  ah->caldata->rtt_done = false;
180 }
181 
183 {
184  bool restore;
185 
186  if (!ah->caldata)
187  return false;
188 
189  if (!ah->caldata->rtt_done)
190  return false;
191 
193  ar9003_hw_rtt_set_mask(ah, 0x10);
194 
195  if (!ath9k_hw_rfbus_req(ah)) {
196  ath_err(ath9k_hw_common(ah), "Could not stop baseband\n");
197  restore = false;
198  goto fail;
199  }
200 
202  restore = ar9003_hw_rtt_force_restore(ah);
203 
204 fail:
205  ath9k_hw_rfbus_done(ah);
207  return restore;
208 }