xref: /linux/drivers/net/wireless/ath/ath9k/ar9003_calib.c (revision c4ee0af3fa0dc65f690fc908f02b8355f9576ea0)
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 
27 struct coeff {
28 	int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
29 	int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
30 	int iqc_coeff[2];
31 };
32 
33 enum ar9003_cal_types {
34 	IQ_MISMATCH_CAL = BIT(0),
35 };
36 
37 static void ar9003_hw_setup_calibration(struct ath_hw *ah,
38 					struct ath9k_cal_list *currCal)
39 {
40 	struct ath_common *common = ath9k_hw_common(ah);
41 
42 	/* Select calibration to run */
43 	switch (currCal->calData->calType) {
44 	case IQ_MISMATCH_CAL:
45 		/*
46 		 * Start calibration with
47 		 * 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples
48 		 */
49 		REG_RMW_FIELD(ah, AR_PHY_TIMING4,
50 			      AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX,
51 			      currCal->calData->calCountMax);
52 		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
53 
54 		ath_dbg(common, CALIBRATE,
55 			"starting IQ Mismatch Calibration\n");
56 
57 		/* Kick-off cal */
58 		REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
59 		break;
60 	default:
61 		ath_err(common, "Invalid calibration type\n");
62 		break;
63 	}
64 }
65 
66 /*
67  * Generic calibration routine.
68  * Recalibrate the lower PHY chips to account for temperature/environment
69  * changes.
70  */
71 static bool ar9003_hw_per_calibration(struct ath_hw *ah,
72 				      struct ath9k_channel *ichan,
73 				      u8 rxchainmask,
74 				      struct ath9k_cal_list *currCal)
75 {
76 	struct ath9k_hw_cal_data *caldata = ah->caldata;
77 	/* Cal is assumed not done until explicitly set below */
78 	bool iscaldone = false;
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 			/*
85 			* Accumulate cal measures for active chains
86 			*/
87 			currCal->calData->calCollect(ah);
88 			ah->cal_samples++;
89 
90 			if (ah->cal_samples >=
91 			    currCal->calData->calNumSamples) {
92 				unsigned int i, numChains = 0;
93 				for (i = 0; i < AR9300_MAX_CHAINS; i++) {
94 					if (rxchainmask & (1 << i))
95 						numChains++;
96 				}
97 
98 				/*
99 				* Process accumulated data
100 				*/
101 				currCal->calData->calPostProc(ah, numChains);
102 
103 				/* Calibration has finished. */
104 				caldata->CalValid |= currCal->calData->calType;
105 				currCal->calState = CAL_DONE;
106 				iscaldone = true;
107 			} else {
108 			/*
109 			 * Set-up collection of another sub-sample until we
110 			 * get desired number
111 			 */
112 			ar9003_hw_setup_calibration(ah, currCal);
113 			}
114 		}
115 	} else if (!(caldata->CalValid & currCal->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 iscaldone;
121 }
122 
123 static bool ar9003_hw_calibrate(struct ath_hw *ah,
124 				struct ath9k_channel *chan,
125 				u8 rxchainmask,
126 				bool longcal)
127 {
128 	bool iscaldone = true;
129 	struct ath9k_cal_list *currCal = ah->cal_list_curr;
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 		ath9k_hw_loadnf(ah, ah->curchan);
166 
167 		/* start NF calibration, without updating BB NF register */
168 		ath9k_hw_start_nfcal(ah, false);
169 	}
170 
171 	return iscaldone;
172 }
173 
174 static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
175 {
176 	int i;
177 
178 	/* Accumulate IQ cal measures for active chains */
179 	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
180 		if (ah->txchainmask & BIT(i)) {
181 			ah->totalPowerMeasI[i] +=
182 				REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
183 			ah->totalPowerMeasQ[i] +=
184 				REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
185 			ah->totalIqCorrMeas[i] +=
186 				(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
187 			ath_dbg(ath9k_hw_common(ah), CALIBRATE,
188 				"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
189 				ah->cal_samples, i, ah->totalPowerMeasI[i],
190 				ah->totalPowerMeasQ[i],
191 				ah->totalIqCorrMeas[i]);
192 		}
193 	}
194 }
195 
196 static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
197 {
198 	struct ath_common *common = ath9k_hw_common(ah);
199 	u32 powerMeasQ, powerMeasI, iqCorrMeas;
200 	u32 qCoffDenom, iCoffDenom;
201 	int32_t qCoff, iCoff;
202 	int iqCorrNeg, i;
203 	static const u_int32_t offset_array[3] = {
204 		AR_PHY_RX_IQCAL_CORR_B0,
205 		AR_PHY_RX_IQCAL_CORR_B1,
206 		AR_PHY_RX_IQCAL_CORR_B2,
207 	};
208 
209 	for (i = 0; i < numChains; i++) {
210 		powerMeasI = ah->totalPowerMeasI[i];
211 		powerMeasQ = ah->totalPowerMeasQ[i];
212 		iqCorrMeas = ah->totalIqCorrMeas[i];
213 
214 		ath_dbg(common, CALIBRATE,
215 			"Starting IQ Cal and Correction for Chain %d\n", i);
216 
217 		ath_dbg(common, CALIBRATE,
218 			"Original: Chn %d iq_corr_meas = 0x%08x\n",
219 			i, ah->totalIqCorrMeas[i]);
220 
221 		iqCorrNeg = 0;
222 
223 		if (iqCorrMeas > 0x80000000) {
224 			iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
225 			iqCorrNeg = 1;
226 		}
227 
228 		ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_i = 0x%08x\n",
229 			i, powerMeasI);
230 		ath_dbg(common, CALIBRATE, "Chn %d pwr_meas_q = 0x%08x\n",
231 			i, powerMeasQ);
232 		ath_dbg(common, CALIBRATE, "iqCorrNeg is 0x%08x\n", iqCorrNeg);
233 
234 		iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256;
235 		qCoffDenom = powerMeasQ / 64;
236 
237 		if ((iCoffDenom != 0) && (qCoffDenom != 0)) {
238 			iCoff = iqCorrMeas / iCoffDenom;
239 			qCoff = powerMeasI / qCoffDenom - 64;
240 			ath_dbg(common, CALIBRATE, "Chn %d iCoff = 0x%08x\n",
241 				i, iCoff);
242 			ath_dbg(common, CALIBRATE, "Chn %d qCoff = 0x%08x\n",
243 				i, qCoff);
244 
245 			/* Force bounds on iCoff */
246 			if (iCoff >= 63)
247 				iCoff = 63;
248 			else if (iCoff <= -63)
249 				iCoff = -63;
250 
251 			/* Negate iCoff if iqCorrNeg == 0 */
252 			if (iqCorrNeg == 0x0)
253 				iCoff = -iCoff;
254 
255 			/* Force bounds on qCoff */
256 			if (qCoff >= 63)
257 				qCoff = 63;
258 			else if (qCoff <= -63)
259 				qCoff = -63;
260 
261 			iCoff = iCoff & 0x7f;
262 			qCoff = qCoff & 0x7f;
263 
264 			ath_dbg(common, CALIBRATE,
265 				"Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
266 				i, iCoff, qCoff);
267 			ath_dbg(common, CALIBRATE,
268 				"Register offset (0x%04x) before update = 0x%x\n",
269 				offset_array[i],
270 				REG_READ(ah, offset_array[i]));
271 
272 			if (AR_SREV_9565(ah) &&
273 			    (iCoff == 63 || qCoff == 63 ||
274 			     iCoff == -63 || qCoff == -63))
275 				return;
276 
277 			REG_RMW_FIELD(ah, offset_array[i],
278 				      AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
279 				      iCoff);
280 			REG_RMW_FIELD(ah, offset_array[i],
281 				      AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
282 				      qCoff);
283 			ath_dbg(common, CALIBRATE,
284 				"Register offset (0x%04x) QI COFF (bitfields 0x%08x) after update = 0x%x\n",
285 				offset_array[i],
286 				AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
287 				REG_READ(ah, offset_array[i]));
288 			ath_dbg(common, CALIBRATE,
289 				"Register offset (0x%04x) QQ COFF (bitfields 0x%08x) after update = 0x%x\n",
290 				offset_array[i],
291 				AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
292 				REG_READ(ah, offset_array[i]));
293 
294 			ath_dbg(common, CALIBRATE,
295 				"IQ Cal and Correction done for Chain %d\n", i);
296 		}
297 	}
298 
299 	REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0,
300 		    AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
301 	ath_dbg(common, CALIBRATE,
302 		"IQ Cal and Correction (offset 0x%04x) enabled (bit position 0x%08x). New Value 0x%08x\n",
303 		(unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
304 		AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
305 		REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
306 }
307 
308 static const struct ath9k_percal_data iq_cal_single_sample = {
309 	IQ_MISMATCH_CAL,
310 	MIN_CAL_SAMPLES,
311 	PER_MAX_LOG_COUNT,
312 	ar9003_hw_iqcal_collect,
313 	ar9003_hw_iqcalibrate
314 };
315 
316 static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
317 {
318 	ah->iq_caldata.calData = &iq_cal_single_sample;
319 
320 	if (AR_SREV_9300_20_OR_LATER(ah)) {
321 		ah->enabled_cals |= TX_IQ_CAL;
322 		if (AR_SREV_9485_OR_LATER(ah) && !AR_SREV_9340(ah))
323 			ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
324 	}
325 
326 	ah->supp_cals = IQ_MISMATCH_CAL;
327 }
328 
329 /*
330  * solve 4x4 linear equation used in loopback iq cal.
331  */
332 static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah,
333 				   s32 sin_2phi_1,
334 				   s32 cos_2phi_1,
335 				   s32 sin_2phi_2,
336 				   s32 cos_2phi_2,
337 				   s32 mag_a0_d0,
338 				   s32 phs_a0_d0,
339 				   s32 mag_a1_d0,
340 				   s32 phs_a1_d0,
341 				   s32 solved_eq[])
342 {
343 	s32 f1 = cos_2phi_1 - cos_2phi_2,
344 	    f3 = sin_2phi_1 - sin_2phi_2,
345 	    f2;
346 	s32 mag_tx, phs_tx, mag_rx, phs_rx;
347 	const s32 result_shift = 1 << 15;
348 	struct ath_common *common = ath9k_hw_common(ah);
349 
350 	f2 = (f1 * f1 + f3 * f3) / result_shift;
351 
352 	if (!f2) {
353 		ath_dbg(common, CALIBRATE, "Divide by 0\n");
354 		return false;
355 	}
356 
357 	/* mag mismatch, tx */
358 	mag_tx = f1 * (mag_a0_d0  - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
359 	/* phs mismatch, tx */
360 	phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
361 
362 	mag_tx = (mag_tx / f2);
363 	phs_tx = (phs_tx / f2);
364 
365 	/* mag mismatch, rx */
366 	mag_rx = mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) /
367 		 result_shift;
368 	/* phs mismatch, rx */
369 	phs_rx = phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) /
370 		 result_shift;
371 
372 	solved_eq[0] = mag_tx;
373 	solved_eq[1] = phs_tx;
374 	solved_eq[2] = mag_rx;
375 	solved_eq[3] = phs_rx;
376 
377 	return true;
378 }
379 
380 static s32 ar9003_hw_find_mag_approx(struct ath_hw *ah, s32 in_re, s32 in_im)
381 {
382 	s32 abs_i = abs(in_re),
383 	    abs_q = abs(in_im),
384 	    max_abs, min_abs;
385 
386 	if (abs_i > abs_q) {
387 		max_abs = abs_i;
388 		min_abs = abs_q;
389 	} else {
390 		max_abs = abs_q;
391 		min_abs = abs_i;
392 	}
393 
394 	return max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4);
395 }
396 
397 #define DELPT 32
398 
399 static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
400 				   s32 chain_idx,
401 				   const s32 iq_res[],
402 				   s32 iqc_coeff[])
403 {
404 	s32 i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0,
405 	    i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1,
406 	    i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0,
407 	    i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
408 	s32 mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1,
409 	    phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1,
410 	    sin_2phi_1, cos_2phi_1,
411 	    sin_2phi_2, cos_2phi_2;
412 	s32 mag_tx, phs_tx, mag_rx, phs_rx;
413 	s32 solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx,
414 	    q_q_coff, q_i_coff;
415 	const s32 res_scale = 1 << 15;
416 	const s32 delpt_shift = 1 << 8;
417 	s32 mag1, mag2;
418 	struct ath_common *common = ath9k_hw_common(ah);
419 
420 	i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
421 	i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
422 	iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
423 
424 	if (i2_m_q2_a0_d0 > 0x800)
425 		i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
426 
427 	if (i2_p_q2_a0_d0 > 0x800)
428 		i2_p_q2_a0_d0 = -((0xfff - i2_p_q2_a0_d0) + 1);
429 
430 	if (iq_corr_a0_d0 > 0x800)
431 		iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
432 
433 	i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
434 	i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
435 	iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
436 
437 	if (i2_m_q2_a0_d1 > 0x800)
438 		i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
439 
440 	if (i2_p_q2_a0_d1 > 0x800)
441 		i2_p_q2_a0_d1 = -((0xfff - i2_p_q2_a0_d1) + 1);
442 
443 	if (iq_corr_a0_d1 > 0x800)
444 		iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
445 
446 	i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
447 	i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
448 	iq_corr_a1_d0 = iq_res[4] & 0xfff;
449 
450 	if (i2_m_q2_a1_d0 > 0x800)
451 		i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
452 
453 	if (i2_p_q2_a1_d0 > 0x800)
454 		i2_p_q2_a1_d0 = -((0xfff - i2_p_q2_a1_d0) + 1);
455 
456 	if (iq_corr_a1_d0 > 0x800)
457 		iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
458 
459 	i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
460 	i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
461 	iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
462 
463 	if (i2_m_q2_a1_d1 > 0x800)
464 		i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
465 
466 	if (i2_p_q2_a1_d1 > 0x800)
467 		i2_p_q2_a1_d1 = -((0xfff - i2_p_q2_a1_d1) + 1);
468 
469 	if (iq_corr_a1_d1 > 0x800)
470 		iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
471 
472 	if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) ||
473 	    (i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) {
474 		ath_dbg(common, CALIBRATE,
475 			"Divide by 0:\n"
476 			"a0_d0=%d\n"
477 			"a0_d1=%d\n"
478 			"a2_d0=%d\n"
479 			"a1_d1=%d\n",
480 			i2_p_q2_a0_d0, i2_p_q2_a0_d1,
481 			i2_p_q2_a1_d0, i2_p_q2_a1_d1);
482 		return false;
483 	}
484 
485 	mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
486 	phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
487 
488 	mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
489 	phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
490 
491 	mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
492 	phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
493 
494 	mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
495 	phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
496 
497 	/* w/o analog phase shift */
498 	sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
499 	/* w/o analog phase shift */
500 	cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
501 	/* w/  analog phase shift */
502 	sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
503 	/* w/  analog phase shift */
504 	cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
505 
506 	/*
507 	 * force sin^2 + cos^2 = 1;
508 	 * find magnitude by approximation
509 	 */
510 	mag1 = ar9003_hw_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
511 	mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
512 
513 	if ((mag1 == 0) || (mag2 == 0)) {
514 		ath_dbg(common, CALIBRATE, "Divide by 0: mag1=%d, mag2=%d\n",
515 			mag1, mag2);
516 		return false;
517 	}
518 
519 	/* normalization sin and cos by mag */
520 	sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
521 	cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
522 	sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
523 	cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
524 
525 	/* calculate IQ mismatch */
526 	if (!ar9003_hw_solve_iq_cal(ah,
527 			     sin_2phi_1, cos_2phi_1,
528 			     sin_2phi_2, cos_2phi_2,
529 			     mag_a0_d0, phs_a0_d0,
530 			     mag_a1_d0,
531 			     phs_a1_d0, solved_eq)) {
532 		ath_dbg(common, CALIBRATE,
533 			"Call to ar9003_hw_solve_iq_cal() failed\n");
534 		return false;
535 	}
536 
537 	mag_tx = solved_eq[0];
538 	phs_tx = solved_eq[1];
539 	mag_rx = solved_eq[2];
540 	phs_rx = solved_eq[3];
541 
542 	ath_dbg(common, CALIBRATE,
543 		"chain %d: mag mismatch=%d phase mismatch=%d\n",
544 		chain_idx, mag_tx/res_scale, phs_tx/res_scale);
545 
546 	if (res_scale == mag_tx) {
547 		ath_dbg(common, CALIBRATE,
548 			"Divide by 0: mag_tx=%d, res_scale=%d\n",
549 			mag_tx, res_scale);
550 		return false;
551 	}
552 
553 	/* calculate and quantize Tx IQ correction factor */
554 	mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
555 	phs_corr_tx = -phs_tx;
556 
557 	q_q_coff = (mag_corr_tx * 128 / res_scale);
558 	q_i_coff = (phs_corr_tx * 256 / res_scale);
559 
560 	ath_dbg(common, CALIBRATE, "tx chain %d: mag corr=%d  phase corr=%d\n",
561 		chain_idx, q_q_coff, q_i_coff);
562 
563 	if (q_i_coff < -63)
564 		q_i_coff = -63;
565 	if (q_i_coff > 63)
566 		q_i_coff = 63;
567 	if (q_q_coff < -63)
568 		q_q_coff = -63;
569 	if (q_q_coff > 63)
570 		q_q_coff = 63;
571 
572 	iqc_coeff[0] = (q_q_coff * 128) + q_i_coff;
573 
574 	ath_dbg(common, CALIBRATE, "tx chain %d: iq corr coeff=%x\n",
575 		chain_idx, iqc_coeff[0]);
576 
577 	if (-mag_rx == res_scale) {
578 		ath_dbg(common, CALIBRATE,
579 			"Divide by 0: mag_rx=%d, res_scale=%d\n",
580 			mag_rx, res_scale);
581 		return false;
582 	}
583 
584 	/* calculate and quantize Rx IQ correction factors */
585 	mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
586 	phs_corr_rx = -phs_rx;
587 
588 	q_q_coff = (mag_corr_rx * 128 / res_scale);
589 	q_i_coff = (phs_corr_rx * 256 / res_scale);
590 
591 	ath_dbg(common, CALIBRATE, "rx chain %d: mag corr=%d  phase corr=%d\n",
592 		chain_idx, q_q_coff, q_i_coff);
593 
594 	if (q_i_coff < -63)
595 		q_i_coff = -63;
596 	if (q_i_coff > 63)
597 		q_i_coff = 63;
598 	if (q_q_coff < -63)
599 		q_q_coff = -63;
600 	if (q_q_coff > 63)
601 		q_q_coff = 63;
602 
603 	iqc_coeff[1] = (q_q_coff * 128) + q_i_coff;
604 
605 	ath_dbg(common, CALIBRATE, "rx chain %d: iq corr coeff=%x\n",
606 		chain_idx, iqc_coeff[1]);
607 
608 	return true;
609 }
610 
611 static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
612 				     int max_delta)
613 {
614 	int mp_max = -64, max_idx = 0;
615 	int mp_min = 63, min_idx = 0;
616 	int mp_avg = 0, i, outlier_idx = 0, mp_count = 0;
617 
618 	/* find min/max mismatch across all calibrated gains */
619 	for (i = 0; i < nmeasurement; i++) {
620 		if (mp_coeff[i] > mp_max) {
621 			mp_max = mp_coeff[i];
622 			max_idx = i;
623 		} else if (mp_coeff[i] < mp_min) {
624 			mp_min = mp_coeff[i];
625 			min_idx = i;
626 		}
627 	}
628 
629 	/* find average (exclude max abs value) */
630 	for (i = 0; i < nmeasurement; i++) {
631 		if ((abs(mp_coeff[i]) < abs(mp_max)) ||
632 		    (abs(mp_coeff[i]) < abs(mp_min))) {
633 			mp_avg += mp_coeff[i];
634 			mp_count++;
635 		}
636 	}
637 
638 	/*
639 	 * finding mean magnitude/phase if possible, otherwise
640 	 * just use the last value as the mean
641 	 */
642 	if (mp_count)
643 		mp_avg /= mp_count;
644 	else
645 		mp_avg = mp_coeff[nmeasurement - 1];
646 
647 	/* detect outlier */
648 	if (abs(mp_max - mp_min) > max_delta) {
649 		if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg))
650 			outlier_idx = max_idx;
651 		else
652 			outlier_idx = min_idx;
653 
654 		mp_coeff[outlier_idx] = mp_avg;
655 	}
656 }
657 
658 static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
659 						 struct coeff *coeff,
660 						 bool is_reusable)
661 {
662 	int i, im, nmeasurement;
663 	u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
664 	struct ath9k_hw_cal_data *caldata = ah->caldata;
665 
666 	memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
667 	for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
668 		tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] =
669 					AR_PHY_TX_IQCAL_CORR_COEFF_B0(i);
670 		if (!AR_SREV_9485(ah)) {
671 			tx_corr_coeff[i * 2][1] =
672 			tx_corr_coeff[(i * 2) + 1][1] =
673 					AR_PHY_TX_IQCAL_CORR_COEFF_B1(i);
674 
675 			tx_corr_coeff[i * 2][2] =
676 			tx_corr_coeff[(i * 2) + 1][2] =
677 					AR_PHY_TX_IQCAL_CORR_COEFF_B2(i);
678 		}
679 	}
680 
681 	/* Load the average of 2 passes */
682 	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
683 		if (!(ah->txchainmask & (1 << i)))
684 			continue;
685 		nmeasurement = REG_READ_FIELD(ah,
686 				AR_PHY_TX_IQCAL_STATUS_B0,
687 				AR_PHY_CALIBRATED_GAINS_0);
688 
689 		if (nmeasurement > MAX_MEASUREMENT)
690 			nmeasurement = MAX_MEASUREMENT;
691 
692 		/* detect outlier only if nmeasurement > 1 */
693 		if (nmeasurement > 1) {
694 			/* Detect magnitude outlier */
695 			ar9003_hw_detect_outlier(coeff->mag_coeff[i],
696 					nmeasurement, MAX_MAG_DELTA);
697 
698 			/* Detect phase outlier */
699 			ar9003_hw_detect_outlier(coeff->phs_coeff[i],
700 					nmeasurement, MAX_PHS_DELTA);
701 		}
702 
703 		for (im = 0; im < nmeasurement; im++) {
704 
705 			coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
706 				((coeff->phs_coeff[i][im] & 0x7f) << 7);
707 
708 			if ((im % 2) == 0)
709 				REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
710 					AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
711 					coeff->iqc_coeff[0]);
712 			else
713 				REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
714 					AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
715 					coeff->iqc_coeff[0]);
716 
717 			if (caldata)
718 				caldata->tx_corr_coeff[im][i] =
719 					coeff->iqc_coeff[0];
720 		}
721 		if (caldata)
722 			caldata->num_measures[i] = nmeasurement;
723 	}
724 
725 	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
726 		      AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
727 	REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
728 		      AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
729 
730 	if (caldata) {
731 		if (is_reusable)
732 			set_bit(TXIQCAL_DONE, &caldata->cal_flags);
733 		else
734 			clear_bit(TXIQCAL_DONE, &caldata->cal_flags);
735 	}
736 
737 	return;
738 }
739 
740 static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
741 {
742 	struct ath_common *common = ath9k_hw_common(ah);
743 	u8 tx_gain_forced;
744 
745 	tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
746 					AR_PHY_TXGAIN_FORCE);
747 	if (tx_gain_forced)
748 		REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
749 			      AR_PHY_TXGAIN_FORCE, 0);
750 
751 	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
752 		      AR_PHY_TX_IQCAL_START_DO_CAL, 1);
753 
754 	if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
755 			AR_PHY_TX_IQCAL_START_DO_CAL, 0,
756 			AH_WAIT_TIMEOUT)) {
757 		ath_dbg(common, CALIBRATE, "Tx IQ Cal is not completed\n");
758 		return false;
759 	}
760 	return true;
761 }
762 
763 static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable)
764 {
765 	struct ath_common *common = ath9k_hw_common(ah);
766 	const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
767 		AR_PHY_TX_IQCAL_STATUS_B0,
768 		AR_PHY_TX_IQCAL_STATUS_B1,
769 		AR_PHY_TX_IQCAL_STATUS_B2,
770 	};
771 	const u_int32_t chan_info_tab[] = {
772 		AR_PHY_CHAN_INFO_TAB_0,
773 		AR_PHY_CHAN_INFO_TAB_1,
774 		AR_PHY_CHAN_INFO_TAB_2,
775 	};
776 	struct coeff coeff;
777 	s32 iq_res[6];
778 	int i, im, j;
779 	int nmeasurement;
780 
781 	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
782 		if (!(ah->txchainmask & (1 << i)))
783 			continue;
784 
785 		nmeasurement = REG_READ_FIELD(ah,
786 				AR_PHY_TX_IQCAL_STATUS_B0,
787 				AR_PHY_CALIBRATED_GAINS_0);
788 		if (nmeasurement > MAX_MEASUREMENT)
789 			nmeasurement = MAX_MEASUREMENT;
790 
791 		for (im = 0; im < nmeasurement; im++) {
792 			ath_dbg(common, CALIBRATE,
793 				"Doing Tx IQ Cal for chain %d\n", i);
794 
795 			if (REG_READ(ah, txiqcal_status[i]) &
796 					AR_PHY_TX_IQCAL_STATUS_FAILED) {
797 				ath_dbg(common, CALIBRATE,
798 					"Tx IQ Cal failed for chain %d\n", i);
799 				goto tx_iqcal_fail;
800 			}
801 
802 			for (j = 0; j < 3; j++) {
803 				u32 idx = 2 * j, offset = 4 * (3 * im + j);
804 
805 				REG_RMW_FIELD(ah,
806 						AR_PHY_CHAN_INFO_MEMORY,
807 						AR_PHY_CHAN_INFO_TAB_S2_READ,
808 						0);
809 
810 				/* 32 bits */
811 				iq_res[idx] = REG_READ(ah,
812 						chan_info_tab[i] +
813 						offset);
814 
815 				REG_RMW_FIELD(ah,
816 						AR_PHY_CHAN_INFO_MEMORY,
817 						AR_PHY_CHAN_INFO_TAB_S2_READ,
818 						1);
819 
820 				/* 16 bits */
821 				iq_res[idx + 1] = 0xffff & REG_READ(ah,
822 						chan_info_tab[i] + offset);
823 
824 				ath_dbg(common, CALIBRATE,
825 					"IQ_RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
826 					idx, iq_res[idx], idx + 1,
827 					iq_res[idx + 1]);
828 			}
829 
830 			if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
831 						coeff.iqc_coeff)) {
832 				ath_dbg(common, CALIBRATE,
833 					"Failed in calculation of IQ correction\n");
834 				goto tx_iqcal_fail;
835 			}
836 
837 			coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
838 			coeff.phs_coeff[i][im] =
839 				(coeff.iqc_coeff[0] >> 7) & 0x7f;
840 
841 			if (coeff.mag_coeff[i][im] > 63)
842 				coeff.mag_coeff[i][im] -= 128;
843 			if (coeff.phs_coeff[i][im] > 63)
844 				coeff.phs_coeff[i][im] -= 128;
845 		}
846 	}
847 	ar9003_hw_tx_iqcal_load_avg_2_passes(ah, &coeff, is_reusable);
848 
849 	return;
850 
851 tx_iqcal_fail:
852 	ath_dbg(common, CALIBRATE, "Tx IQ Cal failed\n");
853 	return;
854 }
855 
856 static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah)
857 {
858 	struct ath9k_hw_cal_data *caldata = ah->caldata;
859 	u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
860 	int i, im;
861 
862 	memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
863 	for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
864 		tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] =
865 					AR_PHY_TX_IQCAL_CORR_COEFF_B0(i);
866 		if (!AR_SREV_9485(ah)) {
867 			tx_corr_coeff[i * 2][1] =
868 			tx_corr_coeff[(i * 2) + 1][1] =
869 					AR_PHY_TX_IQCAL_CORR_COEFF_B1(i);
870 
871 			tx_corr_coeff[i * 2][2] =
872 			tx_corr_coeff[(i * 2) + 1][2] =
873 					AR_PHY_TX_IQCAL_CORR_COEFF_B2(i);
874 		}
875 	}
876 
877 	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
878 		if (!(ah->txchainmask & (1 << i)))
879 			continue;
880 
881 		for (im = 0; im < caldata->num_measures[i]; im++) {
882 			if ((im % 2) == 0)
883 				REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
884 				     AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
885 				     caldata->tx_corr_coeff[im][i]);
886 			else
887 				REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
888 				     AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
889 				     caldata->tx_corr_coeff[im][i]);
890 		}
891 	}
892 
893 	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
894 		      AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
895 	REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
896 		      AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
897 }
898 
899 static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g)
900 {
901 	int offset[8], total = 0, test;
902 	int agc_out, i;
903 
904 	REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
905 		      AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0x1);
906 	REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
907 		      AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC, 0x0);
908 	if (is_2g)
909 		REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
910 			      AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR, 0x0);
911 	else
912 		REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
913 			      AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR, 0x0);
914 
915 	REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
916 		      AR_PHY_65NM_RXTX2_RXON_OVR, 0x1);
917 	REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
918 		      AR_PHY_65NM_RXTX2_RXON, 0x0);
919 
920 	REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
921 		      AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1);
922 	REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
923 		      AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR, 0x1);
924 	REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
925 		      AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1);
926 	if (is_2g)
927 		REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
928 			      AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR, 0x0);
929 	else
930 		REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
931 			      AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR, 0x0);
932 
933 	for (i = 6; i > 0; i--) {
934 		offset[i] = BIT(i - 1);
935 		test = total + offset[i];
936 
937 		if (is_2g)
938 			REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
939 				      AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR,
940 				      test);
941 		else
942 			REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
943 				      AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR,
944 				      test);
945 		udelay(100);
946 		agc_out = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
947 					 AR_PHY_65NM_RXRF_AGC_AGC_OUT);
948 		offset[i] = (agc_out) ? 0 : 1;
949 		total += (offset[i] << (i - 1));
950 	}
951 
952 	if (is_2g)
953 		REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
954 			      AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, total);
955 	else
956 		REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
957 			      AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, total);
958 
959 	REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
960 		      AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0);
961 	REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
962 		      AR_PHY_65NM_RXTX2_RXON_OVR, 0);
963 	REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
964 		      AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0);
965 }
966 
967 static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah,
968 					 struct ath9k_channel *chan,
969 					 bool run_rtt_cal)
970 {
971 	struct ath9k_hw_cal_data *caldata = ah->caldata;
972 	int i;
973 
974 	if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah) && !AR_SREV_9485(ah))
975 		return;
976 
977 	if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && !run_rtt_cal)
978 		return;
979 
980 	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
981 		if (!(ah->rxchainmask & (1 << i)))
982 			continue;
983 		ar9003_hw_manual_peak_cal(ah, i, IS_CHAN_2GHZ(chan));
984 	}
985 
986 	if (caldata)
987 		set_bit(SW_PKDET_DONE, &caldata->cal_flags);
988 
989 	if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && caldata) {
990 		if (IS_CHAN_2GHZ(chan)){
991 			caldata->caldac[0] = REG_READ_FIELD(ah,
992 						    AR_PHY_65NM_RXRF_AGC(0),
993 						    AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR);
994 			caldata->caldac[1] = REG_READ_FIELD(ah,
995 						    AR_PHY_65NM_RXRF_AGC(1),
996 						    AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR);
997 		} else {
998 			caldata->caldac[0] = REG_READ_FIELD(ah,
999 						    AR_PHY_65NM_RXRF_AGC(0),
1000 						    AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR);
1001 			caldata->caldac[1] = REG_READ_FIELD(ah,
1002 						    AR_PHY_65NM_RXRF_AGC(1),
1003 						    AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR);
1004 		}
1005 	}
1006 }
1007 
1008 static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable)
1009 {
1010 	u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0,
1011 					  AR_PHY_CL_TAB_1,
1012 					  AR_PHY_CL_TAB_2 };
1013 	struct ath9k_hw_cal_data *caldata = ah->caldata;
1014 	bool txclcal_done = false;
1015 	int i, j;
1016 
1017 	if (!caldata || !(ah->enabled_cals & TX_CL_CAL))
1018 		return;
1019 
1020 	txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) &
1021 			  AR_PHY_AGC_CONTROL_CLC_SUCCESS);
1022 
1023 	if (test_bit(TXCLCAL_DONE, &caldata->cal_flags)) {
1024 		for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1025 			if (!(ah->txchainmask & (1 << i)))
1026 				continue;
1027 			for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
1028 				REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]),
1029 					  caldata->tx_clcal[i][j]);
1030 		}
1031 	} else if (is_reusable && txclcal_done) {
1032 		for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1033 			if (!(ah->txchainmask & (1 << i)))
1034 				continue;
1035 			for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
1036 				caldata->tx_clcal[i][j] =
1037 					REG_READ(ah, CL_TAB_ENTRY(cl_idx[i]));
1038 		}
1039 		set_bit(TXCLCAL_DONE, &caldata->cal_flags);
1040 	}
1041 }
1042 
1043 static bool ar9003_hw_init_cal(struct ath_hw *ah,
1044 			       struct ath9k_channel *chan)
1045 {
1046 	struct ath_common *common = ath9k_hw_common(ah);
1047 	struct ath9k_hw_cal_data *caldata = ah->caldata;
1048 	bool txiqcal_done = false;
1049 	bool is_reusable = true, status = true;
1050 	bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false;
1051 	bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT);
1052 	u32 rx_delay = 0;
1053 	u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL |
1054 					  AR_PHY_AGC_CONTROL_FLTR_CAL   |
1055 					  AR_PHY_AGC_CONTROL_PKDET_CAL;
1056 
1057 	/* Use chip chainmask only for calibration */
1058 	ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
1059 
1060 	if (rtt) {
1061 		if (!ar9003_hw_rtt_restore(ah, chan))
1062 			run_rtt_cal = true;
1063 
1064 		if (run_rtt_cal)
1065 			ath_dbg(common, CALIBRATE, "RTT calibration to be done\n");
1066 	}
1067 
1068 	run_agc_cal = run_rtt_cal;
1069 
1070 	if (run_rtt_cal) {
1071 		ar9003_hw_rtt_enable(ah);
1072 		ar9003_hw_rtt_set_mask(ah, 0x00);
1073 		ar9003_hw_rtt_clear_hist(ah);
1074 	}
1075 
1076 	if (rtt) {
1077 		if (!run_rtt_cal) {
1078 			agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL);
1079 			agc_supp_cals &= agc_ctrl;
1080 			agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL |
1081 				      AR_PHY_AGC_CONTROL_FLTR_CAL |
1082 				      AR_PHY_AGC_CONTROL_PKDET_CAL);
1083 			REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl);
1084 		} else {
1085 			if (ah->ah_flags & AH_FASTCC)
1086 				run_agc_cal = true;
1087 		}
1088 	}
1089 
1090 	if (ah->enabled_cals & TX_CL_CAL) {
1091 		if (caldata && test_bit(TXCLCAL_DONE, &caldata->cal_flags))
1092 			REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL,
1093 				    AR_PHY_CL_CAL_ENABLE);
1094 		else {
1095 			REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL,
1096 				    AR_PHY_CL_CAL_ENABLE);
1097 			run_agc_cal = true;
1098 		}
1099 	}
1100 
1101 	if ((IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) ||
1102 	    !(ah->enabled_cals & TX_IQ_CAL))
1103 		goto skip_tx_iqcal;
1104 
1105 	/* Do Tx IQ Calibration */
1106 	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
1107 		      AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
1108 		      DELPT);
1109 
1110 	/*
1111 	 * For AR9485 or later chips, TxIQ cal runs as part of
1112 	 * AGC calibration
1113 	 */
1114 	if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
1115 		if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags))
1116 			REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
1117 				    AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
1118 		else
1119 			REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
1120 				    AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
1121 		txiqcal_done = run_agc_cal = true;
1122 	} else if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) {
1123 		run_agc_cal = true;
1124 		sep_iq_cal = true;
1125 	}
1126 
1127 skip_tx_iqcal:
1128 	if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
1129 		ar9003_mci_init_cal_req(ah, &is_reusable);
1130 
1131 	if (sep_iq_cal) {
1132 		txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
1133 		REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1134 		udelay(5);
1135 		REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
1136 	}
1137 
1138 	if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
1139 		rx_delay = REG_READ(ah, AR_PHY_RX_DELAY);
1140 		/* Disable BB_active */
1141 		REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1142 		udelay(5);
1143 		REG_WRITE(ah, AR_PHY_RX_DELAY, AR_PHY_RX_DELAY_DELAY);
1144 		REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
1145 	}
1146 
1147 	if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
1148 		/* Calibrate the AGC */
1149 		REG_WRITE(ah, AR_PHY_AGC_CONTROL,
1150 			  REG_READ(ah, AR_PHY_AGC_CONTROL) |
1151 			  AR_PHY_AGC_CONTROL_CAL);
1152 
1153 		/* Poll for offset calibration complete */
1154 		status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
1155 				       AR_PHY_AGC_CONTROL_CAL,
1156 				       0, AH_WAIT_TIMEOUT);
1157 
1158 		ar9003_hw_do_manual_peak_cal(ah, chan, run_rtt_cal);
1159 	}
1160 
1161 	if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
1162 		REG_WRITE(ah, AR_PHY_RX_DELAY, rx_delay);
1163 		udelay(5);
1164 	}
1165 
1166 	if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
1167 		ar9003_mci_init_cal_done(ah);
1168 
1169 	if (rtt && !run_rtt_cal) {
1170 		agc_ctrl |= agc_supp_cals;
1171 		REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl);
1172 	}
1173 
1174 	if (!status) {
1175 		if (run_rtt_cal)
1176 			ar9003_hw_rtt_disable(ah);
1177 
1178 		ath_dbg(common, CALIBRATE,
1179 			"offset calibration failed to complete in %d ms; noisy environment?\n",
1180 			AH_WAIT_TIMEOUT / 1000);
1181 		return false;
1182 	}
1183 
1184 	if (txiqcal_done)
1185 		ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
1186 	else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags))
1187 		ar9003_hw_tx_iq_cal_reload(ah);
1188 
1189 	ar9003_hw_cl_cal_post_proc(ah, is_reusable);
1190 
1191 	if (run_rtt_cal && caldata) {
1192 		if (is_reusable) {
1193 			if (!ath9k_hw_rfbus_req(ah)) {
1194 				ath_err(ath9k_hw_common(ah),
1195 					"Could not stop baseband\n");
1196 			} else {
1197 				ar9003_hw_rtt_fill_hist(ah);
1198 
1199 				if (test_bit(SW_PKDET_DONE, &caldata->cal_flags))
1200 					ar9003_hw_rtt_load_hist(ah);
1201 			}
1202 
1203 			ath9k_hw_rfbus_done(ah);
1204 		}
1205 
1206 		ar9003_hw_rtt_disable(ah);
1207 	}
1208 
1209 	/* Revert chainmask to runtime parameters */
1210 	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
1211 
1212 	/* Initialize list pointers */
1213 	ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
1214 
1215 	INIT_CAL(&ah->iq_caldata);
1216 	INSERT_CAL(ah, &ah->iq_caldata);
1217 	ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n");
1218 
1219 	/* Initialize current pointer to first element in list */
1220 	ah->cal_list_curr = ah->cal_list;
1221 
1222 	if (ah->cal_list_curr)
1223 		ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
1224 
1225 	if (caldata)
1226 		caldata->CalValid = 0;
1227 
1228 	return true;
1229 }
1230 
1231 void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
1232 {
1233 	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1234 	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1235 
1236 	priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
1237 	priv_ops->init_cal = ar9003_hw_init_cal;
1238 	priv_ops->setup_calibration = ar9003_hw_setup_calibration;
1239 
1240 	ops->calibrate = ar9003_hw_calibrate;
1241 }
1242