blob: fbeb56200a0573481adbe21acd38647fde5b13ac [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
// XHCI Controller 0:14.0
Device (XHCI)
{
Name (_ADR, 0x00140000)
Name (PLSD, 5) // Port Link State - RxDetect
Name (PLSP, 7) // Port Link State - Polling
OperationRegion (XPRT, PCI_Config, 0, 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, ^XMEM << 16, 0x600)
Field (XREG, DWordAcc, Lock, Preserve)
{
Offset (0x510), // PORTSCNUSB3[0]
PSC0, 32,
Offset (0x520), // PORTSCNUSB3[1]
PSC1, 32,
Offset (0x530), // PORTSCNUSB3[2]
PSC2, 32,
Offset (0x540), // PORTSCNUSB3[3]
PSC3, 32,
}
// Port Enabled/Disabled (Bit 1)
Name (PEDB, 1 << 1)
// Change Status (Bits 23:17)
Name (CHST, 0x7f << 17)
// Port 0
Local0 = PSC0 & ~PEDB
PSC0 = Local0 | CHST
// Port 1
Local0 = PSC1 & ~PEDB
PSC1 = Local0 | CHST
// Port 2
Local0 = PSC2 & ~PEDB
PSC2 = Local0 | CHST
// Port 3
Local0 = PSC3 & ~PEDB
PSC3 = Local0 | CHST
}
Method (LPS0, 0, Serialized)
{
OperationRegion (XREG, SystemMemory, ^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
Local0 = 10
While ((PPR1 == 1 && PLS1 == PLSP || PPR2 == 1 && PLS2 == PLSP) ||
(PPR3 == 1 && PLS3 == PLSP || PPR4 == 1 && PLS4 == PLSP))
{
If (Local0 == 0) {
Break
}
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
Local1 = 0
Local2 = 0
Local3 = 0
Local4 = 0
If (PLS1 == PLSD && (CSC1 == 0 && PPR1 == 1)) {
WPR1 = 1 // Issue warm reset
Local1 = 1
}
If (PLS2 == PLSD && (CSC2 == 0 && PPR2 == 1)) {
WPR2 = 1 // Issue warm reset
Local2 = 1
}
If (PLS3 == PLSD && (CSC3 == 0 && PPR3 == 1)) {
WPR3 = 1 // Issue warm reset
Local3 = 1
}
If (PLS4 == PLSD && (CSC4 == 0 && PPR4 == 1)) {
WPR4 = 1 // Issue warm reset
Local4 = 1
}
// Poll for warm reset complete on all ports that were reset
Local0 = 10
While ((Local1 == 1 && WRC1 == 0 || Local2 == 1 && WRC2 == 0) ||
(Local3 == 1 && WRC3 == 0 || Local4 == 1 && WRC4 == 0))
{
If (Local0 == 0) {
Break
}
Local0--
Stall (10)
}
// Clear status bits in all ports
LPCL ()
}
Method (_PSC, 0, NotSerialized)
{
Return (^D0D3)
}
Method (_PS0, 0, Serialized)
{
If (^DVID == 0xFFFF) {
Return ()
}
If (^XMEM == 0xFFFF || ^XMEM == 0) {
Return ()
}
OperationRegion (XREG, SystemMemory, (^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
Local0 = ^D0D3
if (Local0 == 3) {
^D0D3 = 0
}
#if CONFIG(INTEL_LYNXPOINT_LP)
// Clear PCI 0xB0[14:13]
^MB13 = 0
^MB14 = 0
// Clear MMIO 0x816C[14,2]
CLK0 = 0
CLK1 = 0
// Set MMIO 0x8154[31]
CLK2 = 1
// Handle per-port reset if needed
LPS0 ()
// Set MMIO 0x80e0[15]
AX15 = 1
#else
// Set MMIO 0x8154[31]
CLK2 = 1
#endif
Return ()
}
Method (_PS3, 0, Serialized)
{
If (^DVID == 0xFFFF) {
Return ()
}
If (^XMEM == 0xFFFF || ^XMEM == 0) {
Return ()
}
OperationRegion (XREG, SystemMemory, (^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
}
^PMES = 1 // Clear PME Status
^PMEE = 1 // Enable PME
// If device is in D3, set back to D0
Local0 = ^D0D3
if (Local0 == 3) {
^D0D3 = 0
}
#if CONFIG(INTEL_LYNXPOINT_LP)
// Set PCI 0xB0[14:13]
^MB13 = 1
^MB14 = 1
// Set MMIO 0x816C[14,2]
CLK0 = 1
CLK1 = 1
// Clear MMIO 0x8154[31]
CLK2 = 0
// Clear MMIO 0x80e0[15]
AX15 = 0
#else
// Clear MMIO 0x8154[31]
CLK2 = 0
#endif
// Put device in D3
^D0D3 = 3
Return ()
}
Name (_PRW, Package () { DEFAULT_PRW_VALUE, 3 })
// Leave USB ports on for to allow Wake from USB
Method (_S3D, 0) // Highest D State in S3 State
{
Return (3)
}
Method (_S4D, 0) // Highest D State in S4 State
{
Return (3)
}
Device (HUB7)
{
Name (_ADR, 0)
// GPLD: Generate Port Location Data (PLD)
Method (GPLD, 1, Serialized) {
Name (PCKG, Package () {
Buffer (0x10) {}
})
// REV: Revision 2 for ACPI 5.0
CreateField (DerefOf (PCKG [0]), 0, 7, REV)
REV = 2
// VISI: Port visibility to user per port
CreateField (DerefOf (PCKG [0]), 0x40, 1, VISI)
VISI = Arg0
Return (PCKG)
}
Device (PRT1) { Name (_ADR, 1) } // USB Port 0
Device (PRT2) { Name (_ADR, 2) } // USB Port 1
Device (PRT3) { Name (_ADR, 3) } // USB Port 2
Device (PRT4) { Name (_ADR, 4) } // USB Port 3
Device (PRT5) { Name (_ADR, 5) } // USB Port 4
Device (PRT6) { Name (_ADR, 6) } // USB Port 5
Device (PRT7) { Name (_ADR, 7) } // USB Port 6
Device (SSP1) { Name (_ADR, 10) } // USB Port 10
Device (SSP2) { Name (_ADR, 11) } // USB Port 11
Device (SSP3) { Name (_ADR, 12) } // USB Port 12
Device (SSP4) { Name (_ADR, 13) } // USB Port 13
}
}