
/**
 * @file
 *
 * Config Southbridge SATA controller
 *
 * Init SATA features.
 *
 * @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"

//
// Declaration of local functions
//
VOID  sataSetIrqIntResource (IN AMDSBCFG* pConfig);
VOID  sataBar5setting (IN AMDSBCFG* pConfig, IN UINT32 *pBar5);
VOID  shutdownUnconnectedSataPortClock (IN AMDSBCFG* pConfig, IN UINT32 ddBar5);
VOID  sataDriveDetection (IN AMDSBCFG* pConfig, IN UINT32 *pBar5);

/**
 * sataSetIrqIntResource - Config SATA IRQ/INT# resource
 *
 *
 *   - Private function
 *
 * @param[in] pConfig Southbridge configuration structure pointer.
 *
 */
VOID
sataSetIrqIntResource (
  IN       AMDSBCFG*   pConfig
  )
{
  UINT8   dbValue;
  // IRQ14/IRQ15 come from IDE or SATA
  dbValue = 0x08;
  WriteIO (SB_IOMAP_REGC00, AccWidthUint8, &dbValue);
  ReadIO (SB_IOMAP_REGC01, AccWidthUint8, &dbValue);
  dbValue = dbValue & 0x0F;
  if (pConfig->SataClass == 3) {
    dbValue = dbValue | 0x50;
  } else {
    if (pConfig->SataIdeMode == 1) {
      // Both IDE & SATA set to Native mode
      dbValue = dbValue | 0xF0;
    }
  }
  WriteIO (SB_IOMAP_REGC01, AccWidthUint8, &dbValue);
}

/**
 * sataBar5setting - Config SATA BAR5
 *
 *   - Private function
 *
 * @param[in] pConfig - Southbridge configuration structure pointer.
 * @param[in] *pBar5   - SATA BAR5 buffer.
 *
 */
VOID
sataBar5setting (
  IN       AMDSBCFG*   pConfig,
  IN       UINT32      *pBar5
  )
{
  //Get BAR5 value
  ReadPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG24), AccWidthUint32, pBar5);
  //Assign temporary BAR if is not already assigned
  if ( (*pBar5 == 0) || (*pBar5 == - 1) ) {
    //assign temporary BAR5
    if ( (pConfig->TempMMIO == 0) || (pConfig->TempMMIO == - 1) ) {
      *pBar5 = 0xFEC01000;
    } else {
      *pBar5 = pConfig->TempMMIO;
    }
    WritePCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG24), AccWidthUint32, pBar5);
  }
  //Clear Bits 9:0
  *pBar5 = *pBar5 & 0xFFFFFC00;
}
/**
 * shutdownUnconnectedSataPortClock - Shutdown unconnected Sata port clock
 *
 *   - Private function
 *
 * @param[in] pConfig Southbridge configuration structure pointer.
 * @param[in] ddBar5 Sata BAR5 base address.
 *
 */
VOID
shutdownUnconnectedSataPortClock (
  IN       AMDSBCFG* pConfig,
  IN       UINT32 ddBar5
  )
{
  UINT8  dbPortNum;
  UINT8  dbPortSataStatus;
  UINT8  NumOfPorts;
  UINT8  cimSataClkAutoOff;

  cimSataClkAutoOff = (UINT8) pConfig->SataClkAutoOff;
#if  SB_CIMx_PARAMETER == 0
  cimSataClkAutoOff = cimSataClkAutoOffDefault;
#endif
  NumOfPorts = 0;
  if ( cimSataClkAutoOff == TRUE ) {
    for ( dbPortNum = 0; dbPortNum < 6; dbPortNum++ ) {
      ReadMEM (ddBar5 + SB_SATA_BAR5_REG128 + (dbPortNum * 0x80), AccWidthUint8, &dbPortSataStatus);
      // Shutdown the clock for the port and do the necessary port reporting changes.
      // ?? Error port status should be 1 not 3
      if ( ((dbPortSataStatus & 0x0F) != 0x03) && (! ((pConfig->SataEspPort) & (1 << dbPortNum))) ) {
        RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 2), AccWidthUint8, 0xFF, (1 << dbPortNum));
        RWMEM (ddBar5 + SB_SATA_BAR5_REG0C, AccWidthUint8, ~(1 << dbPortNum), 00);
      }
    }     //end of for (dbPortNum=0;dbPortNum<6;dbPortNum++)
    ReadMEM (ddBar5 + SB_SATA_BAR5_REG0C, AccWidthUint8, &dbPortSataStatus);
    //if all ports are in disabled state, report atleast one port
    if ( (dbPortSataStatus & 0x3F) == 0) {
      RWMEM (ddBar5 + SB_SATA_BAR5_REG0C, AccWidthUint8, (UINT32) ~(0x3F), 01);
    }
    ReadMEM (ddBar5 + SB_SATA_BAR5_REG0C, AccWidthUint8, &dbPortSataStatus);
    for (dbPortNum = 0; dbPortNum < 6; dbPortNum ++) {
      if (dbPortSataStatus & (1 << dbPortNum)) {
        NumOfPorts++;
      }
    }
    if ( NumOfPorts == 0) {
      NumOfPorts = 0x01;
    }
    RWMEM (ddBar5 + SB_SATA_BAR5_REG00, AccWidthUint8, 0xE0, NumOfPorts - 1);
  }  //end of SataClkAuto Off option
}

