/**
 * @file
 *
 * ALIB ASL library
 *
 *
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project:     AGESA
 * @e sub-project: GNB
 * @e \$Revision: 63659 $   @e \$Date: 2012-01-03 00:42:47 -0600 (Tue, 03 Jan 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.
* ***************************************************************************
*
*/

DefinitionBlock (
  "PcieAlibSsdtTN.aml",
  "SSDT",
  2,
  "AMD",
  "ALIB",
  0x1
  )
{
  Scope(\_SB) {

    Name (varMaxPortIndexNumber, 6)

    include ("PcieAlibMmioData.asl")
    include ("PcieAlibPciLib.asl")
    include ("PcieAlibDebugLib.asl")
    include ("PcieSmuServiceV4.asl")


    Name (varBapmControl, 0)
    Name (varCstateIntControlState, 0)
    Name (varIsStateInitialized, 0)
    /*----------------------------------------------------------------------------------------*/
    /**
     *  APM/PDM stub
     *
     *  Arg0 - AC/DC state
     *
     */
    Method (procApmPdmActivate, 1, NotSerialized) {
      Store (Or(ShiftLeft (0x18, 3), 4), Local2)
      if (LEqual (varIsStateInitialized, 0)) {
        Store (procPciDwordRead (Local2, 0x124), varCstateIntControlState)
        Store (1, varIsStateInitialized)
      }

      Store (procPciDwordRead (Local2, 0x124), Local3)
      if (LEqual (Arg0,DEF_PSPP_STATE_AC)) {
        // Disable PC6 on AC
        Or (Local3, And (varCstateIntControlState, 0x00400000), Local3)
      } else {
        // Enable PC6 on DC
        And (Local3, 0xFFBFFFFF, Local3)
      }
      procPciDwordWrite (Local2, 0x124, Local3)

      if (LEqual (varBapmControl, 0)) {
        // If GFX present driver manage BAPM if not ALIB manage BAPM
        if (LEqual (procPciDwordRead (0x08, 0x00), 0xffffffff)) {
          And (procIndirectRegisterRead (0x0, 0xB8, 0x1F428), 0x2, Local1);
          // check if BAPM was enable during BIOS post
          if (LEqual (Local1, 0x2)) {
            Store (1, varBapmControl)
          }
        }
      }
      if (LEqual (varBapmControl,1)) {
        if (LEqual (Arg0,DEF_PSPP_STATE_AC)) {
          // Enable BAPM on AC
          Store (32, Local0)
        } else {
          // Disable BAPM on DC
          Store (33, Local0)
        }
        procNbSmuServiceRequest (Local0);
      }
    }

    Name (varRestoreNbps, 0)
    Name (varRestoreNbDpmState, 0)
    /*----------------------------------------------------------------------------------------*/
    /**
     *  _WAK
     *
     *
     *
     */
    Method (AWAK, 1) {
      if (LEqual (Arg0, 3)) {
        // Clear D18F5x170 [SwNbPstateLoDis] only if it was 0 in APTS
        if (LEqual (varRestoreNbps, 1)) {
          Store (procPciDwordRead (0xC5, 0x170), Local0)
          procPciDwordWrite (0xC5, 0x170, And (Local0, Not (ShiftLeft (1, 14))))
           Store (0, varRestoreNbps);
        }
        if (LEqual (varRestoreNbDpmState, 1)) {
          Store (procIndirectRegisterRead (0x0, 0xB8, 0x1F428), Local0)
          procIndirectRegisterWrite (0x0, 0xB8, 0x1F428, Or (Local0, ShiftLeft (1, 5)))
          procNbSmuServiceRequest (22);
          Store (0, varRestoreNbDpmState)
        }
      }
    }
    /*----------------------------------------------------------------------------------------*/
    /**
     *  _PTS
     *
     *
     *
     */
    Method (APTS, 1) {
      if (LEqual (Arg0, 3)) {
         procApmPdmActivate (DEF_PSPP_STATE_DC);
         // Disable NBDPM
         Store (procIndirectRegisterRead (0x0, 0xB8, 0x1F428), Local0)
         if (LNotEqual (And (Local0, ShiftLeft (1, 5)), 0)) {
           // NBDPM enabled lets disable it
           procIndirectRegisterWrite (0x0, 0xB8, 0x1F428, And (Local0, Not (ShiftLeft (1, 5))))
           procNbSmuServiceRequest (22);
           // Indicate needs to restore NBDPM
           Store (1, varRestoreNbDpmState);
         }
         // Save state of D18F5x170 [SwNbPstateLoDis]
         Store (procPciDwordRead (0xC5, 0x170), Local0)
         if (LEqual (And (Local0, ShiftLeft (1, 14)), 0)) {
          // Set D18F5x170 [SwNbPstateLoDis] = 1
          procPciDwordWrite (0xC5, 0x170, Or (Local0, ShiftLeft (1, 14)))
           Store (1, varRestoreNbps);
         }
      }
    }
  } //End of Scope(\_SB)
}   //End of DefinitionBlock


