blob: 5fa1a9774e883df432d7af6d66458e815fe10858 [file] [log] [blame]
/**
* @file
*
* ALIB ASL library
*
*
*
* @xrefitem bom "File Content Label" "Release Content"
* @e project: AGESA
* @e sub-project: GNB
* @e \$Revision: 31805 $ @e \$Date: 2010-05-21 17:58:16 -0700 (Fri, 21 May 2010) $
*
*/
/*
*****************************************************************************
*
* Copyright (c) 2011, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Advanced Micro Devices, Inc. nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************
*
*/
External(\_SB.ALIC, MethodObj)
Name (varStartPhyLane, 0)
Name (varEndPhyLane, 0)
Name (varStartCoreLane, 0)
Name (varEndCoreLane, 0)
Name (varWrapperId, 0)
Name (varPortId, 0)
/*----------------------------------------------------------------------------------------*/
/**
* Set PCIe Bus Width
*
* Arg0 - Data Buffer
*/
Method (procPcieSetBusWidth, 1, NotSerialized) {
Store (Buffer (256) {}, Local7)
CreateWordField (Local7, 0x0, varReturnBufferLength)
CreateWordField (Local7, 0x2, varReturnBusWidth)
CreateByteField (Arg0, 0x2, varArgBusWidth)
//deternime correct lane bitmap (check for reversal) gate/ungate unused lanes
Store (3, varReturnBufferLength)
Store (varArgBusWidth, varReturnBusWidth)
return (Local7)
}
/*----------------------------------------------------------------------------------------*/
/**
* PCIe port hotplug
*
* Arg0 - Data Buffer
* Retval - Return buffer
*/
Method (procPciePortHotplug, 1, Serialized) {
Store ("PciePortHotplug Enter", Debug)
Store (DerefOf (Index (Arg0, 4)), varHotplugStateLocal0)
Store (DerefOf (Index (Arg0, 2)), varPortIndexLocal1)
Subtract (ShiftRight (varPortBdfLocal1, 3), 2, varPortIndexLocal1)
if (LEqual(varHotplugStateLocal0, 1)) {
// Enable port
Store (DEF_TRAINING_STATE_RELEASE_TRAINING, Local2)
} else {
// Disable port
Store (DEF_TRAINING_STATE_NOT_PRESENT, Local2)
}
Store (procPciePortTraining (varPortIndexLocal1, Local2), varHotplugStateLocal0)
Store (Buffer (10) {}, Local7)
CreateWordField (Local7, 0x0, varReturnBufferLength)
CreateByteField (Local7, 0x2, varReturnStatus)
CreateByteField (Local7, 0x3, varReturnDeviceStatus)
Store (0x4, varReturnBufferLength)
Store (0x0, varReturnStatus)
Store (varHotplugStateLocal0, varReturnDeviceStatus)
Store ("PciePortHotplug Exit", Debug)
return (Local7)
}
Name (varSpeedRequest, Buffer (10) {0,0,0,0,0,0,0,0,0,0})
/*----------------------------------------------------------------------------------------*/
/**
* Train PCIe port
*
*
* Arg0 - Port Index
* Arg1 - Initial state
*/
Method (procPciePortTraining, 2, Serialized) {
Store ("PciePortTraining Enter", Debug)
Store (DEF_HOTPLUG_STATUS_DEVICE_NOT_PRESENT, varResultLocal4)
Store (procPcieGetPortInfo (Arg0), Local7)
// Check if port supports basic hotplug
Store (DerefOf (Index (Local7, DEF_OFFSET_LINK_HOTPLUG)), varTempLocal1)
if (LNotEqual (varTempLocal1, DEF_BASIC_HOTPLUG)) {
Store (" No action.[Hotplug type]", Debug)
Store ("procPciePortTraining Exit", Debug)
return (varResultLocal4)
}
Store (Arg1, varStateLocal2)
while (LNotEqual (varStateLocal2, DEF_TRAINING_STATE_EXIT)) {
if (LEqual (varStateLocal2, DEF_TRAINING_STATE_RELEASE_TRAINING)) {
Store (" State: Release training", Debug)
// Remove link speed override
Store (0, Index (varOverrideLinkSpeed, Arg0))
// Enable link width upconfigure
procPciePortIndirectRegisterRMW (Arg0, 0xA2, Not (0x2000), 0x0000)
// Request Max link speed for hotplug by going to AC state
Store (0, varPsppAcDcOverride)
procApplyPsppState ()
// Power on/enable port lanes
procPcieLaneControl (Arg0, DEF_PCIE_LANE_POWERON)
// Release training
procPcieTrainingControl (Arg0, 0)
// Move to next state to check presence detection
Store (DEF_TRAINING_STATE_DETECT_PRESENCE, varStateLocal2)
// Initialize retry count
Store(0, varCountLocal3)
}
if (LEqual (varStateLocal2, DEF_TRAINING_STATE_DETECT_PRESENCE)) {
Store (" State: Detect presence", Debug)
And (procPciePortIndirectRegisterRead (Arg0, 0xa5), 0x3f, varTempLocal1)
if (LGreater (varTempLocal1, 0x4)) {
// device connection detected move to next state
Store (DEF_TRAINING_STATE_PRESENCE_DETECTED, varStateLocal2)
// reset retry counter
Store(0, varCountLocal3)
continue
}
if (LLess (varCountLocal3, 80)) {
Sleep (1)
Increment (varCountLocal3)
} else {
// detection time expired move to device not present state
Store (DEF_TRAINING_STATE_NOT_PRESENT, varStateLocal2)
}
}
if (LEqual (varStateLocal2, DEF_TRAINING_STATE_PRESENCE_DETECTED)) {
Store (" State: Device detected", Debug)
Store (procPciePortIndirectRegisterRead (Arg0, 0xa5), varTempLocal1)
And (varTempLocal1, 0x3f, varTempLocal1)
if (LEqual (varTempLocal1, 0x10)) {
Store (DEF_TRAINING_DEVICE_PRESENT, varStateLocal2)
continue
}
if (LLess (varCountLocal3, 80)) {
Sleep (1)
Increment (varCountLocal3)
continue
}
Store (DEF_TRAINING_STATE_NOT_PRESENT, varStateLocal2)
if (LEqual (DeRefOf (Index (varOverrideLinkSpeed, Arg0)), DEF_LINK_SPEED_GEN1)) {
// GEN2 workaround already applied but device not trained successfully move device not present state
continue
}
if (LEqual (procPcieCheckForGen2Workaround (Arg0), TRUE)) {
Store (" Request Gen2 workaround", Debug)
procPciePortIndirectRegisterRMW (Arg0, 0xA2, Not (0x2000), 0x2000)
Store (DEF_LINK_SPEED_GEN1, Index (varOverrideLinkSpeed, Arg0))
procPcieSetLinkSpeed (Arg0, DEF_LINK_SPEED_GEN1)
Store (DEF_TRAINING_STATE_REQUEST_RESET, varStateLocal2)
}
}
if (LEqual (varStateLocal2, DEF_TRAINING_STATE_NOT_PRESENT)) {
Store (" State: Device not present", Debug)
procPcieTrainingControl (Arg0, 1)
procPcieLaneControl (Arg0, DEF_PCIE_LANE_POWEROFF)
// Exclude device from PSPP managment since it is not present
Store (DEF_LINK_SPEED_GEN1, Index (varOverrideLinkSpeed, Arg0))
Store (DEF_TRAINING_STATE_COMPLETE, varStateLocal2)
}
if (LEqual (varStateLocal2, DEF_TRAINING_STATE_REQUEST_RESET)) {
Store (" State: Request Reset", Debug)
if (CondRefOf (\_SB.ALIC, Local6)) {
Store (" Call ALIC method", Debug)
//varTempLocal1 contain port BDF
Store(ShiftLeft (Add (Arg0, 2), 3), varTempLocal1)
\_SB.ALIC (varTempLocal1, 0)
Sleep (2)
\_SB.ALIC (varTempLocal1, 1)
Store (0, varCountLocal3)
Store (DEF_TRAINING_STATE_DETECT_PRESENCE, varStateLocal2)
continue
}
Store (DEF_TRAINING_STATE_NOT_PRESENT, varStateLocal2)
}
if (LEqual (varStateLocal2, DEF_TRAINING_DEVICE_PRESENT)) {
Store (" State: Device present", Debug)
Store (DEF_HOTPLUG_STATUS_DEVICE_PRESENT, varResultLocal4)
Store (DEF_TRAINING_STATE_COMPLETE, varStateLocal2)
procPcieLaneControl (Arg0, DEF_PCIE_LANE_POWEROFFUNUSED)
}
if (LEqual (varStateLocal2, DEF_TRAINING_STATE_COMPLETE)) {
Store (1, varPsppAcDcOverride)
procApplyPsppState ()
Store (DEF_TRAINING_STATE_EXIT, varStateLocal2)
}
}
Store ("PciePortTraining Exit", Debug)
return (varResultLocal4)
}
/*----------------------------------------------------------------------------------------*/
/**
* Lane control
*
* Arg0 - Port Index
* Arg1 - 0 - Power off all lanes / 1 - Power on all Lanes / 2 Power off unused lanes
*/
Method (procPcieLaneControl, 2, Serialized) {
Store ("PcieLaneControl Enter", Debug)
Store (Concatenate (" Arg0 : ", ToHexString (Arg0), varStringBuffer), Debug)
Store (Concatenate (" Arg1 : ", ToHexString (Arg1), varStringBuffer), Debug)
Store (procPcieGetPortInfo (Arg0), Local7)
#ifdef PCIE_PHY_LANE_POWER_GATE_SUPPORT
Store (DerefOf (Index (Local7, DEF_OFFSET_START_PHY_LANE)), varStartPhyLane)
Store (DerefOf (Index (Local7, DEF_OFFSET_END_PHY_LANE)), varEndPhyLane)
#endif
Store (DerefOf (Index (Local7, DEF_OFFSET_START_CORE_LANE)), varStartCoreLane)
Store (DerefOf (Index (Local7, DEF_OFFSET_END_CORE_LANE)), varEndCoreLane)
if (LEqual (Arg1, DEF_PCIE_LANE_POWEROFF)) {
procPcieLaneEnableControl (Arg0, varStartCoreLane, varEndCoreLane, 1)
#ifdef PCIE_PHY_LANE_POWER_GATE_SUPPORT
procPcieLanePowerControl (varStartPhyLane, varEndPhyLane, 1)
#endif
}
if (LEqual (Arg1, DEF_PCIE_LANE_POWERON)) {
#ifdef PCIE_PHY_LANE_POWER_GATE_SUPPORT
procPcieLanePowerControl (varStartPhyLane, varEndPhyLane, 0)
#endif
procPcieLaneEnableControl (Arg0, varStartCoreLane, varEndCoreLane, 0)
}
if (LNotEqual (Arg1, DEF_PCIE_LANE_POWEROFFUNUSED)) {
return (0)
}
Store (procPcieGetLinkWidth (Arg0, DEF_LINKWIDTH_ACTIVE), varActiveLinkWidthLocal2)
if (LLessEqual (procPcieGetLinkWidth (Arg0, DEF_LINKWIDTH_MAX_PHY), varActiveLinkWidthLocal2)) {
// Active link equal max link width, nothing needs to be done
return (0)
}
Store (procPcieIsPortReversed (Arg0), varIsReversedLocal1)
//There is unused lanes after device plugged
if (LEqual(varIsReversedLocal1, FALSE)) {
Store (" Port Not Reversed", Debug)
// Link not reversed
Add (varStartCoreLane, varActiveLinkWidthLocal2, Local3)
Store (varEndCoreLane, Local4)
} else {
// Link reversed
Store (" Port Reversed", Debug)
Subtract (varEndCoreLane, varActiveLinkWidthLocal2, Local4)
Store (varStartCoreLane, Local3)
}
procPcieLaneEnableControl (Arg0, Local3, Local4, 1)
#ifdef PCIE_PHY_LANE_POWER_GATE_SUPPORT
if (LGreater (varStartPhyLane, varEndPhyLane)) {
Store (varEndPhyLane, Local3)
Store (varStartPhyLane, Local4)
} else {
Store (varEndPhyLane, Local4)
Store (varStartPhyLane, Local3)
}
if (LEqual(varIsReversedLocal1, FALSE)) {
// Not reversed
Add (Local3, varActiveLinkWidthLocal2, Local3)
} else {
// Link reversed
Subtract (Local4, varActiveLinkWidthLocal2, Local4)
}
procPcieLanePowerControl (Local3, Local4, 1)
#endif
return (0)
}
/*----------------------------------------------------------------------------------------*/
/**
* Check if GEN2 workaround applicable
*
* Arg0 - Port Index
* Retval - TRUE / FALSE
*/
Method (procPcieCheckForGen2Workaround, 1, NotSerialized) {
Store (Buffer (16) {}, Local1)
Store (0x0, Local0)
while (LLessEqual (Local0, 0x3)) {
Store (procPciePortIndirectRegisterRead (Arg0, Add (Local0, 0xA5)), Local2)
Store (Local2, Index (Local1, Multiply (Local0, 4)))
Store (ShiftRight (Local2, 8), Index (Local1, Add (Multiply (Local0, 4), 1)))
Store (ShiftRight (Local2, 16), Index (Local1, Add (Multiply (Local0, 4), 2)))
Store (ShiftRight (Local2, 24), Index (Local1, Add (Multiply (Local0, 4), 3)))
Increment (Local0)
}
Store (0, Local0)
while (LLess (Local0, 15)) {
if (LAnd (LEqual (DeRefOf (Index (Local1, Local0)), 0x2a), LEqual (DeRefOf (Index (Local1, Add (Local0, 1))), 0x9))) {
return (TRUE)
}
Increment (Local0)
}
return (FALSE)
}
/*----------------------------------------------------------------------------------------*/
/**
* Is port reversed
*
* Arg0 - Port Index
* Retval - 0 - Not reversed / !=0 - Reversed
*/
Method (procPcieIsPortReversed , 1, Serialized) {
Store (procPcieGetPortInfo (Arg0), Local7)
Store (DerefOf (Index (Local7, DEF_OFFSET_START_PHY_LANE)), varStartPhyLane)
Store (DerefOf (Index (Local7, DEF_OFFSET_END_PHY_LANE)), varEndPhyLane)
Store (0, Local0)
if (LGreater (varStartPhyLane, varEndPhyLane)) {
Store (1, Local0)
}
And (procPciePortIndirectRegisterRead (Arg0, 0x50), 0x1, Local1)
return (And (Xor (Local0, Local1), 0x1))
}
/*----------------------------------------------------------------------------------------*/
/**
* Training Control
*
* Arg0 - Port Index
* Arg1 - Hold Training (1) / Release Training (0)
*/
Method (procPcieTrainingControl , 2, NotSerialized) {
Store ("PcieTrainingControl Enter", Debug)
Store (procPcieGetPortInfo (Arg0), Local7)
Store (DerefOf (Index (Local7, DEF_OFFSET_PORT_ID)), varPortId)
Store (
Or (ShiftLeft (DerefOf (Index (Local7, Add (DEF_OFFSET_WRAPPER_ID, 1))), 8), DerefOf (Index (Local7, DEF_OFFSET_WRAPPER_ID))),
varWrapperId
)
procIndirectRegisterRMW (0x0, 0xE0, Or (ShiftLeft (varWrapperId, 16), Add (0x800, Multiply (0x100, varPortId))), Not (0x1), Arg1);
Store ("PcieTrainingControl Exit", Debug)
}
Name (varLinkWidthBuffer, Buffer () {0, 1, 2, 4, 8, 12, 16})
/*----------------------------------------------------------------------------------------*/
/**
* Get actual negotiated/PHY or core link width
*
* Arg0 - Port Index
* Arg1 - 0/1 Negotiated/Phy
* Retval - Link Width
*/
Method (procPcieGetLinkWidth, 2, NotSerialized) {
Store ("PcieGetLinkWidth Enter", Debug)
Store (Concatenate (" Arg0 : ", ToHexString (Arg0), varStringBuffer), Debug)
Store (Concatenate (" Arg1 : ", ToHexString (Arg1), varStringBuffer), Debug)
if (LEqual (Arg1, DEF_LINKWIDTH_ACTIVE)){
//Get negotiated length
And (ShiftRight (procPciePortIndirectRegisterRead (Arg0, 0xA2), 4), 0x7, Local0)
Store (DeRefOf (Index (varLinkWidthBuffer, Local0)), Local1)
Store (Concatenate (" Active Link Width :", ToHexString (Local1), varStringBuffer), Debug)
} else {
//Get phy length
Store (procPcieGetPortInfo (Arg0), Local7)
Store (DerefOf (Index (Local7, DEF_OFFSET_START_PHY_LANE)), varStartPhyLane)
Store (DerefOf (Index (Local7, DEF_OFFSET_END_PHY_LANE)), varEndPhyLane)
if (LGreater (varStartPhyLane, varEndPhyLane)) {
Subtract (varStartPhyLane, varEndPhyLane, Local1)
} else {
Subtract (varEndPhyLane, varStartPhyLane, Local1)
}
Increment (Local1)
Store (Concatenate (" PHY Link Width :", ToHexString (Local1), varStringBuffer), Debug)
}
Store ("PcieGetLinkWidth Exit", Debug)
return (Local1)
}
/*----------------------------------------------------------------------------------------*/
/**
* PCIe lane mux lane enable control (hotplug support)
*
* Arg0 - Port Index
* Arg1 - Start Lane
* Arg2 - End Lane
* Arg3 - Enable(0) / Disable(1)
*/
Method (procPcieLaneEnableControl, 4, Serialized) {
Store ("PcieLaneEnableControl Enter", Debug)
Store (Concatenate (" Arg0 : ", ToHexString (Arg0), varStringBuffer), Debug)
Store (Concatenate (" Arg1 : ", ToHexString (Arg1), varStringBuffer), Debug)
Store (Concatenate (" Arg2 : ", ToHexString (Arg2), varStringBuffer), Debug)
Store (Concatenate (" Arg3 : ", ToHexString (Arg3), varStringBuffer), Debug)
Store (procPcieGetPortInfo (Arg0), Local7)
Store (Arg1, varStartCoreLane)
Store (Arg2, varEndCoreLane)
Store (
Or (ShiftLeft (DerefOf (Index (Local7, Add (DEF_OFFSET_WRAPPER_ID, 1))), 8), DerefOf (Index (Local7, DEF_OFFSET_WRAPPER_ID))),
varWrapperId
)
if (LGreater (varStartCoreLane, varEndCoreLane)) {
Subtract (varStartCoreLane, varEndCoreLane, Local1)
Store (varEndCoreLane, Local2)
} else {
Subtract (varEndCoreLane, varStartCoreLane, Local1)
Store (varStartCoreLane, Local2)
}
ShiftLeft (Subtract (ShiftLeft (1, Add (Local1, 1)), 1), Local2, varLaneBitmapOrMaskLocal3)
Store (Not (varLaneBitmapOrMaskLocal3), varLaneBitmapAndMaskLocal4)
Store (Concatenate ("Lane Bitmap : ", ToHexString (varLaneBitmapOrMaskLocal3), varStringBuffer), Debug)
if (Lequal (Arg3, 1)) {
Store (0, varLaneBitmapOrMaskLocal3)
}
procIndirectRegisterRMW (0x0, 0xE0, Or (ShiftLeft (varWrapperId, 16), 0x8023), varLaneBitmapAndMaskLocal4, varLaneBitmapOrMaskLocal3);
Stall (10)
Store ("PcieLaneEnableControl Exit", Debug)
}