linux/drivers/net/wireless/ath/ath9k/ar9003_calib.c
<<
>>
Prefs
   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        const struct ath9k_percal_data *cur_caldata = currCal->calData;
  79
  80        /* Calibration in progress. */
  81        if (currCal->calState == CAL_RUNNING) {
  82                /* Check to see if it has finished. */
  83                if (REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)
  84                        return false;
  85
  86                /*
  87                * Accumulate cal measures for active chains
  88                */
  89                cur_caldata->calCollect(ah);
  90                ah->cal_samples++;
  91
  92                if (ah->cal_samples >= cur_caldata->calNumSamples) {
  93                        unsigned int i, numChains = 0;
  94                        for (i = 0; i < AR9300_MAX_CHAINS; i++) {
  95                                if (rxchainmask & (1 << i))
  96                                        numChains++;
  97                        }
  98
  99                        /*
 100                        * Process accumulated data
 101                        */
 102                        cur_caldata->calPostProc(ah, numChains);
 103
 104                        /* Calibration has finished. */
 105                        caldata->CalValid |= cur_caldata->calType;
 106                        currCal->calState = CAL_DONE;
 107                        return true;
 108                } else {
 109                        /*
 110                         * Set-up collection of another sub-sample until we
 111                         * get desired number
 112                         */
 113                        ar9003_hw_setup_calibration(ah, currCal);
 114                }
 115        } else if (!(caldata->CalValid & cur_caldata->calType)) {
 116                /* If current cal is marked invalid in channel, kick it off */
 117                ath9k_hw_reset_calibration(ah, currCal);
 118        }
 119
 120        return false;
 121}
 122
 123static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
 124                               u8 rxchainmask, bool longcal)
 125{
 126        bool iscaldone = true;
 127        struct ath9k_cal_list *currCal = ah->cal_list_curr;
 128        int ret;
 129
 130        /*
 131         * For given calibration:
 132         * 1. Call generic cal routine
 133         * 2. When this cal is done (isCalDone) if we have more cals waiting
 134         *    (eg after reset), mask this to upper layers by not propagating
 135         *    isCalDone if it is set to TRUE.
 136         *    Instead, change isCalDone to FALSE and setup the waiting cal(s)
 137         *    to be run.
 138         */
 139        if (currCal &&
 140            (currCal->calState == CAL_RUNNING ||
 141             currCal->calState == CAL_WAITING)) {
 142                iscaldone = ar9003_hw_per_calibration(ah, chan,
 143                                                      rxchainmask, currCal);
 144                if (iscaldone) {
 145                        ah->cal_list_curr = currCal = currCal->calNext;
 146
 147                        if (currCal->calState == CAL_WAITING) {
 148                                iscaldone = false;
 149                                ath9k_hw_reset_calibration(ah, currCal);
 150                        }
 151                }
 152        }
 153
 154        /*
 155         * Do NF cal only at longer intervals. Get the value from
 156         * the previous NF cal and update history buffer.
 157         */
 158        if (longcal && ath9k_hw_getnf(ah, chan)) {
 159                /*
 160                 * Load the NF from history buffer of the current channel.
 161                 * NF is slow time-variant, so it is OK to use a historical
 162                 * value.
 163                 */
 164                ret = ath9k_hw_loadnf(ah, ah->curchan);
 165                if (ret < 0)
 166                        return ret;
 167
 168                /* start NF calibration, without updating BB NF register */
 169                ath9k_hw_start_nfcal(ah, false);
 170        }
 171
 172        return iscaldone;
 173}
 174
 175static 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
 197static 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
 309static 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
 317static 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
 333static 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 */
 551static 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
 599static 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
 618static 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
 840static 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
 888static 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
 980static 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
