527 lines
21 KiB
Plaintext
527 lines
21 KiB
Plaintext
/** @file
|
|
ACPI PD SSDT table for the platform has EC-less PD
|
|
|
|
@copyright
|
|
INTEL CONFIDENTIAL
|
|
Copyright 2020 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 rules:
|
|
// - Print debug message in the beginning and end of each function method with "[USBC] xxx Start" and "[USBC] xxx End"
|
|
// - All local variables and parameters must be dumped at the beginning and right before exit the call
|
|
// - All dumps should give full messages instead of simple ACPI name
|
|
// - All timeout must be specified with interval in comment and print
|
|
|
|
|
|
// GPRV is a PS_ON control method implemented in ACPI RTD3 SSDT table
|
|
// for veto : GPRV (2, 1)
|
|
// for allowing PD PS_ON : GPRV (2, 0)
|
|
// the first parameter (2) is an interface index for all commands from USBC PD
|
|
// the second parameter (either 1 or 0) is for disabling or enabling PS_ON
|
|
External (\GPRV, MethodObj) // PS_ON control method
|
|
// PCH lib imports
|
|
External (\PSOS, MethodObj) // PS_ON status method
|
|
External (\PSON, IntObj) // Indicates if PS_ON is enabled
|
|
|
|
External (\_SB.SGOV, MethodObj)
|
|
External (\_SB.GGOV, MethodObj)
|
|
External (\_SB.GGIV, MethodObj)
|
|
|
|
// External declarations for optional objects.
|
|
// Defined by board specific code or in BIOS settings.
|
|
External (UCMS, IntObj)
|
|
External (PPOE, IntObj)
|
|
External (POVP, IntObj)
|
|
External (PSG1, IntObj)
|
|
External (PSG2, IntObj)
|
|
|
|
|
|
#define PSG1_ACTIVATE 1 // Active high
|
|
#define PSG1_DEACTIVATE 0
|
|
|
|
Name (PDLV, 0) // PD Level
|
|
// 0 - PD is not in PS_ON mode
|
|
// 1 - PD request not entering PS_ON mode
|
|
// 2 - PD is in PS_ON mode
|
|
Name (PDLK, 0) // PD Lock
|
|
// 0 - platform allows to exit PD PS_ON mode
|
|
// 1 - platform locks PD PS_ON mode state (power gating).
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Debug Methods //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// PDDP PD PS_ON Mode Debug Method for EC-less Design
|
|
Method (PDDP, 0, Serialized) {
|
|
}
|
|
|
|
// PDBG PD_PSON Debug Method
|
|
Method (PDBG, 0, Serialized) {
|
|
PDDP ()
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// PD PS_ON Mode Methods //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Method (PDOF, 0, Serialized) {
|
|
// ECless USBC Sx workaround
|
|
PDDP ()
|
|
|
|
// The feature is only available with EC-less PD design, hence UCMCx for PD must be enabled.
|
|
If (LEqual (UCMS, 2)) {
|
|
// Check if S0IX_EN_TRY_REQ is high,
|
|
// if not then pull high to push PD entering PS_ON state
|
|
If (LNotEqual (\_SB.GGOV (PSG1), PSG1_ACTIVATE)) {
|
|
// Pull PLX_SX_ENTRY_G1_PCH_N GPIO down to notify PD controller
|
|
\_SB.SGOV (PSG1, PSG1_ACTIVATE)
|
|
|
|
Store (0, Local0)
|
|
|
|
While (LLess (Local0, 100)) {// Timeout is 1 second
|
|
Sleep (10) // In ms
|
|
// Wait for S0IX_EN_TRY_ACK to high until timeout
|
|
If (LEqual (\_SB.GGIV (PSG2), PSG1_ACTIVATE)) {
|
|
Break
|
|
} Else {
|
|
Increment (Local0)
|
|
}
|
|
}
|
|
} else {
|
|
}
|
|
}
|
|
PDDP ()
|
|
}
|
|
|
|
Method (PDON) {
|
|
// ECless USBC Sx workaround
|
|
PDDP ()
|
|
|
|
// The feature is only available with EC-less PD design, hence UCMCx for PD must be enabled.
|
|
If (LEqual (UCMS, 2)) {
|
|
// Check if S0IX_EN_TRY_REQ is high,
|
|
// if yes then notify PD to exit PS_ON state
|
|
If (LEqual (\_SB.GGOV (PSG1), PSG1_ACTIVATE)) {
|
|
// Pull S0IX_EN_TRY_REQ GPIO to low to notify PD controller
|
|
\_SB.SGOV (PSG1, PSG1_DEACTIVATE)
|
|
|
|
Store (0, Local0)
|
|
While (LLess (Local0, 100)) { // Timeout is 1 second
|
|
Sleep (10)
|
|
|
|
// Wait for PD_SX_ACK_G2_FP_PCH to low until timeout
|
|
If (LEqual (\_SB.GGIV (PSG2), PSG1_DEACTIVATE)) {
|
|
Break
|
|
} Else {
|
|
// Time out in 1 sec
|
|
Increment (Local0)
|
|
}
|
|
}
|
|
} else {
|
|
}
|
|
}
|
|
PDDP ()
|
|
}
|
|
|
|
|
|
// In some platforms BIOS to PD handshake was limited to only Sx flows and handled during OSPM call to _PTS control method.
|
|
// In order to support PS_ON# during S0ix and still have legacy support for Sx, changes had to be made to the BIOS flow.
|
|
// The following section highlights the changes:
|
|
// - BIOS will configure USB controller and PCIe root port to which TBT controller is connected as a shared power resource package to OSPM.
|
|
// - The new method is invoked when USB controller is in D3 hot and PCIe downstream ports are in D3 cold state.
|
|
// - The high-level flow for entry and exit is described as below:
|
|
// Entry of the shared power resource package -
|
|
// - The entry of shared power resource package is only invoked by OSPM after USB host controller is in D3 hot and TBT downstream ports
|
|
// are in D3 cold, or OSPM invokes low power S0 idle entry indication as a strong hint.
|
|
// - In order to support better user experience, BIOS may allow PS_ON override check when the devices are in D3 and system is in S0
|
|
// yet to low power S0 idle.
|
|
// And when the devices are in D3 state and OSPM signaled low power S0 idle entry as well, BIOS can disable PS_ON override, proceed PD
|
|
// low power transition in case they don't want to support wake for bus powered devices.
|
|
//
|
|
//
|
|
// Handshaking is locked when PPEN is invoked back to back.
|
|
// Handshaking will be unblocked when S0ix exit is invoked.
|
|
//
|
|
//
|
|
// Power Sequence RTD3 Entry RTD3 Exit
|
|
//
|
|
// USBC_PSON_OVERRIDE_N
|
|
// (by PD, 0 means override enabled) 0 0
|
|
//
|
|
// Level - Before 0 1
|
|
//
|
|
// PS_ON State Veto No change
|
|
//
|
|
// Level - After 1 0
|
|
//
|
|
// Lock False False
|
|
//
|
|
// PLX_SX_ENTRY_G1_PCH
|
|
// (by BIOS, 1 means to request PD 0 0
|
|
// to PS_ON mode)
|
|
//
|
|
//
|
|
// Power Sequence RTD3 Entry MS Fun#5 RTD3 Exit RTD3 Entry MS Fun#6 RTD3 Exit (?? What if no??)
|
|
//
|
|
// USBC_PSON_OVERRIDE_N
|
|
// (by PD, 0 means override enabled) 0 0 0 0 0 0
|
|
//
|
|
// Level - Before 0 1 2 2 2 1
|
|
//
|
|
// PS_ON State Veto Restore No change No change No change No change
|
|
//
|
|
// Level - After 1 2 2 2 1 0
|
|
//
|
|
// Lock False True True True False False
|
|
//
|
|
// PLX_SX_ENTRY_G1_PCH
|
|
// (by BIOS, 1 means to request PD 0 1 1 1 1 0
|
|
// to PS_ON mode)
|
|
//
|
|
//
|
|
//
|
|
// Power Sequence MS Fun#5 RTD3 Entry MS Fun#6 RTD3 Exit RTD3 entry
|
|
//
|
|
// USBC_PSON_OVERRIDE_N
|
|
// (by PD, 0 means override enabled) 0 0 0 0 0
|
|
//
|
|
// Level - Before 0 1 2 1 0
|
|
//
|
|
// PS_ON State Veto Restore No change No change Veto
|
|
//
|
|
// Level - After 1 2 1 0 1
|
|
//
|
|
// Lock False True False False False
|
|
//
|
|
// PLX_SX_ENTRY_G1_PCH
|
|
// (by BIOS, 1 means to request PD 0 1 1 0 0
|
|
// to PS_ON mode)
|
|
//
|
|
//
|
|
//
|
|
// Power Sequence MS Fun#5 RTD3 Entry MS Fun#6 MS Fun#5
|
|
//
|
|
// USBC_PSON_OVERRIDE_N
|
|
// (by PD, 0 means override enabled) 0 0 0 0
|
|
//
|
|
// Level - Before 0 1 2 1
|
|
//
|
|
// PS_ON State Veto Restore No change No change
|
|
//
|
|
// Level - After 1 2 1 2
|
|
//
|
|
// Lock False True False True
|
|
//
|
|
// PLX_SX_ENTRY_G1_PCH
|
|
// (by BIOS, 1 means to request PD 0 1 1 1
|
|
// to PS_ON mode)
|
|
//
|
|
//
|
|
//
|
|
// Power Sequence RTD3 Entry RTD3 Exit
|
|
//
|
|
// USBC_PSON_OVERRIDE_N
|
|
// (by PD, 0 means override enabled) 1 1
|
|
//
|
|
// Level - Before 0 1
|
|
//
|
|
// PS_ON State No change No change
|
|
//
|
|
// Level - After 1 0
|
|
//
|
|
// Lock False False
|
|
//
|
|
// PLX_SX_ENTRY_G1_PCH
|
|
// (by BIOS, 1 means to request PD 1 0
|
|
// to PS_ON mode)
|
|
//
|
|
//
|
|
//
|
|
// Power Sequence RTD3 Entry MS Fun#5 RTD3 Exit RTD3 Entry MS Fun#6 RTD3 Exit (?? What if no??)
|
|
//
|
|
// USBC_PSON_OVERRIDE_N
|
|
// (by PD, 0 means override enabled) 1 1 1 1 1 1
|
|
//
|
|
// Level - Before 0 1 2 2 2 1
|
|
//
|
|
// PS_ON State No change No change No change No change No change No change
|
|
//
|
|
// Level - After 1 2 2 2 1 0
|
|
//
|
|
// Lock False True True True False False
|
|
//
|
|
// PLX_SX_ENTRY_G1_PCH
|
|
// (by BIOS, 1 means to request PD 1 1 1 1 1 0
|
|
// to PS_ON mode)
|
|
//
|
|
//
|
|
// Power Sequence MS Fun#5 RTD3 Entry MS Fun#6 RTD3 Exit RTD3 entry
|
|
//
|
|
// USBC_PSON_OVERRIDE_N
|
|
// (by PD, 0 means override enabled) 1 1 1 1 1
|
|
//
|
|
// Level - Before 0 1 2 1 0
|
|
//
|
|
// PS_ON State No change No change No change No change No change
|
|
//
|
|
// Level - After 1 2 1 0 1
|
|
//
|
|
// Lock False True False False False
|
|
//
|
|
// PLX_SX_ENTRY_G1_PCH
|
|
// (by BIOS, 1 means to request PD 1 1 1 0 1
|
|
// to PS_ON mode)
|
|
//
|
|
//
|
|
// Power Sequence MS Fun#5 RTD3 Entry MS Fun#6 MS Fun#5
|
|
//
|
|
// USBC_PSON_OVERRIDE_N
|
|
// (by PD, 0 means override enabled) 1 1 1 1
|
|
//
|
|
// Level - Before 0 1 2 1
|
|
//
|
|
// PS_ON State No change No change No change No change
|
|
//
|
|
// Level - After 1 2 1 2
|
|
//
|
|
// Lock False True False True
|
|
//
|
|
// PLX_SX_ENTRY_G1_PCH
|
|
// (by BIOS, 1 means to request PD 1 1 1 1
|
|
// to PS_ON mode)
|
|
//
|
|
|
|
// NCS1 Method
|
|
Method (NCS1, 0, Serialized) {
|
|
|
|
If (LEqual (PSON, 1)) {
|
|
PDOF ()
|
|
} else {
|
|
}
|
|
|
|
GPRV (2, 0) // Allow PS_ON# (restore)
|
|
}
|
|
|
|
// XCS1 Method
|
|
Method (XCS1, 0, Serialized) {
|
|
PDON ()
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// PD PS ON Override Methods //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// PPEN PD PSON Entry Method
|
|
// When ENABLE_OVERRIDE (BIOS option) is enabled by platform, BIOS checks if USBC_PSON_OVERRIDE_N is asserted by PD to override PS_ON.
|
|
// - If USBC_PSON_OVERRIDE_N (PD signal) is asserted, which means "PD PS_ON override" is requested by PD, then BIOS override(veto) PS_ON#.
|
|
// - If USBC_PSON_OVERRIDE_N (PD signal) is deasserted, then continue with PD handshake to request PD transit to PS_ON state.
|
|
// # Assert PLX_SX_ENTRY_G1_PCH_N to high
|
|
// # Wait for PD_SX_ACK_G2_PCH being pulled high by PD or until timeout
|
|
//
|
|
// Moreover, in order to support better user experience, BIOS may allow PS_ON override check when (1) the devices are in D3 and system is in S0
|
|
// yet to low power S0 idle or (2) the devices are still in D0 while OSPM gives low power S0 idle entry notification.
|
|
// And when the devices are in D3 state and OSPM signaled low power S0 idle entry as well, BIOS can disable PS_ON override, proceed PD
|
|
// PS_ON transition in case they don't want to support wake for bus powered devices. Each one condition upgrade one level
|
|
// (starting from 0). Once both conditions are satisfied, enforce PD to PS_ON state to support PS_ON unless platform disables
|
|
// PD PS_ON support.
|
|
|
|
Method (PPEN, 0, Serialized) {
|
|
PDBG ()
|
|
|
|
Switch (ToInteger(PDLV)) {
|
|
Case (0) { // This is new cycle of PD PS_ON flow
|
|
|
|
Increment (PDLV) // Level++
|
|
// POVP is the GPIO pin for USBC_PSON_OVERRIDE_N
|
|
// PPOE is the BIOS setting for PD PS_ON Enable
|
|
// PPOE = 0 : PD PS_ON disable
|
|
// PPOE = 1 : PD PS_ON enable
|
|
// PPOE = 2 : PD PS_ON enable with override enable
|
|
If (LAnd (LEqual (PPOE, 2), LEqual (\_SB.GGIV (POVP), 0))) {
|
|
// PD requests to override(veto) PS_ON
|
|
GPRV (2, 1) // Veto PS_ON#
|
|
Break
|
|
} else {
|
|
// PD doesn't request to override(veto) PS_ON
|
|
// Continue to PD PS_ON enable
|
|
NCS1 ()
|
|
Break
|
|
}
|
|
}
|
|
Case (1) {
|
|
NCS1 ()
|
|
Increment (PDLV) // Level++
|
|
Store (1, PDLK) // Lock the PD PS_ON override for this group
|
|
Break
|
|
}
|
|
Default {
|
|
If (LEqual (PDLK, 0)) {
|
|
}
|
|
}
|
|
}
|
|
|
|
PDBG ()
|
|
Return (PDLV)
|
|
}
|
|
|
|
// PPEX PD PSON Exit Method
|
|
// When ENABLE_OVERRIDE (BIOS option) is enabled by platform, BIOS checks if PLX_SX_ENTRY_G1_PCH_N (PD signal) is low. If it is, which means
|
|
// "PD PS_ON" was entered, then BIOS notify PD to exit PS_ON mode as following
|
|
// - BIOS pulls PLX_SX_ENTRY_G1_PCH_N to high.
|
|
// - BIOS wait for PD_SX_ACK_G2_PCH being pulled to low by PD or until timeout.
|
|
//
|
|
// Moreover, in order to support better user experience, BIOS may wait for PD response in USB and PCIe RP _PS0 while PD delay introduce
|
|
// responsiveness impact.
|
|
|
|
Method (PPEX, 0, Serialized) {
|
|
PDBG ()
|
|
|
|
If (LEqual (PDLK, 1)) {
|
|
Return (PDLV)
|
|
}
|
|
|
|
Switch (ToInteger (PDLV)) {
|
|
Case (0) { // This is new cycle of PD PS_ON flow
|
|
Break
|
|
}
|
|
|
|
Case (1) {
|
|
XCS1 () // remove this when the "break" issue will be fixed
|
|
Decrement (PDLV)
|
|
Break
|
|
}
|
|
|
|
Case (2) {
|
|
Decrement (PDLV)
|
|
Break
|
|
}
|
|
Default {
|
|
If (LEqual (PDLK, 0)) {
|
|
}
|
|
}
|
|
}
|
|
|
|
PDBG ()
|
|
Return (PDLV)
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// PD PS_ON Low Power S0 idle Method //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// PSLI PD PS_ON Low Power S0 idle Method
|
|
// Invoke the method by Low Power S0 idle Entry Notification
|
|
//
|
|
// Input: Arg0 -> Low Power S0 idle function#
|
|
// If Arg0 = 5, execute low power S0 idle entry notification
|
|
// If Arg0 = 6, execute low power S0 idle exit notification
|
|
|
|
Method (PSLI, 1, Serialized) {
|
|
Switch (ToInteger (Arg0)) {
|
|
Case (5) {
|
|
If (LLess (PDLV, 1)) {
|
|
Store (1, PDLV)
|
|
}
|
|
PPEN ()
|
|
}
|
|
Case (6) {
|
|
Store (0, PDLK) // Unlock the PD PS_ON override for this group
|
|
Store (1, PDLV)
|
|
PPEX ()
|
|
}
|
|
Default {
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// PD PS_ON Sleep Method //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// PSLP PD PS_ON Sleep Method
|
|
// Invoke the method by Sleep Entry Notification
|
|
//
|
|
// Input: Arg0 -> Sleep type, not used now; placeholder
|
|
|
|
Method (PSLP, 1, Serialized) {
|
|
Store (1, PDLV)
|
|
PPEN ()
|
|
|
|
// Reset this group for next Sx exit
|
|
Store (0, PDLV)
|
|
Store (0, PDLK)
|
|
}
|
|
|
|
|
|
// A group includes a PCIe RP where the TBT controller connected to, and a set of USB2/3 port or xHCI
|
|
// Each group has unique variable to manage the PD PS_ON flow
|
|
|
|
Name (PDSA, 0x1) // PD State; variable to save power state
|
|
// 0 - PD PS_ON request sent, PD is in PS_ON mode
|
|
// 1 - PD PS_ON request cleared
|
|
|
|
PowerResource (PDPG,
|
|
0,
|
|
0) // Turn on second, turn off second to last
|
|
{
|
|
|
|
Method (_STA, 0)
|
|
{
|
|
Return (PDSA)
|
|
}
|
|
|
|
Method (_ON)
|
|
{
|
|
PPEX ()
|
|
if (LEqual (PDLV, 0)) {
|
|
Store (1, PDSA) // PD is not in PS_ON mode
|
|
}
|
|
}
|
|
|
|
Method (_OFF)
|
|
{
|
|
PPEN ()
|
|
if (LEqual (PDLV, 2)) {
|
|
Store (0, PDSA) // PD is in PS_ON mode
|
|
}
|
|
}
|
|
} // End PowerResource (PDPG)
|