/**
 * Table for class code of SATA Controller in different modes
 *
 *
 *
 *
 */
static const UINT32 sataIfCodeTable[] =
{
  0x01018F40, //sata class ID of IDE
  0x01040040, //sata class ID of RAID
  0x01060140, //sata class ID of AHCI
  0x01018A40, //sata class ID of Legacy IDE
  0x01018F40, //sata class ID of IDE to AHCI mode
};

/**
 * Table for device id of SATA Controller in different modes
 *
 *
 *
 *
 */
static const UINT16 sataDeviceIDTable[] =
{
  0x4390,  //sata device ID of IDE
  0x4392,  //sata device ID of RAID
  0x4391,  //sata class ID of AHCI
  0x4390,  //sata device ID of Legacy IDE
  0x4390,  //sata device ID of IDE->AHCI mode
};

/**
 * Table for Sata Phy Fine Setting
 *
 *
 *
 *
 */
static const SATAPHYSETTING sataPhyTable[] =
{
  {0x3006, 0x0056A607},
  {0x2006, 0x00061400},
  {0x1006, 0x00061302},

  {0x3206, 0x0056A607},
  {0x2206, 0x00061400},
  {0x1206, 0x00061302},

  {0x3406, 0x0056A607},
  {0x2406, 0x00061402},
  {0x1406, 0x00064300},

  {0x3606, 0x0056A607},
  {0x2606, 0x00061402},
  {0x1606, 0x00064300},

  {0x3806, 0x0056A700},
  {0x2806, 0x00061502},
  {0x1806, 0x00064302},

  {0x3A06, 0x0056A700},
  {0x2A06, 0x00061502},
  {0x1A06, 0x00064302}
};

/**
 * sataInitBeforePciEnum - Config SATA controller before PCI emulation
 *
 *
 *
 * @param[in] pConfig Southbridge configuration structure pointer.
 *
 */
