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


  /*----------------------------------------------------------------------------------------*/
  /**
   *  PCIe MMIO Base address
   *
   */

  Name (
    AD01,
    0xE0000000
  )

  Alias (
    AD01,
    varPcieBase
  )



  /*----------------------------------------------------------------------------------------*/
  /**
   *  PCIe port info
   *
   */
   
  Name (
    AD07,
    Package () {
      Buffer () {0,0,0,0,0,0,0,0,0,0},    //dev2
      Buffer () {0,0,0,0,0,0,0,0,0,0},    //dev3
      Buffer () {0,0,0,0,0,0,0,0,0,0},    //dev4
      Buffer () {0,0,0,0,0,0,0,0,0,0},    //dev5
      Buffer () {0,0,0,0,0,0,0,0,0,0},    //dev6
      Buffer () {0,0,0,0,0,0,0,0,0,0},    //dev7
      Buffer () {0,0,0,0,0,0,0,0,0,0},    //dev8
      Buffer () {0,0,0,0,0,0,0,0,0,0},    //dev9
    }
  )

  Alias (
    AD07,
    varPortInfo
  )


  Name (varStringBuffer, Buffer (256) {})

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Master control method
   *
   *  Arg0 - Function ID
   *  Arg1 - Function specific data buffer
   */
  Method (ALIB, 2, NotSerialized) {
    If (Lequal (Arg0, 0x1)) {
      return (procPsppReportAcDsState (Arg1))
    } 
    If (LEqual (Arg0, 0x2)) {
      return (procPsppPerformanceRequest (Arg1))
    } 
    If (LEqual (Arg0, 0x3)) {
      return (procPsppControl (Arg1))
    } 
    If (LEqual (Arg0, 0x4)) {
      return (procPcieSetBusWidth (Arg1))
    } 
    If (LEqual (Arg0, 0x5)) {
      return (procAlibInit ())
    } 
    If (LEqual (Arg0, 0x6)) {
      return (procPciePortHotplug (Arg1))
    }
    return (0)
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Alib Init
   *
   *
   */
  Method (procAlibInit, 0, Serialized) {

    return (0)
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Read PCI config register through MMIO
   *
   *  Arg0 - PCI address Bus/device/func
   *  Arg1 - Register offset
   */
  Method (procPciDwordRead, 2, Serialized) {
    Add (varPcieBase, ShiftLeft (Arg0, 12), Local0)
    Add (Arg1, Local0, Local0)
    OperationRegion(varOperationRegionMmio, SystemMemory, Local0, 0x4)
      Field(varOperationRegionMmio, DWordAcc, NoLock, Preserve) {
      Offset (0x0),
      varPciReg32, 32,
      }
    return (varPciReg32)
  }
  /*----------------------------------------------------------------------------------------*/
  /**
   *  Write PCI config register through MMIO
   *
   *  Arg0 - PCI address Bus/device/func
   *  Arg1 - Register offset
   *  Arg2 - Value
   */
  Method (procPciDwordWrite, 3, Serialized) {
    Add (varPcieBase, ShiftLeft (Arg0, 12), Local0)
    Add (Arg1, Local0, Local0)
    OperationRegion(varOperationRegionMmio, SystemMemory, Local0, 0x4)
      Field(varOperationRegionMmio, DWordAcc, NoLock, Preserve) {
      Offset (0x0),
      varPciReg32, 32,
      }
    Store (Arg2, varPciReg32)
  }
  /*----------------------------------------------------------------------------------------*/
  /**
   *  Write PCI config register through MMIO
   *
   *  Arg0 - PCI address Bus/device/func
   *  Arg1 - Register offset
   *  Arg2 - AND mask
   *  Arg3 - OR mask
   */
  Method (procPciDwordRMW, 4, Serialized) {
    Store (procPciDwordRead (Arg0, Arg1), Local0)
    Or (And (Local0, Arg2), Arg3, Local0)
    procPciDwordWrite (Arg0, Arg1, Local0)
  }

  Mutex(varPciePortAccessMutex, 0)    
  /*----------------------------------------------------------------------------------------*/
  /**
   *  Read PCIe port indirect register
   *
   *  Arg0 - Port Index
   *  Arg1 - Register offset
   *
   */
  Method (procPciePortIndirectRegisterRead, 2, NotSerialized) {
    Acquire(varPciePortAccessMutex, 0xFFFF)
    Store (ShiftLeft (Add( Arg0, 2), 3), Local0)
    procPciDwordWrite (Local0, 0xe0, Arg1)
    Store (procPciDwordRead (Local0, 0xe4), Local0)
    Release (varPciePortAccessMutex)  
    return (Local0)
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Write PCIe port indirect register
   *
   *  Arg0 - Port Index
   *  Arg1 - Register offset
   *  Arg2 - Value
   */
  Method (procPciePortIndirectRegisterWrite, 3, NotSerialized) {
    Acquire(varPciePortAccessMutex, 0xFFFF)
    Store (ShiftLeft (Add( Arg0, 2), 3), Local0)
    procPciDwordWrite (Local0, 0xe0, Arg1)
    procPciDwordWrite (Local0, 0xe4, Arg2)
    Release (varPciePortAccessMutex)
  }
  /*----------------------------------------------------------------------------------------*/
  /**
   *  Read PCIe port indirect register
   *
   *  Arg0 - Port Index
   *  Arg1 - Register offset
   *  Arg2 - AND Mask
   *  Arg3 - OR Mask
   *
   */
  Method (procPciePortIndirectRegisterRMW, 4, NotSerialized) {
    Store (procPciePortIndirectRegisterRead (Arg0, Arg1), Local0)
    Or (And (Local0, Arg2), Arg3, Local0)
    procPciePortIndirectRegisterWrite (Arg0, Arg1, Local0)
  }
  Mutex(varHostAccessMutex, 0)
  /*----------------------------------------------------------------------------------------*/
  /**
   *  Read PCIe port indirect register
   *
   *  Arg0 - BDF
   *  Arg1 - Register offset
   *  Arg2 - Register address
   *
   */
  Method (procIndirectRegisterRead, 3, NotSerialized) {
    Acquire(varHostAccessMutex, 0xFFFF)
    procPciDwordWrite (Arg0, Arg1, Arg2)
    Store (procPciDwordRead (Arg0, Add (Arg1, 4)), Local0)
    Release(varHostAccessMutex)
    return (Local0)
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Write PCIe port indirect register
   *
   *  Arg0 - BDF
   *  Arg1 - Register offset
   *  Arg2 - Register address
   *  Arg3 - Value
   */
  Method (procIndirectRegisterWrite, 4, NotSerialized) {
    Acquire(varHostAccessMutex, 0xFFFF)
    procPciDwordWrite (Arg0, Arg1, Arg2)
    procPciDwordWrite (Arg0, Add (Arg1, 4), Arg3)
    Release(varHostAccessMutex)
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Read Modify Write indirect registers
   *
   *  Arg0 - BDF
   *  Arg1 - Register Offset
   *  Arg2 - Register Address
   *  Arg3 - AND Mask
   *  Arg4 - OR Mask
   *
   */
  Method (procIndirectRegisterRMW, 5, NotSerialized) {
    Store (procIndirectRegisterRead (Arg0, Arg1, Arg2), Local0)
    Or (And (Local0, Arg3), Arg4, Local0)
    procIndirectRegisterWrite (Arg0, Arg1, Arg2, Local0)
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *  
   *
   *  Arg0 	- Port ID
   *  Retval	- buffer that represent port data set
   */
  Method (procPcieGetPortInfo, 1, NotSerialized) {
    return (DeRefOf (Index (varPortInfo, Arg0)))
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *  Find Pci Capability
   *
   *  Arg0 - PCI address Bus/device/func
   *  Arg1 - Capability id
   */
  Method (procFindPciCapability, 2, NotSerialized) {
    Store (0x34, Local1)
    if (LEqual (procPciDwordRead (Arg0, 0x0), 0xFFFFFFFF)) {
      // Device not present
      return  (0)
    }
    Store (1, Local0)
    while (LEqual (Local0, 1)) {
      Store (And (procPciDwordRead (Arg0, Local1), 0xFF), Local1)
      if (LEqual (Local1, 0)) {
        break
      }
        if (LEqual (And (procPciDwordRead (Arg0, Local1), 0xFF), Arg1)) {
        	Store (0, Local0)
        } else {
        	Increment (Local1)
        }
      }
    return (Local1)
  }

  /*----------------------------------------------------------------------------------------*/
  /**
   *  
   *
   *  Arg0 	- Aspm
   *  Arg1 	- 0: Read, 1: Write
   */
  Method (procPcieSbAspmControl, 2, Serialized) {
	  // Create an opregion for PM IO Registers
	  OperationRegion (PMIO, SystemIO, 0xCD6, 0x2)
	  Field (PMIO, ByteAcc, NoLock, Preserve)
	  {
	  	PMRI, 8,
	  	PMRD, 8
	  }
	  IndexField (PMRI, PMRD, ByteAcc, NoLock, Preserve)
	  {
	  	Offset(0xE0),               // IO Base address of A-Link Express/ A-Link Bridge register
	  	ABAR, 32, 
	  }
    OperationRegion (ACFG, SystemIO, ABAR, 0x8)
	  Field (ACFG, DWordAcc, Nolock, Preserve) //AB_INDX/AB_DATA
	  {
	  	ABIX, 32,
	  	ABDA, 32
	  }

    Store (0, Local0)
    if (LEqual (Arg1, 0)) {
      Store (0x80000068, ABIX)
      Store (ABDA, Local0)
      return (Local0)
    } else {
      Store (0x80000068, ABIX)
      Store (ABDA, Local0)
      Or (And (Local0, 0xfffffffc), Arg0, Local0)
      Store (Local0, ABDA)
    }
  }

