aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k/hw.c
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2009-02-10 18:35:22 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-13 13:46:09 -0500
commit24c1a280c8db6beddbb62662c30b79cd3c8d4d01 (patch)
treeda6641b7ee1bf9ea30f374c22fb7405fde990e06 /drivers/net/wireless/ath9k/hw.c
parenta89d03c4230beb50756c98d2d1ba036c83da7680 (diff)
ath9k: add comments for ath9k_hw_configpcipowersave()
This is used for ASPM. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k/hw.c')
-rw-r--r--drivers/net/wireless/ath9k/hw.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index 72ca1c8ff09..cfcaaf886d0 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -2632,6 +2632,15 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
2632 return status; 2632 return status;
2633} 2633}
2634 2634
2635/*
2636 * Helper for ASPM support.
2637 *
2638 * Disable PLL when in L0s as well as receiver clock when in L1.
2639 * This power saving option must be enabled through the SerDes.
2640 *
2641 * Programming the SerDes must go through the same 288 bit serial shift
2642 * register as the other analog registers. Hence the 9 writes.
2643 */
2635void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore) 2644void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
2636{ 2645{
2637 u8 i; 2646 u8 i;
@@ -2639,13 +2648,20 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
2639 if (ah->is_pciexpress != true) 2648 if (ah->is_pciexpress != true)
2640 return; 2649 return;
2641 2650
2651 /* Do not touch SerDes registers */
2642 if (ah->config.pcie_powersave_enable == 2) 2652 if (ah->config.pcie_powersave_enable == 2)
2643 return; 2653 return;
2644 2654
2655 /* Nothing to do on restore for 11N */
2645 if (restore) 2656 if (restore)
2646 return; 2657 return;
2647 2658
2648 if (AR_SREV_9280_20_OR_LATER(ah)) { 2659 if (AR_SREV_9280_20_OR_LATER(ah)) {
2660 /*
2661 * AR9280 2.0 or later chips use SerDes values from the
2662 * initvals.h initialized depending on chipset during
2663 * ath9k_hw_do_attach()
2664 */
2649 for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) { 2665 for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
2650 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0), 2666 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
2651 INI_RA(&ah->iniPcieSerdes, i, 1)); 2667 INI_RA(&ah->iniPcieSerdes, i, 1));
@@ -2656,10 +2672,12 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
2656 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00); 2672 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
2657 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); 2673 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
2658 2674
2675 /* RX shut off when elecidle is asserted */
2659 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019); 2676 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
2660 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820); 2677 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
2661 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560); 2678 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
2662 2679
2680 /* Shut off CLKREQ active in L1 */
2663 if (ah->config.pcie_clock_req) 2681 if (ah->config.pcie_clock_req)
2664 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc); 2682 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
2665 else 2683 else
@@ -2669,29 +2687,46 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
2669 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); 2687 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
2670 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007); 2688 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
2671 2689
2690 /* Load the new settings */
2672 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); 2691 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
2673 2692
2674 udelay(1000); 2693 udelay(1000);
2675 } else { 2694 } else {
2676 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); 2695 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
2677 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); 2696 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
2697
2698 /* RX shut off when elecidle is asserted */
2678 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039); 2699 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
2679 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824); 2700 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
2680 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579); 2701 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
2702
2703 /*
2704 * Ignore ah->ah_config.pcie_clock_req setting for
2705 * pre-AR9280 11n
2706 */
2681 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff); 2707 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
2708
2682 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); 2709 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
2683 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); 2710 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
2684 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007); 2711 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
2712
2713 /* Load the new settings */
2685 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); 2714 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
2686 } 2715 }
2687 2716
2717 /* set bit 19 to allow forcing of pcie core into L1 state */
2688 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); 2718 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
2689 2719
2720 /* Several PCIe massages to ensure proper behaviour */
2690 if (ah->config.pcie_waen) { 2721 if (ah->config.pcie_waen) {
2691 REG_WRITE(ah, AR_WA, ah->config.pcie_waen); 2722 REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
2692 } else { 2723 } else {
2693 if (AR_SREV_9285(ah)) 2724 if (AR_SREV_9285(ah))
2694 REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT); 2725 REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
2726 /*
2727 * On AR9280 chips bit 22 of 0x4004 needs to be set to
2728 * otherwise card may disappear.
2729 */
2695 else if (AR_SREV_9280(ah)) 2730 else if (AR_SREV_9280(ah))
2696 REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT); 2731 REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT);
2697 else 2732 else