/**
 * @file
 *
 * Southbridge Init during POWER-ON
 *
 * Prepare Southbridge environment during power on stage.
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project:      CIMx-SB
 * @e sub-project:
 * @e \$Revision:$   @e \$Date:$
 *
 */
/*
 *****************************************************************************
 *
 * 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.
 * 
 * ***************************************************************************
 *
 */

#include    "SBPLATFORM.h"
#include "cbtypes.h"
/**
 * sbPorInitPciTable - PCI device registers initial during the power on stage.
 */
const static REG8MASK sbPorInitPciTable[] =
{
  // SATA device
  {0x00, SATA_BUS_DEV_FUN, 0},
  {SB_SATA_REG84 + 3, ~BIT2, 0},
  {SB_SATA_REG84 + 1, ~(BIT4 + BIT5), BIT4 + BIT5},
  {SB_SATA_REGA0, ~(BIT2 + BIT3 + BIT4 + BIT5 + BIT6), BIT2 + BIT3 + BIT4 + BIT5},
  {0xFF, 0xFF, 0xFF},
  // LPC Device (Bus 0, Dev 20, Func 3)
  {0x00, LPC_BUS_DEV_FUN, 0},
  {SB_LPC_REG48, 0x00, BIT0 + BIT1 + BIT2},
  {SB_LPC_REG7C, 0x00, BIT0 + BIT2},
  {SB_LPC_REGBB, 0xFF, BIT3 + BIT4 + BIT5},
  // A12 set 0xBB [5:3] = 111 to improve SPI timing margin.
  // A12 Set 0xBA [6:5] = 11 improve SPI timing margin. (SPI Prefetch enhancement)
  {SB_LPC_REGBB, 0xBE, BIT0 + BIT3 + BIT4 + BIT5},
  {SB_LPC_REGBA, 0x9F, BIT5 + BIT6},
  {0xFF, 0xFF, 0xFF},
  // P2P Bridge (Bus 0, Dev 20, Func 4)
  {0x00, PCIB_BUS_DEV_FUN, 0},
  {SB_PCIB_REG4B, 0xFF, BIT6 + BIT7 + BIT4},
  // Enable IO but not allocate any IO range. This is for post code display on debug port behind P2P bridge.
  {SB_PCIB_REG1C, 0x00, 0xF0},
  {SB_PCIB_REG1D, 0x00, 0x00},
  {SB_PCIB_REG04, 0x00, 0x21},
  {SB_PCIB_REG40, 0xDF, 0x20},
  {SB_PCIB_REG50, 0x02, 0x01},
  {0xFF, 0xFF, 0xFF},
};

/**
 * sbPmioPorInitTable - Southbridge ACPI MMIO initial during the power on stage.
 */
const static AcpiRegWrite sbPmioPorInitTable[] =
{
  {PMIO_BASE >> 8,  SB_PMIOA_REG5D, 0x00, BIT0},
  {PMIO_BASE >> 8,  SB_PMIOA_REGD2, 0xCF, BIT4 + BIT5},
  {SMBUS_BASE >> 8, SB_SMBUS_REG12, 0x00, BIT0},
  {PMIO_BASE >> 8,  SB_PMIOA_REG28, 0xFF, BIT0},
  {PMIO_BASE >> 8,  SB_PMIOA_REG44 + 3, 0x7F, BIT7},
  {PMIO_BASE >> 8,  SB_PMIOA_REG48, 0xFF, BIT0},
  {PMIO_BASE >> 8,  SB_PMIOA_REG00, 0xFF, 0x0E},
  {PMIO_BASE >> 8,  SB_PMIOA_REG00 + 2, 0xFF, 0x40},
  {PMIO_BASE >> 8,  SB_PMIOA_REG00 + 3, 0xFF, 0x08},
  {PMIO_BASE >> 8,  SB_PMIOA_REG34, 0xEF, BIT0 + BIT1},
  {PMIO_BASE >> 8,  SB_PMIOA_REGEC, 0xFD, BIT1},
  {PMIO_BASE >> 8,  SB_PMIOA_REG5B, 0xF9, BIT1 + BIT2},
  {PMIO_BASE >> 8,  SB_PMIOA_REG08, 0xFE, BIT2 + BIT4},
  {PMIO_BASE >> 8,  SB_PMIOA_REG08 + 1, 0xFF, BIT0},
  {PMIO_BASE >> 8,  SB_PMIOA_REG54, 0x00, BIT4 + BIT7},
  {PMIO_BASE >> 8,  SB_PMIOA_REG04 + 3, 0xFD, BIT1},
  {PMIO_BASE >> 8,  SB_PMIOA_REG74, 0xF6, BIT0 + BIT3},
  {PMIO_BASE >> 8,  SB_PMIOA_REGF0, ~BIT2, 0x00},
  // RPR GEC I/O Termination Setting
  // PM_Reg 0xF6 = Power-on default setting
  // PM_Reg 0xF7 = Power-on default setting
  // PM_Reg 0xF8 = 0x6C
  // PM_Reg 0xF9 = 0x21
  // PM_Reg 0xFA = 0x00 SB800 A12 GEC I/O Pad settings for 3.3V CMOS
  {PMIO_BASE >> 8, SB_PMIOA_REGF8,     0x00, 0x6C},
  {PMIO_BASE >> 8, SB_PMIOA_REGF8 + 1, 0x00, 0x27},
  {PMIO_BASE >> 8, SB_PMIOA_REGF8 + 2, 0x00, 0x00},
  {PMIO_BASE >> 8, SB_PMIOA_REGC4, 0xFE, 0x14},
  {PMIO_BASE >> 8, SB_PMIOA_REGC0 + 2, 0xBF, 0x40},

  {PMIO_BASE >> 8,  SB_PMIOA_REGBE, 0xDF, BIT5},//ENH210907  SB800: request to no longer clear kb_pcirst_en (bit 1) of PM_Reg BEh per the RPR

  {0xFF, 0xFF, 0xFF, 0xFF},
};

/**
 * sbPowerOnInit - Config Southbridge during power on stage.
 *
 *
 *
 * @param[in] pConfig Southbridge configuration structure pointer.
 *
 */
VOID
sbPowerOnInit (
  IN       AMDSBCFG* pConfig
  )
{

  UINT8  dbPortStatus;
  UINT8  dbSysConfig;
  UINT32  abValue;
  UINT8   dbValue;
  UINT8   dbEfuse;
  UINT8   dbCg2WR;
  UINT8   dbCg1Pll;
  UINT8  cimNbSbGen2;
  UINT8  cimSataMode;
  UINT8  cimSpiFastReadEnable;
  UINT8  cimSpiFastReadSpeed;
  UINT8  cimSioHwmPortEnable;
  UINT8  SataPortNum;

  cimNbSbGen2 = pConfig->NbSbGen2;
  cimSataMode = pConfig->SATAMODE.SataModeReg;
// Adding Fast Read Function support
  if (pConfig->BuildParameters.SpiFastReadEnable != 0 ) {
    cimSpiFastReadEnable = (UINT8) pConfig->BuildParameters.SpiFastReadEnable;
  } else {
    cimSpiFastReadEnable = cimSpiFastReadEnableDefault;
  }
  cimSpiFastReadSpeed = (UINT8) pConfig->BuildParameters.SpiFastReadSpeed;
  cimSioHwmPortEnable = pConfig->SioHwmPortEnable;
#if  SB_CIMx_PARAMETER == 0
  cimNbSbGen2 = cimNbSbGen2Default;
  cimSataMode = (UINT8) ((cimSataMode & 0xFB) | cimSataSetMaxGen2Default);
    cimSataMode = (UINT8) ((cimSataMode & 0x0F) | (cimSATARefClkSelDefault + cimSATARefDivSelDefault));
  cimSpiFastReadEnable = cimSpiFastReadEnableDefault;
  cimSpiFastReadSpeed = cimSpiFastReadSpeedDefault;
  cimSioHwmPortEnable = cimSioHwmPortEnableDefault;
#endif

// SB800 Only Enabled (Mmio_mem_enablr)  // Default value is correct
  RWPMIO (SB_PMIOA_REG24, AccWidthUint8, 0xFF, BIT0);

// Set A-Link bridge access address. This address is set at device 14h, function 0,
// register 0f0h.   This is an I/O address. The I/O address must be on 16-byte boundary.
  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGE0, AccWidthUint32, 00, ALINK_ACCESS_INDEX);
  writeAlink (0x80000004, 0x04);     // RPR 4.2 Enable SB800 to issue memory read/write requests in the upstream direction
  abValue = readAlink (SB_ABCFG_REG9C | (UINT32) (ABCFG << 29));      // RPR 4.5 Disable the credit variable in the downstream arbitration equation
  abValue = abValue | BIT0;
  writeAlink (SB_ABCFG_REG9C | (UINT32) (ABCFG << 29), abValue);
  writeAlink (0x30, 0x10);         // AXINDC 0x10[9]=1, Enabling Non-Posted memory write for K8 platform.
  writeAlink (0x34, readAlink (0x34) | BIT9);

  dbEfuse = FUSE_ID_EFUSE_LOC;
  getEfuseStatus (&dbEfuse);
  if ( dbEfuse == M1_D1_FUSE_ID ) {
    dbEfuse = MINOR_ID_EFUSE_LOC;
    getEfuseStatus (&dbEfuse);
    if ( dbEfuse == M1_MINOR_ID ) {
      // Limit ALink speed to 2.5G if Hudson-M1
      cimNbSbGen2 = 0;
    }
  }
