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

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

ath9k_hw: fix ASPM setting for AR9003



The AR_WA register should not be read when in sleep state so
add a variable we can stash its value into for when we need
to set it. Additionally the AR_WA_D3_TO_L1_DISABLE_REAL
(bit 16) needs to be removed.

Cc: Aeolus Yang <aeolus.yang@atheros.com>
Cc: Madhan Jaganathan <madhan.jaganathan@atheros.com>
signed-off-by: default avatarLuis R. Rodriguez <lrodriguez@atheros.com>

Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 1047d5ed
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -295,6 +295,8 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
		/* Several PCIe massages to ensure proper behaviour */
		if (ah->config.pcie_waen)
			REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
		else
			REG_WRITE(ah, AR_WA, ah->WARegVal);
	}
}

+39 −6
Original line number Diff line number Diff line
@@ -575,14 +575,8 @@ static int __ath9k_hw_init(struct ath_hw *ah)
	 * This enables PCIe low power mode.
	 */
	if (AR_SREV_9300_20_OR_LATER(ah)) {
		u32 regval;
		unsigned int i;

		/* Set Bits 16 and 17 in the AR_WA register. */
		regval = REG_READ(ah, AR_WA);
		regval |= 0x00030000;
		REG_WRITE(ah, AR_WA, regval);

		for (i = 0; i < ah->iniPcieSerdesLowPower.ia_rows; i++) {
			REG_WRITE(ah,
				  INI_RA(&ah->iniPcieSerdesLowPower, i, 0),
@@ -590,6 +584,15 @@ static int __ath9k_hw_init(struct ath_hw *ah)
		}
	}

	/*
	 * Read back AR_WA into a permanent copy and set bits 14 and 17.
	 * We need to do this to avoid RMW of this register. We cannot
	 * read the reg when chip is asleep.
	 */
	ah->WARegVal = REG_READ(ah, AR_WA);
	ah->WARegVal |= (AR_WA_D3_L1_DISABLE |
			 AR_WA_ASPM_TIMER_BASED_DISABLE);

	if (ah->is_pciexpress)
		ath9k_hw_configpcipowersave(ah, 0, 0);
	else
@@ -1009,6 +1012,11 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)

	ENABLE_REGWRITE_BUFFER(ah);

	if (AR_SREV_9300_20_OR_LATER(ah)) {
		REG_WRITE(ah, AR_WA, ah->WARegVal);
		udelay(10);
	}

	REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
		  AR_RTC_FORCE_WAKE_ON_INT);

@@ -1063,6 +1071,11 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
{
	ENABLE_REGWRITE_BUFFER(ah);

	if (AR_SREV_9300_20_OR_LATER(ah)) {
		REG_WRITE(ah, AR_WA, ah->WARegVal);
		udelay(10);
	}

	REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
		  AR_RTC_FORCE_WAKE_ON_INT);

@@ -1099,6 +1112,11 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)

static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
{
	if (AR_SREV_9300_20_OR_LATER(ah)) {
		REG_WRITE(ah, AR_WA, ah->WARegVal);
		udelay(10);
	}

	REG_WRITE(ah, AR_RTC_FORCE_WAKE,
		  AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);

@@ -1768,6 +1786,11 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
			REG_CLR_BIT(ah, (AR_RTC_RESET),
				    AR_RTC_RESET_EN);
	}

	/* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */
	if (AR_SREV_9300_20_OR_LATER(ah))
		REG_WRITE(ah, AR_WA,
			  ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
}

/*
@@ -1794,6 +1817,10 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
				    AR_RTC_FORCE_WAKE_EN);
		}
	}

	/* Clear Bit 14 of AR_WA after putting chip into Net Sleep mode. */
	if (AR_SREV_9300_20_OR_LATER(ah))
		REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
}

static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
@@ -1801,6 +1828,12 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
	u32 val;
	int i;

	/* Set Bits 14 and 17 of AR_WA before powering on the chip. */
	if (AR_SREV_9300_20_OR_LATER(ah)) {
		REG_WRITE(ah, AR_WA, ah->WARegVal);
		udelay(10);
	}

	if (setChip) {
		if ((REG_READ(ah, AR_RTC_STATUS) &
		     AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) {
+6 −0
Original line number Diff line number Diff line
@@ -819,6 +819,12 @@ struct ath_hw {

	u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
	u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
	/*
	 * Store the permanent value of Reg 0x4004in WARegVal
	 * so we dont have to R/M/W. We should not be reading
	 * this register when in sleep states.
	 */
	u32 WARegVal;
};

static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
+5 −0
Original line number Diff line number Diff line
@@ -704,6 +704,11 @@
#define AR_WA_BIT7			(1 << 7)
#define AR_WA_BIT23			(1 << 23)
#define AR_WA_D3_L1_DISABLE		(1 << 14)
#define AR_WA_D3_TO_L1_DISABLE_REAL     (1 << 16)
#define AR_WA_ASPM_TIMER_BASED_DISABLE  (1 << 17)
#define AR_WA_RESET_EN                  (1 << 18) /* Sw Control to enable PCI-Reset to POR (bit 15) */
#define AR_WA_ANALOG_SHIFT              (1 << 20)
#define AR_WA_POR_SHORT                 (1 << 21) /* PCI-E Phy reset control */
#define AR9285_WA_DEFAULT		0x004a050b
#define AR9280_WA_DEFAULT           	0x0040073b
#define AR_WA_DEFAULT               	0x0000073f