1003static 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
1040static 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
1057static 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
1154tx_iqcal_fail:
1155        ath_dbg(common, CALIBRATE, "Tx IQ Cal failed\n");
1156        return;
1157}
1158
1159static 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
1202static 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, peak_detect_threshold = 0;
1206
1207        if (AR_SREV_9550(ah) || AR_SREV_9531(ah))
1208                peak_detect_threshold = 8;
1209        else if (AR_SREV_9561(ah))
1210                peak_detect_threshold = 11;
1211
1212        /*
1213         * Turn off LNA/SW.
1214         */
1215        REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1216                      AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0x1);
1217        REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1218                      AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC, 0x0);
1219
1220        if (AR_SREV_9003_PCOEM(ah) || AR_SREV_9330_11(ah)) {
1221                if (is_2g)
1222                        REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1223                                      AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR, 0x0);
1224                else
1225                        REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1226                                      AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR, 0x0);
1227        }
1228
1229        /*
1230         * Turn off RXON.
1231         */
1232        REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
1233                      AR_PHY_65NM_RXTX2_RXON_OVR, 0x1);
1234        REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
1235                      AR_PHY_65NM_RXTX2_RXON, 0x0);
1236
1237        /*
1238         * Turn on AGC for cal.
1239         */
1240        REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1241                      AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1);
1242        REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1243                      AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR, 0x1);
1244        REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1245                      AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1);
1246
1247        if (AR_SREV_9330_11(ah))
1248                REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1249                              AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, 0x0);
1250
1251        if (is_2g)
1252                REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1253                              AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR,
1254                              peak_detect_threshold);
1255        else
1256                REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1257                              AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR,
1258                              peak_detect_threshold);
1259
1260        for (i = 6; i > 0; i--) {
1261                offset[i] = BIT(i - 1);
1262                test = total + offset[i];
1263
1264                if (is_2g)
1265                        REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1266                                      AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR,
1267                                      test);
1268                else
1269                        REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1270                                      AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR,
1271                                      test);
1272                udelay(100);
1273                agc_out = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1274                                         AR_PHY_65NM_RXRF_AGC_AGC_OUT);
1275                offset[i] = (agc_out) ? 0 : 1;
1276                total += (offset[i] << (i - 1));
1277        }
1278
1279        if (is_2g)
1280                REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1281                              AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, total);
1282        else
1283                REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1284                              AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, total);
1285
1286        /*
1287         * Turn on LNA.
1288         */
1289        REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1290                      AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0);
1291        /*
1292         * Turn off RXON.
1293         */
1294        REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
1295                      AR_PHY_65NM_RXTX2_RXON_OVR, 0);
1296        /*
1297         * Turn off peak detect calibration.
1298         */
1299        REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1300                      AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0);
1301}
1302
1303static void ar9003_hw_do_pcoem_manual_peak_cal(struct ath_hw *ah,
1304                                               struct ath9k_channel *chan,
1305                                               bool run_rtt_cal)
1306{
1307        struct ath9k_hw_cal_data *caldata = ah->caldata;
1308        int i;
1309
1310        if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && !run_rtt_cal)
1311                return;
1312
1313        for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1314                if (!(ah->rxchainmask & (1 << i)))
1315                        continue;
1316                ar9003_hw_manual_peak_cal(ah, i, IS_CHAN_2GHZ(chan));
1317        }
1318
1319        if (caldata)
1320                set_bit(SW_PKDET_DONE, &caldata->cal_flags);
1321
1322        if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && caldata) {
1323                if (IS_CHAN_2GHZ(chan)){
1324                        caldata->caldac[0] = REG_READ_FIELD(ah,
1325                                                    AR_PHY_65NM_RXRF_AGC(0),
1326                                                    AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR);
1327                        caldata->caldac[1] = REG_READ_FIELD(ah,
1328                                                    AR_PHY_65NM_RXRF_AGC(1),
1329                                                    AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR);
1330                } else {
1331                        caldata->caldac[0] = REG_READ_FIELD(ah,
1332                                                    AR_PHY_65NM_RXRF_AGC(0),
1333                                                    AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR);
1334                        caldata->caldac[1] = REG_READ_FIELD(ah,
1335                                                    AR_PHY_65NM_RXRF_AGC(1),
1336                                                    AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR);
1337                }
1338        }
1339}
1340
1341static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable)
1342{
1343        u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0,
1344                                          AR_PHY_CL_TAB_1,
1345                                          AR_PHY_CL_TAB_2 };
1346        struct ath9k_hw_cal_data *caldata = ah->caldata;
1347        bool txclcal_done = false;
1348        int i, j;
1349
1350        if (!caldata || !(ah->enabled_cals & TX_CL_CAL))
1351                return;
1352
1353        txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) &
1354                          AR_PHY_AGC_CONTROL_CLC_SUCCESS);
1355
1356        if (test_bit(TXCLCAL_DONE, &caldata->cal_flags)) {
1357                for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1358                        if (!(ah->txchainmask & (1 << i)))
1359                                continue;
1360                        for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
1361                                REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]),
1362                                          caldata->tx_clcal[i][j]);
1363                }
1364        } else if (is_reusable && txclcal_done) {
1365                for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1366                        if (!(ah->txchainmask & (1 << i)))
1367                                continue;
1368                        for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
1369                                caldata->tx_clcal[i][j] =
1370                                        REG_READ(ah, CL_TAB_ENTRY(cl_idx[i]));
1371                }
1372                set_bit(TXCLCAL_DONE, &caldata->cal_flags);
1373        }
1374}
1375
1376static void ar9003_hw_init_cal_common(struct ath_hw *ah)
1377{
1378        struct ath9k_hw_cal_data *caldata = ah->caldata;
1379
1380        /* Initialize list pointers */
1381        ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
1382
1383        INIT_CAL(&ah->iq_caldata);
1384        INSERT_CAL(ah, &ah->iq_caldata);
1385
1386        /* Initialize current pointer to first element in list */
1387        ah->cal_list_curr = ah->cal_list;
1388
1389        if (ah->cal_list_curr)
1390                ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
1391
1392        if (caldata)
1393                caldata->CalValid = 0;
1394}
1395
1396static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah,
1397                                     struct ath9k_channel *chan)
1398{
1399        struct ath_common *common = ath9k_hw_common(ah);
1400        struct ath9k_hw_cal_data *caldata = ah->caldata;
1401        bool txiqcal_done = false;
1402        bool is_reusable = true, status = true;
1403        bool run_rtt_cal = false, run_agc_cal;
1404        bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT);
1405        u32 rx_delay = 0;
1406        u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL |
1407                                          AR_PHY_AGC_CONTROL_FLTR_CAL   |
1408                                          AR_PHY_AGC_CONTROL_PKDET_CAL;
1409
1410        /* Use chip chainmask only for calibration */
1411        ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
1412
1413        if (rtt) {
1414                if (!ar9003_hw_rtt_restore(ah, chan))
1415                        run_rtt_cal = true;
1416
1417                if (run_rtt_cal)
1418                        ath_dbg(common, CALIBRATE, "RTT calibration to be done\n");
1419        }
1420
1421        run_agc_cal = run_rtt_cal;
1422
1423        if (run_rtt_cal) {
1424                ar9003_hw_rtt_enable(ah);
1425                ar9003_hw_rtt_set_mask(ah, 0x00);
1426                ar9003_hw_rtt_clear_hist(ah);
1427        }
1428
1429        if (rtt) {
1430                if (!run_rtt_cal) {
1431                        agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL);
1432                        agc_supp_cals &= agc_ctrl;
1433                        agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL |
1434                                      AR_PHY_AGC_CONTROL_FLTR_CAL |
1435                                      AR_PHY_AGC_CONTROL_PKDET_CAL);
1436                        REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl);
1437                } else {
1438                        if (ah->ah_flags & AH_FASTCC)
1439                                run_agc_cal = true;
1440                }
1441        }
1442
1443        if (ah->enabled_cals & TX_CL_CAL) {
1444                if (caldata && test_bit(TXCLCAL_DONE, &caldata->cal_flags))
1445                        REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL,
1446                                    AR_PHY_CL_CAL_ENABLE);
1447                else {
1448                        REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL,
1449                                    AR_PHY_CL_CAL_ENABLE);
1450                        run_agc_cal = true;
1451                }
1452        }
1453
1454        if ((IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) ||
1455            !(ah->enabled_cals & TX_IQ_CAL))
1456                goto skip_tx_iqcal;
1457
1458        /* Do Tx IQ Calibration */
1459        REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
1460                      AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
1461                      DELPT);
1462
1463        /*
1464         * For AR9485 or later chips, TxIQ cal runs as part of
1465         * AGC calibration
1466         */
1467        if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
1468                if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags))
1469                        REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
1470                                    AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
1471                else
1472                        REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
1473                                    AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
1474                txiqcal_done = run_agc_cal = true;
1475        }
1476
1477skip_tx_iqcal:
1478        if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
1479                ar9003_mci_init_cal_req(ah, &is_reusable);
1480
1481        if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
1482                rx_delay = REG_READ(ah, AR_PHY_RX_DELAY);
1483                /* Disable BB_active */
1484                REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1485                udelay(5);
1486                REG_WRITE(ah, AR_PHY_RX_DELAY, AR_PHY_RX_DELAY_DELAY);
1487                REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
1488        }
1489
1490        if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
1491                /* Calibrate the AGC */
1492                REG_WRITE(ah, AR_PHY_AGC_CONTROL,
1493                          REG_READ(ah, AR_PHY_AGC_CONTROL) |
1494                          AR_PHY_AGC_CONTROL_CAL);
1495
1496                /* Poll for offset calibration complete */
1497                status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
1498                                       AR_PHY_AGC_CONTROL_CAL,
1499                                       0, AH_WAIT_TIMEOUT);
1500
1501                ar9003_hw_do_pcoem_manual_peak_cal(ah, chan, run_rtt_cal);
1502        }
1503
1504        if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
1505                REG_WRITE(ah, AR_PHY_RX_DELAY, rx_delay);
1506                udelay(5);
1507        }
1508
1509        if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
1510                ar9003_mci_init_cal_done(ah);
1511
1512        if (rtt && !run_rtt_cal) {
1513                agc_ctrl |= agc_supp_cals;
1514                REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl);
1515        }
1516
1517        if (!status) {
1518                if (run_rtt_cal)
1519                        ar9003_hw_rtt_disable(ah);
1520
1521                ath_dbg(common, CALIBRATE,
1522                        "offset calibration failed to complete in %d ms; noisy environment?\n",
1523                        AH_WAIT_TIMEOUT / 1000);
1524                return false;
1525        }
1526
1527        if (txiqcal_done)
1528                ar9003_hw_tx_iq_cal_post_proc(ah, 0, is_reusable);
1529        else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags))
1530                ar9003_hw_tx_iq_cal_reload(ah);
1531
1532        ar9003_hw_cl_cal_post_proc(ah, is_reusable);
1533
1534        if (run_rtt_cal && caldata) {
1535                if (is_reusable) {
1536                        if (!ath9k_hw_rfbus_req(ah)) {
1537                                ath_err(ath9k_hw_common(ah),
1538                                        "Could not stop baseband\n");
1539                        } else {
1540                                ar9003_hw_rtt_fill_hist(ah);
1541
1542                                if (test_bit(SW_PKDET_DONE, &caldata->cal_flags))
1543                                        ar9003_hw_rtt_load_hist(ah);
1544                        }
1545
1546                        ath9k_hw_rfbus_done(ah);
1547                }
1548
1549                ar9003_hw_rtt_disable(ah);
1550        }
1551
1552        /* Revert chainmask to runtime parameters */
1553        ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
1554
1555        ar9003_hw_init_cal_common(ah);
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        bool txiqcal_done = false;
1587        bool status = true;
1588        bool run_agc_cal = false, sep_iq_cal = false;
1589        int i = 0;
1590
1591        /* Use chip chainmask only for calibration */
1592        ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
1593
1594        if (ah->enabled_cals & TX_CL_CAL) {
1595                REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
1596                run_agc_cal = true;
1597        }
1598
1599        if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))
1600                goto skip_tx_iqcal;
1601
1602        /* Do Tx IQ Calibration */
1603        REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
1604                      AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
1605                      DELPT);
1606
1607        /*
1608         * For AR9485 or later chips, TxIQ cal runs as part of
1609         * AGC calibration. Specifically, AR9550 in SoC chips.
1610         */
1611        if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
1612                if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
1613                                   AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) {
1614                                txiqcal_done = true;
1615                } else {
1616                        txiqcal_done = false;
1617                }
1618                run_agc_cal = true;
1619        } else {
1620                sep_iq_cal = true;
1621                run_agc_cal = true;
1622        }
1623
1624        /*
1625         * In the SoC family, this will run for AR9300, AR9331 and AR9340.
1626         */
1627        if (sep_iq_cal) {
1628                txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
1629                REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1630                udelay(5);
1631                REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
1632        }
1633
1634        if (AR_SREV_9550(ah) && IS_CHAN_2GHZ(chan)) {
1635                if (!ar9003_hw_dynamic_osdac_selection(ah, txiqcal_done))
1636                        return false;
1637        }
1638
1639skip_tx_iqcal:
1640        if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
1641                for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1642                        if (!(ah->rxchainmask & (1 << i)))
1643                                continue;
1644
1645                        ar9003_hw_manual_peak_cal(ah, i,
1646                                                  IS_CHAN_2GHZ(chan));
1647                }
1648
1649                /*
1650                 * For non-AR9550 chips, we just trigger AGC calibration
1651                 * in the HW, poll for completion and then process
1652                 * the results.
1653                 *
1654                 * For AR955x, we run it multiple times and use
1655                 * median IQ correction.
1656                 */
1657                if (!AR_SREV_9550(ah)) {
1658                        status = do_ar9003_agc_cal(ah);
1659                        if (!status)
1660                                return false;
1661
1662                        if (txiqcal_done)
1663                                ar9003_hw_tx_iq_cal_post_proc(ah, 0, false);
1664                } else {
1665                        if (!txiqcal_done) {
1666                                status = do_ar9003_agc_cal(ah);
1667                                if (!status)
1668                                        return false;
1669                        } else {
1670                                for (i = 0; i < MAXIQCAL; i++) {
1671                                        status = do_ar9003_agc_cal(ah);
1672                                        if (!status)
1673                                                return false;
1674                                        ar9003_hw_tx_iq_cal_post_proc(ah, i, false);
1675                                }
1676                        }
1677                }
1678        }
1679
1680        /* Revert chainmask to runtime parameters */
1681        ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
1682
1683        ar9003_hw_init_cal_common(ah);
1684
1685        return true;
1686}
1687
1688void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
1689{
1690        struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1691        struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1692
1693        if (AR_SREV_9003_PCOEM(ah))
1694                priv_ops->init_cal = ar9003_hw_init_cal_pcoem;
1695        else
1696                priv_ops->init_cal = ar9003_hw_init_cal_soc;
1697
1698        priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
1699        priv_ops->setup_calibration = ar9003_hw_setup_calibration;
1700
1701        ops->calibrate = ar9003_hw_calibrate;
1702}
1703