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 /* Cal is assumed not done until explicitly set below */ 79 bool iscaldone = false; 80 81 /* Calibration in progress. */ 82 if (currCal->calState == CAL_RUNNING) { 83 /* Check to see if it has finished. */ 84 if (!(REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) { 85 /* 86 * Accumulate cal measures for active chains 87 */ 88 currCal->calData->calCollect(ah); 89 ah->cal_samples++; 90 91 if (ah->cal_samples >= 92 currCal->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 currCal->calData->calPostProc(ah, numChains); 103 104 /* Calibration has finished. */ 105 caldata->CalValid |= currCal->calData->calType; 106 currCal->calState = CAL_DONE; 107 iscaldone = 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 } 116 } else if (!(caldata->CalValid & currCal->calData->calType)) { 117 /* If current cal is marked invalid in channel, kick it off */ 118 ath9k_hw_reset_calibration(ah, currCal); 119 } 120 121 return iscaldone; 122 } 123 124 static bool ar9003_hw_calibrate(struct ath_hw *ah, 125 struct ath9k_channel *chan, 126 u8 rxchainmask, 127 bool longcal) 128 { 129 bool iscaldone = true; 130 struct ath9k_cal_list *currCal = ah->cal_list_curr; 131 132 /* 133 * For given calibration: 134 * 1. Call generic cal routine 135 * 2. When this cal is done (isCalDone) if we have more cals waiting 136 * (eg after reset), mask this to upper layers by not propagating 137 * isCalDone if it is set to TRUE. 138 * Instead, change isCalDone to FALSE and setup the waiting cal(s) 139 * to be run. 140 */ 141 if (currCal && 142 (currCal->calState == CAL_RUNNING || 143 currCal->calState == CAL_WAITING)) { 144 iscaldone = ar9003_hw_per_calibration(ah, chan, 145 rxchainmask, currCal); 146 if (iscaldone) { 147 ah->cal_list_curr = currCal = currCal->calNext; 148 149 if (currCal->calState == CAL_WAITING) { 150 iscaldone = false; 151 ath9k_hw_reset_calibration(ah, currCal); 152 } 153 } 154 } 155 156 /* 157 * Do NF cal only at longer intervals. Get the value from 158 * the previous NF cal and update history buffer. 159 */ 160 if (longcal && ath9k_hw_getnf(ah, chan)) { 161 /* 162 * Load the NF from history buffer of the current channel. 163 * NF is slow time-variant, so it is OK to use a historical 164 * value. 165 */ 166 ath9k_hw_loadnf(ah, ah->curchan); 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 < AR5416_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, temp; 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 temp = coeff->mag_coeff[i][im][ix]; 1016 coeff->mag_coeff[i][im][ix] = 1017 coeff->mag_coeff[i][im][iy]; 1018 coeff->mag_coeff[i][im][iy] = temp; 1019 } 1020 if (coeff->phs_coeff[i][im][iy] < 1021 coeff->phs_coeff[i][im][ix]) { 1022 temp = coeff->phs_coeff[i][im][ix]; 1023 coeff->phs_coeff[i][im][ix] = 1024 coeff->phs_coeff[i][im][iy]; 1025 coeff->phs_coeff[i][im][iy] = temp; 1026 } 1027 } 1028 } 1029 coeff->mag_coeff[i][im][0] = coeff->mag_coeff[i][im][MAXIQCAL / 2]; 1030 coeff->phs_coeff[i][im][0] = coeff->phs_coeff[i][im][MAXIQCAL / 2]; 1031 1032 ath_dbg(common, CALIBRATE, 1033 "IQCAL: Median [ch%d][gain%d]: mag = %d phase = %d\n", 1034 i, im, 1035 coeff->mag_coeff[i][im][0], 1036 coeff->phs_coeff[i][im][0]); 1037 } 1038 } 1039 1040 static bool ar955x_tx_iq_cal_median(struct ath_hw *ah, 1041 struct coeff *coeff, 1042 int iqcal_idx, 1043 int nmeasurement) 1044 { 1045 int i; 1046 1047 if ((iqcal_idx + 1) != MAXIQCAL) 1048 return false; 1049 1050 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 1051 __ar955x_tx_iq_cal_sort(ah, coeff, i, nmeasurement); 1052 } 1053 1054 return true; 1055 } 1056 1057 static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, 1058 int iqcal_idx, 1059 bool is_reusable) 1060 { 1061 struct ath_common *common = ath9k_hw_common(ah); 1062 const u32 txiqcal_status[AR9300_MAX_CHAINS] = { 1063 AR_PHY_TX_IQCAL_STATUS_B0, 1064 AR_PHY_TX_IQCAL_STATUS_B1, 1065 AR_PHY_TX_IQCAL_STATUS_B2, 1066 }; 1067 const u_int32_t chan_info_tab[] = { 1068 AR_PHY_CHAN_INFO_TAB_0, 1069 AR_PHY_CHAN_INFO_TAB_1, 1070 AR_PHY_CHAN_INFO_TAB_2, 1071 }; 1072 static struct coeff coeff; 1073 s32 iq_res[6]; 1074 int i, im, j; 1075 int nmeasurement = 0; 1076 bool outlier_detect = true; 1077 1078 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 1079 if (!(ah->txchainmask & (1 << i))) 1080 continue; 1081 1082 nmeasurement = REG_READ_FIELD(ah, 1083 AR_PHY_TX_IQCAL_STATUS_B0, 1084 AR_PHY_CALIBRATED_GAINS_0); 1085 if (nmeasurement > MAX_MEASUREMENT) 1086 nmeasurement = MAX_MEASUREMENT; 1087 1088 for (im = 0; im < nmeasurement; im++) { 1089 ath_dbg(common, CALIBRATE, 1090 "Doing Tx IQ Cal for chain %d\n", i); 1091 1092 if (REG_READ(ah, txiqcal_status[i]) & 1093 AR_PHY_TX_IQCAL_STATUS_FAILED) { 1094 ath_dbg(common, CALIBRATE, 1095 "Tx IQ Cal failed for chain %d\n", i); 1096 goto tx_iqcal_fail; 1097 } 1098 1099 for (j = 0; j < 3; j++) { 1100 u32 idx = 2 * j, offset = 4 * (3 * im + j); 1101 1102 REG_RMW_FIELD(ah, 1103 AR_PHY_CHAN_INFO_MEMORY, 1104 AR_PHY_CHAN_INFO_TAB_S2_READ, 1105 0); 1106 1107 /* 32 bits */ 1108 iq_res[idx] = REG_READ(ah, 1109 chan_info_tab[i] + 1110 offset); 1111 1112 REG_RMW_FIELD(ah, 1113 AR_PHY_CHAN_INFO_MEMORY, 1114 AR_PHY_CHAN_INFO_TAB_S2_READ, 1115 1); 1116 1117 /* 16 bits */ 1118 iq_res[idx + 1] = 0xffff & REG_READ(ah, 1119 chan_info_tab[i] + offset); 1120 1121 ath_dbg(common, CALIBRATE, 1122 "IQ_RES[%d]=0x%x IQ_RES[%d]=0x%x\n", 1123 idx, iq_res[idx], idx + 1, 1124 iq_res[idx + 1]); 1125 } 1126 1127 if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, 1128 coeff.iqc_coeff)) { 1129 ath_dbg(common, CALIBRATE, 1130 "Failed in calculation of IQ correction\n"); 1131 goto tx_iqcal_fail; 1132 } 1133 1134 coeff.phs_coeff[i][im][iqcal_idx] = 1135 coeff.iqc_coeff[0] & 0x7f; 1136 coeff.mag_coeff[i][im][iqcal_idx] = 1137 (coeff.iqc_coeff[0] >> 7) & 0x7f; 1138 1139 if (coeff.mag_coeff[i][im][iqcal_idx] > 63) 1140 coeff.mag_coeff[i][im][iqcal_idx] -= 128; 1141 if (coeff.phs_coeff[i][im][iqcal_idx] > 63) 1142 coeff.phs_coeff[i][im][iqcal_idx] -= 128; 1143 } 1144 } 1145 1146 if (AR_SREV_9550(ah)) 1147 outlier_detect = ar955x_tx_iq_cal_median(ah, &coeff, 1148 iqcal_idx, nmeasurement); 1149 if (outlier_detect) 1150 ar9003_hw_tx_iq_cal_outlier_detection(ah, &coeff, is_reusable); 1151 1152 return; 1153 1154 tx_iqcal_fail: 1155 ath_dbg(common, CALIBRATE, "Tx IQ Cal failed\n"); 1156 return; 1157 } 1158 1159 static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah) 1160 { 1161 struct ath9k_hw_cal_data *caldata = ah->caldata; 1162 u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; 1163 int i, im; 1164 1165 memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff)); 1166 for (i = 0; i < MAX_MEASUREMENT / 2; i++) { 1167 tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] = 1168 AR_PHY_TX_IQCAL_CORR_COEFF_B0(i); 1169 if (!AR_SREV_9485(ah)) { 1170 tx_corr_coeff[i * 2][1] = 1171 tx_corr_coeff[(i * 2) + 1][1] = 1172 AR_PHY_TX_IQCAL_CORR_COEFF_B1(i); 1173 1174 tx_corr_coeff[i * 2][2] = 1175 tx_corr_coeff[(i * 2) + 1][2] = 1176 AR_PHY_TX_IQCAL_CORR_COEFF_B2(i); 1177 } 1178 } 1179 1180 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 1181 if (!(ah->txchainmask & (1 << i))) 1182 continue; 1183 1184 for (im = 0; im < caldata->num_measures[i]; im++) { 1185 if ((im % 2) == 0) 1186 REG_RMW_FIELD(ah, tx_corr_coeff[im][i], 1187 AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE, 1188 caldata->tx_corr_coeff[im][i]); 1189 else 1190 REG_RMW_FIELD(ah, tx_corr_coeff[im][i], 1191 AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, 1192 caldata->tx_corr_coeff[im][i]); 1193 } 1194 } 1195 1196 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, 1197 AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1); 1198 REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, 1199 AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); 1200 } 1201 1202 static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g) 1203 { 1204 int offset[8] = {0}, total = 0, test; 1205 int agc_out, i; 1206 1207 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), 1208 AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0x1); 1209 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), 1210 AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC, 0x0); 1211 if (is_2g) 1212 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), 1213 AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR, 0x0); 1214 else 1215 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), 1216 AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR, 0x0); 1217 1218 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), 1219 AR_PHY_65NM_RXTX2_RXON_OVR, 0x1); 1220 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), 1221 AR_PHY_65NM_RXTX2_RXON, 0x0); 1222 1223 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1224 AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1); 1225 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1226 AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR, 0x1); 1227 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1228 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1); 1229 1230 if (AR_SREV_9330_11(ah)) { 1231 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1232 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, 0x0); 1233 } else { 1234 if (is_2g) 1235 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1236 AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR, 0x0); 1237 else 1238 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1239 AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR, 0x0); 1240 } 1241 1242 for (i = 6; i > 0; i--) { 1243 offset[i] = BIT(i - 1); 1244 test = total + offset[i]; 1245 1246 if (is_2g) 1247 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1248 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, 1249 test); 1250 else 1251 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1252 AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, 1253 test); 1254 udelay(100); 1255 agc_out = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1256 AR_PHY_65NM_RXRF_AGC_AGC_OUT); 1257 offset[i] = (agc_out) ? 0 : 1; 1258 total += (offset[i] << (i - 1)); 1259 } 1260 1261 if (is_2g) 1262 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1263 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, total); 1264 else 1265 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1266 AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, total); 1267 1268 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), 1269 AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0); 1270 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), 1271 AR_PHY_65NM_RXTX2_RXON_OVR, 0); 1272 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1273 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0); 1274 } 1275 1276 static void ar9003_hw_do_pcoem_manual_peak_cal(struct ath_hw *ah, 1277 struct ath9k_channel *chan, 1278 bool run_rtt_cal) 1279 { 1280 struct ath9k_hw_cal_data *caldata = ah->caldata; 1281 int i; 1282 1283 if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah) && !AR_SREV_9485(ah)) 1284 return; 1285 1286 if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && !run_rtt_cal) 1287 return; 1288 1289 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 1290 if (!(ah->rxchainmask & (1 << i))) 1291 continue; 1292 ar9003_hw_manual_peak_cal(ah, i, IS_CHAN_2GHZ(chan)); 1293 } 1294 1295 if (caldata) 1296 set_bit(SW_PKDET_DONE, &caldata->cal_flags); 1297 1298 if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && caldata) { 1299 if (IS_CHAN_2GHZ(chan)){ 1300 caldata->caldac[0] = REG_READ_FIELD(ah, 1301 AR_PHY_65NM_RXRF_AGC(0), 1302 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR); 1303 caldata->caldac[1] = REG_READ_FIELD(ah, 1304 AR_PHY_65NM_RXRF_AGC(1), 1305 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR); 1306 } else { 1307 caldata->caldac[0] = REG_READ_FIELD(ah, 1308 AR_PHY_65NM_RXRF_AGC(0), 1309 AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR); 1310 caldata->caldac[1] = REG_READ_FIELD(ah, 1311 AR_PHY_65NM_RXRF_AGC(1), 1312 AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR); 1313 } 1314 } 1315 } 1316 1317 static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable) 1318 { 1319 u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0, 1320 AR_PHY_CL_TAB_1, 1321 AR_PHY_CL_TAB_2 }; 1322 struct ath9k_hw_cal_data *caldata = ah->caldata; 1323 bool txclcal_done = false; 1324 int i, j; 1325 1326 if (!caldata || !(ah->enabled_cals & TX_CL_CAL)) 1327 return; 1328 1329 txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & 1330 AR_PHY_AGC_CONTROL_CLC_SUCCESS); 1331 1332 if (test_bit(TXCLCAL_DONE, &caldata->cal_flags)) { 1333 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 1334 if (!(ah->txchainmask & (1 << i))) 1335 continue; 1336 for (j = 0; j < MAX_CL_TAB_ENTRY; j++) 1337 REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]), 1338 caldata->tx_clcal[i][j]); 1339 } 1340 } else if (is_reusable && txclcal_done) { 1341 for (i = 0; i < AR9300_MAX_CHAINS; i++) { 1342 if (!(ah->txchainmask & (1 << i))) 1343 continue; 1344 for (j = 0; j < MAX_CL_TAB_ENTRY; j++) 1345 caldata->tx_clcal[i][j] = 1346 REG_READ(ah, CL_TAB_ENTRY(cl_idx[i])); 1347 } 1348 set_bit(TXCLCAL_DONE, &caldata->cal_flags); 1349 } 1350 } 1351 1352 static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah, 1353 struct ath9k_channel *chan) 1354 { 1355 struct ath_common *common = ath9k_hw_common(ah); 1356 struct ath9k_hw_cal_data *caldata = ah->caldata; 1357 bool txiqcal_done = false; 1358 bool is_reusable = true, status = true; 1359 bool run_rtt_cal = false, run_agc_cal; 1360 bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); 1361 u32 rx_delay = 0; 1362 u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | 1363 AR_PHY_AGC_CONTROL_FLTR_CAL | 1364 AR_PHY_AGC_CONTROL_PKDET_CAL; 1365 1366 /* Use chip chainmask only for calibration */ 1367 ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); 1368 1369 if (rtt) { 1370 if (!ar9003_hw_rtt_restore(ah, chan)) 1371 run_rtt_cal = true; 1372 1373 if (run_rtt_cal) 1374 ath_dbg(common, CALIBRATE, "RTT calibration to be done\n"); 1375 } 1376 1377 run_agc_cal = run_rtt_cal; 1378 1379 if (run_rtt_cal) { 1380 ar9003_hw_rtt_enable(ah); 1381 ar9003_hw_rtt_set_mask(ah, 0x00); 1382 ar9003_hw_rtt_clear_hist(ah); 1383 } 1384 1385 if (rtt) { 1386 if (!run_rtt_cal) { 1387 agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL); 1388 agc_supp_cals &= agc_ctrl; 1389 agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL | 1390 AR_PHY_AGC_CONTROL_FLTR_CAL | 1391 AR_PHY_AGC_CONTROL_PKDET_CAL); 1392 REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl); 1393 } else { 1394 if (ah->ah_flags & AH_FASTCC) 1395 run_agc_cal = true; 1396 } 1397 } 1398 1399 if (ah->enabled_cals & TX_CL_CAL) { 1400 if (caldata && test_bit(TXCLCAL_DONE, &caldata->cal_flags)) 1401 REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, 1402 AR_PHY_CL_CAL_ENABLE); 1403 else { 1404 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, 1405 AR_PHY_CL_CAL_ENABLE); 1406 run_agc_cal = true; 1407 } 1408 } 1409 1410 if ((IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) || 1411 !(ah->enabled_cals & TX_IQ_CAL)) 1412 goto skip_tx_iqcal; 1413 1414 /* Do Tx IQ Calibration */ 1415 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, 1416 AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, 1417 DELPT); 1418 1419 /* 1420 * For AR9485 or later chips, TxIQ cal runs as part of 1421 * AGC calibration 1422 */ 1423 if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { 1424 if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) 1425 REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, 1426 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); 1427 else 1428 REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, 1429 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); 1430 txiqcal_done = run_agc_cal = true; 1431 } 1432 1433 skip_tx_iqcal: 1434 if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) 1435 ar9003_mci_init_cal_req(ah, &is_reusable); 1436 1437 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { 1438 rx_delay = REG_READ(ah, AR_PHY_RX_DELAY); 1439 /* Disable BB_active */ 1440 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); 1441 udelay(5); 1442 REG_WRITE(ah, AR_PHY_RX_DELAY, AR_PHY_RX_DELAY_DELAY); 1443 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 1444 } 1445 1446 if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { 1447 /* Calibrate the AGC */ 1448 REG_WRITE(ah, AR_PHY_AGC_CONTROL, 1449 REG_READ(ah, AR_PHY_AGC_CONTROL) | 1450 AR_PHY_AGC_CONTROL_CAL); 1451 1452 /* Poll for offset calibration complete */ 1453 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, 1454 AR_PHY_AGC_CONTROL_CAL, 1455 0, AH_WAIT_TIMEOUT); 1456 1457 ar9003_hw_do_pcoem_manual_peak_cal(ah, chan, run_rtt_cal); 1458 } 1459 1460 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { 1461 REG_WRITE(ah, AR_PHY_RX_DELAY, rx_delay); 1462 udelay(5); 1463 } 1464 1465 if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) 1466 ar9003_mci_init_cal_done(ah); 1467 1468 if (rtt && !run_rtt_cal) { 1469 agc_ctrl |= agc_supp_cals; 1470 REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl); 1471 } 1472 1473 if (!status) { 1474 if (run_rtt_cal) 1475 ar9003_hw_rtt_disable(ah); 1476 1477 ath_dbg(common, CALIBRATE, 1478 "offset calibration failed to complete in %d ms; noisy environment?\n", 1479 AH_WAIT_TIMEOUT / 1000); 1480 return false; 1481 } 1482 1483 if (txiqcal_done) 1484 ar9003_hw_tx_iq_cal_post_proc(ah, 0, is_reusable); 1485 else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags)) 1486 ar9003_hw_tx_iq_cal_reload(ah); 1487 1488 ar9003_hw_cl_cal_post_proc(ah, is_reusable); 1489 1490 if (run_rtt_cal && caldata) { 1491 if (is_reusable) { 1492 if (!ath9k_hw_rfbus_req(ah)) { 1493 ath_err(ath9k_hw_common(ah), 1494 "Could not stop baseband\n"); 1495 } else { 1496 ar9003_hw_rtt_fill_hist(ah); 1497 1498 if (test_bit(SW_PKDET_DONE, &caldata->cal_flags)) 1499 ar9003_hw_rtt_load_hist(ah); 1500 } 1501 1502 ath9k_hw_rfbus_done(ah); 1503 } 1504 1505 ar9003_hw_rtt_disable(ah); 1506 } 1507 1508 /* Revert chainmask to runtime parameters */ 1509 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); 1510 1511 /* Initialize list pointers */ 1512 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; 1513 1514 INIT_CAL(&ah->iq_caldata); 1515 INSERT_CAL(ah, &ah->iq_caldata); 1516 ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); 1517 1518 /* Initialize current pointer to first element in list */ 1519 ah->cal_list_curr = ah->cal_list; 1520 1521 if (ah->cal_list_curr) 1522 ath9k_hw_reset_calibration(ah, ah->cal_list_curr); 1523 1524 if (caldata) 1525 caldata->CalValid = 0; 1526 1527 return true; 1528 } 1529 1530 static bool do_ar9003_agc_cal(struct ath_hw *ah) 1531 { 1532 struct ath_common *common = ath9k_hw_common(ah); 1533 bool status; 1534 1535 REG_WRITE(ah, AR_PHY_AGC_CONTROL, 1536 REG_READ(ah, AR_PHY_AGC_CONTROL) | 1537 AR_PHY_AGC_CONTROL_CAL); 1538 1539 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, 1540 AR_PHY_AGC_CONTROL_CAL, 1541 0, AH_WAIT_TIMEOUT); 1542 if (!status) { 1543 ath_dbg(common, CALIBRATE, 1544 "offset calibration failed to complete in %d ms," 1545 "noisy environment?\n", 1546 AH_WAIT_TIMEOUT / 1000); 1547 return false; 1548 } 1549 1550 return true; 1551 } 1552 1553 static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, 1554 struct ath9k_channel *chan) 1555 { 1556 struct ath_common *common = ath9k_hw_common(ah); 1557 struct ath9k_hw_cal_data *caldata = ah->caldata; 1558 bool txiqcal_done = false; 1559 bool status = true; 1560 bool run_agc_cal = false, sep_iq_cal = false; 1561 int i = 0; 1562 1563 /* Use chip chainmask only for calibration */ 1564 ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); 1565 1566 if (ah->enabled_cals & TX_CL_CAL) { 1567 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); 1568 run_agc_cal = true; 1569 } 1570 1571 if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) 1572 goto skip_tx_iqcal; 1573 1574 /* Do Tx IQ Calibration */ 1575 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, 1576 AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, 1577 DELPT); 1578 1579 /* 1580 * For AR9485 or later chips, TxIQ cal runs as part of 1581 * AGC calibration. Specifically, AR9550 in SoC chips. 1582 */ 1583 if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { 1584 if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0, 1585 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) { 1586 txiqcal_done = true; 1587 } else { 1588 txiqcal_done = false; 1589 } 1590 run_agc_cal = true; 1591 } else { 1592 sep_iq_cal = true; 1593 run_agc_cal = true; 1594 } 1595 1596 /* 1597 * In the SoC family, this will run for AR9300, AR9331 and AR9340. 1598 */ 1599 if (sep_iq_cal) { 1600 txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); 1601 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); 1602 udelay(5); 1603 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 1604 } 1605 1606 if (AR_SREV_9550(ah) && IS_CHAN_2GHZ(chan)) { 1607 if (!ar9003_hw_dynamic_osdac_selection(ah, txiqcal_done)) 1608 return false; 1609 } 1610 1611 skip_tx_iqcal: 1612 if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { 1613 if (AR_SREV_9330_11(ah)) 1614 ar9003_hw_manual_peak_cal(ah, 0, IS_CHAN_2GHZ(chan)); 1615 1616 /* 1617 * For non-AR9550 chips, we just trigger AGC calibration 1618 * in the HW, poll for completion and then process 1619 * the results. 1620 * 1621 * For AR955x, we run it multiple times and use 1622 * median IQ correction. 1623 */ 1624 if (!AR_SREV_9550(ah)) { 1625 status = do_ar9003_agc_cal(ah); 1626 if (!status) 1627 return false; 1628 1629 if (txiqcal_done) 1630 ar9003_hw_tx_iq_cal_post_proc(ah, 0, false); 1631 } else { 1632 if (!txiqcal_done) { 1633 status = do_ar9003_agc_cal(ah); 1634 if (!status) 1635 return false; 1636 } else { 1637 for (i = 0; i < MAXIQCAL; i++) { 1638 status = do_ar9003_agc_cal(ah); 1639 if (!status) 1640 return false; 1641 ar9003_hw_tx_iq_cal_post_proc(ah, i, false); 1642 } 1643 } 1644 } 1645 } 1646 1647 /* Revert chainmask to runtime parameters */ 1648 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); 1649 1650 /* Initialize list pointers */ 1651 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; 1652 1653 INIT_CAL(&ah->iq_caldata); 1654 INSERT_CAL(ah, &ah->iq_caldata); 1655 ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); 1656 1657 /* Initialize current pointer to first element in list */ 1658 ah->cal_list_curr = ah->cal_list; 1659 1660 if (ah->cal_list_curr) 1661 ath9k_hw_reset_calibration(ah, ah->cal_list_curr); 1662 1663 if (caldata) 1664 caldata->CalValid = 0; 1665 1666 return true; 1667 } 1668 1669 void ar9003_hw_attach_calib_ops(struct ath_hw *ah) 1670 { 1671 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1672 struct ath_hw_ops *ops = ath9k_hw_ops(ah); 1673 1674 if (AR_SREV_9485(ah) || AR_SREV_9462(ah) || AR_SREV_9565(ah)) 1675 priv_ops->init_cal = ar9003_hw_init_cal_pcoem; 1676 else 1677 priv_ops->init_cal = ar9003_hw_init_cal_soc; 1678 1679 priv_ops->init_cal_settings = ar9003_hw_init_cal_settings; 1680 priv_ops->setup_calibration = ar9003_hw_setup_calibration; 1681 1682 ops->calibrate = ar9003_hw_calibrate; 1683 } 1684