alder_lake_bios/Intel/AlderLake/AlderLakeBoardPkg/Acpi/AcpiTables/SsdtRtd3/Rtd3PcieTbt.asl

633 lines
16 KiB
Plaintext

/** @file
ACPI RTD3 SSDT table for Thunderbolt
@copyright
INTEL CONFIDENTIAL
Copyright 2011 - 2021 Intel Corporation.
The source code contained or described herein and all documents related to the
source code ("Material") are owned by Intel Corporation or its suppliers or
licensors. Title to the Material remains with Intel Corporation or its suppliers
and licensors. The Material may contain trade secrets and proprietary and
confidential information of Intel Corporation and its suppliers and licensors,
and is protected by worldwide copyright and trade secret laws and treaty
provisions. No part of the Material may be used, copied, reproduced, modified,
published, uploaded, posted, transmitted, distributed, or disclosed in any way
without Intel's prior express written permission.
No license under any patent, copyright, trade secret or other intellectual
property right is granted to or conferred upon you by disclosure or delivery
of the Materials, either expressly, by implication, inducement, estoppel or
otherwise. Any license under such intellectual property rights must be
express and approved by Intel in writing.
Unless otherwise agreed by Intel in writing, you may not remove or alter
this notice or any other notice embedded in Materials by Intel or
Intel's suppliers or licensors in any way.
This file contains a 'Sample Driver' and is licensed as such under the terms
of your license agreement with Intel or your vendor. This file may be modified
by the user, subject to the additional terms of the license agreement.
@par Specification Reference:
**/
/// @details
/// Code in this file uses following variables:
/// SCLK: ICC Clock number - optional
/// WAKG: WAKE GPIO pad - optional
/// Below objects should be defined according to the format described in PinDriverLib.asl
/// RSTG: reset pin definition - mandatory
/// PWRG: power GPIO pad - optional
/// WAKP: Flag to indicate that power gating must not be performed if WAKE is enabled - optional
/// @defgroup pcie_scope PCIe Root Port Scope **/
#define DTBT_TYPE_PCH 0x01
#define TBT_DATA_WIDTH 4 // This represent DATA WIDTH for Each TBT Controller in a Variable
External(\MMRP, MethodObj)
External(\MMTB, MethodObj)
External(PDOF, MethodObj)
External(PDON, MethodObj)
External(\TVCF, MethodObj)
External(\TVRF, MethodObj)
//
// AcpiPinDriverLib imports(from DSDT in platform)
//
External(\PIN.STA, MethodObj)
External(\PIN.ON, MethodObj)
External(\PIN.OFF, MethodObj)
//
// GpioLib imports(DSDT)
//
External(\_SB.SHPO, MethodObj)
//
// HSIO lib imports
//
External(\_SB.PSD0, MethodObj)
External(\_SB.PSD3, MethodObj)
//
// External decalarations for optional objects.
// Defined by board specific code.
//
External(WAKG) //WAKE GPIO pad
External(PWRG)
External(SCLK)
External(WAKP)
External(TUID)
External(PSON)
External(TBDC)
External(NCB7)
External(LASX)
External(D3HT)
External(L23E)
External(L23R)
External(DPGE)
External(HPEX)
External(PMEX)
External(HPSX)
External(PMSX)
External(PDCX)
External(PDSX)
External(PSPX)
External(TRDO)
External(TRD3)
External(TBPE)
External(TOFF)
External(TEDC)
External(PCPB) // PCIe core power veto bitmask, default 0 - allow for core power removal
Name(G2SD, 0) // Go2Sx done, set by GO2S, cleaned by _ON
Name(RSTF, 0) // Reset Flag
Name(CSEN, 0) // If enable wait for RTD3 Exit command respond in _PS0() method
Name(PSHR, 0) // Global Variable to Save Power State Value of TBT HR
Name(WKEN, 0) // WAKE enable on PCIe device.
Method(_S0W, 0, Serialized) {
Return(4)
}
//
// TBT Debug Method - Scan hierarchy
//
Method(TSCH, 0, Serialized) {
Store (\MMTB (SLOT, DTBT_TYPE_PCH), Local7)
// TODO Make one generic copy
OperationRegion(TBDM, SystemMemory, Local7, 0x550)// TBT HR PCICFG MMIO
Field(TBDM,DWordAcc, NoLock, Preserve) {
DIVI, 32,
CMDR, 32,
Offset(0x84),
TBPS, 2, // PowerState of TBT
Offset(0x548),
TB2P, 32,
P2TB, 32
}
If(LNotEqual(VDID,0xFFFFFFFF)) {
}
If(LNotEqual(DIVI,0xFFFFFFFF)) {
}
Add(Local7, 0x00108000, Local7) // Advance 1 Bus 1 Dev No. Bus N+1 Device 1
OperationRegion(TDS0, SystemMemory, Local7, 0x100)// TBT DS0 PCICFG MMIO
Field(TDS0,DWordAcc, NoLock, Preserve) {
Offset (0),
P0ID, 32,
Offset(0xD0),
, 29,
LAI0, 1, // PCIe Link Active Indicator of DS port 0
Offset(0xD8),
, 19,
PDC0, 1, // PCIe Presence Detect Changed Indicator of DS port 0
, 2,
PDS0, 1, // PCIe Presence Detect State Indicator of DS port 0
}
If(LNotEqual(P0ID,0xFFFFFFFF)) {
}
Add(Local7, 0x00010000, Local7) // Advacne 2 Dev No. Bus N+1 Device 3
OperationRegion(TDS1, SystemMemory, Local7, 0x100)// TBT DS1 PCICFG MMIO
Field(TDS1,DWordAcc, NoLock, Preserve) {
Offset (0),
P1ID, 32,
Offset(0xD0),
, 29,
LAI1, 1, // PCIe Link Active Indicator of DS port 1
Offset(0xD8),
, 19,
PDC1, 1, // PCIe Presence Detect Changed Indicator of DS port 1
, 2,
PDS1, 1, // PCIe Presence Detect State Indicator of DS port 1
}
If(LNotEqual(P1ID,0xFFFFFFFF)) {
}
TVAL()
}
//
// TBT Debug Method - Dump All Variables
//
Method(TVAL, 0, Serialized) {
}
Method (PPS0, 0, Serialized) { // Platform specific PCIe root port _PS0 Hook Function.
TSCH()
if (LEqual (CSEN, 1)) {
Store (\MMRP (SLOT, DTBT_TYPE_PCH), Local7)
OperationRegion(L23P,SystemMemory,Local7,0x100)
Field(L23P,WordAcc, NoLock, Preserve)
{
Offset(0xA4),// PMCSR
D3HT, 2, // PowerState
}
CSPL ()
Store (0, CSEN) // Disable _PS0 once called
Store (PSHR, D3HT) // Store Back D3HT value
Store (0, PSHR)
}
TSCH()
}
Method(PPS3, 0, Serialized) { // Platform specific PCIe root port _PS3 Hook Function.
TSCH()
}
Method (_DSD, 0) {
Return (
Package () {
ToUUID("6211E2C0-58A3-4AF3-90E1-927A4E0C55A4"),
Package () {
Package (2) {"HotPlugSupportInD3", 1},
},
ToUUID("EFCC06CC-73AC-4BC3-BFF0-76143807C389"),
Package () {
Package (2) {"ExternalFacingPort", 1}, // Property 1: This is a TBT/CIO port
Package (2) {"UID", TUID}, // Property 2: UID of the TBT RP on platform, range is: 0, 1, ..., NumOfTBTRP - 1
}
}
) // End of Return ()
}
Method(_DSW, 3)
{
/// This method is used to enable/disable wake from PCIe (WKEN)
If (LGreaterEqual(Arg1, 1)) { /// If entering Sx, need to disable WAKE# from generating runtime PME also set 2 to TOFF.
Store(0, WKEN)
Store (TVCF (TUID, 2, TBT_DATA_WIDTH, TOFF), TOFF)
} Else { /// If Staying in S0
If(LAnd(Arg0, Arg2)) ///- Check if Exiting D0 and arming for wake
{ ///- Set PME
Store (1, WKEN)
Store (TVCF (TUID, 1, TBT_DATA_WIDTH, TOFF), TOFF)
} Else { ///- Disable runtime PME, either because staying in D0 or disabling wake
Store (0, WKEN)
Store (TVCF (TUID, 0, TBT_DATA_WIDTH, TOFF), TOFF)
}
}
/** @defgroup pcie_dsw PCIE _DSW **/
} // End _DSW
//
// PCIe slot power resource definition
//
PowerResource(PXP, 0, 0) {
Method(_STA, 0) {
If (LEqual (VDID, 0xFFFFFFFF)) {
Return(0)
}
Return(PSTA())
}
Method(_ON) {
//Store (TVCF (TUID, 1, TBT_DATA_WIDTH, TRDO), TRDO)
TSCH()
PON()
//Store (TVCF (TUID, 0, TBT_DATA_WIDTH, TRDO), TRDO)
TSCH()
}
Method(_OFF) {
//Store (TVCF (TUID, 0, TBT_DATA_WIDTH, TRD3), TRD3)
TSCH()
POFF()
//Store (TVCF (TUID, 1, TBT_DATA_WIDTH, TRD3), TRD3)
TSCH()
}
}
//
// Returns the status of PCIe slot core power
//
Method(PSTA, 0) {
//
// RESET# assertion is mandatory for PCIe RTD3
// So if RESET# is asserted the whole slot is off
//
If(\PIN.STA(RSTG)) {
Return(0)
} Else {
Return (1)
}
}
Method (CSEX, 0, Serialized) {
Store (\MMTB (SLOT, DTBT_TYPE_PCH), Local7)
OperationRegion(TBDI, SystemMemory, Local7, 0x550)// TBT HR PCICFG MMIO
Field(TBDI,DWordAcc, NoLock, Preserve) {
DIVI, 32,
CMDR, 32,
Offset(0x548),
TB2P, 32,
P2TB, 32
}
Store(200, Local1)
Store(0x0209, P2TB) // Write SX_EXIT_TBT_CONNECTED to PCIe2TBT with Data parameter = 0x02 (TBT RTD3 EXIT Command)
While (LGreater(Local1, 0)) {
Store(Subtract(Local1, 1), Local1)
Store(TB2P, Local2)
If(LAnd(LEqual(Local2, 0xFFFFFFFF), LEqual(Local1, 0x1))) // Device gone
{
Return(0)
}
If(LAnd(LNotEqual(Local2, 0xFFFFFFFF), And(Local2, 1))) // Done
{
break
}
Sleep(5)
}
Store(0x0, P2TB) // Write 0 to PCIe2TBT
Return (1)
} // End of Method(CSEX, 0, Serialized)
Method (CSPL, 0, Serialized) {
Store (\MMTB (SLOT, DTBT_TYPE_PCH), Local7)
OperationRegion(TBDI, SystemMemory, Local7, 0x550)// TBT HR PCICFG MMIO
Field(TBDI,DWordAcc, NoLock, Preserve) {
DIVI, 32,
CMDR, 32,
Offset(0x548),
TB2P, 32,
P2TB, 32
}
// Fast Link bring-up flow
Store(500, Local1)
While (LGreater(Local1, 0)) {
Store(Subtract(Local1, 1), Local1)
Store(TB2P, Local2)
If (LEqual(Local2, 0xFFFFFFFF)) {// Device gone
Return()
}
If (LNotEqual(DIVI, 0xFFFFFFFF)) {
break
}
Sleep(10)
}
} // End of Method(CSPL, 0, Serialized)
Method(PON, 0, Serialized) /// Turn on core power to PCIe Slot
{
Store (\MMTB (SLOT, DTBT_TYPE_PCH), Local6)
OperationRegion(TBDI, SystemMemory, Local6, 0x550)// TBT HR PCICFG MMIO
Field(TBDI,DWordAcc, NoLock, Preserve) {
DIVI, 32,
CMDR, 32,
Offset(0x84),
TBPS, 2, // PowerState of TBT
Offset(0x548),
TB2P, 32,
P2TB, 32
}
// Check RTD3 power enable, if already ON, no need to execute sx_exit
If (TVRF (TUID, TBT_DATA_WIDTH, TBPE)) {
Return()
}
Store(0,G2SD)
//
// dTBT special requirement on RTD3 exit:
// 1. Guarantee that PCIe clock is running - MR clock request is asserted and BIOS can unmask the request and plus custom delay.
// 2. Toggle RTD3 pin - This will indicate to MR that it can reset the PHY. Reset of the PHY requires a running clock.
// 3. After 10ms de-assert the PERST (same as done today)
//
//
// On RTD3 Exit, BIOS will instruct the PMC to Enable source clocks.
// This is done through sending a PMC IPC command.
//
If (CondRefOf (\DTRC)) {
If (\DTRC) {
/// de-assert CLK_REQ MSK
If (CondRefOf (SCLK)) {
SPCO (SCLK, 1)
}
If (CondRefOf (\DTRD)) {
Sleep (\DTRD)
}
}
}
/// Turn ON Power for PCIe Slot
If (CondRefOf (PWRG)) {
\PIN.ON (PWRG)
Sleep (PEP0)
}
/// De-Assert Reset Pin
\PIN.OFF(RSTG)
Store(0, RSTF) // Clear Reset Flag
Store(TVCF (TUID, 1, TBT_DATA_WIDTH, TBPE), TBPE)
L23D()
// Check if any TBT Endpoint Device was connected, if no TBT Endpoint Device is Connected, no need to execute sx_exit
If (LEqual (TVRF (TUID, TBT_DATA_WIDTH, TEDC), 0)) {
Return()
}
// TBT special sleep.
Store (D3HT, PSHR) // Save D3HT Value to PSHR Global Variable
Store (0, D3HT)// D0
Store (20, Local2) // Poll for TBT, up to 200 ms
While (LGreater(Local2, 0)) {
Store(Subtract(Local2, 1), Local2)
Store(TB2P, Local3)
If (LNotEqual(Local3, 0xFFFFFFFF)) { // Done
break
}
Sleep(10)
}
TSCH()
If (LLessEqual(Local2, 0)) {
}
If ( LEqual (CSEX(), 1)) {
If (CondRefOf (TBDC)) {
If (LGreater (TBDC, 0)) {
CSPL ()
} else {
Store (1, CSEN)
}
}
} // If ( LEqual (CSEX(), 1))
if (LEqual(CSEN, 0)) {
Store (PSHR, D3HT) // Store Back D3HT value
}
If(CondRefOf(PDON)) {
PDON()
}
} // End of ON
Method(POFF, 0, Serialized) { /// Turn off core power to PCIe Slot
If (LEqual (TVRF (TUID, TBT_DATA_WIDTH, TOFF), 0)) {
Return()
}
Store (\MMTB (SLOT, DTBT_TYPE_PCH), Local6)
OperationRegion(TBDI, SystemMemory, Local6, 0x550)// TBT HR PCICFG MMIO
Field(TBDI,DWordAcc, NoLock, Preserve) {
DIVI, 32,
CMDR, 32,
Offset(0x84),
TBPS, 2, // PowerState of TBT
Offset(0x548),
TB2P, 32,
P2TB, 32
}
Add(Local6, 0x00108000, Local6) // Advance 1 Bus 1 Dev No. Bus N+1 Device 1
OperationRegion(DSP0, SystemMemory, Local6, 0x100)// TBT DS0 PCICFG MMIO
Field(DSP0,DWordAcc, NoLock, Preserve) {
Offset (0),
P0ID, 32,
Offset(0xD0),
, 29,
LAI0, 1, // PCIe Link Active Indicator of DS port 0
Offset(0xD8),
, 19,
PDC0, 1, // PCIe Presence Detect Changed Indicator of DS port 0
, 2,
PDS0, 1, // PCIe Presence Detect State Indicator of DS port 0
}
Add(Local6, 0x00010000, Local6) // Advacne 2 Dev No. Bus N+1 Device 3
OperationRegion(DSP1, SystemMemory, Local6, 0x100)// TBT DS1 PCICFG MMIO
Field(DSP1,DWordAcc, NoLock, Preserve) {
Offset (0),
P1ID, 32,
Offset(0xD0),
, 29,
LAI1, 1, // PCIe Link Active Indicator of DS port 1
Offset(0xD8),
, 19,
PDC1, 1, // PCIe Presence Detect Changed Indicator of DS port 1
, 2,
PDS1, 1, // PCIe Presence Detect State Indicator of DS port 1
}
If (Lgreater(TVRF (TUID, TBT_DATA_WIDTH, TOFF), 1)) {
Store (TVCF (TUID, 0, TBT_DATA_WIDTH, TOFF), TOFF)
Store(1, RSTF) // Set Reset Flag
Return()
}
Store(D3HT, Local1)
Store(0, D3HT)// D0
Store(P2TB, Local3)
Store (TVCF (TUID, 0, TBT_DATA_WIDTH, TOFF), TOFF)
Sleep(10)
Store(TBPS, Local6)
Store(0, TBPS)
Sleep(10)
Store(PDS0, Local2) // Store Device Presence under DS0
Store(PDS1, Local3) // Store Device Presence under DS1
TSCH()
If(LAnd(LNotEqual(P0ID, 0xFFFFFFFF), LNotEqual(P1ID, 0xFFFFFFFF))) {
If(LOr(LEqual(PDC0, 1), LEqual(PDC1, 1))) {
Notify (^, 0)
Return()
}
}
// Updating TEDC value if any TBT Endpoint device is connected behind TUID TBT Controller.
Store (TVCF (TUID, Or (PDS0, PDS1), TBT_DATA_WIDTH, TEDC), TEDC)
Store(Local6, TBPS)
Store(Local1, D3HT) // Back to Local1
DL23()
// Assert Reset Pin
// Reset pin is mandatory for correct PCIe RTD3 flow
\PIN.ON(RSTG)
Store(1, RSTF) // Set Reset Flag
//
// On RTD3 entry, BIOS will instruct the PMC to disable source clocks.
// This is done through sending a PMC IPC command.
//
If (\DTRC) {
/// assert CLK_REQ MSK
If (CondRefOf (SCLK)) {
SPCO (SCLK, 0)
}
If (CondRefOf (\DTRD)) {
Sleep (\DTRD)
}
}
Sleep (10)
/// Power OFF for TBT
If(CondRefOf(PWRG)) {
// If WAKP has not been defined we can safely disable power.
// If WAKP is defined this slot does not supply device with auxilary power and we have to keep primary power
// to allow for WAKE. If WAKP is not equal to 0 and WKEN has been enabled do not disable the power.
If(CondRefOf (WAKP)) {
If(LOr(LEqual(WAKP, 0), LNot(WKEN))) {
If(CondRefOf(PCPB)) {
If(LEqual(PCPB, 0)) {
\PIN.OFF(PWRG)
}
}
Else
{
\PIN.OFF(PWRG)
}
} Else {
}
} Else {
If(CondRefOf(PCPB)) {
If(LEqual(PCPB, 0)) {
\PIN.OFF(PWRG)
}
}
Else
{
\PIN.OFF(PWRG)
}
}
}
// enable WAKE
If(CondRefOf (WAKG)) {
If(LAnd(LNotEqual(WAKG, 0), WKEN)) {
\_SB.SHPO(WAKG, 0)
}
}
Store(TVCF (TUID, 0, TBT_DATA_WIDTH, TBPE), TBPE)
If (LEqual(\DTOE, 0)) { // Optimization not enabled, Sleep (DTRO)
Sleep (\DTRO)
} Else {
If (LOr(LEqual(Local2, 1), LEqual(Local3, 1))) { // If there is a device present under DS0 or DS1, Sleep(DTRO)
Sleep (\DTRO)
} Else { // Otherwise, Sleep (1000)
Sleep (1000)
}
}
If(CondRefOf(PDOF)) {
If (PSON) {
PDOF()
}
}
} // End of Method_OFF
Method (NFRP, 0, Serialized) /// Notify root port
{
If (LEqual (VDID, 0xFFFFFFFF))
{
Return ()
}
Store (0, Local1)
Store (0, Local2)
If (LEqual (\DTFS, 0x01)) {// if Thunderbolt(TM) support is enabled
Store (0, HPEX) //Hot Plug SCI Disable
Store (0, PMEX) //Power Management SCI Enable
Notify (^, 0)
If (LEqual (PMSX, 1)) { //clear the PME SCI status bit
Store (1, Local2)
}
Notify (^, 2)
Store (1, Local1) // Enable clear status bit
}
If (LEqual (Local1, 1))
{
Store (1, HPSX)
If (LEqual (Local2, 1)) {
Store (1, PMSX)
}
}
}