0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include "hw.h"
0018 #include "hw-ops.h"
0019 #include "ar9003_phy.h"
0020 #include "ar9003_rtt.h"
0021
0022 #define RTT_RESTORE_TIMEOUT 1000
0023 #define RTT_ACCESS_TIMEOUT 100
0024 #define RTT_BAD_VALUE 0x0bad0bad
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 void ar9003_hw_rtt_enable(struct ath_hw *ah)
0039 {
0040 REG_WRITE(ah, AR_PHY_RTT_CTRL, 1);
0041 }
0042
0043 void ar9003_hw_rtt_disable(struct ath_hw *ah)
0044 {
0045 REG_WRITE(ah, AR_PHY_RTT_CTRL, 0);
0046 }
0047
0048 void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask)
0049 {
0050 REG_RMW_FIELD(ah, AR_PHY_RTT_CTRL,
0051 AR_PHY_RTT_CTRL_RESTORE_MASK, rtt_mask);
0052 }
0053
0054 bool ar9003_hw_rtt_force_restore(struct ath_hw *ah)
0055 {
0056 if (!ath9k_hw_wait(ah, AR_PHY_RTT_CTRL,
0057 AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE,
0058 0, RTT_RESTORE_TIMEOUT))
0059 return false;
0060
0061 REG_RMW_FIELD(ah, AR_PHY_RTT_CTRL,
0062 AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE, 1);
0063
0064 if (!ath9k_hw_wait(ah, AR_PHY_RTT_CTRL,
0065 AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE,
0066 0, RTT_RESTORE_TIMEOUT))
0067 return false;
0068
0069 return true;
0070 }
0071
0072 static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain,
0073 u32 index, u32 data28)
0074 {
0075 u32 val;
0076
0077 val = SM(data28, AR_PHY_RTT_SW_RTT_TABLE_DATA);
0078 REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain), val);
0079
0080 val = SM(0, AR_PHY_RTT_SW_RTT_TABLE_ACCESS) |
0081 SM(1, AR_PHY_RTT_SW_RTT_TABLE_WRITE) |
0082 SM(index, AR_PHY_RTT_SW_RTT_TABLE_ADDR);
0083 REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
0084 udelay(1);
0085
0086 val |= SM(1, AR_PHY_RTT_SW_RTT_TABLE_ACCESS);
0087 REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
0088 udelay(1);
0089
0090 if (!ath9k_hw_wait(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain),
0091 AR_PHY_RTT_SW_RTT_TABLE_ACCESS, 0,
0092 RTT_ACCESS_TIMEOUT))
0093 return;
0094
0095 val &= ~SM(1, AR_PHY_RTT_SW_RTT_TABLE_WRITE);
0096 REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
0097 udelay(1);
0098
0099 ath9k_hw_wait(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain),
0100 AR_PHY_RTT_SW_RTT_TABLE_ACCESS, 0,
0101 RTT_ACCESS_TIMEOUT);
0102 }
0103
0104 void ar9003_hw_rtt_load_hist(struct ath_hw *ah)
0105 {
0106 int chain, i;
0107
0108 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
0109 if (!(ah->caps.rx_chainmask & (1 << chain)))
0110 continue;
0111 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
0112 ar9003_hw_rtt_load_hist_entry(ah, chain, i,
0113 ah->caldata->rtt_table[chain][i]);
0114 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
0115 "Load RTT value at idx %d, chain %d: 0x%x\n",
0116 i, chain, ah->caldata->rtt_table[chain][i]);
0117 }
0118 }
0119 }
0120
0121 static void ar9003_hw_patch_rtt(struct ath_hw *ah, int index, int chain)
0122 {
0123 int agc, caldac;
0124
0125 if (!test_bit(SW_PKDET_DONE, &ah->caldata->cal_flags))
0126 return;
0127
0128 if ((index != 5) || (chain >= 2))
0129 return;
0130
0131 agc = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
0132 AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE);
0133 if (!agc)
0134 return;
0135
0136 caldac = ah->caldata->caldac[chain];
0137 ah->caldata->rtt_table[chain][index] &= 0xFFFF05FF;
0138 caldac = (caldac & 0x20) | ((caldac & 0x1F) << 7);
0139 ah->caldata->rtt_table[chain][index] |= (caldac << 4);
0140 }
0141
0142 static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index)
0143 {
0144 u32 val;
0145
0146 val = SM(0, AR_PHY_RTT_SW_RTT_TABLE_ACCESS) |
0147 SM(0, AR_PHY_RTT_SW_RTT_TABLE_WRITE) |
0148 SM(index, AR_PHY_RTT_SW_RTT_TABLE_ADDR);
0149
0150 REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
0151 udelay(1);
0152
0153 val |= SM(1, AR_PHY_RTT_SW_RTT_TABLE_ACCESS);
0154 REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
0155 udelay(1);
0156
0157 if (!ath9k_hw_wait(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain),
0158 AR_PHY_RTT_SW_RTT_TABLE_ACCESS, 0,
0159 RTT_ACCESS_TIMEOUT))
0160 return RTT_BAD_VALUE;
0161
0162 val = MS(REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain)),
0163 AR_PHY_RTT_SW_RTT_TABLE_DATA);
0164
0165
0166 return val;
0167 }
0168
0169 void ar9003_hw_rtt_fill_hist(struct ath_hw *ah)
0170 {
0171 int chain, i;
0172
0173 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
0174 if (!(ah->caps.rx_chainmask & (1 << chain)))
0175 continue;
0176 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
0177 ah->caldata->rtt_table[chain][i] =
0178 ar9003_hw_rtt_fill_hist_entry(ah, chain, i);
0179
0180 ar9003_hw_patch_rtt(ah, i, chain);
0181
0182 ath_dbg(ath9k_hw_common(ah), CALIBRATE,
0183 "RTT value at idx %d, chain %d is: 0x%x\n",
0184 i, chain, ah->caldata->rtt_table[chain][i]);
0185 }
0186 }
0187
0188 set_bit(RTT_DONE, &ah->caldata->cal_flags);
0189 }
0190
0191 void ar9003_hw_rtt_clear_hist(struct ath_hw *ah)
0192 {
0193 int chain, i;
0194
0195 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
0196 if (!(ah->caps.rx_chainmask & (1 << chain)))
0197 continue;
0198 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
0199 ar9003_hw_rtt_load_hist_entry(ah, chain, i, 0);
0200 }
0201
0202 if (ah->caldata)
0203 clear_bit(RTT_DONE, &ah->caldata->cal_flags);
0204 }
0205
0206 bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
0207 {
0208 bool restore;
0209
0210 if (!ah->caldata)
0211 return false;
0212
0213 if (test_bit(SW_PKDET_DONE, &ah->caldata->cal_flags)) {
0214 if (IS_CHAN_2GHZ(chan)){
0215 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(0),
0216 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR,
0217 ah->caldata->caldac[0]);
0218 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(1),
0219 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR,
0220 ah->caldata->caldac[1]);
0221 } else {
0222 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(0),
0223 AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR,
0224 ah->caldata->caldac[0]);
0225 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(1),
0226 AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR,
0227 ah->caldata->caldac[1]);
0228 }
0229 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(1),
0230 AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1);
0231 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(0),
0232 AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1);
0233 }
0234
0235 if (!test_bit(RTT_DONE, &ah->caldata->cal_flags))
0236 return false;
0237
0238 ar9003_hw_rtt_enable(ah);
0239
0240 if (test_bit(SW_PKDET_DONE, &ah->caldata->cal_flags))
0241 ar9003_hw_rtt_set_mask(ah, 0x30);
0242 else
0243 ar9003_hw_rtt_set_mask(ah, 0x10);
0244
0245 if (!ath9k_hw_rfbus_req(ah)) {
0246 ath_err(ath9k_hw_common(ah), "Could not stop baseband\n");
0247 restore = false;
0248 goto fail;
0249 }
0250
0251 ar9003_hw_rtt_load_hist(ah);
0252 restore = ar9003_hw_rtt_force_restore(ah);
0253
0254 fail:
0255 ath9k_hw_rfbus_done(ah);
0256 ar9003_hw_rtt_disable(ah);
0257 return restore;
0258 }