/** * @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) }