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