// Step 1:
// AXINDP_Reg 0xA4[0] = 0x1
// Step 2:
// AXCFG_Reg 0x88[3:0] = 0x2
// Step3:
// AXINDP_Reg 0xA4[18] = 0x1
  if ( cimNbSbGen2 == TRUE ) {
    rwAlink (SB_AX_INDXP_REGA4, 0xFFFFFFFF, BIT0);
    rwAlink ((UINT32)SB_AX_CFG_REG88, 0xFFFFFFF0, 0x2);
    rwAlink (SB_AX_INDXP_REGA4, 0xFFFFFFFF, BIT18);
  }

// Set Build option into SB
  WritePCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG64, AccWidthUint16 | S3_SAVE, &(pConfig->BuildParameters.SioPmeBaseAddress));
  if (cimSioHwmPortEnable) {
    // Use Wide IO Port 1 to provide access to the superio HWM registers.
    WritePCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG66 , AccWidthUint16 | S3_SAVE, &(pConfig->BuildParameters.SioHwmBaseAddress));
    RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG48 + 3, AccWidthUint8  | S3_SAVE, 0xFF, BIT0); // Wide IO Port 1: enable
    RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG74    , AccWidthUint8  | S3_SAVE, 0xFF, BIT2); // set width 0:512, 1:16 bytes
  }
  RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REGA0, AccWidthUint32 | S3_SAVE, 0x001F, (pConfig->BuildParameters.SpiRomBaseAddress));
  RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG9C, AccWidthUint32 | S3_SAVE, 0, (pConfig->BuildParameters.GecShadowRomBase + 1));
// Enabled SMBUS0/SMBUS1 (ASF) Base Address
  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG2C, AccWidthUint16, 06, (pConfig->BuildParameters.Smbus0BaseAddress) + BIT0); //protect BIT[2:1]
  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG28, AccWidthUint16, 00, (pConfig->BuildParameters.Smbus1BaseAddress));
  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG60, AccWidthUint16, 00, (pConfig->BuildParameters.AcpiPm1EvtBlkAddr));
  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG62, AccWidthUint16, 00, (pConfig->BuildParameters.AcpiPm1CntBlkAddr));
  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG64, AccWidthUint16, 00, (pConfig->BuildParameters.AcpiPmTmrBlkAddr));
  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG66, AccWidthUint16, 00, (pConfig->BuildParameters.CpuControlBlkAddr));
  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG68, AccWidthUint16, 00, (pConfig->BuildParameters.AcpiGpe0BlkAddr));
  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG6A, AccWidthUint16, 00, (pConfig->BuildParameters.SmiCmdPortAddr));
  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG6C, AccWidthUint16, 00, (pConfig->BuildParameters.AcpiPmaCntBlkAddr));
  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG6E, AccWidthUint16, 00, (pConfig->BuildParameters.SmiCmdPortAddr) + 8);
  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG48, AccWidthUint32, 00, (pConfig->BuildParameters.WatchDogTimerBase));

  dbEfuse = SATA_FIS_BASE_EFUSE_LOC;
  getEfuseStatus (&dbEfuse);

  programSbAcpiMmioTbl ((AcpiRegWrite*) FIXUP_PTR (&sbPmioPorInitTable[0]));


  SataPortNum = 0;
  for ( SataPortNum = 0; SataPortNum < 0x06; SataPortNum++ ) {
    RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 2), AccWidthUint8, 0xFF, 1 << SataPortNum);
    SbStall (2);
    RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 2), AccWidthUint8, (0xFF ^ (1 << SataPortNum)) , 0x00);
    SbStall (2);
  }


  //The following bits must be set before enabling SPI prefetch.
  //  Set SPI MMio bit offset 00h[19] to 1 and offset 00h[26:24] to 111, offset 0ch[21:16] to 1, Set LPC cfg BBh[6] to 0 ( by default it is 0).
  // if Ec is enable
  //    Maximum spi speed that can be supported by SB is 22M (SPI Mmio offset 0ch[13:12] to 10) if the rom can run at the speed.
  // else
  //    Maximum spi speed that can be supported by SB is 33M (SPI Mmio offset 0ch[13:12] to 01 in normal mode or offset 0ch[15:14] in fast mode) if the rom can run at
  //    the speed.
  getChipSysMode (&dbSysConfig);
  if (pConfig->BuildParameters.SpiSpeed < 0x02) {
    pConfig->BuildParameters.SpiSpeed = 0x01;
    if (dbSysConfig & ChipSysEcEnable) pConfig->BuildParameters.SpiSpeed = 0x02;
  }

  if (pConfig->SbSpiSpeedSupport) {
    RWMEM ((pConfig->BuildParameters.SpiRomBaseAddress) + SB_SPI_MMIO_REG00, AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, (BIT19 + BIT24 + BIT25 + BIT26));
    RWMEM ((pConfig->BuildParameters.SpiRomBaseAddress) + SB_SPI_MMIO_REG0C, AccWidthUint32 | S3_SAVE, 0xFFC0FFFF, 1 << 16 );
    RWMEM ((pConfig->BuildParameters.SpiRomBaseAddress) + SB_SPI_MMIO_REG0C, AccWidthUint16 | S3_SAVE, ~(BIT13 + BIT12), (pConfig->BuildParameters.SpiSpeed << 12));
  }
  // SPI Fast Read Function
  if ( cimSpiFastReadEnable ) {
    RWMEM ((pConfig->BuildParameters.SpiRomBaseAddress) + SB_SPI_MMIO_REG00, AccWidthUint32 | S3_SAVE, 0xFFFBFFFF, BIT18);
  } else {
    RWMEM ((pConfig->BuildParameters.SpiRomBaseAddress) + SB_SPI_MMIO_REG00, AccWidthUint32 | S3_SAVE, 0xFFFBFFFF, 0x00);
  }

  if ( cimSpiFastReadSpeed ) {
    RWMEM ((pConfig->BuildParameters.SpiRomBaseAddress) + SB_SPI_MMIO_REG0C, AccWidthUint16 | S3_SAVE, ~(BIT15 + BIT14), ( cimSpiFastReadSpeed << 14));
  }
  //Program power on pci init table
  programPciByteTable ( (REG8MASK*) FIXUP_PTR (&sbPorInitPciTable[0]), sizeof (sbPorInitPciTable) / sizeof (REG8MASK) );

  programSbAcpiMmioTbl ((AcpiRegWrite *) (pConfig->OEMPROGTBL.OemProgrammingTablePtr_Ptr));

  dbValue = 0x0A;
  WriteIO (SB_IOMAP_REG70, AccWidthUint8, &dbValue);
  ReadIO (SB_IOMAP_REG71, AccWidthUint8, &dbValue);
  dbValue &= 0xEF;
  WriteIO (SB_IOMAP_REG71, AccWidthUint8, &dbValue);

