Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64773964 authored by Luis R. Rodriguez's avatar Luis R. Rodriguez Committed by John W. Linville
Browse files

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: default avatarLuis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent bbd79af5
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -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;
}
+31 −0
Original line number Diff line number Diff line
@@ -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;
}
+7 −57
Original line number Diff line number Diff line
@@ -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;

	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);
	u32 pll = ath9k_hw_compute_pll_control(ah, chan);

			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 */
+4 −0
Original line number Diff line number Diff line
@@ -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);
};

/**