[coreboot-gerrit] Patch set updated for coreboot: 55b0ef7 lynxpoint xhci: Add ACPI D0/D3 workarounds

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Thu Dec 12 22:14:52 CET 2013


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4374

-gerrit

commit 55b0ef78ffb047817ee096886bf24c91bfb060da
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Fri Jul 19 08:41:38 2013 -0700

    lynxpoint xhci: Add ACPI D0/D3 workarounds
    
    There are specific programming requirements for the usb3 ports
    on all LynxPoint chipsets when transitioning to D0 or D3.
    
    LynxPoint-LP has additional workaround steps needed involving
    resetting the disconnected ports when transitioning to D0.
    
    The workarounds are implemented in ACPI code so the controller
    can transition properly into D3 at runtime.
    
    Change-Id: I3b428562f48c9cb250b97779a3b2753ed4f81509
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
    Reviewed-on: https://gerrit.chromium.org/gerrit/62632
    Reviewed-by: Aaron Durbin <adurbin at chromium.org>
---
 src/southbridge/intel/lynxpoint/acpi/usb.asl | 292 ++++++++++++++++++++++++++-
 1 file changed, 291 insertions(+), 1 deletion(-)

diff --git a/src/southbridge/intel/lynxpoint/acpi/usb.asl b/src/southbridge/intel/lynxpoint/acpi/usb.asl
index 6583cb3..1a0ad34 100644
--- a/src/southbridge/intel/lynxpoint/acpi/usb.asl
+++ b/src/southbridge/intel/lynxpoint/acpi/usb.asl
@@ -68,7 +68,297 @@ Device (EHCI)
 
 Device (XHCI)
 {
-	Name(_ADR, 0x00140000)
+	Name (_ADR, 0x00140000)
+
+	Name (PLSD, 5) // Port Link State - RxDetect
+	Name (PLSP, 7) // Port Link State - Polling
+
+	OperationRegion (XPRT, PCI_Config, 0x00, 0x100)
+	Field (XPRT, AnyAcc, NoLock, Preserve)
+	{
+		Offset (0x0),
+		DVID, 16,
+		Offset (0x10),
+		, 16,
+		XMEM, 16, // MEM_BASE
+		Offset (0x74),
+		D0D3, 2,
+		, 6,
+		PMEE, 1,  // PME_EN
+		, 6,
+		PMES, 1,  // PME_STS
+		Offset (0xb0),
+		, 13,
+		MB13, 1,
+		MB14, 1,
+		Offset (0xd0),
+		PR2R, 32,  // USB2PR
+		PR2M, 32,  // USB2PRM
+		PR3R, 32,  // USB3PR
+		PR3M, 32,  // USB3PRM
+	}
+
+	// Clear status bits
+	Method (LPCL, 0, Serialized)
+	{
+		OperationRegion (XREG, SystemMemory,
+				 ShiftLeft (^XMEM, 16), 0x600)
+		Field (XREG, DWordAcc, Lock, Preserve)
+		{
+			Offset (0x510), // PORTSCNUSB3[0]
+			, 17,
+			CLR1, 7,	// Status Change bits 23:17
+			Offset (0x520), // PORTSCNUSB3[1]
+			, 17,
+			CLR2, 7,	// Status Change Bits 23:17
+			Offset (0x530), // PORTSCNUSB3[2]
+			, 17,
+			CLR3, 7,	// Status Change Bits 23:17
+			Offset (0x540), // PORTSCNUSB3[3]
+			, 17,
+			CLR4, 7,	// Status Change Bits 23:17
+		}
+
+		Store (0x7f, CLR1)
+		Store (0x7f, CLR2)
+		Store (0x7f, CLR3)
+		Store (0x7f, CLR4)
+	}
+
+	Method (LPS0, 0, Serialized)
+	{
+		OperationRegion (XREG, SystemMemory,
+				 ShiftLeft (^XMEM, 16), 0x600)
+		Field (XREG, DWordAcc, Lock, Preserve)
+		{
+			Offset (0x510), // PORTSCNUSB3
+			, 5,
+			PLS1, 4,	// [8:5] Port Link State
+			PPR1, 1,	// [9] Port Power
+			, 7,
+			CSC1, 1,	// [17] Connect Status Change
+			, 1,
+			WRC1, 1,	// [19] Warm Port Reset Change
+			, 11,
+			WPR1, 1,	// [31] Warm Port Reset
+			Offset (0x520), // PORTSCNUSB3
+			, 5,
+			PLS2, 4,	// [8:5] Port Link State
+			PPR2, 1,	// [9] Port Power
+			, 7,
+			CSC2, 1,	// [17] Connect Status Change
+			, 1,
+			WRC2, 1,	// [19] Warm Port Reset Change
+			, 11,
+			WPR2, 1,	// [31] Warm Port Reset
+			Offset (0x530), // PORTSCNUSB3
+			, 5,
+			PLS3, 4,	// [8:5] Port Link State
+			PPR3, 1,	// [9] Port Power
+			, 7,
+			CSC3, 1,	// [17] Connect Status Change
+			, 1,
+			WRC3, 1,	// [19] Warm Port Reset Change
+			, 11,
+			WPR3, 1,	// [31] Warm Port Reset
+			Offset (0x540), // PORTSCNUSB3
+			, 5,
+			PLS4, 4,	// [8:5] Port Link State
+			PPR4, 1,	// [9] Port Power
+			, 7,
+			CSC4, 1,	// [17] Connect Status Change
+			, 1,
+			WRC4, 1,	// [19] Warm Port Reset Change
+			, 11,
+			WPR4, 1,	// [31] Warm Port Reset
+		}
+
+		// Wait for all powered ports to finish polling
+		Store (10, Local0)
+		While (LOr (LOr (LAnd (LEqual (PPR1, 1), LEqual (PLS1, PLSP)),
+				 LAnd (LEqual (PPR2, 1), LEqual (PLS2, PLSP))),
+			    LOr (LAnd (LEqual (PPR3, 1), LEqual (PLS3, PLSP)),
+				 LAnd (LEqual (PPR4, 1), LEqual (PLS4, PLSP)))))
+		{
+			If (LEqual (Local0, 0)) {
+				Break
+			}
+			Decrement (Local0)
+			Stall (10)
+		}
+
+		// For each USB3 Port:
+		//   If port is disconnected (PLS=5 PP=1 CSC=0)
+		//     1) Issue warm reset (WPR=1)
+		//     2) Poll for warm reset complete (WRC=0)
+		//     3) Write 1 to port status to clear
+
+		// Local# indicate if port is reset
+		Store (0, Local1)
+		Store (0, Local2)
+		Store (0, Local3)
+		Store (0, Local4)
+
+		If (LAnd (LEqual (PLS1, PLSD),
+		          LAnd (LEqual (CSC1, 0), LEqual (PPR1, 1)))) {
+			Store (1, WPR1)	      // Issue warm reset
+			Store (1, Local1)
+		}
+		If (LAnd (LEqual (PLS2, PLSD),
+		          LAnd (LEqual (CSC2, 0), LEqual (PPR2, 1)))) {
+			Store (1, WPR2)	      // Issue warm reset
+			Store (1, Local2)
+		}
+		If (LAnd (LEqual (PLS3, PLSD),
+		          LAnd (LEqual (CSC3, 0), LEqual (PPR3, 1)))) {
+			Store (1, WPR3)	      // Issue warm reset
+			Store (1, Local3)
+		}
+		If (LAnd (LEqual (PLS4, PLSD),
+		          LAnd (LEqual (CSC4, 0), LEqual (PPR4, 1)))) {
+			Store (1, WPR4)	      // Issue warm reset
+			Store (1, Local4)
+		}
+
+		// Poll for warm reset complete on all ports that were reset
+		Store (10, Local0)
+		While (LOr (LOr (LAnd (LEqual (Local1, 1), LEqual (WRC1, 0)),
+				 LAnd (LEqual (Local2, 1), LEqual (WRC2, 0))),
+			    LOr (LAnd (LEqual (Local3, 1), LEqual (WRC3, 0)),
+			         LAnd (LEqual (Local4, 1), LEqual (WRC4, 0)))))
+		{
+			If (LEqual (Local0, 0)) {
+				Break
+			}
+			Decrement (Local0)
+			Stall (10)
+		}
+
+		// Clear status bits in all ports
+		LPCL ()
+	}
+
+	Method (_PS0, 0, Serialized)
+	{
+		If (LEqual (^DVID, 0xFFFF)) {
+			Return ()
+		}
+		If (LOr (LEqual (^XMEM, 0xFFFF), LEqual (^XMEM, 0x0000))) {
+			Return ()
+		}
+
+		OperationRegion (XREG, SystemMemory,
+				 Add (ShiftLeft (^XMEM, 16), 0x8000), 0x200)
+		Field (XREG, DWordAcc, Lock, Preserve)
+		{
+			Offset (0x0e0), // AUX Reset Control 1
+			, 15,
+			AX15, 1,
+			Offset (0x154), // AUX Domain PM Control Register 2
+			, 31,
+			CLK2, 1,
+			Offset (0x16c), // AUX Clock Control
+			, 2,
+			CLK0, 1,
+			, 11,
+			CLK1, 1, // USB3 Port Aux/Core Clock Gating Enable
+		}
+
+		// If device is in D3, set back to D0
+		Store (^D0D3, Local0)
+		if (LEqual (Local0, 3)) {
+			Store (0, ^D0D3)
+		}
+
+		If (\ISLP ()) {
+			// Clear PCI 0xB0[14:13]
+			Store (0, ^MB13)
+			Store (0, ^MB14)
+
+			// Clear MMIO 0x816C[14,2]
+			Store (0, CLK0)
+			Store (0, CLK1)
+		}
+
+		// Set MMIO 0x8154[31]
+		Store (1, CLK2)
+
+		If (\ISLP ()) {
+			// Handle per-port reset if needed
+			LPS0 ()
+
+			// Set MMIO 0x80e0[15]
+			Store (1, AX15)
+		}
+
+		// Put device in D3 if it was there originally
+		If (LEqual (Local0, 3)) {
+			Store (3, ^D0D3)
+		}
+
+		Return ()
+	}
+
+	Method (_PS3, 0, Serialized)
+	{
+		If (LEqual (^DVID, 0xFFFF)) {
+			Return ()
+		}
+		If (LOr (LEqual (^XMEM, 0xFFFF), LEqual (^XMEM, 0x0000))) {
+			Return ()
+		}
+
+		OperationRegion (XREG, SystemMemory,
+				 Add (ShiftLeft (^XMEM, 16), 0x8000), 0x200)
+		Field (XREG, DWordAcc, Lock, Preserve)
+		{
+			Offset (0x0e0), // AUX Reset Control 1
+			, 15,
+			AX15, 1,
+			Offset (0x154), // AUX Domain PM Control Register 2
+			, 31,
+			CLK2, 1,
+			Offset (0x16c), // AUX Clock Control
+			, 2,
+			CLK0, 1,
+			, 11,
+			CLK1, 1, // USB3 Port Aux/Core Clock Gating Enable
+		}
+
+		Store (1, ^PMES) // Clear PME Status
+		Store (1, ^PMEE) // Enable PME
+
+		// If device is in D3, set back to D0
+		Store (^D0D3, Local0)
+		if (LEqual (Local0, 3)) {
+			Store (0, ^D0D3)
+		}
+
+		If (\ISLP ()) {
+			// Set PCI 0xB0[14:13]
+			Store (1, ^MB13)
+			Store (1, ^MB14)
+
+			// Set MMIO 0x816C[14,2]
+			Store (1, CLK0)
+			Store (1, CLK1)
+		}
+
+		// Clear MMIO 0x8154[31]
+		Store (0, CLK2)
+
+		If (\ISLP ()) {
+			// Clear MMIO 0x80e0[15]
+			Store (0, AX15)
+		}
+
+		// Put device in D3
+		If (LEqual (Local0, 3)) {
+			Store (3, ^D0D3)
+		}
+
+		Return ()
+	}
 
 	Name (PRWH, Package(){ 0x0d, 3 }) // LPT-H
 	Name (PRWL, Package(){ 0x6d, 3 }) // LPT-LP



More information about the coreboot-gerrit mailing list