diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibHotplug.esl')
-rw-r--r-- | src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibHotplug.esl | 787 |
1 files changed, 787 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibHotplug.esl b/src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibHotplug.esl new file mode 100644 index 0000000000..951193a57b --- /dev/null +++ b/src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbPcieAlibV1/PcieAlibHotplug.esl @@ -0,0 +1,787 @@ +/** + * @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 + + |