ath9k_hw: Fix AR9462 power consumption on idle associated
The HW statemachine is sometimes found stuck in the state WL_LNA_CTRL_DISABLE when BT is in sleep, which will cause TX_HOLD always asserted and resmgr stuck in PENDING_TX state Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
8389fb3fd7
commit
9dd9b0dc1d
|
@ -1404,3 +1404,37 @@ void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah)
|
|||
/* Force another 2g5g update at next scanning */
|
||||
mci->update_2g5g = true;
|
||||
}
|
||||
|
||||
void ar9003_mci_set_power_awake(struct ath_hw *ah)
|
||||
{
|
||||
u32 btcoex_ctrl2, diag_sw;
|
||||
int i;
|
||||
u8 lna_ctrl, bt_sleep;
|
||||
|
||||
for (i = 0; i < AH_WAIT_TIMEOUT; i++) {
|
||||
btcoex_ctrl2 = REG_READ(ah, AR_BTCOEX_CTRL2);
|
||||
if (btcoex_ctrl2 != 0xdeadbeef)
|
||||
break;
|
||||
udelay(AH_TIME_QUANTUM);
|
||||
}
|
||||
REG_WRITE(ah, AR_BTCOEX_CTRL2, (btcoex_ctrl2 | BIT(23)));
|
||||
|
||||
for (i = 0; i < AH_WAIT_TIMEOUT; i++) {
|
||||
diag_sw = REG_READ(ah, AR_DIAG_SW);
|
||||
if (diag_sw != 0xdeadbeef)
|
||||
break;
|
||||
udelay(AH_TIME_QUANTUM);
|
||||
}
|
||||
REG_WRITE(ah, AR_DIAG_SW, (diag_sw | BIT(27) | BIT(19) | BIT(18)));
|
||||
lna_ctrl = REG_READ(ah, AR_OBS_BUS_CTRL) & 0x3;
|
||||
bt_sleep = REG_READ(ah, AR_MCI_RX_STATUS) & AR_MCI_RX_REMOTE_SLEEP;
|
||||
|
||||
REG_WRITE(ah, AR_BTCOEX_CTRL2, btcoex_ctrl2);
|
||||
REG_WRITE(ah, AR_DIAG_SW, diag_sw);
|
||||
|
||||
if (bt_sleep && (lna_ctrl == 2)) {
|
||||
REG_SET_BIT(ah, AR_BTCOEX_RC, 0x1);
|
||||
REG_CLR_BIT(ah, AR_BTCOEX_RC, 0x1);
|
||||
udelay(50);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -265,8 +265,6 @@ void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
|
|||
void ar9003_mci_cleanup(struct ath_hw *ah);
|
||||
void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
|
||||
u32 *rx_msg_intr);
|
||||
void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah);
|
||||
|
||||
/*
|
||||
* These functions are used by ath9k_hw.
|
||||
*/
|
||||
|
@ -285,6 +283,8 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
|||
void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
|
||||
bool is_full_sleep);
|
||||
void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked);
|
||||
void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah);
|
||||
void ar9003_mci_set_power_awake(struct ath_hw *ah);
|
||||
|
||||
#else
|
||||
|
||||
|
@ -322,6 +322,12 @@ static inline void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
|
|||
static inline void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
|
||||
{
|
||||
}
|
||||
static inline void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah)
|
||||
{
|
||||
}
|
||||
static inline void ar9003_mci_set_power_awake(struct ath_hw *ah)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2111,6 +2111,9 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah)
|
|||
AR_RTC_FORCE_WAKE_EN);
|
||||
udelay(50);
|
||||
|
||||
if (ath9k_hw_mci_is_enabled(ah))
|
||||
ar9003_mci_set_power_awake(ah);
|
||||
|
||||
for (i = POWER_UP_TIME / 50; i > 0; i--) {
|
||||
val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
|
||||
if (val == AR_RTC_STATUS_ON)
|
||||
|
|
Loading…
Reference in New Issue