Commit 4e845168 authored by Senthil Balasubramanian's avatar Senthil Balasubramanian Committed by John W. Linville

ath9k: INI update for AR9285 and periodic PA offset caliberation

This patch updates the initvalues for AR9285 chipset and also adds
periodic PA offset caliberation.
Signed-off-by: default avatarSenthil Balasubramanian <senthilkumar@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent b03a9db9
...@@ -745,43 +745,6 @@ static void ath9k_olc_temp_compensation(struct ath_hw *ah) ...@@ -745,43 +745,6 @@ static void ath9k_olc_temp_compensation(struct ath_hw *ah)
} }
} }
bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
u8 rxchainmask, bool longcal,
bool *isCalDone)
{
struct hal_cal_list *currCal = ah->cal_list_curr;
*isCalDone = true;
if (currCal &&
(currCal->calState == CAL_RUNNING ||
currCal->calState == CAL_WAITING)) {
ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal,
isCalDone);
if (*isCalDone) {
ah->cal_list_curr = currCal = currCal->calNext;
if (currCal->calState == CAL_WAITING) {
*isCalDone = false;
ath9k_hw_reset_calibration(ah, currCal);
}
}
}
if (longcal) {
if (OLC_FOR_AR9280_20_LATER)
ath9k_olc_temp_compensation(ah);
ath9k_hw_getnf(ah, chan);
ath9k_hw_loadnf(ah, ah->curchan);
ath9k_hw_start_nfcal(ah);
if (chan->channelFlags & CHANNEL_CW_INT)
chan->channelFlags &= ~CHANNEL_CW_INT;
}
return true;
}
static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah) static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
{ {
...@@ -877,22 +840,104 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah) ...@@ -877,22 +840,104 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
} }
bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
u8 rxchainmask, bool longcal,
bool *isCalDone)
{
struct hal_cal_list *currCal = ah->cal_list_curr;
*isCalDone = true;
if (currCal &&
(currCal->calState == CAL_RUNNING ||
currCal->calState == CAL_WAITING)) {
ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal,
isCalDone);
if (*isCalDone) {
ah->cal_list_curr = currCal = currCal->calNext;
if (currCal->calState == CAL_WAITING) {
*isCalDone = false;
ath9k_hw_reset_calibration(ah, currCal);
}
}
}
if (longcal) {
if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
ath9k_hw_9285_pa_cal(ah);
if (OLC_FOR_AR9280_20_LATER)
ath9k_olc_temp_compensation(ah);
ath9k_hw_getnf(ah, chan);
ath9k_hw_loadnf(ah, ah->curchan);
ath9k_hw_start_nfcal(ah);
if (chan->channelFlags & CHANNEL_CW_INT)
chan->channelFlags &= ~CHANNEL_CW_INT;
}
return true;
}
bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
{
REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
if (chan->channelFlags & CHANNEL_HT20) {
REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_FLTR_CAL);
REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset "
"calibration failed to complete in "
"1ms; noisy ??\n");
return false;
}
REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
}
REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
0, AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset calibration "
"failed to complete in 1ms; noisy ??\n");
return false;
}
REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
return true;
}
bool ath9k_hw_init_cal(struct ath_hw *ah, bool ath9k_hw_init_cal(struct ath_hw *ah,
struct ath9k_channel *chan) struct ath9k_channel *chan)
{ {
if (AR_SREV_9280_10_OR_LATER(ah)) { if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
if (!ar9285_clc(ah, chan))
return false;
} else if (AR_SREV_9280_10_OR_LATER(ah)) {
REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
/* Kick off the cal */ /* Kick off the cal */
REG_WRITE(ah, AR_PHY_AGC_CONTROL, REG_WRITE(ah, AR_PHY_AGC_CONTROL,
REG_READ(ah, AR_PHY_AGC_CONTROL) | REG_READ(ah, AR_PHY_AGC_CONTROL) |
AR_PHY_AGC_CONTROL_CAL); AR_PHY_AGC_CONTROL_CAL);
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_CAL, 0, AR_PHY_AGC_CONTROL_CAL, 0,
AH_WAIT_TIMEOUT)) { AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"offset calibration failed to complete in 1ms; " "offset calibration failed to complete in 1ms; "
"noisy environment?\n"); "noisy environment?\n");
...@@ -906,11 +951,11 @@ bool ath9k_hw_init_cal(struct ath_hw *ah, ...@@ -906,11 +951,11 @@ bool ath9k_hw_init_cal(struct ath_hw *ah,
/* Calibrate the AGC */ /* Calibrate the AGC */
REG_WRITE(ah, AR_PHY_AGC_CONTROL, REG_WRITE(ah, AR_PHY_AGC_CONTROL,
REG_READ(ah, AR_PHY_AGC_CONTROL) | REG_READ(ah, AR_PHY_AGC_CONTROL) |
AR_PHY_AGC_CONTROL_CAL); AR_PHY_AGC_CONTROL_CAL);
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
0, AH_WAIT_TIMEOUT)) { 0, AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"offset calibration failed to complete in 1ms; " "offset calibration failed to complete in 1ms; "
"noisy environment?\n"); "noisy environment?\n");
...@@ -928,8 +973,8 @@ bool ath9k_hw_init_cal(struct ath_hw *ah, ...@@ -928,8 +973,8 @@ bool ath9k_hw_init_cal(struct ath_hw *ah,
/* Do NF Calibration */ /* Do NF Calibration */
REG_WRITE(ah, AR_PHY_AGC_CONTROL, REG_WRITE(ah, AR_PHY_AGC_CONTROL,
REG_READ(ah, AR_PHY_AGC_CONTROL) | REG_READ(ah, AR_PHY_AGC_CONTROL) |
AR_PHY_AGC_CONTROL_NF); AR_PHY_AGC_CONTROL_NF);
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
...@@ -938,19 +983,19 @@ bool ath9k_hw_init_cal(struct ath_hw *ah, ...@@ -938,19 +983,19 @@ bool ath9k_hw_init_cal(struct ath_hw *ah,
INIT_CAL(&ah->adcgain_caldata); INIT_CAL(&ah->adcgain_caldata);
INSERT_CAL(ah, &ah->adcgain_caldata); INSERT_CAL(ah, &ah->adcgain_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"enabling ADC Gain Calibration.\n"); "enabling ADC Gain Calibration.\n");
} }
if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) { if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
INIT_CAL(&ah->adcdc_caldata); INIT_CAL(&ah->adcdc_caldata);
INSERT_CAL(ah, &ah->adcdc_caldata); INSERT_CAL(ah, &ah->adcdc_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"enabling ADC DC Calibration.\n"); "enabling ADC DC Calibration.\n");
} }
if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
INIT_CAL(&ah->iq_caldata); INIT_CAL(&ah->iq_caldata);
INSERT_CAL(ah, &ah->iq_caldata); INSERT_CAL(ah, &ah->iq_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"enabling IQ Calibration.\n"); "enabling IQ Calibration.\n");
} }
ah->cal_list_curr = ah->cal_list; ah->cal_list_curr = ah->cal_list;
......
...@@ -261,7 +261,7 @@ struct base_eep_header_4k { ...@@ -261,7 +261,7 @@ struct base_eep_header_4k {
u16 deviceCap; u16 deviceCap;
u32 binBuildNumber; u32 binBuildNumber;
u8 deviceType; u8 deviceType;
u8 futureBase[1]; u8 txGainType;
} __packed; } __packed;
......
...@@ -678,6 +678,7 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, ...@@ -678,6 +678,7 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
ah->hw_version.macVersion, ah->hw_version.macRev); ah->hw_version.macVersion, ah->hw_version.macRev);
if (AR_SREV_9285_12_OR_LATER(ah)) { if (AR_SREV_9285_12_OR_LATER(ah)) {
INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2, INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
ARRAY_SIZE(ar9285Modes_9285_1_2), 6); ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2, INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
...@@ -817,6 +818,22 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, ...@@ -817,6 +818,22 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
if (ecode != 0) if (ecode != 0)
goto bad; goto bad;
if (AR_SREV_9285_12_OR_LATER(ah)) {
u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
/* txgain table */
if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9285Modes_high_power_tx_gain_9285_1_2,
ARRAY_SIZE(ar9285Modes_high_power_tx_gain_9285_1_2), 6);
} else {
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9285Modes_original_tx_gain_9285_1_2,
ARRAY_SIZE(ar9285Modes_original_tx_gain_9285_1_2), 6);
}
}
/* rxgain table */ /* rxgain table */
if (AR_SREV_9280_20(ah)) if (AR_SREV_9280_20(ah))
ath9k_hw_init_rxgain_ini(ah); ath9k_hw_init_rxgain_ini(ah);
...@@ -1293,7 +1310,8 @@ static int ath9k_hw_process_ini(struct ath_hw *ah, ...@@ -1293,7 +1310,8 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
if (AR_SREV_9280(ah)) if (AR_SREV_9280(ah))
REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites); REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
if (AR_SREV_9280(ah)) if (AR_SREV_9280(ah) || (AR_SREV_9285(ah) &&
AR_SREV_9285_12_OR_LATER(ah)))
REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
for (i = 0; i < ah->iniCommon.ia_rows; i++) { for (i = 0; i < ah->iniCommon.ia_rows; i++) {
......
This diff is collapsed.
...@@ -446,6 +446,9 @@ bool ath9k_hw_init_rf(struct ath_hw *ah, ...@@ -446,6 +446,9 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
#define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000 #define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000
#define AR_PHY_TPCRG1_PD_GAIN_3_S 20 #define AR_PHY_TPCRG1_PD_GAIN_3_S 20
#define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000
#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
#define AR_PHY_TX_PWRCTRL4 0xa264 #define AR_PHY_TX_PWRCTRL4 0xa264
#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001 #define AR_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001
#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0 #define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0
...@@ -513,6 +516,7 @@ bool ath9k_hw_init_rf(struct ath_hw *ah, ...@@ -513,6 +516,7 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
/* Carrier leak calibration control, do it after AGC calibration */ /* Carrier leak calibration control, do it after AGC calibration */
#define AR_PHY_CL_CAL_CTL 0xA358 #define AR_PHY_CL_CAL_CTL 0xA358
#define AR_PHY_CL_CAL_ENABLE 0x00000002 #define AR_PHY_CL_CAL_ENABLE 0x00000002
#define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001
#define AR_PHY_POWER_TX_RATE5 0xA38C #define AR_PHY_POWER_TX_RATE5 0xA38C
#define AR_PHY_POWER_TX_RATE6 0xA390 #define AR_PHY_POWER_TX_RATE6 0xA390
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment