/**
 * @file
 *
 * ALIB PSPP Pcie Smu Lib V1
 *
 *
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project:     AGESA
 * @e sub-project: GNB
 * @e \$Revision: 61048 $   @e \$Date: 2011-10-31 12:20:41 +0800 (Mon, 31 Oct 2011) $
 *
 */
/*
*****************************************************************************
*
 * 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.
* ***************************************************************************
*
*/
  /*----------------------------------------------------------------------------------------*/
  /**
   *   Request VID
   *
   *  Arg0 - 1 - GEN1 2 - GEN2
   *  Arg1 - 0 = do not wait intil voltage is set
   *         1 = wait until voltage is set
   */
  Method (procPcieSetVoltage, 2, Serialized) {
    Store ("PcieSetVoltage Enter", Debug)
    Store (procIndirectRegisterRead (0x0, 0x60, 0xEA), Local1)
    //Enable voltage change
    Or (Local1, 0x2, Local1)
    procIndirectRegisterWrite (0x0, 0x60, 0xEA, Local1)
    //Clear voltage index
    And (Local1, Not (ShiftLeft (0x3, 3)), Local1)

    if (LEqual (Arg0, DEF_LINK_SPEED_GEN1)) {
      Store (varGen1Vid, Local3)
    } else {
      Store (varGen2Vid, Local3)
    }

    Store (Concatenate ("  Voltage Index:", ToHexString (Local3), Local6), Debug)
    //Set new voltage index
    Or (Local1, ShiftLeft (Local3, 3), Local1)
    //Togle request
    And (Not (Local1), 0x4, Local2)
    Or (And (Local1, Not (0x4)), Local2, Local1)
    procIndirectRegisterWrite (0x0, 0x60, 0xEA, Local1)
    if (LNotEqual (Arg1, 0)) {
      while (LNotEqual (ShiftLeft(Local1, 0x2), Local2)) {
        And (procIndirectRegisterRead (0x0, 0x60, 0xEB), 0x1, Local1)
      }
    }
    Store ("PcieSetVoltage Exit", Debug)
  }
