/**
* @file
*
* ALIB PSPP 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.
* ***************************************************************************
*
*/

  /*----------------------------------------------------------------------------------------*/
  /**
   *  PCIe Performance Policy
   *
   *  varPsppPolicy - 0 Disabled
   *                  1 Performance
   *                  2 Balance Hight
   *                  3 Balance Low
   *                  4 Power Saving
   */
  Name (
    AD02,
    0x0
  )

  Alias (
    AD02,
    varPsppPolicy
  )

  /*----------------------------------------------------------------------------------------*/
  /**
   *  GEN2 VID
   *
   */

  Name (
    AD03,
    0x0
  )

  Alias (
    AD03,
    varGen2Vid
  )

  /*----------------------------------------------------------------------------------------*/
  /**
   *  GEN1 VID
   *
   */
  Name (
    AD04,
    0x0
  )

  Alias (
    AD04,
    varGen1Vid
  )

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Boot VID
   *
   */

  Name (
    AD05,
    0x0
  )

  Alias (
    AD05,
    varBootVid
  )

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Max Port link speed
   *
   */
  Name (AD06, Package () {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})

  Alias (AD06, varMaxLinkSpeed)


  /*----------------------------------------------------------------------------------------*/
  /**
   *  Max link speed that was changed during runtime (hotplug for instance)
   *
   */

  Name (AD08, Package () {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})

  Alias (AD08,  varOverrideLinkSpeed)

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Policy service status
   *
   *  varPsppPolicyService - 0 (Stopped)
   *                         1 (Started)
   */

  Name (varPsppPolicyService, 0x0 )

  /*----------------------------------------------------------------------------------------*/
  /**
   *  AC DC state
   *
   *  varPsppAcDcState - 0 (AC)
   *                     1 (DC)
   */

  Name (varPsppAcDcState, 0x0)
  Name (varPsppAcDcOverride, 0x1)

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Client ID array
   *
   */

  Name (varPsppClientIdArray,
    Package () {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
    )

  Name (varDefaultPsppClientIdArray,
    Package () {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
    )
  /*----------------------------------------------------------------------------------------*/
  /**
   *  LInk speed requested by device driver
   *
   */

  Name (varRequestedLinkSpeed, Package () {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Current link speed
   *
   */
  Name (AD09, Package () {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
  Alias (AD09,  varCurrentLinkSpeed)
  /*----------------------------------------------------------------------------------------*/
  /**
   *  Template link speed
   *
   */
  Name (
    varGen1LinkSpeedTemplate,
    Package () {
    DEF_LINK_SPEED_GEN1,
    DEF_LINK_SPEED_GEN1,
    DEF_LINK_SPEED_GEN1,
    DEF_LINK_SPEED_GEN1,
    DEF_LINK_SPEED_GEN1,
    DEF_LINK_SPEED_GEN1,
    DEF_LINK_SPEED_GEN1,
    DEF_LINK_SPEED_GEN1
    })

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Template link speed
   *
   */
  Name (varLowVoltageRequest, Package () {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 })

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Global varuable
   *
   */
  Name (varPortIndex, 0)

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Sclk VID that was changed during runtime
   *
   */

  Name (AD10, Package () {0x00, 0x00, 0x00, 0x00})

  Alias (AD10,  varSclkVid)

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Report AC/DC state
   *
   *  Arg0 - Data Buffer
   */
  Method (procPsppReportAcDsState, 1, Serialized) {
    Store ("PsppReportAcDsState Enter", Debug)

    Store (DeRefOf (Index (Arg0, 0x2)), varArgAcDcStateLocal1)
    Store (Concatenate ("  AC/DC state: ", ToHexString (varArgAcDcStateLocal1), varStringBuffer), Debug)

    Store (procPsppGetAcDcState(), varCurrentAcDcStateLocal0)
    Store (varArgAcDcStateLocal1, varPsppAcDcState)

    Or (ShiftLeft (1, DEF_SCARTCH_PSPP_ACDC_OFFSET), ShiftLeft (1, DEF_SCARTCH_PSPP_ACDC_OVR_OFFSET), Local2)
    Or (ShiftLeft (varPsppAcDcState, DEF_SCARTCH_PSPP_ACDC_OFFSET), ShiftLeft (varPsppAcDcOverride, DEF_SCARTCH_PSPP_ACDC_OVR_OFFSET), Local3)
    procIndirectRegisterRMW (0x0, 0x60, 0xF4, Not (Local2), And (Local2, Local3))


    if (LEqual (varArgAcDcStateLocal1, varCurrentAcDcStateLocal0)) {
      Store ("  No action. [AC/DC state not changed]", Debug)
      Store ("PsppReportAcDsState Exit", Debug)
      return (0)
    }

    // Disable both APM (boost) and PDM flow on DC event enable it on AC.
    procApmPdmActivate(varPsppAcDcState)

    // Set DPM state for Power Saving, due to this policy will not attend ApplyPsppState service.
    if (LEqual (varPsppPolicy, DEF_PSPP_POLICY_POWERSAVING)) {
      procNbLclkDpmActivate(DEF_LINK_SPEED_GEN1)
#ifdef ALTVDDNB_SUPPORT
      procNbAltVddNb (DEF_LINK_SPEED_GEN1)
#endif
    }
    if (LOr (LLessEqual (varPsppPolicy, DEF_PSPP_POLICY_PERFORMANCE), LGreaterEqual (varPsppPolicy, DEF_PSPP_POLICY_POWERSAVING))) {
      Store ("  No action. [Policy type]", Debug)
      Store ("PsppReportAcDsState Exit", Debug)
      return (0)
    }
    if (LEqual (varPsppPolicyService, DEF_PSPP_POLICY_STOP)) {
      Store ("  No action. [Policy not started]", Debug)
      Store ("PsppReportAcDsState Exit", Debug)
      return (0)
    }
    procApplyPsppState ()
    Store ("PsppReportAcDsState Exit", Debug)
    return (0)
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *  PCIe Performance Request
   *
   *  Arg0 - Data Buffer
   */
  Method (procPsppPerformanceRequest, 1, NotSerialized) {
    Store (procPsppProcessPerformanceRequest (Arg0), Local7)
    Store (DeRefOf (Index (Local7, 2)), varReturnStatusLocal0)
    if (LNotEqual (varReturnStatusLocal0, 2)) {
      return (Local7)
    }
    procApplyPsppState ()
    return (Local7)
  }
  /*----------------------------------------------------------------------------------------*/
  /**
   *  PCIe Performance Request
   *
   *  Arg0 - Data Buffer
   */
  Method (procPsppProcessPerformanceRequest, 1, NotSerialized) {
    Store ("PsppProcessPerformanceRequest Enter", Debug)
    Name (varClientBus, 0)
    Store (0, varPortIndex)
    Store (Buffer (10) {}, Local7)
    CreateWordField (Local7, 0x0, varReturnBufferLength)
    Store (3, varReturnBufferLength)
    CreateByteField (Local7, 0x2, varReturnStatus)
    Store (1, varReturnStatus)

    if (LOr (LLessEqual (varPsppPolicy, DEF_PSPP_POLICY_PERFORMANCE), LGreaterEqual (varPsppPolicy, DEF_PSPP_POLICY_POWERSAVING))) {
      Store ("  No action. [Policy type]", Debug)
      Store ("PsppPerformanceRequest Exit", Debug)
      return (Local7)
    }
    if (LEqual (varPsppPolicyService, DEF_PSPP_POLICY_STOP)) {
      Store ("  No action. [Policy not started]", Debug)
      Store ("PsppPerformanceRequest Exit", Debug)
      return (Local7)
    }
    CreateWordField (Arg0, 0x2, varClientId)
    CreateWordField (Arg0, 0x4, varValidFlag)
    CreateWordField (Arg0, 0x6, varFlag)
    CreateByteField (Arg0, 0x8, varRequestType)
    CreateByteField (Arg0, 0x9, varRequestData)

    Store (Concatenate ("  Client ID   : ", ToHexString (varClientId), varStringBuffer), Debug)
    Store (Concatenate ("  Valid Flags : ", ToHexString (varValidFlag), varStringBuffer), Debug)
    Store (Concatenate ("  Flags       : ", ToHexString (varFlag), varStringBuffer), Debug)
    Store (Concatenate ("  Request Type: ", ToHexString (varRequestType), varStringBuffer), Debug)
    Store (Concatenate ("  Request Data: ", ToHexString (varRequestData), varStringBuffer), Debug)


    And (ShiftRight (varClientId, 8), 0xff, varClientBus)
    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 ("PsppPerformanceRequest Exit", Debug)
      return (Local7)
    }

    Store (Concatenate ("  Performance request for port index : ", ToHexString (varPortIndex), Local6), Debug)

    if (LEqual (DeRefOf (Index (varPsppClientIdArray, varPortIndex)), 0x0000)) {
      Store (varClientId, Index (varPsppClientIdArray, varPortIndex))
    } ElseIf (LNotEqual (DeRefOf (Index (varPsppClientIdArray, varPortIndex)), varClientId)) {
      // We already have registered client
      Store ("  No action. [Unsupported request]", Debug)
      Store ("PsppPerformanceRequest Exit", Debug)
      return (Local7)
    }
    Store (0, Index (varLowVoltageRequest, varPortIndex))
    if (LEqual (varRequestData, 0)) {
      Store (0x0000, Index (varPsppClientIdArray, varPortIndex))
    }
    if (LEqual (varRequestData, 1)) {
      Store (1, Index (varLowVoltageRequest, varPortIndex))
    }
    if (LEqual (varRequestData, 2)) {
      Store (DEF_LINK_SPEED_GEN1, Index (varRequestedLinkSpeed, varPortIndex))
    }
    if (LEqual (varRequestData, 3)) {
      Store (DEF_LINK_SPEED_GEN2, Index (varRequestedLinkSpeed, varPortIndex))
    }
    if (LEqual (And (varValidFlag, varFlag), 0x1)) {
      Store (DerefOf (Index (varMaxLinkSpeed, varPortIndex)), Index (varRequestedLinkSpeed, varPortIndex))
    }
    Store (2, varReturnStatus)
    Store ("PsppProcessPerformanceRequest Exit", Debug)
    return (Local7)
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *  PSPP Start/Stop Management Request
   *
   *  Arg0 - Data Buffer
   */

  Method (procChecPortAllocated, 1, Serialized) {
    if (LEqual (DeRefOf (Index (varMaxLinkSpeed, Arg0)), 0)) {
      return (DEF_PORT_NOT_ALLOCATED)
    }
    return (DEF_PORT_ALLOCATED)
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *  PSPP Start/Stop Management Request
   *
   *  Arg0 - Data Buffer
   */
  Method (procPsppControl, 1, Serialized) {
    Store ("PsppControl Enter", Debug)
    Store (Buffer (256) {}, Local7)
    Store (3, Index (Local7, 0x0)) // Return Buffer Length
    Store (0, Index (Local7, 0x1)) // Return Buffer Length
    Store (0, Index (Local7, 0x2)) // Return Status

    Store (DerefOf (Index (Arg0, 0x2)), varPsppPolicyService)

    Store (procIndirectRegisterRead (0x0, 0x60, 0xF4), varPsppScratchLocal0)

    if (LEqual (varPsppPolicyService, DEF_PSPP_POLICY_START)) {
      if (LEqual (And (varPsppScratchLocal0, 1), DEF_PSPP_POLICY_START)) {
      // Policy already started
        Store (" No action. [Policy already started]", Debug)
        Store ("PsppControl Exit", Debug)
        return (Local7)
      }
      Or (varPsppScratchLocal0, DEF_PSPP_POLICY_START, varPsppScratchLocal0)
    }
    if (LEqual (varPsppPolicyService, DEF_PSPP_POLICY_STOP)) {
      if (LEqual (And (varPsppScratchLocal0, 1), DEF_PSPP_POLICY_STOP)) {
        // Policy already stopped
        Store ("  No action. [Policy already stopped]", Debug)
        Store ("PsppControl Exit", Debug)
        return (Local7)
      }
      And (varPsppScratchLocal0, Not (DEF_PSPP_POLICY_START), varPsppScratchLocal0)
    }
    Or (varPsppScratchLocal0, Shiftleft (varPsppPolicy, DEF_SCARTCH_PSPP_POLICY_OFFSET), varPsppScratchLocal0)
    procIndirectRegisterWrite (0x0, 0x60, 0xF4, varPsppScratchLocal0)

    procCopyPackage (RefOf (varDefaultPsppClientIdArray), RefOf (varPsppClientIdArray))

    // Reevaluate APM/PDM state here on S3 resume while staying on DC.
    procApmPdmActivate(varPsppAcDcState)

    // Set DPM state for PSPP Power Saving, due to this policy will not attend ApplyPsppState service.
    if (LEqual (varPsppPolicy, DEF_PSPP_POLICY_POWERSAVING)) {
      procNbLclkDpmActivate(DEF_LINK_SPEED_GEN1)
#ifdef ALTVDDNB_SUPPORT
      procNbAltVddNb (DEF_LINK_SPEED_GEN1)
#endif
    }
    //Reevaluate PCIe speed for all devices base on PSPP state switch to boot up voltage
    if (LAnd (LGreater (varPsppPolicy, DEF_PSPP_POLICY_PERFORMANCE), LLess (varPsppPolicy, DEF_PSPP_POLICY_POWERSAVING))) {
      // Load default speed capability state
      if (LEqual (varPsppPolicy, DEF_PSPP_POLICY_BALANCEHIGH)) {
        procCopyPackage (RefOf (varMaxLinkSpeed), RefOf (varCurrentLinkSpeed))
        Store (0, varPortIndex)
        while (LLessEqual (varPortIndex, varMaxPortIndexNumber)) {
          if (LNotEqual (DeRefOf (Index (varOverrideLinkSpeed, varPortIndex)), 0)) {
            Store (DeRefOf (Index (varOverrideLinkSpeed, varPortIndex)), Index (varCurrentLinkSpeed, varPortIndex))
          }
          Increment (varPortIndex)
        }
      } else {
        procCopyPackage (RefOf (varGen1LinkSpeedTemplate), RefOf (varCurrentLinkSpeed))
#ifdef SBLINK_BALANCE_LOW_GEN2_SUPPORT
       Store (DeRefOf (Index (varMaxLinkSpeed, DEF_SB_PORT_INDEX)),Index (varCurrentLinkSpeed, DEF_SB_PORT_INDEX))
       //Store (DEF_LINK_SPEED_GEN2, Index (varCurrentLinkSpeed, DEF_SB_PORT_INDEX))
#endif

      }
      procApplyPsppState ()
    }
    Store ("PsppControl Exit", Debug)
    return (Local7)
  }

  Name (varNewLinkSpeed, Package () {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Evaluate PCIe speed on all links according to PSPP state and client requests
   *
   *
   *
   */
  Method (procApplyPsppState, 0, Serialized) {
    Store ("ApplyPsppState Enter", Debug)
    Store (0, varPortIndex)

    procCopyPackage (RefOf (varGen1LinkSpeedTemplate), RefOf (varNewLinkSpeed))
    while (LLessEqual (varPortIndex, varMaxPortIndexNumber)) {
      if (LEqual (procChecPortAllocated(varPortIndex), DEF_PORT_ALLOCATED)) {
        Store (procGetPortRequestedCapability (varPortIndex), Index (varNewLinkSpeed, varPortIndex))
      }
      Increment (varPortIndex)
    }
    if (LNotEqual(Match (varLowVoltageRequest, MEQ, 0x01, MTR, 0, 0), ONES)) {
      procCopyPackage (RefOf (varGen1LinkSpeedTemplate), RefOf (varNewLinkSpeed))
    }
    if (LNotEqual(Match (varNewLinkSpeed, MEQ, DEF_LINK_SPEED_GEN2, MTR, 0, 0), ONES)) {
      // Set GEN2 voltage
      Store ("Set GEN2 VID", Debug)
#ifdef ALTVDDNB_SUPPORT
      procNbAltVddNb (DEF_LINK_SPEED_GEN2)
#endif
      procPcieSetVoltage (DEF_LINK_SPEED_GEN2, 1)
//      procPcieAdjustPll (DEF_LINK_SPEED_GEN2)
      procNbLclkDpmActivate(DEF_LINK_SPEED_GEN2)
    }
    Store (0, varPortIndex)
    while (LLessEqual (varPortIndex, varMaxPortIndexNumber)) {
      if (LEqual (procChecPortAllocated(varPortIndex), DEF_PORT_NOT_ALLOCATED)) {
        Increment (varPortIndex)
        continue
      }
      Store (DerefOf (Index (varCurrentLinkSpeed, varPortIndex)), varCurrentLinkSpeedLocal0)
      Store (DerefOf (Index (varNewLinkSpeed, varPortIndex)), varNewLinkSpeedLocal2)
      if (LEqual (varCurrentLinkSpeedLocal0, varNewLinkSpeedLocal2)) {
        Increment (varPortIndex)
        continue
      }
      Store (varNewLinkSpeedLocal2, Index (varCurrentLinkSpeed, varPortIndex))
      procSetPortCapabilityAndSpeed (varPortIndex, varNewLinkSpeedLocal2)
      Increment (varPortIndex)
    }
    if (LEqual(Match (varNewLinkSpeed, MEQ, DEF_LINK_SPEED_GEN2, MTR, 0, 0), ONES)) {
      // Set GEN1 voltage
      Store ("Set GEN1 VID", Debug)
      procNbLclkDpmActivate(DEF_LINK_SPEED_GEN1)
//      procPcieAdjustPll (DEF_LINK_SPEED_GEN1)
      procPcieSetVoltage (DEF_LINK_SPEED_GEN1, 0)
#ifdef ALTVDDNB_SUPPORT
      procNbAltVddNb (DEF_LINK_SPEED_GEN1)
#endif
    }
#ifdef PHY_SPEED_REPORT_SUPPORT
    procReportPhySpeedCap ()
#endif
    Store ("ApplyPsppState Exit", Debug)
  }
  /*----------------------------------------------------------------------------------------*/
  /**
   *  Read PCI config register
   *
   *  Arg0 - Port Index
   *
   */
  Method (procGetPortRequestedCapability, 1) {
    Store (DEF_LINK_SPEED_GEN2, varCurrentSpeedLocal0)
    Store (procPsppGetAcDcState(), varAcDcStateLocal1)
    if (LEqual (DerefOf (Index (varPsppClientIdArray, Arg0)), 0x0000)) {
      if (LOr (LEqual (varAcDcStateLocal1, DEF_PSPP_STATE_DC), LEqual (varPsppPolicy, DEF_PSPP_POLICY_BALANCELOW))) {
        // Default policy cap to GEN1
        Store (DEF_LINK_SPEED_GEN1, varCurrentSpeedLocal0)
      }
#ifdef SBLINK_BALANCE_LOW_GEN2_SUPPORT
      if (LAnd (LEqual (varAcDcStateLocal1, DEF_PSPP_STATE_AC), LEqual (varPsppPolicy, DEF_PSPP_POLICY_BALANCELOW))) {
        if (LEqual (Arg0, DEF_SB_PORT_INDEX)) {
          Store (DEF_LINK_SPEED_GEN2, varCurrentSpeedLocal0)
        }
      }
#endif
      if (LNotEqual (DerefOf (Index (varOverrideLinkSpeed, Arg0)), 0)) {
        Store (DerefOf (Index (varOverrideLinkSpeed, Arg0)), varCurrentSpeedLocal0)
      }
    } else {
      Store (DerefOf (Index (varRequestedLinkSpeed, Arg0)), varCurrentSpeedLocal0)
    }
    Store (DerefOf (Index (varMaxLinkSpeed, varPortIndex)),varMaxLinkSpeedLocal2)
    if (LLess (varMaxLinkSpeedLocal2, varCurrentSpeedLocal0)) {
      Store (varMaxLinkSpeedLocal2, varCurrentSpeedLocal0)
    }


    return (varCurrentSpeedLocal0)
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Set capability and speed
   *
   *  Arg0 - Port Index
   *  Arg1 - Link speed
   */
  Method (procSetPortCapabilityAndSpeed, 2, NotSerialized) {
    Store ("SetPortCapabilityAndSpeed Enter", Debug)
    Store (Concatenate ("  Port Index : ", ToHexString (Arg0), varStringBuffer), Debug)
    Store (Concatenate ("  Speed      : ", ToHexString (Arg1), varStringBuffer), Debug)

    //UnHide UMI port
    if (LEqual (Arg0, 6)) {
      procIndirectRegisterRMW (0x0, 0x60, 0x80, Not (0x40), 0x40);
    }

    procPcieSetLinkSpeed (Arg0, Arg1)

    // Programming for LcInitSpdChgWithCsrEn
    if (LNotEqual (DeRefOf (Index (varPsppClientIdArray, Arg0)), 0x0000)) {
      // Registered port, LcInitSpdChgWithCsrEn = 0.
      procPciePortIndirectRegisterRMW (Arg0, 0xA1, Not (0x00001000), 0x0)
    } else {
      procPciePortIndirectRegisterRMW (Arg0, 0xA1, Not (0x00001000), 0x00001000)
    }

    // Determine port PCI address and check port present
    Store (ShiftLeft (Add( Arg0, 2), 3), varPortBdfLocal1)
    And (procPciePortIndirectRegisterRead (Arg0, 0xA5), 0x3f, varPortPresentLocal3)
    procPciePortIndirectRegisterWrite (Arg0, 0x1, varPortPresentLocal3)
    if (LGreaterEqual (varPortPresentLocal3, 0x10)) {
      procDisableAndSaveAspm (Arg0)
      Store (1, Local2)
      while (Local2) {
        //retrain port
        procPciDwordRMW (varPortBdfLocal1, 0x68, Not (0x00000000), 0x20)
        Sleep (30)
        while (And (procPciDwordRead (varPortBdfLocal1, 0x68), 0x08000000)) {
          Sleep (10)
        }
        Store (0, Local2)
        if (LEqual (Arg1, DEF_LINK_SPEED_GEN1)) {
          //Store (procPciePortIndirectRegisterRead (Arg0, 0xA4), varLcCurrentLinkSpeedLocal4)
          if (LNotEqual (procPciePortGetCurrentLinkSpeed (Arg0), DEF_LINK_SPEED_GEN1)) {
            Store (1, Local2)
          }
        }
      }
      procRestoreAspm (Arg0)
    } else {
      Store ("  Device not present. Set capability and speed only", Debug)
    }
    //Hide UMI port
    if (LEqual (Arg0, 6)) {
      procIndirectRegisterRMW (0x0, 0x60, 0x80, Not (0x40), 0x00);
    }
    Store ("SetPortCapabilityAndSpeed Exit", Debug)
  }

  Name (varPcieLinkControlArray, Package () {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0})
  Name (varPcieLinkControlOffset, 0)
  Name (varPcieLinkControlData, 0)
  Name (varPcieRcControlData, 0)

  /*----------------------------------------------------------------------------------------*/
  /**
   *   Disable and save ASPM state
   *
   *  Arg0 - Port Index
   */
  Method (procDisableAndSaveAspm, 1, Serialized) {
    Store (0, varPcieLinkControlOffset)
    Store (0, varPcieLinkControlData)

    Store (ShiftLeft (Add( Arg0, 2), 3), varPortBdfLocal1)
    if (LEqual (Arg0, 6)) {
      Store ("  Disable SB ASPM", Debug)
      Store (procPcieSbAspmControl (0, 0),  Index (varPcieLinkControlArray, 0))
      Store (Concatenate ("  PcieLinkControl Data : ", ToHexString (DerefOf(Index (varPcieLinkControlArray, 0))), varStringBuffer), Debug)
      procPcieSbAspmControl (0, 1)
      return (0)
    }

    Store (procPciDwordRead (varPortBdfLocal1, 0x18), varTempLocal3)
    Store (And (ShiftRight (varTempLocal3, 8), 0xFF),  varTempLocal3)

    Store (Concatenate ("  Disable EP ASPM on Secondary Bus : ", ToHexString (varTempLocal3), varStringBuffer), Debug)

    Store (ShiftLeft (varTempLocal3, 8), varEndpointBdfLocal2)
    Store (procPciDwordRead (varEndpointBdfLocal2, 0xC), varTempLocal3)
    Store (And (ShiftRight (varTempLocal3, 16), 0xFF),  varTempLocal3)

    Store (Concatenate ("  EP Header type : ", ToHexString (varTempLocal3), varStringBuffer), Debug)

    if (LNotEqual (And (varTempLocal3, 0x80), 0)) {
      Store (0x7, varMaxFunctionLocal0)
    } else {
      Store (0x0, varMaxFunctionLocal0)
    }
    Store (0, varFunctionLocal4)
    while (LLessEqual (varFunctionLocal4, varMaxFunctionLocal0)) {
      //Find PcieLinkControl register offset = PcieCapPtr + 0x10
      Store (procFindPciCapability (Add (varEndpointBdfLocal2, varFunctionLocal4), 0x10), varPcieLinkControlOffset)
      if (LEqual (varPcieLinkControlOffset, 0)) {
        Increment (varFunctionLocal4)
        continue
      }
      Add (varPcieLinkControlOffset, 0x10, varPcieLinkControlOffset)

      Store (Concatenate ("  Function number of Secondary Bus : ", ToHexString (varFunctionLocal4), varStringBuffer), Debug)
      Store (Concatenate ("  PcieLinkControl register offset  : ", ToHexString (varPcieLinkControlOffset), varStringBuffer), Debug)
      // Save ASPM on EP
      Store (procPciDwordRead (Add (varEndpointBdfLocal2, varFunctionLocal4) , varPcieLinkControlOffset), varPcieLinkControlData)
      Store (And (varPcieLinkControlData, 0x3), Index (varPcieLinkControlArray, varFunctionLocal4))

      Store (Concatenate ("  PcieLinkControl Data : ", ToHexString (varPcieLinkControlData), varStringBuffer), Debug)

      procPciDwordRMW (Add (varEndpointBdfLocal2, varFunctionLocal4), varPcieLinkControlOffset, Not (0x00000003), 0x00)
      Store ("Disable ASPM on EP Complete!!", Debug)
      Increment (varFunctionLocal4)
    }
    //Disable ASPM on RC
    Store (procPciDwordRead (varPortBdfLocal1, 0x68), varPcieRcControlData)
    procPciDwordRMW (varPortBdfLocal1, 0x68, Not (0x00000003), 0x00)
  }
  /*----------------------------------------------------------------------------------------*/
  /**
   *  Restore ASPM
   *
   *  Arg0 - Port Index
   */
   Method (procRestoreAspm, 1, Serialized) {

    Store (0, varPcieLinkControlOffset)
    Store (0, varPcieLinkControlData)


    // Restore SB ASPM
    if (LEqual (Arg0, 6)) {
      Store ("  Restore SB ASPM", Debug)
      Store (Concatenate ("  PcieLinkControl Data : ", ToHexString (DerefOf(Index (varPcieLinkControlArray, 0))), varStringBuffer), Debug)
      procPcieSbAspmControl (DerefOf(Index (varPcieLinkControlArray, 0)), 1)
      return (0)
    }
    Store (ShiftLeft (Add( Arg0, 2), 3), varPortBdfLocal1)
    // Restore EP ASPM
    Store (procPciDwordRead (varPortBdfLocal1, 0x18), varTempLocal3)
    Store (And (ShiftRight (varTempLocal3, 8), 0xFF),  varTempLocal3)
    // Restore ASPM on RC
    procPciDwordRMW (varPortBdfLocal1, 0x68, Not (0x00000003), And (varPcieRcControlData, 0x3))

    Store (Concatenate ("  Disable EP ASPM on SecondaryBus : ", ToHexString (varTempLocal3), varStringBuffer), Debug)

    Store (ShiftLeft (varTempLocal3, 8), varEndpointBdfLocal2)
    Store (procPciDwordRead (varEndpointBdfLocal2, 0xC), varTempLocal3)
    Store (And (ShiftRight (varTempLocal3, 16), 0xFF),  varTempLocal3)

    Store (Concatenate ("  EP Header type : ", ToHexString (varTempLocal3), varStringBuffer), Debug)

    if (LNotEqual (And (varTempLocal3, 0x80), 0)) {
      Store (0x7, varMaxFunctionLocal0)
    } else {
      Store (0x0, varMaxFunctionLocal0)
    }
    Store (0, varFunctionLocal4)
    while (LLessEqual (varFunctionLocal4, varMaxFunctionLocal0)) {
      //Find PcieLinkControl register offset = PcieCapPtr + 0x10
      Store (procFindPciCapability (Add (varEndpointBdfLocal2, varFunctionLocal4), 0x10), varPcieLinkControlOffset)
      if (LEqual (varPcieLinkControlOffset, 0)) {
        Increment (varFunctionLocal4)
        continue
      }
      Add (varPcieLinkControlOffset, 0x10, varPcieLinkControlOffset)

      Store (Concatenate ("  Restore Function number of SecondaryBus : ", ToHexString (varFunctionLocal4), varStringBuffer), Debug)
      Store (Concatenate ("  Restore PcieLinkControl register offset : ", ToHexString (varPcieLinkControlOffset), varStringBuffer), Debug)
      Store (Concatenate ("  PcieLinkControl Data : ", ToHexString (DerefOf (Index (varPcieLinkControlArray, varFunctionLocal4))), varStringBuffer), Debug)

      procPciDwordWrite (Add (varEndpointBdfLocal2, varFunctionLocal4), varPcieLinkControlOffset, DerefOf (Index (varPcieLinkControlArray, varFunctionLocal4)))
      Increment (varFunctionLocal4)
    }
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *   Request VID
   *
   *  Arg0 - Port Index
   *  Arg1 - PCIe speed
   */

  Method (procPcieSetLinkSpeed, 2) {
    Store (ShiftLeft (Add( Arg0, 2), 3), Local0)
    if (LEqual (Arg1, DEF_LINK_SPEED_GEN1)) {
      procPciDwordRMW (Local0, 0x88, Not (0x0000002f), 0x21)
      procPciePortIndirectRegisterRMW (Arg0, 0xA4, Not (0x20000001), 0x0)
    } else {
      procPciePortIndirectRegisterRMW (Arg0, 0xA4, Not (0x20000001), 0x20000001)
      procPciDwordRMW (Local0, 0x88, Not (0x0000002f), 0x2)
    }
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Read PCIe port indirect register
   *
   *  Arg0 - Ref Source Pckage
   *  Arg1 - Ref to Destination Package
   *
   */
  Method (procCopyPackage, 2, NotSerialized) {

    Store (SizeOf (Arg0), Local1)
    Store (0, Local0)
    While (LLess (Local0, Local1)) {
      Store (DerefOf(Index(DerefOf (Arg0), Local0)), Index(DerefOf (Arg1), Local0))
      Increment (Local0)
    }
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Read PCIe port indirect register
   *
   *  Arg0 - Ref Source Pckage
   *  Arg1 - Ref to Destination Package
   *
   */
  Method (procPsppGetAcDcState, 0 , NotSerialized) {
    Return (And (varPsppAcDcState, varPsppAcDcOverride))
  }
