/** * @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 (c) 2008 - 2012, 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) 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