VOID
sataInitBeforePciEnum (
  IN       AMDSBCFG*   pConfig
  )
{
  UINT32  ddTempVar;
  UINT32  ddValue;
  UINT32  *tempptr;
  UINT16  *pDeviceIdptr;
  UINT32  dwDeviceId;
  UINT8   dbValue;
  UINT8   pValue;
  UINT16    i;
  SATAPHYSETTING  *pPhyTable;

  ddTempVar = 0;
  // BIT0 Enable write access to PCI header (reg 08h-0Bh) by setting SATA PCI register 40h
  // BIT4: Disable fast boot
  RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, 0xff, BIT0 + BIT2 + BIT4);
  // BIT0 Enable write access to PCI header (reg 08h-0Bh) by setting IDE PCI register 40h
  RWPCI (((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG40), AccWidthUint8 | S3_SAVE, 0xff, BIT0);
  RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 2), AccWidthUint8 | S3_SAVE, 0, pConfig->SataPortPower);
  dbValue = (UINT8)pConfig->SataClass;
  if (dbValue == AHCI_MODE_4394) {
    dbValue = AHCI_MODE;
  }
  if (dbValue == IDE_TO_AHCI_MODE_4394) {
    dbValue = IDE_TO_AHCI_MODE;
  }
  // Disable PATA MSI
  RWPCI (((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG34), AccWidthUint8 | S3_SAVE, 0x00, 0x00);
  RWPCI (((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG06), AccWidthUint8 | S3_SAVE, 0xEF, 0x00);

  // Get the appropriate class code from the table and write it to PCI register 08h-0Bh
  // Set the appropriate SATA class based on the input parameters
  // SATA IDE Controller Class ID & SSID
  tempptr = (UINT32 *) FIXUP_PTR (&sataIfCodeTable[0]);
  if ( (pConfig->SataIdeMode == 1) && (pConfig->SataClass != 3) ) {
    ddValue = tempptr[0];
    // Write the class code to IDE PCI register 08h-0Bh
    RWPCI (((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG08), AccWidthUint32 | S3_SAVE, 0, ddValue);
  }
  ddValue = tempptr[dbValue];
  // Write the class code to SATA PCI register 08h-0Bh
  RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG08), AccWidthUint32 | S3_SAVE, 0, ddValue);
  if ( pConfig->SataClass == LEGACY_IDE_MODE ) {
    //Set PATA controller to native mode
    RWPCI (((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG09), AccWidthUint8 | S3_SAVE, 0x00, 0x08F);
  }
  if (pConfig->BuildParameters.IdeSsid != 0 ) {
    RWPCI ((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG2C, AccWidthUint32 | S3_SAVE, 0x00, pConfig->BuildParameters.IdeSsid);
  }
  // SATA Controller Class ID & SSID
  pDeviceIdptr = (UINT16 *) FIXUP_PTR (&sataDeviceIDTable[0]);
  if ( pConfig->BuildParameters.SataIDESsid != 0 ) {
    ddTempVar = pConfig->BuildParameters.SataIDESsid;
  }
  dwDeviceId = pDeviceIdptr[dbValue];
  if ( pConfig->SataClass == RAID_MODE) {
    if ( pConfig->BuildParameters.SataRAID5Ssid != 0 ) {
      ddTempVar = pConfig->BuildParameters.SataRAID5Ssid;
    }
    dwDeviceId = V_SB_SATA_RAID5_DID;
    pValue = SATA_EFUSE_LOCATION;
    getEfuseStatus (&pValue);
    if (( pValue & SATA_EFUSE_BIT ) || ( pConfig->SataForceRaid == 1 )) {
      dwDeviceId = V_SB_SATA_RAID_DID;
      if ( pConfig->BuildParameters.SataRAIDSsid != 0 ) {
        ddTempVar = pConfig->BuildParameters.SataRAIDSsid;
      }
    }
  }
  if ( ((pConfig->SataClass) == AHCI_MODE) || ((pConfig->SataClass) == IDE_TO_AHCI_MODE) ||
    ((pConfig->SataClass) == AHCI_MODE_4394) || ((pConfig->SataClass) == IDE_TO_AHCI_MODE_4394) ) {
    if ( pConfig->BuildParameters.SataAHCISsid != 0 ) {
      ddTempVar = pConfig->BuildParameters.SataAHCISsid;
    }
  }
  RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG02), AccWidthUint16 | S3_SAVE, 0, dwDeviceId);
  if ( ddTempVar != 0 ) {
    RWPCI ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG2C, AccWidthUint32 | S3_SAVE, 0x00, ddTempVar);
  }
  // SATA IRQ Resource
  sataSetIrqIntResource (pConfig);

  // 8.4 SATA PHY Programming Sequence
  pPhyTable = (SATAPHYSETTING*)FIXUP_PTR (&sataPhyTable[0]);
  for (i = 0; i < (sizeof (sataPhyTable) / sizeof (SATAPHYSETTING)); i++) {
    RWPCI ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG84, AccWidthUint16 | S3_SAVE, ~(BIT1 + BIT2 + BIT9 + BIT10 + BIT11 + BIT12 + BIT13 + BIT14), pPhyTable->wPhyCoreControl);
    RWPCI ((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG94, AccWidthUint32 | S3_SAVE, 0x00, pPhyTable->dwPhyFineTune);
    ++pPhyTable;
  }

