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@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/62632 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/4374 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
This commit is contained in:
parent
af98062817
commit
80fd5c4461
|
@ -70,6 +70,296 @@ Device (XHCI)
|
|||
{
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue