Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 May 2012 17:53:58 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r236017 - head/sys/dev/ath/ath_hal/ar5416
Message-ID:  <201205251753.q4PHrw0O025080@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Fri May 25 17:53:57 2012
New Revision: 236017
URL: http://svn.freebsd.org/changeset/base/236017

Log:
  Add some AR5416/AR5418 WAR's for power-on and suspend/resume:
  
  * Now that ah_configPCIE is called for both power on and suspend/resume,
    make sure the right bit(s) are cleared and set when suspending and
    resuming.  Specifically:
  
    + force disable/enable the PCIe PHY upon suspend/resume;
    + reprogram the PCIe WAR register when resuming and upon power-on.
  
  * Add a recipe which powers down any PCIe PHY hardware inside the AR5416
    (which is the PCI variant) to save on power.  I have (currently) no way
    to test exactly how much power is saved, if any.
  
  Tested on:
  
  * AR5416 cardbus - although unfortunately pccard/cbb/cardbus currently
    detaches the NIC upon suspend, I don't think it's a proper test case.
  
  * AR5418 PCIe attached to expresscard - since we're not doing PCIe APSM,
    it's also not likely a full/good test case.
  
  In both instances I went through a handful of suspend/resume cycles and
  ensured that the STA vap reassociated correctly.
  
  TODO:
  
  * Setup a laptop to simply sit in a suspend/resume loop, making sure that
    the NIC always correctly comes back;
  
  * Start doing suspend/resume tests with actual traffic going on in the
    background, as I bet this process is all quite racy at the present;
  
  * Test adhoc/hostap mode, just to be completely sure it's working correctly;
  
  * See if I can jury rig an external power source to an AR5416 to test out
    whether ah_disablePCIE() works.
  
  Obtained from:	Qualcomm Atheros

Modified:
  head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c	Fri May 25 17:50:50 2012	(r236016)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c	Fri May 25 17:53:57 2012	(r236017)
@@ -468,18 +468,63 @@ ar5416AttachPCIE(struct ath_hal *ah)
 static void
 ar5416ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore, HAL_BOOL power_off)
 {
-	if (AH_PRIVATE(ah)->ah_ispcie && !restore) {
+
+	/* This is only applicable for AR5418 (AR5416 PCIe) */
+	if (! AH_PRIVATE(ah)->ah_ispcie)
+		return;
+
+	if (! restore) {
 		ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_pcieserdes, 1, 0);
 		OS_DELAY(1000);
-		OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+	}
+
+	if (power_off) {		/* Power-off */
+		/* clear bit 19 to disable L1 */
+		OS_REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+	} else {			/* Power-on */
+		/* Set default WAR values for Owl */
 		OS_REG_WRITE(ah, AR_WA, AR_WA_DEFAULT);
+
+		/* set bit 19 to allow forcing of pcie core into L1 state */
+		OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
 	}
 }
 
+/*
+ * Disable PCIe PHY if PCIe isn't used.
+ */
 static void
 ar5416DisablePCIE(struct ath_hal *ah)
 {
-	/* XXX TODO */
+
+	/* PCIe? Don't */
+	if (AH_PRIVATE(ah)->ah_ispcie)
+		return;
+
+	/* .. Only applicable for AR5416v2 or later */
+	if (! (AR_SREV_OWL(ah) && AR_SREV_OWL_20_OR_LATER(ah)))
+		return;
+
+	OS_REG_WRITE_BUFFER_ENABLE(ah);
+
+	/*
+	 * Disable the PCIe PHY.
+	 */
+	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
+	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
+	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
+	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
+	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
+	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+	OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
+
+	/* Load the new settings */
+	OS_REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+
+	OS_REG_WRITE_BUFFER_FLUSH(ah);
+	OS_REG_WRITE_BUFFER_DISABLE(ah);
 }
 
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205251753.q4PHrw0O025080>