//   CallBackToOEM (SATA_PHY_PROGRAMMING, NULL, pConfig);

  RWPCI (((IDE_BUS_DEV_FUN << 16) + SB_IDE_REG40), AccWidthUint8 | S3_SAVE, ~BIT0, 0);
  // Disable write access to PCI header
  RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, ~BIT0, 0);
}

/**
 * sataInitAfterPciEnum - Config SATA controller after PCI emulation
 *
 *
 *
 * @param[in] pConfig Southbridge configuration structure pointer.
 *
 */
VOID
sataInitAfterPciEnum (
  IN       AMDSBCFG* pConfig
  )
{
  UINT32  ddAndMask;
  UINT32  ddOrMask;
  UINT32  ddBar5;
  UINT8  dbVar;
  UINT8  dbPortNum;
  UINT8  dbEfuse;
  UINT8  dbPortMode;
  UINT16  SataPortMode;
  UINT8  cimSataAggrLinkPmCap;
  UINT8  cimSataPortMultCap;
  UINT8  cimSataPscCap;
  UINT8  cimSataSscCap;
  UINT8  cimSataFisBasedSwitching;
  UINT8  cimSataCccSupport;

  cimSataAggrLinkPmCap = (UINT8) pConfig->SataAggrLinkPmCap;
  cimSataPortMultCap = (UINT8) pConfig->SataPortMultCap;
  cimSataPscCap = (UINT8) pConfig->SataPscCap;
  cimSataSscCap = (UINT8) pConfig->SataSscCap;
  cimSataFisBasedSwitching = (UINT8) pConfig->SataFisBasedSwitching;
  cimSataCccSupport = (UINT8) pConfig->SataCccSupport;

#if  SB_CIMx_PARAMETER == 0
  cimSataAggrLinkPmCap = cimSataAggrLinkPmCapDefault;
  cimSataPortMultCap = cimSataPortMultCapDefault;
  cimSataPscCap = cimSataPscCapDefault;
  cimSataSscCap = cimSataSscCapDefault;
  cimSataFisBasedSwitching = cimSataFisBasedSwitchingDefault;
  cimSataCccSupport = cimSataCccSupportDefault;
#endif

  ddAndMask = 0;
  ddOrMask = 0;
  ddBar5 = 0;
  if ( pConfig->SATAMODE.SataMode.SataController == 0 ) {
    return;   //return if SATA controller is disabled.
  }

  //Enable write access to pci header, pm capabilities
  RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, 0xFF, BIT0);
  //Disable AHCI Prefetch function
  RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 2), AccWidthUint8 | S3_SAVE, 0x7F, BIT7);

  sataBar5setting (pConfig, &ddBar5);

  ReadPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar);
  RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8,0xFF, 0x03);   //memory and io access enable
  dbEfuse = SATA_FIS_BASE_EFUSE_LOC;
  getEfuseStatus (&dbEfuse);

  if ( !cimSataPortMultCap ) {
    ddAndMask |= BIT12;
  }
  if ( cimSataAggrLinkPmCap ) {
    ddOrMask |= BIT11;
  } else {
    ddAndMask |= BIT11;
  }
  if ( cimSataPscCap ) {
    ddOrMask |= BIT1;
  }
  if ( cimSataSscCap ) {
    ddOrMask |= BIT26;
  }
  if ( cimSataFisBasedSwitching ) {
    if (dbEfuse & BIT1) {
      ddAndMask |= BIT10;
    } else {
      ddOrMask |= BIT10;
    }
  } else {
    ddAndMask |= BIT10;
  }
  // RPR 8.10 Disabling CCC (Command Completion Coalescing) support.
  if ( cimSataCccSupport ) {
    ddOrMask |= BIT19;
  } else {
    ddAndMask |= BIT19;
  }
  RWMEM ((ddBar5 + SB_SATA_BAR5_REGFC), AccWidthUint32 | S3_SAVE, ~ddAndMask, ddOrMask);


  // SATA ESP port setting
  // These config bits are set for SATA driver to identify which ports are external SATA ports and need to
  // support hotplug. If a port is set as an external SATA port and need to support hotplug, then driver will
  // not enable power management (HIPM & DIPM) for these ports.
  if ( pConfig->SataEspPort != 0 ) {
    RWMEM ((ddBar5 + SB_SATA_BAR5_REGF8), AccWidthUint32 | S3_SAVE, ~(pConfig->SataEspPort), 0);
    RWMEM ((ddBar5 + SB_SATA_BAR5_REGF8), AccWidthUint32 | S3_SAVE, ~(BIT12 + BIT13 + BIT14 + BIT15 + BIT16 + BIT17 + BIT5 + BIT4 + BIT3 + BIT2 + BIT1 + BIT0), (pConfig->SataEspPort << 12));
    // RPR 8.7 External SATA Port Indication Registers
    // If any of the ports was programmed as an external port, HCAP.SXS should also be set
    RWMEM ((ddBar5 + SB_SATA_BAR5_REGFC), AccWidthUint32 | S3_SAVE, ~(BIT20), BIT20);
  } else {
    // RPR 8.7 External SATA Port Indication Registers
    // If any of the ports was programmed as an external port, HCAP.SXS should also be set (Clear for no ESP port)
    RWMEM ((ddBar5 + SB_SATA_BAR5_REGF8), AccWidthUint32 | S3_SAVE, ~(BIT5 + BIT4 + BIT3 + BIT2 + BIT1 + BIT0), 0x00);
    RWMEM ((ddBar5 + SB_SATA_BAR5_REGFC), AccWidthUint32 | S3_SAVE, ~(BIT20), 0x00);
  }
  if ( cimSataFisBasedSwitching ) {
    if (dbEfuse & BIT1) {
      RWMEM ((ddBar5 + SB_SATA_BAR5_REGF8), AccWidthUint32 | S3_SAVE, ~(BIT22 + BIT23 + BIT24 + BIT25 + BIT26 + BIT27), 0x00);
    } else {
      RWMEM ((ddBar5 + SB_SATA_BAR5_REGF8), AccWidthUint32 | S3_SAVE, ~(BIT22 + BIT23 + BIT24 + BIT25 + BIT26 + BIT27), (BIT22 + BIT23 + BIT24 + BIT25 + BIT26 + BIT27));
    }
  } else {
    RWMEM ((ddBar5 + SB_SATA_BAR5_REGF8), AccWidthUint32 | S3_SAVE, ~(BIT22 + BIT23 + BIT24 + BIT25 + BIT26 + BIT27), 0x00);
  }

  // Disabled SATA MSI and D3 Power State capability
  // RPR 8.13 SATA MSI and D3 Power State Capability
  RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG34), AccWidthUint8 | S3_SAVE, 0, 0x70);

  if (((pConfig->SataClass) != NATIVE_IDE_MODE) && ((pConfig->SataClass) != LEGACY_IDE_MODE)) {
    // RAID or AHCI
    if ((pConfig->SATAMODE.SataMode.SataIdeCombinedMode) == SATA_IDE_COMBINE_DISABLE) {
      RWMEM ((ddBar5 + SB_SATA_BAR5_REG00), AccWidthUint8 | S3_SAVE, ~(BIT2 + BIT1 + BIT0), BIT2 + BIT0);
      RWMEM ((ddBar5 + SB_SATA_BAR5_REG0C), AccWidthUint8 | S3_SAVE, 0xC0, 0x3F);
      // RPR 8.10 Disabling CCC (Command Completion Coalescing) support.
      // 8 messages
      RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG50 + 2), AccWidthUint8, ~(BIT3 + BIT2 + BIT1), BIT2 + BIT1);
    } else {
      // RPR 8.10 Disabling CCC (Command Completion Coalescing) support.
      if ( pConfig->SataCccSupport ) {
          // 8 messages
        RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG50 + 2), AccWidthUint8, ~(BIT3 + BIT2 + BIT1), BIT2 + BIT1);
      } else {
          // 4 messages
        RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG50 + 2), AccWidthUint8, ~(BIT3 + BIT2 + BIT1), BIT2);
      }
    }
  }

  if ( pConfig->BIOSOSHandoff == 1 ) {
    RWMEM ((ddBar5 + SB_SATA_BAR5_REG24), AccWidthUint8 | S3_SAVE, ~BIT0, BIT0);
  } else {
    RWMEM ((ddBar5 + SB_SATA_BAR5_REG24), AccWidthUint8 | S3_SAVE, ~BIT0, 0x00);
  }

  SataPortMode = (UINT16)pConfig->SataPortMode;
  dbPortNum = 0;
  while ( dbPortNum < 6 ) {
    dbPortMode = (UINT8) (SataPortMode & 3);
    if ( (dbPortMode == BIT0) || (dbPortMode == BIT1) ) {
      if ( dbPortMode == BIT0 ) {
        // set GEN 1
        RWMEM (ddBar5 + SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0x0F, 0x10);
      }
      if ( dbPortMode == BIT1 ) {
        // set GEN2 (default is GEN3)
        RWMEM (ddBar5 + SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0x0F, 0x20);
      }
      RWMEM (ddBar5 + SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0xFF, 0x01);
    }
    SataPortMode >>= 2;
    dbPortNum ++;
  }
  SbStall (1000);
  SataPortMode = (UINT16)pConfig->SataPortMode;
  dbPortNum = 0;
  while ( dbPortNum < 6 ) {
    dbPortMode = (UINT8) (SataPortMode & 3);
    if ( (dbPortMode == BIT0) || (dbPortMode == BIT1) ) {
      RWMEM (ddBar5 + SB_SATA_BAR5_REG12C + dbPortNum * 0x80, AccWidthUint8, 0xFE, 0x00);
    }
    dbPortNum ++;
    SataPortMode >>= 2;
  }
  WritePCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar);
  //Disable write access to pci header, pm capabilities
  RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, ~BIT0, 0);
}


/**
 * sataInitMidPost - Config SATA controller in Middle POST.
 *
 *
 *
 * @param[in] pConfig Southbridge configuration structure pointer.
 *
 */
VOID
sataInitMidPost (
  IN       AMDSBCFG* pConfig
  )
{
  UINT32   ddBar5;
  sataBar5setting (pConfig, &ddBar5);
  //If this is not S3 resume and also if SATA set to one of IDE mode, then implement drive detection workaround.
  if ( ! (pConfig->S3Resume) && ( ((pConfig->SataClass) != AHCI_MODE)  && ((pConfig->SataClass) != RAID_MODE) ) ) {
    sataDriveDetection (pConfig, &ddBar5);
  }
}

/**
 * sataDriveDetection - Sata drive detection
 *
 *
 * @param[in] pConfig Southbridge configuration structure pointer.
 * @param[in] *pBar5 Sata BAR5 base address.
 *
 */
VOID
sataDriveDetection (
  IN       AMDSBCFG* pConfig,
  IN       UINT32 *pBar5
  )
{
  UINT32   ddVar0;
  UINT8   dbPortNum;
  UINT8   dbVar0;
  UINT16   dwIoBase;
  UINT32   dwVar0;
  if ( (pConfig->SataClass == NATIVE_IDE_MODE) || (pConfig->SataClass == LEGACY_IDE_MODE) || (pConfig->SataClass == IDE_TO_AHCI_MODE) ) {
    for ( dbPortNum = 0; dbPortNum < 4; dbPortNum++ ) {
      ReadMEM (*pBar5 + SB_SATA_BAR5_REG128 + dbPortNum * 0x80, AccWidthUint32, &ddVar0);
      if ( ( ddVar0 & 0x0F ) == 0x03 ) {
        if ( dbPortNum & BIT0 ) {
          //this port belongs to secondary channel
          ReadPCI (((UINT32) (SATA_BUS_DEV_FUN << 16) + SB_SATA_REG18), AccWidthUint16, &dwIoBase);
        } else {
          //this port belongs to primary channel
          ReadPCI (((UINT32) (SATA_BUS_DEV_FUN << 16) + SB_SATA_REG10), AccWidthUint16, &dwIoBase);
        }
        //if legacy ide mode, then the bar registers don't contain the correct values. So we need to hardcode them
        if ( pConfig->SataClass == LEGACY_IDE_MODE ) {
          dwIoBase = ( (0x170) | ((UINT16) ( (~((UINT8) (dbPortNum & BIT0) << 7)) & 0x80 )) );
        }
        if ( dbPortNum & BIT1 ) {
          //this port is slave
          dbVar0 = 0xB0;
        } else {
          //this port is master
          dbVar0 = 0xA0;
        }
        dwIoBase &= 0xFFF8;
        WriteIO (dwIoBase + 6, AccWidthUint8, &dbVar0);
        //Wait in loop for 30s for the drive to become ready
        for ( dwVar0 = 0; dwVar0 < 300000; dwVar0++ ) {
          ReadIO (dwIoBase + 7, AccWidthUint8, &dbVar0);
          if ( (dbVar0 & 0x88) == 0 ) {
            break;
          }
          SbStall (100);
        }
      } //end of if ( ( ddVar0 & 0x0F ) == 0x03)
    } //for (dbPortNum = 0; dbPortNum < 4; dbPortNum++)
  } //if ( (pConfig->SataClass == NATIVE_IDE_MODE) || (pConfig->SataClass == LEGACY_IDE_MODE) || (pConfig->SataClass == IDE_TO_AHCI_MODE))
}