// Change the CG PLL multiplier to x1.1
  if ( pConfig->UsbRxMode !=0 ) {
    dbCg2WR = 0x00;
    dbCg1Pll = 0x3A;
    ReadMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC8, AccWidthUint8, &dbCg2WR);
    RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGD8, AccWidthUint8, 0, 0x3A);
    ReadMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGD9, AccWidthUint8, &dbCg1Pll);
    dbCg2WR &= BIT4;
    if (( dbCg2WR == 0x00 ) && ( dbCg1Pll !=0x10 ))
    {
      RWMEM (ACPI_MMIO_BASE + MISC_BASE + 0x18, AccWidthUint8, 0xE1, 0x10);
      RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGD8, AccWidthUint8, 0, 0x3A);
      RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGD9, AccWidthUint8, 0, USB_PLL_Voltage);
      RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC8, AccWidthUint8, 0xEF, 0x10);
      dbValue = 0x06;
      WriteIO (0xCF9, AccWidthUint8, &dbValue);      
    } else {
      RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC8, AccWidthUint8, 0xEF, 0x00);
    }
  }

  RWPCI ((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG6C, AccWidthUint32 | S3_SAVE, ~(pConfig->BuildParameters.BiosSize << 4), 0);

  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGDA, AccWidthUint8, 0, (pConfig->SATAMODE.SataModeReg) & 0xFD );

  if (dbEfuse & BIT0) {
    RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGDA, AccWidthUint8, 0xFB, 0x04);
  }

  ReadMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGDA, AccWidthUint8, &dbPortStatus);
  if ( ((dbPortStatus & 0xF0) == 0x10) ) {
    RWMEM (ACPI_MMIO_BASE + MISC_BASE + SB_PMIOA_REG08, AccWidthUint8, 0, BIT5);
  }

  if ( pConfig->BuildParameters.LegacyFree ) {
    RWPCI (((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG44), AccWidthUint32 | S3_SAVE, 00, 0x0003C000);
  } else {
    RWPCI (((LPC_BUS_DEV_FUN << 16) + SB_LPC_REG44), AccWidthUint32 | S3_SAVE, 00, 0xFF03FFD5);
  }

  dbValue = 0x09;
  WriteIO (SB_IOMAP_REGC00, AccWidthUint8, &dbValue);
  ReadIO (SB_IOMAP_REGC01, AccWidthUint8, &dbValue);
  if ( !pConfig->BuildParameters.EcKbd ) {
    // Route SIO IRQ1/IRQ12 to USB IRQ1/IRQ12 input
    dbValue = dbValue & 0xF9;
  }
  if ( pConfig->BuildParameters.LegacyFree ) {
    // Disable IRQ1/IRQ12 filter enable for Legacy free with USB KBC emulation.
    dbValue = dbValue & 0x9F;
  }
  // Enabled IRQ input
  dbValue = dbValue | BIT4;
  WriteIO (SB_IOMAP_REGC01, AccWidthUint8, &dbValue);

#ifndef NO_EC_SUPPORT
  getChipSysMode (&dbPortStatus);
  if ( ((dbPortStatus & ChipSysEcEnable) == 0x00) ) {
    // EC is disabled by jumper setting or board config
    RWPCI (((LPC_BUS_DEV_FUN << 16) + SB_LPC_REGA4), AccWidthUint16 | S3_SAVE, 0xFFFE, BIT0);
  } else {
    RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC4, AccWidthUint8, 0xF7, 0x08);
    ecPowerOnInit ( pConfig);
  }
#endif

  ReadMEM (ACPI_MMIO_BASE + MISC_BASE + SB_MISC_REG80, AccWidthUint8, &dbValue);
  if (dbValue & ChipSysIntClkGen) {
    ReadMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC4, AccWidthUint8, &dbValue);
    if (dbValue & BIT2) {
      RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC0 + 2, AccWidthUint8, 0xDF, 0x20);
    } else {
      RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC4, AccWidthUint8, 0xFB, 0x40);
      RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC0 + 2, AccWidthUint8, 0xDF, 0x20);
      RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REGC4, AccWidthUint8, 0xFB, 0x00);
    }
  }

  // Restore GPP clock to on as it may be off during last POST when some device was disabled;
  // the device can't be detected if enabled again as the values retain on S5 and warm reset.
  RWMEM (ACPI_MMIO_BASE + MISC_BASE + SB_MISC_REG00, AccWidthUint32, 0xFFFFFFFF, 0xFFFFFFFF);
  RWMEM (ACPI_MMIO_BASE + MISC_BASE + SB_MISC_REG04, AccWidthUint8, 0xFF, 0xFF);

  // Set PMx88[5]to enable LdtStp# output to do the C3 or FidVid transation
  RWMEM (ACPI_MMIO_BASE + PMIO_BASE + SB_PMIOA_REG88, AccWidthUint8, 0xFF, BIT5);
}