/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * The PCI-SIG engineering change requirement provides the ACPI additions for firmware latency * optimization. Both of FW_RESET_TIME and FW_D3HOT_TO_D0_TIME are applicable to the upstream * port of the USB4/TBT topology. */ /* Number of microseconds to wait after a conventional reset */ #define FW_RESET_TIME 50000 /* Number of microseconds to wait after data link layer active report */ #define FW_DL_UP_TIME 1 /* Number of microseconds to wait after a function level reset */ #define FW_FLR_RESET_TIME 1 /* Number of microseconds to wait from D3 hot to D0 transition */ #define FW_D3HOT_TO_D0_TIME 50000 /* Number of microseconds to wait after setting the VF enable bit */ #define FW_VF_ENABLE_TIME 1 OperationRegion (PXCS, SystemMemory, BASE(_ADR), 0x800) Field (PXCS, AnyAcc, NoLock, Preserve) { VDID, 32, Offset(0x50), /* LCTL - Link Control Register */ L0SE, 1, /* 0, L0s Entry Enabled */ , 3, LDIS, 1, /* 1, Link Disable */ , 3, Offset(0x52), /* LSTS - Link Status Register */ , 13, LASX, 1, /* 0, Link Active Status */ Offset(0x5A), /* SLSTS[7:0] - Slot Status Register */ ABPX, 1, /* 0, Attention Button Pressed */ , 2, PDCX, 1, /* 3, Presence Detect Changed */ , 2, PDSX, 1, /* 6, Presence Detect State */ , 1, DLSC, 1, /* 8, Data Link Layer State Changed */ Offset(0x60), /* RSTS - Root Status Register */ , 16, PSPX, 1, /* 16, PME Status */ Offset(0xA4), D3HT, 2, /* Power State */ Offset(0xD8), /* 0xD8, MPC - Miscellaneous Port Configuration Register */ , 30, HPEX, 1, /* 30, Hot Plug SCI Enable */ PMEX, 1, /* 31, Power Management SCI Enable */ Offset(0xE2), /* 0xE2, RPPGEN - Root Port Power Gating Enable */ , 2, L23E, 1, /* 2, L23_Rdy Entry Request (L23ER) */ L23R, 1, /* 3, L23_Rdy to Detect Transition (L23R2DT) */ Offset(0x420), /* 0x420, PCIEPMECTL (PCIe PM Extension Control) */ , 30, DPGE, 1, /* PCIEPMECTL[30]: Disabled, Detect and L23_Rdy State PHY Lane */ /* Power Gating Enable (DLSULPPGE) */ Offset(0x5BC), /* 0x5BC, PCIE ADVMCTRL */ , 3, RPER, 1, /* RTD3PERST[3] */ RPFE, 1, /* RTD3PFETDIS[4] */ } Field (PXCS, AnyAcc, NoLock, WriteAsZeros) { Offset(0xDC), /* 0xDC, SMSCS - SMI/SCI Status Register */ , 30, HPSX, 1, /* 30, Hot Plug SCI Status */ PMSX, 1 /* 31, Power Management SCI Status */ } /* * _DSM Device Specific Method * * Arg0: UUID Unique function identifier * Arg1: Integer Revision Level * Arg2: Integer Function Index (0 = Return Supported Functions) * Arg3: Package Parameters */ Method (_DSM, 4, Serialized) { Return (Buffer() { 0x00 }) } /* * A bitmask of functions support */ Name(OPTS, Buffer(2) {0, 0}) Device (PXSX) { Name (_ADR, 0x00000000) /* * _DSM Device Specific Method * * Arg0: UUID: E5C937D0-3553-4d7a-9117-EA4D19C3434D * Arg1: Revision ID: 3 * Arg2: Function index: 0, 9 * Arg3: Empty package */ Method (_DSM, 4, Serialized) { If (Arg0 == ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D")) { If (Arg1 >= 3) { If (Arg2 == 0) { /* * Function index: 0 * Standard query - A bitmask of functions supported */ CreateBitField(OPTS, 9, FUN9) FUN9 = 1 Return (OPTS) } ElseIf (Arg2 == 9) { /* * Function index: 9 * Specifying device readiness durations */ Return (Package() { FW_RESET_TIME, FW_DL_UP_TIME, FW_FLR_RESET_TIME, FW_D3HOT_TO_D0_TIME, FW_VF_ENABLE_TIME }) } } } Return (Buffer() { 0x0 }) } Method (_PRW, 0) { Return (Package() { 0x69, 4 }) } } Method (_DSW, 3) { /* If entering Sx (Arg1 > 1), need to skip TCSS D3Cold & TBT RTD3/D3Cold. */ If ((TUID == 0) || (TUID == 1)) { \_SB.PCI0.TDM0.SD3C = Arg1 } Else { \_SB.PCI0.TDM1.SD3C = Arg1 } C2PM (Arg0, Arg1, Arg2, DCPM) } Method (_PRW, 0) { Return (Package() { 0x69, 4 }) } /* * Sub-Method of _L61 Hot-Plug event * _L61 event handler should invoke this method to support HotPlug wake event from TBT RP. */ Method (HPEV, 0, Serialized) { If ((VDID != 0xFFFFFFFF) && HPSX) { If ((PDCX == 1) && (DLSC == 1)) { /* Clear all status bits first. */ PDCX = 1 HPSX = 1 /* Perform proper notification to the OS. */ Notify (^, 0) } Else { /* False event. Clear Hot-Plug Status, then exit. */ HPSX = 1 } } } /* * Power Management routine for D3 */ Name (STAT, 0x1) /* Variable to save power state 1 - D0, 0 - D3C */ /* * RTD3 Exit Method to bring TBT controller out of RTD3 mode. */ Method (D3CX, 0, Serialized) { If (STAT == 0x1) { Return } RPFE = 0 /* Set RTD3PFETDIS = 0 */ RPER = 0 /* Set RTD3PERST = 0 */ L23R = 1 /* Set L23r2dt = 1 */ /* * Poll for L23r2dt == 0. Wait for transition to Detect. */ Local0 = 0 Local1 = L23R While (Local1) { If (Local0 > 20) { Break } Sleep(5) Local0++ Local1 = L23R } STAT = 0x1 } /* * RTD3 Entry method to enable TBT controller RTD3 mode. */ Method (D3CE, 0, Serialized) { If (STAT == 0x0) { Return } L23E = 1 /* Set L23er = 1 */ /* Poll until L23er == 0 */ Local0 = 0 Local1 = L23E While (Local1) { If (Local0 > 20) { Break } Sleep(5) Local0++ Local1 = L23E } STAT = 0 /* D3Cold */ RPFE = 1 /* Set RTD3PFETDIS = 1 */ RPER = 1 /* Set RTD3PERST = 1 */ } Method (_PS0, 0, Serialized) { HPEV () /* Check and handle Hot Plug SCI status. */ If (HPEX == 1) { HPEX = 0 /* Disable Hot Plug SCI */ } HPME () /* Check and handle PME SCI status */ If (PMEX == 1) { PMEX = 0 /* Disable Power Management SCI */ } } Method (_PS3, 0, Serialized) { /* Check it is hotplug SCI or not, then clear PDC accordingly */ If (PDCX == 1) { If (DLSC == 0) { /* Clear PDC since it is not a hotplug. */ PDCX = 1 } } If (HPEX == 0) { HPEX = 1 /* Enable Hot Plug SCI. */ HPEV () /* Check and handle Hot Plug SCI status. */ } If (PMEX == 0) { PMEX = 1 /* Enable Power Management SCI. */ HPME () /* Check and handle PME SCI status. */ } } Method (_S0W, 0x0, NotSerialized) { #if !CONFIG(SOC_INTEL_ALDERLAKE_S3) Return (0x4) #else Return (0x3) #endif } Method (_PR0) { #if !CONFIG(SOC_INTEL_ALDERLAKE_S3) If ((TUID == 0) || (TUID == 1)) { Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT0 }) } Else { Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT1 }) } #else If ((TUID == 0) || (TUID == 1)) { Return (Package() { \_SB.PCI0.TBT0 }) } Else { Return (Package() { \_SB.PCI0.TBT1 }) } #endif } Method (_PR3) { #if !CONFIG(SOC_INTEL_ALDERLAKE_S3) If ((TUID == 0) || (TUID == 1)) { Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT0 }) } Else { Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT1 }) } #else If ((TUID == 0) || (TUID == 1)) { Return (Package() { \_SB.PCI0.TBT0 }) } Else { Return (Package() { \_SB.PCI0.TBT1 }) } #endif } /* * PCI_EXP_STS Handler for PCIE Root Port */ Method (HPME, 0, Serialized) { If ((VDID != 0xFFFFFFFF) && (PMSX == 1)) { /* if port exists and PME SCI Status set */ /* * Notify child device; this will cause its driver to clear PME_Status from * device. */ Notify (PXSX, 0x2) PMSX = 1 /* clear rootport's PME SCI status */ /* * Consume one pending PME notification to prevent it from blocking the queue. */ PSPX = 1 Return (0x01) } Return (0x00) }