/**
 * sataInitLatePost - Prepare SATA controller to boot to OS.
 *
 *              - Set class ID to AHCI (if set to AHCI * Mode)
 *              - Enable AHCI interrupt
 *
 * @param[in] pConfig Southbridge configuration structure pointer.
 *
 */
VOID
sataInitLatePost (
  IN       AMDSBCFG* pConfig
  )
{
  UINT32  ddBar5;
  UINT8  dbVar;
  UINT8  dbPortNum;

  //Return immediately is sata controller is not enabled
  if ( pConfig->SATAMODE.SataMode.SataController == 0 ) {
    return;
  }
  //Enable write access to pci header, pm capabilities
  RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, 0xff, BIT0);

//  if ((pConfig->SATAMODE.SataMode.SataIdeCombinedMode) == SATA_IDE_COMBINE_DISABLE) {
  RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40 + 1), AccWidthUint8 | S3_SAVE, ~BIT7, BIT7);
//  }
  sataBar5setting (pConfig, &ddBar5);

  ReadPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar);
  //Enable memory and io access
  RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, 0xFF, 0x03);

  shutdownUnconnectedSataPortClock (pConfig, ddBar5);

  if (( pConfig->SataClass == IDE_TO_AHCI_MODE) || ( pConfig->SataClass == IDE_TO_AHCI_MODE_4394 )) {
    //program the AHCI class code
    RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG08), AccWidthUint32 | S3_SAVE, 0, 0x01060100);
    //Set interrupt enable bit
    RWMEM ((ddBar5 + 0x04), AccWidthUint8, (UINT32)~0, BIT1);
    //program the correct device id for AHCI mode
    RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG02), AccWidthUint16 | S3_SAVE, 0, 0x4391);
  }

  if (( pConfig->SataClass == AHCI_MODE_4394 ) || ( pConfig->SataClass == IDE_TO_AHCI_MODE_4394 )) {
    //program the correct device id for AHCI 4394 mode
    RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG02), AccWidthUint16 | S3_SAVE, 0, 0x4394);
  }

  //Clear error status ?? only 4 port
  RWMEM ((ddBar5 + SB_SATA_BAR5_REG130), AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF);
  RWMEM ((ddBar5 + SB_SATA_BAR5_REG1B0), AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF);
  RWMEM ((ddBar5 + SB_SATA_BAR5_REG230), AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF);
  RWMEM ((ddBar5 + SB_SATA_BAR5_REG2B0), AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF);
  RWMEM ((ddBar5 + SB_SATA_BAR5_REG330), AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF);
  RWMEM ((ddBar5 + SB_SATA_BAR5_REG3B0), AccWidthUint32 | S3_SAVE, 0xFFFFFFFF, 0xFFFFFFFF);
  //Restore memory and io access bits
  WritePCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG04), AccWidthUint8, &dbVar );
  //Disable write access to pci header and pm capabilities
  RWPCI (((SATA_BUS_DEV_FUN << 16) + SB_SATA_REG40), AccWidthUint8 | S3_SAVE, ~BIT0, 0);
  for ( dbPortNum = 0; dbPortNum < 6; dbPortNum++ ) {
    RWMEM ((ddBar5 + 0x110 + (dbPortNum * 0x80)), AccWidthUint32, 0xFFFFFFFF, 0x00);
  }
}


