/* * Helper for ASPM support. * * Disable PLL when in L0s as well as receiver clock when in L1. * This power saving option must be enabled through the SerDes. * * Programming the SerDes must go through the same 288 bit serial shift * register as the other analog registers. Hence the 9 writes. */ static void ar9003_hw_configpcipowersave(struct ath_hw *ah, bool power_off) { /* Nothing to do on restore for 11N */ if (!power_off /* !restore */) { /* set bit 19 to allow forcing of pcie core into L1 state */ REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); /* 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); } /* * Configire PCIE after Ini init. SERDES values now come from ini file * This enables PCIe low power mode. */ if (ah->config.pcieSerDesWrite) { unsigned int i; struct ar5416IniArray *array; array = power_off ? &ah->iniPcieSerdes : &ah->iniPcieSerdesLowPower; for (i = 0; i < array->ia_rows; i++) { REG_WRITE(ah, INI_RA(array, i, 0), INI_RA(array, i, 1)); } } }
static void ar9003_hw_prog_ini(struct ath_hw *ah, struct ar5416IniArray *iniArr, int column) { unsigned int i, regWrites = 0; /* New INI format: Array may be undefined (pre, core, post arrays) */ if (!iniArr->ia_array) return; /* * New INI format: Pre, core, and post arrays for a given subsystem * may be modal (> 2 columns) or non-modal (2 columns). Determine if * the array is non-modal and force the column to 1. */ if (column >= iniArr->ia_columns) column = 1; for (i = 0; i < iniArr->ia_rows; i++) { u32 reg = INI_RA(iniArr, i, 0); u32 val = INI_RA(iniArr, i, column); if (reg >= 0x16000 && reg < 0x17000) ath9k_hw_analog_shift_regwrite(ah, reg, val); else REG_WRITE(ah, reg, val); DO_DELAY(regWrites); } }
/* * This routine is called to configure the SerDes register for the * Merlin 2.0 and above chip during WOW sleep. */ static void ar928xConfigSerDes_WowSleep(struct ath_hal *ah) { int i; struct ath_hal_5416 *ahp = AH5416(ah); /* * For WOW sleep, we reprogram the SerDes so that the PLL and CHK REQ * are both enabled. This uses more power but the Maverick team reported * that otherwise, WOW sleep is unstable and chip may disappears. */ for (i = 0; i < ahp->ah_iniPcieSerdesWow.ia_rows; i++) { OS_REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdesWow, i, 0), INI_RA(&ahp->ah_iniPcieSerdesWow, i, 1)); } OS_DELAY(1000); }