blob: 951193a57ba30fe2ba15f684f710e11978e697af [file] [log] [blame]
/**
* @file
*
* ALIB ASL library
*
*
*
* @xrefitem bom "File Content Label" "Release Content"
* @e project: AGESA
* @e sub-project: GNB
* @e \$Revision: 65976 $ @e \$Date: 2012-02-27 22:24:12 -0600 (Mon, 27 Feb 2012) $
*
*/
/*
*****************************************************************************
*
* Copyright 2008 - 2012 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
*
* AMD is granting you permission to use this software (the Materials)
* pursuant to the terms and conditions of your Software License Agreement
* with AMD. This header does *NOT* give you permission to use the Materials
* or any rights under AMD's intellectual property. Your use of any portion
* of these Materials shall constitute your acceptance of those terms and
* conditions. If you do not agree to the terms and conditions of the Software
* License Agreement, please do not use any portion of these Materials.
*
* CONFIDENTIALITY: The Materials and all other information, identified as
* confidential and provided to you by AMD shall be kept confidential in
* accordance with the terms and conditions of the Software License Agreement.
*
* LIMITATION OF LIABILITY: THE MATERIALS AND ANY OTHER RELATED INFORMATION
* PROVIDED TO YOU BY AMD ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE,
* OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR USAGE OF TRADE.
* IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER
* (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS
* INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF AMD'S NEGLIGENCE,
* GROSS NEGLIGENCE, THE USE OF OR INABILITY TO USE THE MATERIALS OR ANY OTHER
* RELATED INFORMATION PROVIDED TO YOU BY AMD, EVEN IF AMD HAS BEEN ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE
* EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES,
* THE ABOVE LIMITATION MAY NOT APPLY TO YOU.
*
* AMD does not assume any responsibility for any errors which may appear in
* the Materials or any other related information provided to you by AMD, or
* result from use of the Materials or any related information.
*
* You agree that you will not reverse engineer or decompile the Materials.
*
* NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any
* further information, software, technical information, know-how, or show-how
* available to you. Additionally, AMD retains the right to modify the
* Materials at any time, without notice, and is not obligated to provide such
* modified Materials to you.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with
* "RESTRICTED RIGHTS." Use, duplication, or disclosure by the Government is
* subject to the restrictions as set forth in FAR 52.227-14 and
* DFAR252.227-7013, et seq., or its successor. Use of the Materials by the
* Government constitutes acknowledgement of AMD's proprietary rights in them.
*
* EXPORT ASSURANCE: You agree and certify that neither the Materials, nor any
* direct product thereof will be exported directly or indirectly, into any
* country prohibited by the United States Export Administration Act and the
* regulations thereunder, without the required authorization from the U.S.
* government nor will be used for any purpose prohibited by the same.
* ***************************************************************************
*
*/
External(\_SB.ALIC, MethodObj)
External(P80H)
Name (varStartPhyLane, 0)
Name (varEndPhyLane, 0)
Name (varStartCoreLane, 0)
Name (varEndCoreLane, 0)
Name (varWrapperId, 0)
Name (varPortId, 0)
Name (varMaxPhyLinkWidth, 0)
Name (varNormalizeLinkWidthBuffer, Buffer () {1, 2, 4, 4, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16})
/*----------------------------------------------------------------------------------------*/
/**
* Set PCIe Bus Width
*
* Arg0 - Data Buffer
*/
Method (procPcieSetBusWidth, 1, NotSerialized) {
Store ("procPcieSetBusWidth Enter", Debug)
Name (varClientBus, 0)
Name (varArgBusWidth, 0)
Store (0, varPortIndex)
Store (Buffer (10) {}, Local7)
//ClientId: WORD
//Bits 2-0: Function number.
//Bits 7-3: Device number.
//Bits 15-8: Bus number.
Store (DerefOf (Index (Arg0, 0x3)), varClientBus)
Store (DerefOf (Index (Arg0, 0x4)), varArgBusWidth)
Store (Concatenate (" Client Bus : ", ToHexString (varClientBus), varStringBuffer), Debug)
Store (Concatenate (" Arg Bus Width : ", ToHexString (varArgBusWidth), varStringBuffer), Debug)
Store (3, Index (Local7, 0x0)) // Return Buffer Length
Store (0, Index (Local7, 0x1)) // Return Buffer Length
Store (varArgBusWidth, Index (Local7, 0x2)) // Return BusWidth
// disable interface
return (Local7)
//deternime correct lane bitmap (check for reversal) gate/ungate unused lanes
// determine port index base on "Client ID"
while (LLessEqual (varPortIndex, varMaxPortIndexNumber)) {
if (LEqual (procChecPortAllocated (varPortIndex), DEF_PORT_ALLOCATED)) {
Store (procPciDwordRead (ShiftLeft (Add( varPortIndex, 2), 3), 0x18), Local1)
And (ShiftRight (Local1, 16), 0xff, varSubordinateBusLocal2) //Local2 Port Subordinate Bus number
And (ShiftRight (Local1, 8), 0xff, varSecondaryBusLocal1) //Local1 Port Secondary Bus number
if (LAnd (LGreaterEqual (varClientBus, Local1), LLessEqual(varClientBus, Local2))) {
break
}
}
Increment (varPortIndex)
}
if (LGreater (varPortIndex, varMaxPortIndexNumber)) {
Store ("procPcieSetBusWidth Exit -- over max port index", Debug)
return (Local7)
}
Store (Concatenate (" Pcie Set BusWidth for port index : ", ToHexString (varPortIndex), varStringBuffer), Debug)
// Normalize link width (Num Lanes) to correct value x1, x2.x4,x8,x16,
// make sure that number of lanes requested to be powered on less or equal mx port link width
if (LLessEqual (procPcieGetLinkWidth (varPortIndex, DEF_LINKWIDTH_MAX_PHY), varArgBusWidth)) {
// Active link equal max link width, nothing needs to be done
Store ("procPcieSetBusWidth Exit -- over max lanes supported", Debug)
return (Local7)
}
Store (DeRefOf (Index (varNormalizeLinkWidthBuffer, varArgBusWidth)), Local1)
// call procPcieLaneControl to power on all lanes (Arg0 - port index , Arg1 - 1, Arg2 = 0)
procPcieLaneControl (varPortIndex, DEF_PCIE_LANE_POWERON, 0)
// call procPcieLaneControl power off unused lanes (Arg0 - port index, Arg1 - 1, Arg2 = Link width)
procPcieLaneControl (varPortIndex, DEF_PCIE_LANE_POWEROFFUNUSED, Local1)
#ifdef PHY_SPEED_REPORT_SUPPORT
procReportPhySpeedCap ()
#endif
Store (Local1, Index (Local7, 0x2)) // Return BusWidth
Store ("procPcieSetBusWidth Exit", Debug)
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)), varPortBdfLocal1)
Subtract (ShiftRight (varPortBdfLocal1, 3), 2, varPortIndexLocal4)
if (LEqual(varHotplugStateLocal0, 1)) {
// Enable port
Store (DEF_TRAINING_STATE_RELEASE_TRAINING, Local2)
} else {
// Disable port
Store (DEF_TRAINING_STATE_NOT_PRESENT, Local2)
}
//Disable ASPM
Store (procPciDwordRead (varPortBdfLocal1, 0x68), Local3)
procPciDwordRMW (varPortBdfLocal1, 0x68, Not (0x00000003), 0x00)
Store (procPciePortTraining (varPortIndexLocal4, Local2), varHotplugStateLocal0)
//Restore ASPM
procPciDwordRMW (varPortBdfLocal1, 0x68, Not (0x00000003), And (Local3, 0x3))
#ifdef PHY_SPEED_REPORT_SUPPORT
procReportPhySpeedCap ()
#endif
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)
if (LAnd (LGreater (varPsppPolicy, DEF_PSPP_POLICY_PERFORMANCE), LLess (varPsppPolicy, DEF_PSPP_POLICY_POWERSAVING))) {
// Request Max link speed for hotplug by going to AC state
Store (0, varPsppAcDcOverride)
procApplyPsppState ()
} else {
procPcieSetLinkSpeed (Arg0, DeRefOf (Index (varMaxLinkSpeed, Arg0)))
}
// Power on/enable port lanes
procPcieLaneControl (Arg0, DEF_PCIE_LANE_POWERON, 0)
// 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 (LAnd (LGreaterEqual (varTempLocal1, 0x10), LLessEqual (varTempLocal1, 0x13))) {
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, 0)
#ifdef PCIE_MAX_PAYLOAD_SUPPORT
procPcieClearMaxPayload (Arg0)
#endif
// Find device on secondary bus
Store (ShiftLeft (Add( Arg0, 2), 3), varTempBdfLocal0)
Store (procPciDwordRead (varTempBdfLocal0, 0x18), varTempLocal1)
And (ShiftRight (varTempLocal1, 8), 0xFF, varTempLocal1)
Store (Concatenate (" Remove device from Bus : ", ToHexString (varTempLocal1), varStringBuffer), Debug)
ShiftLeft (varTempLocal1, 8, varTempBdfLocal0)
Store (procPciDwordRead (varTempBdfLocal0, 0x0), varTempLocal0)
if (LEqual (varTempLocal0, 0xFFFFFFFF)) {
Store (" Device has been un-pluged!! ", Debug)
}
// 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)
#ifdef PCIE_DISABLE_UNUSED_LANES_ON_ACTIVE_LINK
procPcieLaneControl (Arg0, DEF_PCIE_LANE_POWEROFFUNUSED, 0)
#endif
#ifdef PCIE_MAX_PAYLOAD_SUPPORT
procPcieSetMaxPayload (Arg0)
#endif
#ifdef PCIE_CLKPM_SUPPORT
procPcieClkPmConfigure (Arg0)
#endif
}
if (LEqual (varStateLocal2, DEF_TRAINING_STATE_COMPLETE)) {
if (LAnd (LGreater (varPsppPolicy, DEF_PSPP_POLICY_PERFORMANCE), LLess (varPsppPolicy, DEF_PSPP_POLICY_POWERSAVING))) {
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
* Arg2 - link width
*/
Method (procPcieLaneControl, 3, 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)
Store (procPcieGetLinkWidth (Arg0, DEF_LINKWIDTH_MAX_PHY), varMaxPhyLinkWidth)
if (LEqual (Arg1, DEF_PCIE_LANE_POWEROFF)) {
procPcieLaneEnableControl (Arg0, varStartCoreLane, Add (varStartCoreLane, Subtract(varMaxPhyLinkWidth, 1)), 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, Add (varStartCoreLane, Subtract(varMaxPhyLinkWidth, 1)), 0)
}
if (LNotEqual (Arg1, DEF_PCIE_LANE_POWEROFFUNUSED)) {
return (0)
}
// Local2 should have link width (active lanes)
// Local3 should have first non active lanes
// Local4 should have last non active lanes
if (LEqual(Arg2, 0)) {
Store (procPcieGetLinkWidth (Arg0, DEF_LINKWIDTH_ACTIVE), varActiveLinkWidthLocal2)
} else {
Store ( Arg2 , varActiveLinkWidthLocal2)
}
// Let say Link width is x1 than local2 = 1, Local3 = 1 Local4 = 15 for non reversed case
// while for reversed case should be Local2 = 1 Local3 = 0 and Local4 = 14
if (LLessEqual (varMaxPhyLinkWidth, 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)
}
#ifdef PCIE_MAX_PAYLOAD_SUPPORT
/*----------------------------------------------------------------------------------------*/
/**
* Max_Payload_Size Blacklist
*
* Entry 1 = Vendor & Device ID
* Entry 2 = Max_Payload_Size for this device
*/
Name (varPayloadBlacklist, Package () {
Package() {0x10831969, 0}
})
/*----------------------------------------------------------------------------------------*/
/**
* Set Max_Payload_Size
*
* Arg0 - Port Index
*/
Method (procPcieSetMaxPayload, 1, Serialized) {
// Local variable usage
// varTempLocal0 - Temporary storage
// varBdfLocal1 - Address of port config space
// varCapLocal2 - Offset of port PCIe Capabilities
// varMaxPayloadLocal3 - Largest common value of Max_Payload_Size capability
// varMaxFunctionLocal4 - Max function number
// varFunctionLocal5 - Current function number
// varDeviceIDLocal6 - Root port BDF and Vendor and device ID for blacklist workaround
// varIndexLocal7 - Package index for blacklist workaround
Store ("PcieSetMaxPayload Enter", Debug)
// Get Port BDF from Port Index
Store (ShiftLeft (Add( Arg0, 2), 3), varDeviceIDLocal6)
Store (procFindPciCapability (varDeviceIDLocal6, 0x10), varCapLocal2)
if (LNotEqual (varCapLocal2, 0)) {
// Find device on secondary bus
Store (procPciDwordRead (varDeviceIDLocal6, 0x18), varTempLocal0)
And (ShiftRight (varTempLocal0, 8), 0xFF, varTempLocal0)
Store (Concatenate (" EP on SecondaryBus : ", ToHexString (varTempLocal0), varStringBuffer), Debug)
ShiftLeft (varTempLocal0, 8, varBdfLocal1)
Store (procPciDwordRead (varBdfLocal1, 0xC), varTempLocal0)
Store (And (ShiftRight (varTempLocal0, 16), 0xFF), varTempLocal0)
if (LNotEqual (And (varTempLocal0, 0x80), 0)) {
Store (0x7, varMaxFunctionLocal4)
} else {
Store (0x0, varMaxFunctionLocal4)
}
// Start with illegal value so we will know if a device is foudn
Store (0x08, varMaxPayloadLocal3)
// Search all functions and find smallest Max_Payload_Size
Store (0x0, varFunctionLocal5)
while (LLessEqual (varFunctionLocal5, varMaxFunctionLocal4)) {
Store (procFindPciCapability (Add (varBdfLocal1, varFunctionLocal5), 0x10), varCapLocal2)
if (LNotEqual (varCapLocal2, 0)) {
And (procPciDwordRead (Add (varBdfLocal1, varFunctionLocal5), Add (varCapLocal2, 0x04)), 0x07, varTempLocal0)
// Scan blacklist package for workaround
Store(procPciDwordRead (Add (varBdfLocal1, varFunctionLocal5), 0), varDeviceIDLocal6)
Store (0, varIndexLocal7)
while (LLess (varIndexLocal7, SizeOf (varPayloadBlacklist))) {
if (LEqual (DeRefOf (Index (DeRefOf (Index (varPayloadBlacklist, varIndexLocal7)), 0)), varDeviceIDLocal6)) {
Store (DeRefOf (Index (DeRefOf (Index (varPayloadBlacklist, varIndexLocal7)), 1)), varTempLocal0)
}
Increment (varIndexLocal7)
}
if (LLess (varTempLocal0, varMaxPayloadLocal3)) {
Store (varTempLocal0, varMaxPayloadLocal3)
}
}
Increment(varFunctionLocal5)
}
// We will only set Max_Payload_Size if PCIe capabilties were found on the downstream side
if (LNotEqual (varMaxPayloadLocal3, 0x08)) {
// Read root port Max_Payload_Size and compare with device supported value
Store (ShiftLeft (Add( Arg0, 2), 3), varDeviceIDLocal6)
Store (procFindPciCapability (varDeviceIDLocal6, 0x10), varCapLocal2)
And (procPciDwordRead (varDeviceIDLocal6, Add (varCapLocal2, 0x04)), 0x07, varTempLocal0)
if (LLess (varTempLocal0, varMaxPayloadLocal3)) {
Store (varTempLocal0, varMaxPayloadLocal3)
}
// Search all functions and set smallest Max_Payload_Size to all functions
// Relocate Max_Payload_Size data to bits 7-5
Store (Concatenate (" Setting Max_Payload_Size : ", ToHexString (varMaxPayloadLocal3), varStringBuffer), Debug)
ShiftLeft (varMaxPayloadLocal3, 5, varMaxPayloadLocal3)
// Set the root port Max_Payload_Size
procPciDwordRMW (varDeviceIDLocal6, Add (varCapLocal2, 0x08), Not (0x000000E0), varMaxPayloadLocal3)
//Set the Max_Payload_Size in each function that has PCIe Capabilities
Store (0x0, varFunctionLocal5)
while (LLessEqual (varFunctionLocal5, varMaxFunctionLocal4)) {
Store (procFindPciCapability (Add (varBdfLocal1, varFunctionLocal5), 0x10), varCapLocal2)
if (LNotEqual (varCapLocal2, 0)) {
procPciDwordRMW (varBdfLocal1, Add (varCapLocal2, 0x08), Not (0x000000E0), varMaxPayloadLocal3)
}
Increment(varFunctionLocal5)
}
}
}
Store ("PcieSetMaxPayload Exit", Debug)
}
/*----------------------------------------------------------------------------------------*/
/**
* Clear Max_Payload_Size
*
* Arg0 - Port Index
*/
Method (procPcieClearMaxPayload, 1, Serialized) {
// Local variable usage
// varPortBdfLocal0 - Address of root port config space
// varPortCapLocal1 - Offset of root port PCIe Capabilities
Store ("PcieClearMaxPayload Enter", Debug)
// Get Port BDF from Port Index
Store (ShiftLeft (Add( Arg0, 2), 3), varPortBdfLocal0)
Store (procFindPciCapability (varPortBdfLocal0, 0x10), varPortCapLocal1)
if (LNotEqual (varPortCapLocal1, 0)) {
// Set the root port Max_Payload_Size to default = 0x0
procPciDwordRMW (varPortBdfLocal0, Add (varPortCapLocal1, 0x08), Not (0x000000E0), 0x0)
}
Store ("PcieClearMaxPayload Exit", Debug)
}
#endif
#ifdef PCIE_CLKPM_SUPPORT
Method (procPcieClkPmConfigure, 1, Serialized) {
Store ("PcieClkPmConfigure Enter", Debug)
Store (procPcieGetPortInfo (Arg0), Local7)
Store (DerefOf (Index (Local7, DEF_OFFSET_CLK_PM_SUPPORT)), varTempLocal0)
if (LEqual (varTempLocal0, 0)) {
Store ("PcieClkPmConfigure Exit", Debug)
return (0)
}
// Get Port PCI address
Store (ShiftLeft (Add( Arg0, 2), 3), varPortBdfLocal1)
Store (procPciDwordRead (varPortBdfLocal1, 0x18), varTempLocal0)
// Get device BDf on secondary bus
And (varTempLocal0, 0xFF00, varEndpointBdfLocal2)
Store (procPciDwordRead (varEndpointBdfLocal2, 0xC), varTempLocal0)
Store (And (ShiftRight (varTempLocal0, 16), 0xFF), varTempLocal0)
if (LNotEqual (And (varTempLocal0, 0x80), 0)) {
Store (0x7, varMaxFunctionLocal3)
} else {
Store (0x0, varMaxFunctionLocal3)
}
Store (0, varFunctionLocal4)
Store (0, varIsClkPmSupportedLocal5)
while (LLessEqual (varFunctionLocal4, varMaxFunctionLocal3)) {
//Find PcieLinkControl register offset = PcieCapPtr + 0x10
Store (procFindPciCapability (Or (varEndpointBdfLocal2, varFunctionLocal4), 0x10), varPcieCapabilityOffsetLocal6)
if (LEqual (varPcieCapabilityOffsetLocal6, 0)) {
Increment (varFunctionLocal4)
continue
}
// Found PCI capability
if (LNotEqual (And (procPciDwordRead (Or (varEndpointBdfLocal2, varFunctionLocal4), Add (varPcieCapabilityOffsetLocal6, 0xC)), ShiftLeft (1,18)), 0)) {
Store (1, varIsClkPmSupportedLocal5)
} else {
Store (0, varIsClkPmSupportedLocal5)
break
}
Increment (varFunctionLocal4)
}
if (LEqual (varIsClkPmSupportedLocal5, 0)) {
Store ("PcieClkPmConfigure Exit", Debug)
return (0)
}
Store (0, varFunctionLocal4)
while (LLessEqual (varFunctionLocal4, varMaxFunctionLocal3)) {
//Find PcieLinkControl register offset = PcieCapPtr + 0x10
Store (procFindPciCapability (Or (varEndpointBdfLocal2, varFunctionLocal4), 0x10), varPcieCapabilityOffsetLocal6)
if (LEqual (varPcieCapabilityOffsetLocal6, 0)) {
Increment (varFunctionLocal4)
continue
}
// Enable CLK PM Capability
procPciDwordRMW (Or (varEndpointBdfLocal2, varFunctionLocal4), Add (varPcieCapabilityOffsetLocal6, 0x10), 0xffffffff, ShiftLeft (1, 8))
Increment (varFunctionLocal4)
}
Store ("PcieClkPmConfigure Exit", Debug)
}
#endif