ath9k_hw: add a private callback for PLL control computation
The PLL control computation used to program the AR_RTC_PLL_CONTROL register varies between our harware so just add a private callback for it. AR9003 will use its own callback. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
bbd79af563
commit
647739645b
|
@ -967,6 +967,54 @@ static void ar5008_set_diversity(struct ath_hw *ah, bool value)
|
|||
REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
|
||||
}
|
||||
|
||||
static u32 ar9100_hw_compute_pll_control(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
if (chan && IS_CHAN_5GHZ(chan))
|
||||
return 0x1450;
|
||||
return 0x1458;
|
||||
}
|
||||
|
||||
static u32 ar9160_hw_compute_pll_control(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
u32 pll;
|
||||
|
||||
pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
|
||||
|
||||
if (chan && IS_CHAN_HALF_RATE(chan))
|
||||
pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
|
||||
else if (chan && IS_CHAN_QUARTER_RATE(chan))
|
||||
pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
|
||||
|
||||
if (chan && IS_CHAN_5GHZ(chan))
|
||||
pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
|
||||
else
|
||||
pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
|
||||
|
||||
return pll;
|
||||
}
|
||||
|
||||
static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
u32 pll;
|
||||
|
||||
pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
|
||||
|
||||
if (chan && IS_CHAN_HALF_RATE(chan))
|
||||
pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
|
||||
else if (chan && IS_CHAN_QUARTER_RATE(chan))
|
||||
pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
|
||||
|
||||
if (chan && IS_CHAN_5GHZ(chan))
|
||||
pll |= SM(0xa, AR_RTC_PLL_DIV);
|
||||
else
|
||||
pll |= SM(0xb, AR_RTC_PLL_DIV);
|
||||
|
||||
return pll;
|
||||
}
|
||||
|
||||
void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
|
@ -988,4 +1036,11 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
|
|||
priv_ops->enable_rfkill = ar5008_hw_enable_rfkill;
|
||||
priv_ops->restore_chainmask = ar5008_restore_chainmask;
|
||||
priv_ops->set_diversity = ar5008_set_diversity;
|
||||
|
||||
if (AR_SREV_9100(ah))
|
||||
priv_ops->compute_pll_control = ar9100_hw_compute_pll_control;
|
||||
else if (AR_SREV_9160_10_OR_LATER(ah))
|
||||
priv_ops->compute_pll_control = ar9160_hw_compute_pll_control;
|
||||
else
|
||||
priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;
|
||||
}
|
||||
|
|
|
@ -437,6 +437,36 @@ static void ar9002_olc_init(struct ath_hw *ah)
|
|||
}
|
||||
}
|
||||
|
||||
static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
u32 pll;
|
||||
|
||||
pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
|
||||
|
||||
if (chan && IS_CHAN_HALF_RATE(chan))
|
||||
pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
|
||||
else if (chan && IS_CHAN_QUARTER_RATE(chan))
|
||||
pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
|
||||
|
||||
if (chan && IS_CHAN_5GHZ(chan)) {
|
||||
pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
|
||||
|
||||
|
||||
if (AR_SREV_9280_20(ah)) {
|
||||
if (((chan->channel % 20) == 0)
|
||||
|| ((chan->channel % 10) == 0))
|
||||
pll = 0x2850;
|
||||
else
|
||||
pll = 0x142c;
|
||||
}
|
||||
} else {
|
||||
pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
|
||||
}
|
||||
|
||||
return pll;
|
||||
}
|
||||
|
||||
void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
|
@ -447,4 +477,5 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
|
|||
priv_ops->rf_set_freq = ar9002_hw_set_channel;
|
||||
priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
|
||||
priv_ops->olc_init = ar9002_olc_init;
|
||||
priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
|
||||
}
|
||||
|
|
|
@ -66,6 +66,12 @@ static bool ath9k_hw_macversion_supported(struct ath_hw *ah)
|
|||
return priv_ops->macversion_supported(ah->hw_version.macVersion);
|
||||
}
|
||||
|
||||
static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->compute_pll_control(ah, chan);
|
||||
}
|
||||
|
||||
/********************/
|
||||
/* Helper Functions */
|
||||
/********************/
|
||||
|
@ -1023,64 +1029,8 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
|
|||
static void ath9k_hw_init_pll(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
u32 pll;
|
||||
u32 pll = ath9k_hw_compute_pll_control(ah, chan);
|
||||
|
||||
if (AR_SREV_9100(ah)) {
|
||||
if (chan && IS_CHAN_5GHZ(chan))
|
||||
pll = 0x1450;
|
||||
else
|
||||
pll = 0x1458;
|
||||
} else {
|
||||
if (AR_SREV_9280_10_OR_LATER(ah)) {
|
||||
pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
|
||||
|
||||
if (chan && IS_CHAN_HALF_RATE(chan))
|
||||
pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
|
||||
else if (chan && IS_CHAN_QUARTER_RATE(chan))
|
||||
pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
|
||||
|
||||
if (chan && IS_CHAN_5GHZ(chan)) {
|
||||
pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
|
||||
|
||||
|
||||
if (AR_SREV_9280_20(ah)) {
|
||||
if (((chan->channel % 20) == 0)
|
||||
|| ((chan->channel % 10) == 0))
|
||||
pll = 0x2850;
|
||||
else
|
||||
pll = 0x142c;
|
||||
}
|
||||
} else {
|
||||
pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
|
||||
}
|
||||
|
||||
} else if (AR_SREV_9160_10_OR_LATER(ah)) {
|
||||
|
||||
pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
|
||||
|
||||
if (chan && IS_CHAN_HALF_RATE(chan))
|
||||
pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
|
||||
else if (chan && IS_CHAN_QUARTER_RATE(chan))
|
||||
pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
|
||||
|
||||
if (chan && IS_CHAN_5GHZ(chan))
|
||||
pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
|
||||
else
|
||||
pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
|
||||
} else {
|
||||
pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
|
||||
|
||||
if (chan && IS_CHAN_HALF_RATE(chan))
|
||||
pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
|
||||
else if (chan && IS_CHAN_QUARTER_RATE(chan))
|
||||
pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
|
||||
|
||||
if (chan && IS_CHAN_5GHZ(chan))
|
||||
pll |= SM(0xa, AR_RTC_PLL_DIV);
|
||||
else
|
||||
pll |= SM(0xb, AR_RTC_PLL_DIV);
|
||||
}
|
||||
}
|
||||
REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
|
||||
|
||||
/* Switch the core clock for ar9271 to 117Mhz */
|
||||
|
|
|
@ -454,6 +454,8 @@ struct ath_gen_timer_table {
|
|||
* @rf_alloc_ext_banks:
|
||||
* @rf_free_ext_banks:
|
||||
* @set_rf_regs:
|
||||
* @compute_pll_control: compute the PLL control value to use for
|
||||
* AR_RTC_PLL_CONTROL for a given channel
|
||||
*/
|
||||
struct ath_hw_private_ops {
|
||||
void (*init_cal_settings)(struct ath_hw *ah);
|
||||
|
@ -483,6 +485,8 @@ struct ath_hw_private_ops {
|
|||
void (*enable_rfkill)(struct ath_hw *ah);
|
||||
void (*restore_chainmask)(struct ath_hw *ah);
|
||||
void (*set_diversity)(struct ath_hw *ah, bool value);
|
||||
u32 (*compute_pll_control)(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue