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 #include "ar9003_mci.h" 22 23 #define MAX_MEASUREMENT MAX_IQCAL_MEASUREMENT 24 #define MAX_MAG_DELTA 11 25 #define MAX_PHS_DELTA 10 26 #define MAXIQCAL 3 27 28 struct coeff { 29 int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL]; 30 int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL]; 31 int iqc_coeff[2]; 32 }; 33 34 enum ar9003_cal_types { 35 IQ_MISMATCH_CAL = BIT(0), 36 }; 37 38 static void ar9003_hw_setup_calibration(struct ath_hw *ah, 39 struct ath9k_cal_list *currCal) 40 { 41 struct ath_common *common = ath9k_hw_common(ah); 42 43 /* Select calibration to run */ 44 switch (currCal->calData->calType) { 45 case IQ_MISMATCH_CAL: 46 /* 47 * Start calibration with 48 * 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples 49 */ 50 REG_RMW_FIELD(ah, AR_PHY_TIMING4, 51 AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX, 52 currCal->calData->calCountMax); 53 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); 54 55 ath_dbg(common, CALIBRATE, 56 "starting IQ Mismatch Calibration\n"); 57 58 /* Kick-off cal */ 59 REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL); 60 break; 61 default: 62 ath_err(common, "Invalid calibration type\n"); 63 break; 64 } 65 } 66 67 /* 68 * Generic calibration routine. 69 * Recalibrate the lower PHY chips to account for temperature/environment 70 * changes. 71 */ 72 static bool ar9003_hw_per_calibration(struct ath_hw *ah, 73 struct ath9k_channel *ichan, 74 u8 rxchainmask, 75 struct ath9k_cal_list *currCal) 76 { 77 struct ath9k_hw_cal_data *caldata = ah->caldata; 78 const struct ath9k_percal_data *cur_caldata = currCal->calData; 79 80 /* Calibration in progress. */ 81 if (currCal->calState == CAL_RUNNING) { 82 /* Check to see if it has finished. */ 83 if (REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL) 84 return false; 85 86 /* 87 * Accumulate cal measures for active chains 88 */ 89 cur_caldata->calCollect(ah); 90 ah->cal_samples++; 91 92 if (ah->cal_samples >= cur_caldata->calNumSamples) { 93 unsigned int i, numChains = 0; 94 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 95 if (rxchainmask & (1 << i)) 96 numChains++; 97 } 98 99 /* 100 * Process accumulated data 101 */ 102 cur_caldata->calPostProc(ah, numChains); 103 104 /* Calibration has finished. */ 105 caldata->CalValid |= cur_caldata->calType; 106 currCal->calState = CAL_DONE; 107 return true; 108 } else { 109 /* 110 * Set-up collection of another sub-sample until we 111 * get desired number 112 */ 113 ar9003_hw_setup_calibration(ah, currCal); 114 } 115 } else if (!(caldata->CalValid & cur_caldata->calType)) { 116 /* If current cal is marked invalid in channel, kick it off */ 117 ath9k_hw_reset_calibration(ah, currCal); 118 } 119 120 return false; 121 } 122 123 static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, 124 u8 rxchainmask, bool longcal) 125 { 126 bool iscaldone = true; 127 struct ath9k_cal_list *currCal = ah->cal_list_curr; 128 int ret; 129 130 /* 131 * For given calibration: 132 * 1. Call generic cal routine 133 * 2. When this cal is done (isCalDone) if we have more cals waiting 134 * (eg after reset), mask this to upper layers by not propagating 135 * isCalDone if it is set to TRUE. 136 * Instead, change isCalDone to FALSE and setup the waiting cal(s) 137 * to be run. 138 */ 139 if (currCal && 140 (currCal->calState == CAL_RUNNING || 141 currCal->calState == CAL_WAITING)) { 142 iscaldone = ar9003_hw_per_calibration(ah, chan, 143 rxchainmask, currCal); 144 if (iscaldone) { 145 ah->cal_list_curr = currCal = currCal->calNext; 146 147 if (currCal->calState == CAL_WAITING) { 148 iscaldone = false; 149 ath9k_hw_reset_calibration(ah, currCal); 150 } 151 } 152 } 153 154 /* 155 * Do NF cal only at longer intervals. Get the value from 156 * the previous NF cal and update history buffer. 157 */ 158 if (longcal && ath9k_hw_getnf(ah, chan)) { 159 /* 160 * Load the NF from history buffer of the current channel. 161 * NF is slow time-variant, so it is OK to use a historical 162 * value. 163 */ 164 ret = ath9k_hw_loadnf(ah, ah->curchan); 165 if (ret < 0) 166 return ret; 167 168 /* start NF calibration, without updating BB NF register */ 169 ath9k_hw_start_nfcal(ah, false); 170 } 171 172 return iscaldone; 173 } 174 175 static void ar9003_hw_iqcal_collect(struct ath_hw *ah) 176 { 177 int i; 178 179 /* Accumulate IQ cal measures for active chains */ 180 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 181 if (ah->txchainmask & BIT(i)) { 182 ah->totalPowerMeasI[i] += 183 REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); 184 ah->totalPowerMeasQ[i] += 185 REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); 186 ah->totalIqCorrMeas[i] += 187 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); 188 ath_dbg(ath9k_hw_common(ah), CALIBRATE, 189 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", 190 ah->cal_samples, i, ah->totalPowerMeasI[i], 191 ah->totalPowerMeasQ[i], 192 ah->totalIqCorrMeas[i]); 193 } 194 } 195 } 196 197 static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) 198 { 199 struct ath_common *common = ath9k_hw_common(ah); 200 u32 powerMeasQ, powerMeasI, iqCorrMeas; 201 u32 qCoffDenom, iCoffDenom; 202 int32_t qCoff, iCoff; 203 int iqCorrNeg, i; 204 static const u_int32_t offset_array[3] = { 205 AR_PHY_RX_IQCAL_CORR_B0, 206 AR_PHY_RX_IQCAL_CORR_B1, 207 AR_PHY_RX_IQCAL_CORR_B2, 208 }; 209 210 for (i = 0; i < numChains; i++) { 211 powerMeasI = ah->totalPowerMeasI[i]; 212 powerMeasQ = ah->totalPowerMeasQ[i]; 213 iqCorrMeas = ah->totalIqCorrMeas[i]; 214 215 ath_dbg(common, CALIBRATE, 216 "Starting IQ Cal and Correction for Chain %d\n", i); 217 218 ath_dbg(common, CALIBRATE, 219 "Original: Chn %d iq_corr_meas = 0x%08x\n", 220 i, ah->totalIqCorrMeas[i]); 221 222 iqCorrNeg = 0; 223 224 if (iqCorrMeas > 0x80000000) { 225 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1; 226 iqCorrNeg = 1; 227 } 228 229 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_i = 0x%08x\n", 230 i, powerMeasI); 231 ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_q = 0x%08x\n", 232 i, powerMeasQ); 233 ath_dbg(common, CALIBRATE, "iqCorrNeg is 0x%08x\n", iqCorrNeg); 234 235 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256; 236 qCoffDenom = powerMeasQ / 64; 237 238 if ((iCoffDenom != 0) && (qCoffDenom != 0)) { 239 iCoff = iqCorrMeas / iCoffDenom; 240 qCoff = powerMeasI / qCoffDenom - 64; 241 ath_dbg(common, CALIBRATE, "Chn %d iCoff = 0x%08x\n", 242 i, iCoff); 243 ath_dbg(common, CALIBRATE, "Chn %d qCoff = 0x%08x\n", 244 i, qCoff); 245 246 /* Force bounds on iCoff */ 247 if (iCoff >= 63) 248 iCoff = 63; 249 else if (iCoff <= -63) 250 iCoff = -63; 251 252 /* Negate iCoff if iqCorrNeg == 0 */ 253 if (iqCorrNeg == 0x0) 254 iCoff = -iCoff; 255 256 /* Force bounds on qCoff */ 257 if (qCoff >= 63) 258 qCoff = 63; 259 else if (qCoff <= -63) 260 qCoff = -63; 261 262 iCoff = iCoff & 0x7f; 263 qCoff = qCoff & 0x7f; 264 265 ath_dbg(common, CALIBRATE, 266 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", 267 i, iCoff, qCoff); 268 ath_dbg(common, CALIBRATE, 269 "Register offset (0x%04x) before update = 0x%x\n", 270 offset_array[i], 271 REG_READ(ah, offset_array[i])); 272 273 if (AR_SREV_9565(ah) && 274 (iCoff == 63 || qCoff == 63 || 275 iCoff == -63 || qCoff == -63)) 276 return; 277 278 REG_RMW_FIELD(ah, offset_array[i], 279 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, 280 iCoff); 281 REG_RMW_FIELD(ah, offset_array[i], 282 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, 283 qCoff); 284 ath_dbg(common, CALIBRATE, 285 "Register offset (0x%04x) QI COFF (bitfields 0x%08x) after update = 0x%x\n", 286 offset_array[i], 287 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, 288 REG_READ(ah, offset_array[i])); 289 ath_dbg(common, CALIBRATE, 290 "Register offset (0x%04x) QQ COFF (bitfields 0x%08x) after update = 0x%x\n", 291 offset_array[i], 292 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, 293 REG_READ(ah, offset_array[i])); 294 295 ath_dbg(common, CALIBRATE, 296 "IQ Cal and Correction done for Chain %d\n", i); 297 } 298 } 299 300 REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0, 301 AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE); 302 ath_dbg(common, CALIBRATE, 303 "IQ Cal and Correction (offset 0x%04x) enabled (bit position 0x%08x). New Value 0x%08x\n", 304 (unsigned) (AR_PHY_RX_IQCAL_CORR_B0), 305 AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE, 306 REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0)); 307 } 308 309 static const struct ath9k_percal_data iq_cal_single_sample = { 310 IQ_MISMATCH_CAL, 311 MIN_CAL_SAMPLES, 312 PER_MAX_LOG_COUNT, 313 ar9003_hw_iqcal_collect, 314 ar9003_hw_iqcalibrate 315 }; 316 317 static void ar9003_hw_init_cal_settings(struct ath_hw *ah) 318 { 319 ah->iq_caldata.calData = &iq_cal_single_sample; 320 321 if (AR_SREV_9300_20_OR_LATER(ah)) { 322 ah->enabled_cals |= TX_IQ_CAL; 323 if (AR_SREV_9485_OR_LATER(ah) && !AR_SREV_9340(ah)) 324 ah->enabled_cals |= TX_IQ_ON_AGC_CAL; 325 } 326 327 ah->supp_cals = IQ_MISMATCH_CAL; 328 } 329 330 #define OFF_UPPER_LT 24 331 #define OFF_LOWER_LT 7 332 333 static bool ar9003_hw_dynamic_osdac_selection(struct ath_hw *ah, 334 bool txiqcal_done) 335 { 336 struct ath_common *common = ath9k_hw_common(ah); 337 int ch0_done, osdac_ch0, dc_off_ch0_i1, dc_off_ch0_q1, dc_off_ch0_i2, 338 dc_off_ch0_q2, dc_off_ch0_i3, dc_off_ch0_q3; 339 int ch1_done, osdac_ch1, dc_off_ch1_i1, dc_off_ch1_q1, dc_off_ch1_i2, 340 dc_off_ch1_q2, dc_off_ch1_i3, dc_off_ch1_q3; 341 int ch2_done, osdac_ch2, dc_off_ch2_i1, dc_off_ch2_q1, dc_off_ch2_i2, 342 dc_off_ch2_q2, dc_off_ch2_i3, dc_off_ch2_q3; 343 bool status; 344 u32 temp, val; 345 346 /* 347 * Clear offset and IQ calibration, run AGC cal. 348 */ 349 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, 350 AR_PHY_AGC_CONTROL_OFFSET_CAL); 351 REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, 352 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); 353 REG_WRITE(ah, AR_PHY_AGC_CONTROL, 354 REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL); 355 356 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, 357 AR_PHY_AGC_CONTROL_CAL, 358 0, AH_WAIT_TIMEOUT); 359 if (!status) { 360 ath_dbg(common, CALIBRATE, 361 "AGC cal without offset cal failed to complete in 1ms"); 362 return false; 363 } 364 365 /* 366 * Allow only offset calibration and disable the others 367 * (Carrier Leak calibration, TX Filter calibration and 368 * Peak Detector offset calibration). 369 */ 370 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, 371 AR_PHY_AGC_CONTROL_OFFSET_CAL); 372 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, 373 AR_PHY_CL_CAL_ENABLE); 374 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, 375 AR_PHY_AGC_CONTROL_FLTR_CAL); 376 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, 377 AR_PHY_AGC_CONTROL_PKDET_CAL); 378 379 ch0_done = 0; 380 ch1_done = 0; 381 ch2_done = 0; 382 383 while ((ch0_done == 0) || (ch1_done == 0) || (ch2_done == 0)) { 384 osdac_ch0 = (REG_READ(ah, AR_PHY_65NM_CH0_BB1) >> 30) & 0x3; 385 osdac_ch1 = (REG_READ(ah, AR_PHY_65NM_CH1_BB1) >> 30) & 0x3; 386 osdac_ch2 = (REG_READ(ah, AR_PHY_65NM_CH2_BB1) >> 30) & 0x3; 387 388 REG_SET_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 389 390 REG_WRITE(ah, AR_PHY_AGC_CONTROL, 391 REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL); 392 393 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, 394 AR_PHY_AGC_CONTROL_CAL, 395 0, AH_WAIT_TIMEOUT); 396 if (!status) { 397 ath_dbg(common, CALIBRATE, 398 "DC offset cal failed to complete in 1ms"); 399 return false; 400 } 401 402 REG_CLR_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 403 404 /* 405 * High gain. 406 */ 407 REG_WRITE(ah, AR_PHY_65NM_CH0_BB3, 408 ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (1 << 8))); 409 REG_WRITE(ah, AR_PHY_65NM_CH1_BB3, 410 ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (1 << 8))); 411 REG_WRITE(ah, AR_PHY_65NM_CH2_BB3, 412 ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (1 << 8))); 413 414 temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3); 415 dc_off_ch0_i1 = (temp >> 26) & 0x1f; 416 dc_off_ch0_q1 = (temp >> 21) & 0x1f; 417 418 temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3); 419 dc_off_ch1_i1 = (temp >> 26) & 0x1f; 420 dc_off_ch1_q1 = (temp >> 21) & 0x1f; 421 422 temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3); 423 dc_off_ch2_i1 = (temp >> 26) & 0x1f; 424 dc_off_ch2_q1 = (temp >> 21) & 0x1f; 425 426 /* 427 * Low gain. 428 */ 429 REG_WRITE(ah, AR_PHY_65NM_CH0_BB3, 430 ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (2 << 8))); 431 REG_WRITE(ah, AR_PHY_65NM_CH1_BB3, 432 ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (2 << 8))); 433 REG_WRITE(ah, AR_PHY_65NM_CH2_BB3, 434 ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (2 << 8))); 435 436 temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3); 437 dc_off_ch0_i2 = (temp >> 26) & 0x1f; 438 dc_off_ch0_q2 = (temp >> 21) & 0x1f; 439 440 temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3); 441 dc_off_ch1_i2 = (temp >> 26) & 0x1f; 442 dc_off_ch1_q2 = (temp >> 21) & 0x1f; 443 444 temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3); 445 dc_off_ch2_i2 = (temp >> 26) & 0x1f; 446 dc_off_ch2_q2 = (temp >> 21) & 0x1f; 447 448 /* 449 * Loopback. 450 */ 451 REG_WRITE(ah, AR_PHY_65NM_CH0_BB3, 452 ((REG_READ(ah, AR_PHY_65NM_CH0_BB3) & 0xfffffcff) | (3 << 8))); 453 REG_WRITE(ah, AR_PHY_65NM_CH1_BB3, 454 ((REG_READ(ah, AR_PHY_65NM_CH1_BB3) & 0xfffffcff) | (3 << 8))); 455 REG_WRITE(ah, AR_PHY_65NM_CH2_BB3, 456 ((REG_READ(ah, AR_PHY_65NM_CH2_BB3) & 0xfffffcff) | (3 << 8))); 457 458 temp = REG_READ(ah, AR_PHY_65NM_CH0_BB3); 459 dc_off_ch0_i3 = (temp >> 26) & 0x1f; 460 dc_off_ch0_q3 = (temp >> 21) & 0x1f; 461 462 temp = REG_READ(ah, AR_PHY_65NM_CH1_BB3); 463 dc_off_ch1_i3 = (temp >> 26) & 0x1f; 464 dc_off_ch1_q3 = (temp >> 21) & 0x1f; 465 466 temp = REG_READ(ah, AR_PHY_65NM_CH2_BB3); 467 dc_off_ch2_i3 = (temp >> 26) & 0x1f; 468 dc_off_ch2_q3 = (temp >> 21) & 0x1f; 469 470 if ((dc_off_ch0_i1 > OFF_UPPER_LT) || (dc_off_ch0_i1 < OFF_LOWER_LT) || 471 (dc_off_ch0_i2 > OFF_UPPER_LT) || (dc_off_ch0_i2 < OFF_LOWER_LT) || 472 (dc_off_ch0_i3 > OFF_UPPER_LT) || (dc_off_ch0_i3 < OFF_LOWER_LT) || 473 (dc_off_ch0_q1 > OFF_UPPER_LT) || (dc_off_ch0_q1 < OFF_LOWER_LT) || 474 (dc_off_ch0_q2 > OFF_UPPER_LT) || (dc_off_ch0_q2 < OFF_LOWER_LT) || 475 (dc_off_ch0_q3 > OFF_UPPER_LT) || (dc_off_ch0_q3 < OFF_LOWER_LT)) { 476 if (osdac_ch0 == 3) { 477 ch0_done = 1; 478 } else { 479 osdac_ch0++; 480 481 val = REG_READ(ah, AR_PHY_65NM_CH0_BB1) & 0x3fffffff; 482 val |= (osdac_ch0 << 30); 483 REG_WRITE(ah, AR_PHY_65NM_CH0_BB1, val); 484 485 ch0_done = 0; 486 } 487 } else { 488 ch0_done = 1; 489 } 490 491 if ((dc_off_ch1_i1 > OFF_UPPER_LT) || (dc_off_ch1_i1 < OFF_LOWER_LT) || 492 (dc_off_ch1_i2 > OFF_UPPER_LT) || (dc_off_ch1_i2 < OFF_LOWER_LT) || 493 (dc_off_ch1_i3 > OFF_UPPER_LT) || (dc_off_ch1_i3 < OFF_LOWER_LT) || 494 (dc_off_ch1_q1 > OFF_UPPER_LT) || (dc_off_ch1_q1 < OFF_LOWER_LT) || 495 (dc_off_ch1_q2 > OFF_UPPER_LT) || (dc_off_ch1_q2 < OFF_LOWER_LT) || 496 (dc_off_ch1_q3 > OFF_UPPER_LT) || (dc_off_ch1_q3 < OFF_LOWER_LT)) { 497 if (osdac_ch1 == 3) { 498 ch1_done = 1; 499 } else { 500 osdac_ch1++; 501 502 val = REG_READ(ah, AR_PHY_65NM_CH1_BB1) & 0x3fffffff; 503 val |= (osdac_ch1 << 30); 504 REG_WRITE(ah, AR_PHY_65NM_CH1_BB1, val); 505 506 ch1_done = 0; 507 } 508 } else { 509 ch1_done = 1; 510 } 511 512 if ((dc_off_ch2_i1 > OFF_UPPER_LT) || (dc_off_ch2_i1 < OFF_LOWER_LT) || 513 (dc_off_ch2_i2 > OFF_UPPER_LT) || (dc_off_ch2_i2 < OFF_LOWER_LT) || 514 (dc_off_ch2_i3 > OFF_UPPER_LT) || (dc_off_ch2_i3 < OFF_LOWER_LT) || 515 (dc_off_ch2_q1 > OFF_UPPER_LT) || (dc_off_ch2_q1 < OFF_LOWER_LT) || 516 (dc_off_ch2_q2 > OFF_UPPER_LT) || (dc_off_ch2_q2 < OFF_LOWER_LT) || 517 (dc_off_ch2_q3 > OFF_UPPER_LT) || (dc_off_ch2_q3 < OFF_LOWER_LT)) { 518 if (osdac_ch2 == 3) { 519 ch2_done = 1; 520 } else { 521 osdac_ch2++; 522 523 val = REG_READ(ah, AR_PHY_65NM_CH2_BB1) & 0x3fffffff; 524 val |= (osdac_ch2 << 30); 525 REG_WRITE(ah, AR_PHY_65NM_CH2_BB1, val); 526 527 ch2_done = 0; 528 } 529 } else { 530 ch2_done = 1; 531 } 532 } 533 534 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, 535 AR_PHY_AGC_CONTROL_OFFSET_CAL); 536 REG_SET_BIT(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 537 538 /* 539 * We don't need to check txiqcal_done here since it is always 540 * set for AR9550. 541 */ 542 REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, 543 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); 544 545 return true; 546 } 547 548 /* 549 * solve 4x4 linear equation used in loopback iq cal. 550 */ 551 static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah, 552 s32 sin_2phi_1, 553 s32 cos_2phi_1, 554 s32 sin_2phi_2, 555 s32 cos_2phi_2, 556 s32 mag_a0_d0, 557 s32 phs_a0_d0, 558 s32 mag_a1_d0, 559 s32 phs_a1_d0, 560 s32 solved_eq[]) 561 { 562 s32 f1 = cos_2phi_1 - cos_2phi_2, 563 f3 = sin_2phi_1 - sin_2phi_2, 564 f2; 565 s32 mag_tx, phs_tx, mag_rx, phs_rx; 566 const s32 result_shift = 1 << 15; 567 struct ath_common *common = ath9k_hw_common(ah); 568 569 f2 = ((f1 >> 3) * (f1 >> 3) + (f3 >> 3) * (f3 >> 3)) >> 9; 570 571 if (!f2) { 572 ath_dbg(common, CALIBRATE, "Divide by 0\n"); 573 return false; 574 } 575 576 /* mag mismatch, tx */ 577 mag_tx = f1 * (mag_a0_d0 - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0); 578 /* phs mismatch, tx */ 579 phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0); 580 581 mag_tx = (mag_tx / f2); 582 phs_tx = (phs_tx / f2); 583 584 /* mag mismatch, rx */ 585 mag_rx = mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) / 586 result_shift; 587 /* phs mismatch, rx */ 588 phs_rx = phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) / 589 result_shift; 590 591 solved_eq[0] = mag_tx; 592 solved_eq[1] = phs_tx; 593 solved_eq[2] = mag_rx; 594 solved_eq[3] = phs_rx; 595 596 return true; 597 } 598 599 static s32 ar9003_hw_find_mag_approx(struct ath_hw *ah, s32 in_re, s32 in_im) 600 { 601 s32 abs_i = abs(in_re), 602 abs_q = abs(in_im), 603 max_abs, min_abs; 604 605 if (abs_i > abs_q) { 606 max_abs = abs_i; 607 min_abs = abs_q; 608 } else { 609 max_abs = abs_q; 610 min_abs = abs_i; 611 } 612 613 return max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4); 614 } 615 616 #define DELPT 32 617 618 static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, 619 s32 chain_idx, 620 const s32 iq_res[], 621 s32 iqc_coeff[]) 622 { 623 s32 i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0, 624 i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1, 625 i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0, 626 i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1; 627 s32 mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1, 628 phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1, 629 sin_2phi_1, cos_2phi_1, 630 sin_2phi_2, cos_2phi_2; 631 s32 mag_tx, phs_tx, mag_rx, phs_rx; 632 s32 solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx, 633 q_q_coff, q_i_coff; 634 const s32 res_scale = 1 << 15; 635 const s32 delpt_shift = 1 << 8; 636 s32 mag1, mag2; 637 struct ath_common *common = ath9k_hw_common(ah); 638 639 i2_m_q2_a0_d0 = iq_res[0] & 0xfff; 640 i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff; 641 iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8); 642 643 if (i2_m_q2_a0_d0 > 0x800) 644 i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1); 645 646 if (i2_p_q2_a0_d0 > 0x800) 647 i2_p_q2_a0_d0 = -((0xfff - i2_p_q2_a0_d0) + 1); 648 649 if (iq_corr_a0_d0 > 0x800) 650 iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1); 651 652 i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff; 653 i2_p_q2_a0_d1 = (iq_res[2] & 0xfff); 654 iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff; 655 656 if (i2_m_q2_a0_d1 > 0x800) 657 i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1); 658 659 if (iq_corr_a0_d1 > 0x800) 660 iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1); 661 662 i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8); 663 i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff; 664 iq_corr_a1_d0 = iq_res[4] & 0xfff; 665 666 if (i2_m_q2_a1_d0 > 0x800) 667 i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1); 668 669 if (i2_p_q2_a1_d0 > 0x800) 670 i2_p_q2_a1_d0 = -((0xfff - i2_p_q2_a1_d0) + 1); 671 672 if (iq_corr_a1_d0 > 0x800) 673 iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1); 674 675 i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff; 676 i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8); 677 iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff; 678 679 if (i2_m_q2_a1_d1 > 0x800) 680 i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1); 681 682 if (i2_p_q2_a1_d1 > 0x800) 683 i2_p_q2_a1_d1 = -((0xfff - i2_p_q2_a1_d1) + 1); 684 685 if (iq_corr_a1_d1 > 0x800) 686 iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1); 687 688 if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) || 689 (i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) { 690 ath_dbg(common, CALIBRATE, 691 "Divide by 0:\n" 692 "a0_d0=%d\n" 693 "a0_d1=%d\n" 694 "a2_d0=%d\n" 695 "a1_d1=%d\n", 696 i2_p_q2_a0_d0, i2_p_q2_a0_d1, 697 i2_p_q2_a1_d0, i2_p_q2_a1_d1); 698 return false; 699 } 700 701 if ((i2_p_q2_a0_d0 < 1024) || (i2_p_q2_a0_d0 > 2047) || 702 (i2_p_q2_a1_d0 < 0) || (i2_p_q2_a1_d1 < 0) || 703 (i2_p_q2_a0_d0 <= i2_m_q2_a0_d0) || 704 (i2_p_q2_a0_d0 <= iq_corr_a0_d0) || 705 (i2_p_q2_a0_d1 <= i2_m_q2_a0_d1) || 706 (i2_p_q2_a0_d1 <= iq_corr_a0_d1) || 707 (i2_p_q2_a1_d0 <= i2_m_q2_a1_d0) || 708 (i2_p_q2_a1_d0 <= iq_corr_a1_d0) || 709 (i2_p_q2_a1_d1 <= i2_m_q2_a1_d1) || 710 (i2_p_q2_a1_d1 <= iq_corr_a1_d1)) { 711 return false; 712 } 713 714 mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0; 715 phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0; 716 717 mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1; 718 phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1; 719 720 mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0; 721 phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0; 722 723 mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1; 724 phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1; 725 726 /* w/o analog phase shift */ 727 sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT); 728 /* w/o analog phase shift */ 729 cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT); 730 /* w/ analog phase shift */ 731 sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT); 732 /* w/ analog phase shift */ 733 cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT); 734 735 /* 736 * force sin^2 + cos^2 = 1; 737 * find magnitude by approximation 738 */ 739 mag1 = ar9003_hw_find_mag_approx(ah, cos_2phi_1, sin_2phi_1); 740 mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2); 741 742 if ((mag1 == 0) || (mag2 == 0)) { 743 ath_dbg(common, CALIBRATE, "Divide by 0: mag1=%d, mag2=%d\n", 744 mag1, mag2); 745 return false; 746 } 747 748 /* normalization sin and cos by mag */ 749 sin_2phi_1 = (sin_2phi_1 * res_scale / mag1); 750 cos_2phi_1 = (cos_2phi_1 * res_scale / mag1); 751 sin_2phi_2 = (sin_2phi_2 * res_scale / mag2); 752 cos_2phi_2 = (cos_2phi_2 * res_scale / mag2); 753 754 /* calculate IQ mismatch */ 755 if (!ar9003_hw_solve_iq_cal(ah, 756 sin_2phi_1, cos_2phi_1, 757 sin_2phi_2, cos_2phi_2, 758 mag_a0_d0, phs_a0_d0, 759 mag_a1_d0, 760 phs_a1_d0, solved_eq)) { 761 ath_dbg(common, CALIBRATE, 762 "Call to ar9003_hw_solve_iq_cal() failed\n"); 763 return false; 764 } 765 766 mag_tx = solved_eq[0]; 767 phs_tx = solved_eq[1]; 768 mag_rx = solved_eq[2]; 769 phs_rx = solved_eq[3]; 770 771 ath_dbg(common, CALIBRATE, 772 "chain %d: mag mismatch=%d phase mismatch=%d\n", 773 chain_idx, mag_tx/res_scale, phs_tx/res_scale); 774 775 if (res_scale == mag_tx) { 776 ath_dbg(common, CALIBRATE, 777 "Divide by 0: mag_tx=%d, res_scale=%d\n", 778 mag_tx, res_scale); 779 return false; 780 } 781 782 /* calculate and quantize Tx IQ correction factor */ 783 mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx); 784 phs_corr_tx = -phs_tx; 785 786 q_q_coff = (mag_corr_tx * 128 / res_scale); 787 q_i_coff = (phs_corr_tx * 256 / res_scale); 788 789 ath_dbg(common, CALIBRATE, "tx chain %d: mag corr=%d phase corr=%d\n", 790 chain_idx, q_q_coff, q_i_coff); 791 792 if (q_i_coff < -63) 793 q_i_coff = -63; 794 if (q_i_coff > 63) 795 q_i_coff = 63; 796 if (q_q_coff < -63) 797 q_q_coff = -63; 798 if (q_q_coff > 63) 799 q_q_coff = 63; 800 801 iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff); 802 803 ath_dbg(common, CALIBRATE, "tx chain %d: iq corr coeff=%x\n", 804 chain_idx, iqc_coeff[0]); 805 806 if (-mag_rx == res_scale) { 807 ath_dbg(common, CALIBRATE, 808 "Divide by 0: mag_rx=%d, res_scale=%d\n", 809 mag_rx, res_scale); 810 return false; 811 } 812 813 /* calculate and quantize Rx IQ correction factors */ 814 mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx); 815 phs_corr_rx = -phs_rx; 816 817 q_q_coff = (mag_corr_rx * 128 / res_scale); 818 q_i_coff = (phs_corr_rx * 256 / res_scale); 819 820 ath_dbg(common, CALIBRATE, "rx chain %d: mag corr=%d phase corr=%d\n", 821 chain_idx, q_q_coff, q_i_coff); 822 823 if (q_i_coff < -63) 824 q_i_coff = -63; 825 if (q_i_coff > 63) 826 q_i_coff = 63; 827 if (q_q_coff < -63) 828 q_q_coff = -63; 829 if (q_q_coff > 63) 830 q_q_coff = 63; 831 832 iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff); 833 834 ath_dbg(common, CALIBRATE, "rx chain %d: iq corr coeff=%x\n", 835 chain_idx, iqc_coeff[1]); 836 837 return true; 838 } 839 840 static void ar9003_hw_detect_outlier(int mp_coeff[][MAXIQCAL], 841 int nmeasurement, 842 int max_delta) 843 { 844 int mp_max = -64, max_idx = 0; 845 int mp_min = 63, min_idx = 0; 846 int mp_avg = 0, i, outlier_idx = 0, mp_count = 0; 847 848 /* find min/max mismatch across all calibrated gains */ 849 for (i = 0; i < nmeasurement; i++) { 850 if (mp_coeff[i][0] > mp_max) { 851 mp_max = mp_coeff[i][0]; 852 max_idx = i; 853 } else if (mp_coeff[i][0] < mp_min) { 854 mp_min = mp_coeff[i][0]; 855 min_idx = i; 856 } 857 } 858 859 /* find average (exclude max abs value) */ 860 for (i = 0; i < nmeasurement; i++) { 861 if ((abs(mp_coeff[i][0]) < abs(mp_max)) || 862 (abs(mp_coeff[i][0]) < abs(mp_min))) { 863 mp_avg += mp_coeff[i][0]; 864 mp_count++; 865 } 866 } 867 868 /* 869 * finding mean magnitude/phase if possible, otherwise 870 * just use the last value as the mean 871 */ 872 if (mp_count) 873 mp_avg /= mp_count; 874 else 875 mp_avg = mp_coeff[nmeasurement - 1][0]; 876 877 /* detect outlier */ 878 if (abs(mp_max - mp_min) > max_delta) { 879 if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg)) 880 outlier_idx = max_idx; 881 else 882 outlier_idx = min_idx; 883 884 mp_coeff[outlier_idx][0] = mp_avg; 885 } 886 } 887 888 static void ar9003_hw_tx_iq_cal_outlier_detection(struct ath_hw *ah, 889 struct coeff *coeff, 890 bool is_reusable) 891 { 892 int i, im, nmeasurement; 893 int magnitude, phase; 894 u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; 895 struct ath9k_hw_cal_data *caldata = ah->caldata; 896 897 memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff)); 898 for (i = 0; i < MAX_MEASUREMENT / 2; i++) { 899 tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] = 900 AR_PHY_TX_IQCAL_CORR_COEFF_B0(i); 901 if (!AR_SREV_9485(ah)) { 902 tx_corr_coeff[i * 2][1] = 903 tx_corr_coeff[(i * 2) + 1][1] = 904 AR_PHY_TX_IQCAL_CORR_COEFF_B1(i); 905 906 tx_corr_coeff[i * 2][2] = 907 tx_corr_coeff[(i * 2) + 1][2] = 908 AR_PHY_TX_IQCAL_CORR_COEFF_B2(i); 909 } 910 } 911 912 /* Load the average of 2 passes */ 913 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 914 if (!(ah->txchainmask & (1 << i))) 915 continue; 916 nmeasurement = REG_READ_FIELD(ah, 917 AR_PHY_TX_IQCAL_STATUS_B0, 918 AR_PHY_CALIBRATED_GAINS_0); 919 920 if (nmeasurement > MAX_MEASUREMENT) 921 nmeasurement = MAX_MEASUREMENT; 922 923 /* 924 * Skip normal outlier detection for AR9550. 925 */ 926 if (!AR_SREV_9550(ah)) { 927 /* detect outlier only if nmeasurement > 1 */ 928 if (nmeasurement > 1) { 929 /* Detect magnitude outlier */ 930 ar9003_hw_detect_outlier(coeff->mag_coeff[i], 931 nmeasurement, 932 MAX_MAG_DELTA); 933 934 /* Detect phase outlier */ 935 ar9003_hw_detect_outlier(coeff->phs_coeff[i], 936 nmeasurement, 937 MAX_PHS_DELTA); 938 } 939 } 940 941 for (im = 0; im < nmeasurement; im++) { 942 magnitude = coeff->mag_coeff[i][im][0]; 943 phase = coeff->phs_coeff[i][im][0]; 944 945 coeff->iqc_coeff[0] = 946 (phase & 0x7f) | ((magnitude & 0x7f) << 7); 947 948 if ((im % 2) == 0) 949 REG_RMW_FIELD(ah, tx_corr_coeff[im][i], 950 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE, 951 coeff->iqc_coeff[0]); 952 else 953 REG_RMW_FIELD(ah, tx_corr_coeff[im][i], 954 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, 955 coeff->iqc_coeff[0]); 956 957 if (caldata) 958 caldata->tx_corr_coeff[im][i] = 959 coeff->iqc_coeff[0]; 960 } 961 if (caldata) 962 caldata->num_measures[i] = nmeasurement; 963 } 964 965 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, 966 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1); 967 REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, 968 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); 969 970 if (caldata) { 971 if (is_reusable) 972 set_bit(TXIQCAL_DONE, &caldata->cal_flags); 973 else 974 clear_bit(TXIQCAL_DONE, &caldata->cal_flags); 975 } 976 977 return; 978 } 979 980 static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah) 981 { 982 struct ath_common *common = ath9k_hw_common(ah); 983 u8 tx_gain_forced; 984 985 tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN, 986 AR_PHY_TXGAIN_FORCE); 987 if (tx_gain_forced) 988 REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, 989 AR_PHY_TXGAIN_FORCE, 0); 990 991 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START, 992 AR_PHY_TX_IQCAL_START_DO_CAL, 1); 993 994 if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START, 995 AR_PHY_TX_IQCAL_START_DO_CAL, 0, 996 AH_WAIT_TIMEOUT)) { 997 ath_dbg(common, CALIBRATE, "Tx IQ Cal is not completed\n"); 998 return false; 999 } 1000 return true; 1001 } 1002 1003 static void __ar955x_tx_iq_cal_sort(struct ath_hw *ah, 1004 struct coeff *coeff, 1005 int i, int nmeasurement) 1006 { 1007 struct ath_common *common = ath9k_hw_common(ah); 1008 int im, ix, iy; 1009 1010 for (im = 0; im < nmeasurement; im++) { 1011 for (ix = 0; ix < MAXIQCAL - 1; ix++) { 1012 for (iy = ix + 1; iy <= MAXIQCAL - 1; iy++) { 1013 if (coeff->mag_coeff[i][im][iy] < 1014 coeff->mag_coeff[i][im][ix]) { 1015 swap(coeff->mag_coeff[i][im][ix], 1016 coeff->mag_coeff[i][im][iy]); 1017 } 1018 if (coeff->phs_coeff[i][im][iy] < 1019 coeff->phs_coeff[i][im][ix]) { 1020 swap(coeff->phs_coeff[i][im][ix], 1021 coeff->phs_coeff[i][im][iy]); 1022 } 1023 } 1024 } 1025 coeff->mag_coeff[i][im][0] = coeff->mag_coeff[i][im][MAXIQCAL / 2]; 1026 coeff->phs_coeff[i][im][0] = coeff->phs_coeff[i][im][MAXIQCAL / 2]; 1027 1028 ath_dbg(common, CALIBRATE, 1029 "IQCAL: Median [ch%d][gain%d]: mag = %d phase = %d\n", 1030 i, im, 1031 coeff->mag_coeff[i][im][0], 1032 coeff->phs_coeff[i][im][0]); 1033 } 1034 } 1035 1036 static bool ar955x_tx_iq_cal_median(struct ath_hw *ah, 1037 struct coeff *coeff, 1038 int iqcal_idx, 1039 int nmeasurement) 1040 { 1041 int i; 1042 1043 if ((iqcal_idx + 1) != MAXIQCAL) 1044 return false; 1045 1046 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 1047 __ar955x_tx_iq_cal_sort(ah, coeff, i, nmeasurement); 1048 } 1049 1050 return true; 1051 } 1052 1053 static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, 1054 int iqcal_idx, 1055 bool is_reusable) 1056 { 1057 struct ath_common *common = ath9k_hw_common(ah); 1058 const u32 txiqcal_status[AR9300_MAX_CHAINS] = { 1059 AR_PHY_TX_IQCAL_STATUS_B0, 1060 AR_PHY_TX_IQCAL_STATUS_B1, 1061 AR_PHY_TX_IQCAL_STATUS_B2, 1062 }; 1063 const u_int32_t chan_info_tab[] = { 1064 AR_PHY_CHAN_INFO_TAB_0, 1065 AR_PHY_CHAN_INFO_TAB_1, 1066 AR_PHY_CHAN_INFO_TAB_2, 1067 }; 1068 static struct coeff coeff; 1069 s32 iq_res[6]; 1070 int i, im, j; 1071 int nmeasurement = 0; 1072 bool outlier_detect = true; 1073 1074 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 1075 if (!(ah->txchainmask & (1 << i))) 1076 continue; 1077 1078 nmeasurement = REG_READ_FIELD(ah, 1079 AR_PHY_TX_IQCAL_STATUS_B0, 1080 AR_PHY_CALIBRATED_GAINS_0); 1081 if (nmeasurement > MAX_MEASUREMENT) 1082 nmeasurement = MAX_MEASUREMENT; 1083 1084 for (im = 0; im < nmeasurement; im++) { 1085 ath_dbg(common, CALIBRATE, 1086 "Doing Tx IQ Cal for chain %d\n", i); 1087 1088 if (REG_READ(ah, txiqcal_status[i]) & 1089 AR_PHY_TX_IQCAL_STATUS_FAILED) { 1090 ath_dbg(common, CALIBRATE, 1091 "Tx IQ Cal failed for chain %d\n", i); 1092 goto tx_iqcal_fail; 1093 } 1094 1095 for (j = 0; j < 3; j++) { 1096 u32 idx = 2 * j, offset = 4 * (3 * im + j); 1097 1098 REG_RMW_FIELD(ah, 1099 AR_PHY_CHAN_INFO_MEMORY, 1100 AR_PHY_CHAN_INFO_TAB_S2_READ, 1101 0); 1102 1103 /* 32 bits */ 1104 iq_res[idx] = REG_READ(ah, 1105 chan_info_tab[i] + 1106 offset); 1107 1108 REG_RMW_FIELD(ah, 1109 AR_PHY_CHAN_INFO_MEMORY, 1110 AR_PHY_CHAN_INFO_TAB_S2_READ, 1111 1); 1112 1113 /* 16 bits */ 1114 iq_res[idx + 1] = 0xffff & REG_READ(ah, 1115 chan_info_tab[i] + offset); 1116 1117 ath_dbg(common, CALIBRATE, 1118 "IQ_RES[%d]=0x%x IQ_RES[%d]=0x%x\n", 1119 idx, iq_res[idx], idx + 1, 1120 iq_res[idx + 1]); 1121 } 1122 1123 if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, 1124 coeff.iqc_coeff)) { 1125 ath_dbg(common, CALIBRATE, 1126 "Failed in calculation of IQ correction\n"); 1127 goto tx_iqcal_fail; 1128 } 1129 1130 coeff.phs_coeff[i][im][iqcal_idx] = 1131 coeff.iqc_coeff[0] & 0x7f; 1132 coeff.mag_coeff[i][im][iqcal_idx] = 1133 (coeff.iqc_coeff[0] >> 7) & 0x7f; 1134 1135 if (coeff.mag_coeff[i][im][iqcal_idx] > 63) 1136 coeff.mag_coeff[i][im][iqcal_idx] -= 128; 1137 if (coeff.phs_coeff[i][im][iqcal_idx] > 63) 1138 coeff.phs_coeff[i][im][iqcal_idx] -= 128; 1139 } 1140 } 1141 1142 if (AR_SREV_9550(ah)) 1143 outlier_detect = ar955x_tx_iq_cal_median(ah, &coeff, 1144 iqcal_idx, nmeasurement); 1145 if (outlier_detect) 1146 ar9003_hw_tx_iq_cal_outlier_detection(ah, &coeff, is_reusable); 1147 1148 return; 1149 1150 tx_iqcal_fail: 1151 ath_dbg(common, CALIBRATE, "Tx IQ Cal failed\n"); 1152 return; 1153 } 1154 1155 static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah) 1156 { 1157 struct ath9k_hw_cal_data *caldata = ah->caldata; 1158 u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; 1159 int i, im; 1160 1161 memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff)); 1162 for (i = 0; i < MAX_MEASUREMENT / 2; i++) { 1163 tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] = 1164 AR_PHY_TX_IQCAL_CORR_COEFF_B0(i); 1165 if (!AR_SREV_9485(ah)) { 1166 tx_corr_coeff[i * 2][1] = 1167 tx_corr_coeff[(i * 2) + 1][1] = 1168 AR_PHY_TX_IQCAL_CORR_COEFF_B1(i); 1169 1170 tx_corr_coeff[i * 2][2] = 1171 tx_corr_coeff[(i * 2) + 1][2] = 1172 AR_PHY_TX_IQCAL_CORR_COEFF_B2(i); 1173 } 1174 } 1175 1176 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 1177 if (!(ah->txchainmask & (1 << i))) 1178 continue; 1179 1180 for (im = 0; im < caldata->num_measures[i]; im++) { 1181 if ((im % 2) == 0) 1182 REG_RMW_FIELD(ah, tx_corr_coeff[im][i], 1183 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE, 1184 caldata->tx_corr_coeff[im][i]); 1185 else 1186 REG_RMW_FIELD(ah, tx_corr_coeff[im][i], 1187 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, 1188 caldata->tx_corr_coeff[im][i]); 1189 } 1190 } 1191 1192 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, 1193 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1); 1194 REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, 1195 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); 1196 } 1197 1198 static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g) 1199 { 1200 int offset[8] = {0}, total = 0, test; 1201 int agc_out, i, peak_detect_threshold = 0; 1202 1203 if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) 1204 peak_detect_threshold = 8; 1205 else if (AR_SREV_9561(ah)) 1206 peak_detect_threshold = 11; 1207 1208 /* 1209 * Turn off LNA/SW. 1210 */ 1211 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), 1212 AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0x1); 1213 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), 1214 AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC, 0x0); 1215 1216 if (AR_SREV_9003_PCOEM(ah) || AR_SREV_9330_11(ah)) { 1217 if (is_2g) 1218 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), 1219 AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR, 0x0); 1220 else 1221 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), 1222 AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR, 0x0); 1223 } 1224 1225 /* 1226 * Turn off RXON. 1227 */ 1228 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), 1229 AR_PHY_65NM_RXTX2_RXON_OVR, 0x1); 1230 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), 1231 AR_PHY_65NM_RXTX2_RXON, 0x0); 1232 1233 /* 1234 * Turn on AGC for cal. 1235 */ 1236 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1237 AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1); 1238 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1239 AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR, 0x1); 1240 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1241 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1); 1242 1243 if (AR_SREV_9330_11(ah)) 1244 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1245 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, 0x0); 1246 1247 if (is_2g) 1248 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1249 AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR, 1250 peak_detect_threshold); 1251 else 1252 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1253 AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR, 1254 peak_detect_threshold); 1255 1256 for (i = 6; i > 0; i--) { 1257 offset[i] = BIT(i - 1); 1258 test = total + offset[i]; 1259 1260 if (is_2g) 1261 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1262 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, 1263 test); 1264 else 1265 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1266 AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, 1267 test); 1268 udelay(100); 1269 agc_out = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1270 AR_PHY_65NM_RXRF_AGC_AGC_OUT); 1271 offset[i] = (agc_out) ? 0 : 1; 1272 total += (offset[i] << (i - 1)); 1273 } 1274 1275 if (is_2g) 1276 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1277 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, total); 1278 else 1279 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1280 AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, total); 1281 1282 /* 1283 * Turn on LNA. 1284 */ 1285 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), 1286 AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0); 1287 /* 1288 * Turn off RXON. 1289 */ 1290 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), 1291 AR_PHY_65NM_RXTX2_RXON_OVR, 0); 1292 /* 1293 * Turn off peak detect calibration. 1294 */ 1295 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1296 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0); 1297 } 1298 1299 static void ar9003_hw_do_pcoem_manual_peak_cal(struct ath_hw *ah, 1300 struct ath9k_channel *chan, 1301 bool run_rtt_cal) 1302 { 1303 struct ath9k_hw_cal_data *caldata = ah->caldata; 1304 int i; 1305 1306 if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && !run_rtt_cal) 1307 return; 1308 1309 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 1310 if (!(ah->rxchainmask & (1 << i))) 1311 continue; 1312 ar9003_hw_manual_peak_cal(ah, i, IS_CHAN_2GHZ(chan)); 1313 } 1314 1315 if (caldata) 1316 set_bit(SW_PKDET_DONE, &caldata->cal_flags); 1317 1318 if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && caldata) { 1319 if (IS_CHAN_2GHZ(chan)){ 1320 caldata->caldac[0] = REG_READ_FIELD(ah, 1321 AR_PHY_65NM_RXRF_AGC(0), 1322 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR); 1323 caldata->caldac[1] = REG_READ_FIELD(ah, 1324 AR_PHY_65NM_RXRF_AGC(1), 1325 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR); 1326 } else { 1327 caldata->caldac[0] = REG_READ_FIELD(ah, 1328 AR_PHY_65NM_RXRF_AGC(0), 1329 AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR); 1330 caldata->caldac[1] = REG_READ_FIELD(ah, 1331 AR_PHY_65NM_RXRF_AGC(1), 1332 AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR); 1333 } 1334 } 1335 } 1336 1337 static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable) 1338 { 1339 u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0, 1340 AR_PHY_CL_TAB_1, 1341 AR_PHY_CL_TAB_2 }; 1342 struct ath9k_hw_cal_data *caldata = ah->caldata; 1343 bool txclcal_done = false; 1344 int i, j; 1345 1346 if (!caldata || !(ah->enabled_cals & TX_CL_CAL)) 1347 return; 1348 1349 txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & 1350 AR_PHY_AGC_CONTROL_CLC_SUCCESS); 1351 1352 if (test_bit(TXCLCAL_DONE, &caldata->cal_flags)) { 1353 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 1354 if (!(ah->txchainmask & (1 << i))) 1355 continue; 1356 for (j = 0; j < MAX_CL_TAB_ENTRY; j++) 1357 REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]), 1358 caldata->tx_clcal[i][j]); 1359 } 1360 } else if (is_reusable && txclcal_done) { 1361 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 1362 if (!(ah->txchainmask & (1 << i))) 1363 continue; 1364 for (j = 0; j < MAX_CL_TAB_ENTRY; j++) 1365 caldata->tx_clcal[i][j] = 1366 REG_READ(ah, CL_TAB_ENTRY(cl_idx[i])); 1367 } 1368 set_bit(TXCLCAL_DONE, &caldata->cal_flags); 1369 } 1370 } 1371 1372 static void ar9003_hw_init_cal_common(struct ath_hw *ah) 1373 { 1374 struct ath9k_hw_cal_data *caldata = ah->caldata; 1375 1376 /* Initialize list pointers */ 1377 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; 1378 1379 INIT_CAL(&ah->iq_caldata); 1380 INSERT_CAL(ah, &ah->iq_caldata); 1381 1382 /* Initialize current pointer to first element in list */ 1383 ah->cal_list_curr = ah->cal_list; 1384 1385 if (ah->cal_list_curr) 1386 ath9k_hw_reset_calibration(ah, ah->cal_list_curr); 1387 1388 if (caldata) 1389 caldata->CalValid = 0; 1390 } 1391 1392 static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah, 1393 struct ath9k_channel *chan) 1394 { 1395 struct ath_common *common = ath9k_hw_common(ah); 1396 struct ath9k_hw_cal_data *caldata = ah->caldata; 1397 bool txiqcal_done = false; 1398 bool is_reusable = true, status = true; 1399 bool run_rtt_cal = false, run_agc_cal; 1400 bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); 1401 u32 rx_delay = 0; 1402 u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | 1403 AR_PHY_AGC_CONTROL_FLTR_CAL | 1404 AR_PHY_AGC_CONTROL_PKDET_CAL; 1405 1406 /* Use chip chainmask only for calibration */ 1407 ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); 1408 1409 if (rtt) { 1410 if (!ar9003_hw_rtt_restore(ah, chan)) 1411 run_rtt_cal = true; 1412 1413 if (run_rtt_cal) 1414 ath_dbg(common, CALIBRATE, "RTT calibration to be done\n"); 1415 } 1416 1417 run_agc_cal = run_rtt_cal; 1418 1419 if (run_rtt_cal) { 1420 ar9003_hw_rtt_enable(ah); 1421 ar9003_hw_rtt_set_mask(ah, 0x00); 1422 ar9003_hw_rtt_clear_hist(ah); 1423 } 1424 1425 if (rtt) { 1426 if (!run_rtt_cal) { 1427 agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL); 1428 agc_supp_cals &= agc_ctrl; 1429 agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL | 1430 AR_PHY_AGC_CONTROL_FLTR_CAL | 1431 AR_PHY_AGC_CONTROL_PKDET_CAL); 1432 REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl); 1433 } else { 1434 if (ah->ah_flags & AH_FASTCC) 1435 run_agc_cal = true; 1436 } 1437 } 1438 1439 if (ah->enabled_cals & TX_CL_CAL) { 1440 if (caldata && test_bit(TXCLCAL_DONE, &caldata->cal_flags)) 1441 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, 1442 AR_PHY_CL_CAL_ENABLE); 1443 else { 1444 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, 1445 AR_PHY_CL_CAL_ENABLE); 1446 run_agc_cal = true; 1447 } 1448 } 1449 1450 if ((IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) || 1451 !(ah->enabled_cals & TX_IQ_CAL)) 1452 goto skip_tx_iqcal; 1453 1454 /* Do Tx IQ Calibration */ 1455 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, 1456 AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, 1457 DELPT); 1458 1459 /* 1460 * For AR9485 or later chips, TxIQ cal runs as part of 1461 * AGC calibration 1462 */ 1463 if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { 1464 if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) 1465 REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, 1466 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); 1467 else 1468 REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, 1469 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); 1470 txiqcal_done = run_agc_cal = true; 1471 } 1472 1473 skip_tx_iqcal: 1474 if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) 1475 ar9003_mci_init_cal_req(ah, &is_reusable); 1476 1477 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { 1478 rx_delay = REG_READ(ah, AR_PHY_RX_DELAY); 1479 /* Disable BB_active */ 1480 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); 1481 udelay(5); 1482 REG_WRITE(ah, AR_PHY_RX_DELAY, AR_PHY_RX_DELAY_DELAY); 1483 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 1484 } 1485 1486 if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { 1487 /* Calibrate the AGC */ 1488 REG_WRITE(ah, AR_PHY_AGC_CONTROL, 1489 REG_READ(ah, AR_PHY_AGC_CONTROL) | 1490 AR_PHY_AGC_CONTROL_CAL); 1491 1492 /* Poll for offset calibration complete */ 1493 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, 1494 AR_PHY_AGC_CONTROL_CAL, 1495 0, AH_WAIT_TIMEOUT); 1496 1497 ar9003_hw_do_pcoem_manual_peak_cal(ah, chan, run_rtt_cal); 1498 } 1499 1500 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { 1501 REG_WRITE(ah, AR_PHY_RX_DELAY, rx_delay); 1502 udelay(5); 1503 } 1504 1505 if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) 1506 ar9003_mci_init_cal_done(ah); 1507 1508 if (rtt && !run_rtt_cal) { 1509 agc_ctrl |= agc_supp_cals; 1510 REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl); 1511 } 1512 1513 if (!status) { 1514 if (run_rtt_cal) 1515 ar9003_hw_rtt_disable(ah); 1516 1517 ath_dbg(common, CALIBRATE, 1518 "offset calibration failed to complete in %d ms; noisy environment?\n", 1519 AH_WAIT_TIMEOUT / 1000); 1520 return false; 1521 } 1522 1523 if (txiqcal_done) 1524 ar9003_hw_tx_iq_cal_post_proc(ah, 0, is_reusable); 1525 else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags)) 1526 ar9003_hw_tx_iq_cal_reload(ah); 1527 1528 ar9003_hw_cl_cal_post_proc(ah, is_reusable); 1529 1530 if (run_rtt_cal && caldata) { 1531 if (is_reusable) { 1532 if (!ath9k_hw_rfbus_req(ah)) { 1533 ath_err(ath9k_hw_common(ah), 1534 "Could not stop baseband\n"); 1535 } else { 1536 ar9003_hw_rtt_fill_hist(ah); 1537 1538 if (test_bit(SW_PKDET_DONE, &caldata->cal_flags)) 1539 ar9003_hw_rtt_load_hist(ah); 1540 } 1541 1542 ath9k_hw_rfbus_done(ah); 1543 } 1544 1545 ar9003_hw_rtt_disable(ah); 1546 } 1547 1548 /* Revert chainmask to runtime parameters */ 1549 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); 1550 1551 ar9003_hw_init_cal_common(ah); 1552 1553 return true; 1554 } 1555 1556 static bool do_ar9003_agc_cal(struct ath_hw *ah) 1557 { 1558 struct ath_common *common = ath9k_hw_common(ah); 1559 bool status; 1560 1561 REG_WRITE(ah, AR_PHY_AGC_CONTROL, 1562 REG_READ(ah, AR_PHY_AGC_CONTROL) | 1563 AR_PHY_AGC_CONTROL_CAL); 1564 1565 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, 1566 AR_PHY_AGC_CONTROL_CAL, 1567 0, AH_WAIT_TIMEOUT); 1568 if (!status) { 1569 ath_dbg(common, CALIBRATE, 1570 "offset calibration failed to complete in %d ms," 1571 "noisy environment?\n", 1572 AH_WAIT_TIMEOUT / 1000); 1573 return false; 1574 } 1575 1576 return true; 1577 } 1578 1579 static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, 1580 struct ath9k_channel *chan) 1581 { 1582 bool txiqcal_done = false; 1583 bool status = true; 1584 bool run_agc_cal = false, sep_iq_cal = false; 1585 int i = 0; 1586 1587 /* Use chip chainmask only for calibration */ 1588 ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); 1589 1590 if (ah->enabled_cals & TX_CL_CAL) { 1591 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); 1592 run_agc_cal = true; 1593 } 1594 1595 if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) 1596 goto skip_tx_iqcal; 1597 1598 /* Do Tx IQ Calibration */ 1599 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, 1600 AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, 1601 DELPT); 1602 1603 /* 1604 * For AR9485 or later chips, TxIQ cal runs as part of 1605 * AGC calibration. Specifically, AR9550 in SoC chips. 1606 */ 1607 if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { 1608 if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0, 1609 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) { 1610 txiqcal_done = true; 1611 } else { 1612 txiqcal_done = false; 1613 } 1614 run_agc_cal = true; 1615 } else { 1616 sep_iq_cal = true; 1617 run_agc_cal = true; 1618 } 1619 1620 /* 1621 * In the SoC family, this will run for AR9300, AR9331 and AR9340. 1622 */ 1623 if (sep_iq_cal) { 1624 txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); 1625 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); 1626 udelay(5); 1627 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 1628 } 1629 1630 if (AR_SREV_9550(ah) && IS_CHAN_2GHZ(chan)) { 1631 if (!ar9003_hw_dynamic_osdac_selection(ah, txiqcal_done)) 1632 return false; 1633 } 1634 1635 skip_tx_iqcal: 1636 if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { 1637 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 1638 if (!(ah->rxchainmask & (1 << i))) 1639 continue; 1640 1641 ar9003_hw_manual_peak_cal(ah, i, 1642 IS_CHAN_2GHZ(chan)); 1643 } 1644 1645 /* 1646 * For non-AR9550 chips, we just trigger AGC calibration 1647 * in the HW, poll for completion and then process 1648 * the results. 1649 * 1650 * For AR955x, we run it multiple times and use 1651 * median IQ correction. 1652 */ 1653 if (!AR_SREV_9550(ah)) { 1654 status = do_ar9003_agc_cal(ah); 1655 if (!status) 1656 return false; 1657 1658 if (txiqcal_done) 1659 ar9003_hw_tx_iq_cal_post_proc(ah, 0, false); 1660 } else { 1661 if (!txiqcal_done) { 1662 status = do_ar9003_agc_cal(ah); 1663 if (!status) 1664 return false; 1665 } else { 1666 for (i = 0; i < MAXIQCAL; i++) { 1667 status = do_ar9003_agc_cal(ah); 1668 if (!status) 1669 return false; 1670 ar9003_hw_tx_iq_cal_post_proc(ah, i, false); 1671 } 1672 } 1673 } 1674 } 1675 1676 /* Revert chainmask to runtime parameters */ 1677 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); 1678 1679 ar9003_hw_init_cal_common(ah); 1680 1681 return true; 1682 } 1683 1684 void ar9003_hw_attach_calib_ops(struct ath_hw *ah) 1685 { 1686 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1687 struct ath_hw_ops *ops = ath9k_hw_ops(ah); 1688 1689 if (AR_SREV_9003_PCOEM(ah)) 1690 priv_ops->init_cal = ar9003_hw_init_cal_pcoem; 1691 else 1692 priv_ops->init_cal = ar9003_hw_init_cal_soc; 1693 1694 priv_ops->init_cal_settings = ar9003_hw_init_cal_settings; 1695 priv_ops->setup_calibration = ar9003_hw_setup_calibration; 1696 1697 ops->calibrate = ar9003_hw_calibrate; 1698 } 1699