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

/**
 * PCIE_CAP_ID - PCIe Cap ID
 *
 */
#define  PCIE_CAP_ID             0x10

//
// Declaration of local functions
//

/**
 * PreInitGppLink - Enable GPP link training.
 *
 * @param[in] pConfig Southbridge configuration structure pointer.
 *
 */
  VOID  PreInitGppLink (IN AMDSBCFG* pConfig);
  UINT8 CheckGppLinkStatus (IN AMDSBCFG* pConfig);
  VOID  AfterGppLinkInit (IN AMDSBCFG* pConfig);
  VOID  sbGppForceGen2 (IN UINT32 portId );
  VOID  sbGppForceGen1 (IN UINT32 portId );
  VOID  sbGppDisableUnusedPadMap (IN AMDSBCFG* pConfig );
  VOID  sbGppSetAspm (IN UINT32 pciAddress, IN UINT8  LxState);
  UINT8 sbFindPciCap (IN UINT32 pciAddress, IN UINT8 targetCapId);

//
// Declaration of external functions
//

//
//-----------------------------------------------------------------------------------
// Early SB800 GPP initialization sequence:
//
// 1) Set port enable bit fields by current GPP link configuration mode
// 2) Deassert GPP reset and pull EP out of reset - Clear GPP_RESET (abcfg:0xC0[8] = 0)
// 3) Loop polling for the link status of all ports
// 4) Misc operations after link training:
//      - (optional) Detect GFX device
//      - Hide empty GPP configuration spaces (Disable empty GPP ports)
//      - (optional) Power down unused GPP ports
//      - (optional) Configure PCIE_P2P_Int_Map (abcfg:0xC4[7:0])
// 5) GPP init completed
//
//
// *) Gen2 vs Gen1
//                                   Gen2 mode     Gen1 mode
//  ---------------------------------------------------------------
//    STRAP_PHY_PLL_CLKF[6:0]          7'h32         7'h19
//    STRAP_BIF_GEN2_EN                  1             0
//
//    PCIE_PHY_PLL clock locks @       5GHz
//
//

/**
 * GPP early programming and link training. On exit all populated EPs should be fully operational.
 *
 *
 *
 * @param[in] pConfig Southbridge configuration structure pointer.
 *
 */
VOID
sbPcieGppEarlyInit (
  IN       AMDSBCFG* pConfig
  )
{
  UINT8   TogglePort;
  UINT8   portNum;
  UINT32  reg32Value;
  UINT8   retryCount;
  UINT8   cimGppMemWrImprove;
  UINT8   cimGppLaneReversal;
  UINT8   cimAlinkPhyPllPowerDown;

  cimGppMemWrImprove = pConfig->GppMemWrImprove;
  cimGppLaneReversal = (UINT8) pConfig->GppLaneReversal;
  cimAlinkPhyPllPowerDown = (UINT8) pConfig->AlinkPhyPllPowerDown;
#if  SB_CIMx_PARAMETER == 0
  cimGppMemWrImprove = cimGppMemWrImproveDefault;
  cimGppLaneReversal = cimGppLaneReversalDefault;
  cimAlinkPhyPllPowerDown = cimAlinkPhyPllPowerDownDefault;
#endif

//
// Configure NB-SB link PCIE PHY PLL power down for L1
//
  if ( cimAlinkPhyPllPowerDown == TRUE ) {
    UINT32  abValue;
    // Set PCIE_P_CNTL in Alink PCIEIND space
    writeAlink (SB_AX_INDXC_REG30 | ((UINT32) AXINDC << 29), 0x40);
    abValue = readAlink (SB_AX_DATAC_REG34 | ((UINT32) AXINDC << 29));
    abValue |= BIT12 + BIT3 + BIT0;
    abValue &= ~(BIT9 + BIT4);
    writeAlink (SB_AX_DATAC_REG34 | ((UINT32) AXINDC << 29), abValue);
    rwAlink (SB_AX_INDXC_REG02 | ((UINT32) AXINDC << 29), ~BIT8, (BIT8));
  }

//
// Set ABCFG 0x031C[0] = 1 enable the lane reversal support.
//
  reg32Value = readAlink (SB_ABCFG_REG31C | ((UINT32) ABCFG << 29));
  if ( cimGppLaneReversal ) {
    writeAlink (SB_ABCFG_REG31C | ((UINT32) ABCFG << 29), reg32Value | BIT0);
  } else {
    writeAlink (SB_ABCFG_REG31C | ((UINT32) ABCFG << 29), reg32Value | 0x00);
  }
//
// Set abcfg:0x90[20] = 1 to enable GPP bridge multi-function
//
  reg32Value = readAlink (SB_ABCFG_REG90 | ((UINT32) ABCFG << 29));
  writeAlink (SB_ABCFG_REG90 | ((UINT32) ABCFG << 29), reg32Value | BIT20);


//
// Initialize and configure GPP
//
  if (pConfig->GppFunctionEnable) {
    // PreInit - Enable GPP link training
    PreInitGppLink (pConfig);

//
// GPP Upstream Memory Write Arbitration Enhancement ABCFG 0x54[26] = 1
// GPP Memory Write Max Payload Improvement RCINDC_Reg 0x10[12:10] = 0x4
//
    if ( cimGppMemWrImprove == TRUE ) {
      rwAlink (SB_ABCFG_REG54 | ((UINT32) ABCFG << 29), ~BIT26, (BIT26));
      rwAlink (SB_RCINDXC_REG10 | ((UINT32) RCINDXC << 29), ~(BIT12 + BIT11 + BIT10), (BIT12));
    }

    if ( pConfig->S3Resume ) {
      for ( portNum = 0; portNum < MAX_GPP_PORTS; portNum++ ) {
        reg32Value = readAlink ((SB_ABCFG_REG340 + portNum * 4) | ((UINT32) ABCFG << 29));
        writeAlink ((SB_ABCFG_REG340 + portNum * 4) | ((UINT32) ABCFG << 29), reg32Value & ~BIT21);
      }
    }
    //
    //  a) Loop polling regA5 -> LcState (timeout ~100ms);
    //  b) if (LcState[5:0] == 0x10), training successful, go to g);
    //  c) if any of (LcState[13:8], [21:16], [29:24]) == 0x29 or 0x2A:
    //  d) Clear De-emphasis bit for relevant ports;
    //  e) Toggle GPP reset signal (via OEM callback);
    //  f) go back to a);
    //  g) exit;
    //
    for (retryCount = 0; retryCount < MAX_GPP_RESETS; retryCount++) {
      // Polling each GPP port for link status
      TogglePort = CheckGppLinkStatus (pConfig);

      if (TogglePort == 0) {
        break;
      } else {
        // Check failure port and clear STRAP_BIF_DE_EMPHASIS_SEL_x_GPP bit (abcfg:0x34[0, 4, 8, C][21]=0)
        for ( portNum = 0; portNum < MAX_GPP_PORTS; portNum++ ) {
          if (TogglePort & (1 << portNum)) {
            reg32Value = readAlink ((SB_ABCFG_REG340 + portNum * 4) | ((UINT32) ABCFG << 29));
            writeAlink ((SB_ABCFG_REG340 + portNum * 4) | ((UINT32) ABCFG << 29), reg32Value & ~BIT21);
          }
          sbGppForceGen1 (portNum);
        }

        // Toggle GPP reset (Note this affects all SB800 GPP ports)
        CallBackToOEM (CB_SBGPP_RESET_ASSERT, (UINT32)TogglePort, pConfig);
        SbStall (500);
        CallBackToOEM (CB_SBGPP_RESET_DEASSERT, (UINT32)TogglePort, pConfig);
      }
    };

    // Misc operations after link training
    AfterGppLinkInit (pConfig);
  } else {

// RPR 5.11 Power Saving With GPP Disable
// ABCFG 0xC0[8] = 0x0
// ABCFG 0xC0[15:12] = 0xF
// Enable "Power Saving Feature for A-Link Express Lanes"
// Enable "Power Saving Feature for GPP Lanes"
// ABCFG 0x90[19] = 1
// ABCFG 0x90[6] = 1
// RCINDC_Reg 0x65 [27:0] = 0xFFFFFFF
// ABCFG 0xC0[7:4] = 0x0

    rwAlink (SB_ABCFG_REGC0 | ((UINT32) ABCFG << 29), ~BIT8, (BIT4 + BIT5 + BIT6 + BIT7));
    rwAlink (SB_ABCFG_REGC0 | ((UINT32) ABCFG << 29), 0xFFFFFFFF, (BIT12 + BIT13 + BIT14 + BIT15));
    rwAlink (SB_AX_INDXC_REG40, ~(BIT9 + BIT4), (BIT0 + BIT3 + BIT12));
    rwAlink (RC_INDXC_REG40, ~(BIT9 + BIT4), (BIT0 + BIT3 + BIT12));
    rwAlink ((SB_ABCFG_REG90 | ((UINT32) ABCFG << 29)), 0xFFFFFFFF, (BIT6 + BIT19));
    rwAlink (RC_INDXC_REG65, 0xFFFFFFFF, 0x0fffffff);
    rwAlink ((SB_ABCFG_REGC0 | ((UINT32) ABCFG << 29)), ~(BIT4 + BIT5 + BIT6 + BIT7), 0);
  }
  sbGppDisableUnusedPadMap ( pConfig );
}

/**
 * PreInitGppLink - Enable GPP link training.
 *
 *
 *
 * @param[in] pConfig Southbridge configuration structure pointer.
 *
 */
VOID
PreInitGppLink (
  IN       AMDSBCFG* pConfig
  )
{
  UINT8 portMask[5] = {0x01,
    0x00,
    0x03,
    0x07,
    0x0F
  };
  UINT8  cfgMode;
  UINT8  portId;
  UINT32 reg32Value;
  UINT16 tmp16Value;

//  PCIE_GPP_ENABLE (abcfg:0xC0):
//
//     GPP_LINK_CONFIG ([3:0])  PortA   PortB   PortC   PortD    Description
//    ----------------------------------------------------------------------------------
//                       0000    0-3                             x4 Config
//                       0001                                    N/A
//                       0010    0-1     2-3      0              2:2 Config
//                       0011    0-1      2       3              2:1:1 Config
//                       0100     0       1       2       3      1:1:1:1 Config
//
//  For A12 and above:
//                  ABCFG:0xC0[12] - Port A hold training (default 1)
//                  ABCFG:0xC0[13] - Port B hold training (default 1)
//                  ABCFG:0xC0[14] - Port C hold training (default 1)
//                  ABCFG:0xC0[15] - Port D hold training (default 1)
//
//
  //
  // Set port enable bit fields based on current GPP link configuration mode
  //
  cfgMode = (UINT8) pConfig->GppLinkConfig;
  if ( cfgMode > GPP_CFGMODE_X1111 || cfgMode == 1 ) {
    cfgMode = GPP_CFGMODE_X4000;
    pConfig->GppLinkConfig = GPP_CFGMODE_X4000;
  }
  reg32Value = (UINT32) portMask[cfgMode];

  // Mask out non-applicable ports according to the target link configuration mode
  for ( portId = 0; portId < MAX_GPP_PORTS; portId++ ) {
    if (!(reg32Value & (1 << portId)))
      pConfig->PORTCONFIG[portId].PortCfg.PortPresent = false;
    else if (!pConfig->PORTCONFIG[portId].PortCfg.PortPresent)
      reg32Value &= ~(1 << portId);
  }

  //
  // Deassert GPP reset and pull EP out of reset - Clear GPP_RESET (abcfg:0xC0[8] = 0)
  //
  tmp16Value = (UINT16) (~reg32Value << 12);
  reg32Value = (UINT32) (tmp16Value + (reg32Value << 4) + cfgMode);
  writeAlink (SB_ABCFG_REGC0 | ((UINT32) ABCFG << 29), reg32Value);

  reg32Value = readAlink (0xC0 | ((UINT32) RCINDXC << 29));
  writeAlink (0xC0 | ((UINT32) RCINDXC << 29), reg32Value | 0x400);  // Set STRAP_F0_MSI_EN

  // A-Link L1 Entry Delay Shortening
  // AXINDP_Reg 0xA0[7:4] = 0x3
  rwAlink (SB_AX_INDXP_REGA0, 0xFFFFFF0F, 0x30);
  rwAlink (SB_AX_INDXP_REGB1, 0xFFFFFFFF, BIT19);
  rwAlink (SB_AX_INDXP_REGB1, 0xFFFFFFFF, BIT28);

  // RPR5.22 GPP L1 Entry Delay Shortening
  // RCINDP_Reg 0xA0[7:4] = 0x1 Enter L1 sooner after ACK'ing PM request.
  // This is done to reduce number of NAK received with L1 enabled.
  for ( portId = 0; portId < MAX_GPP_PORTS; portId++ ) {
    rwAlink (SB_RCINDXP_REGA0 | portId << 24, 0xFFFFFF0F, 0x10);
  }
}

/**
 * CheckGppLinkStatus - loop polling the link status for each GPP port
 *
 *
 * Return:     ToggleStatus[3:0] = Port bitmap for those need to clear De-emphasis
 *
 * @param[in] pConfig Southbridge configuration structure pointer.
 *
 */
UINT8
CheckGppLinkStatus (
  IN       AMDSBCFG* pConfig
  )
{
  UINT32  retryCounter;
  UINT32  portId;
  UINT32  abIndex;
  UINT32  Data32;
  UINT8   portScanMap;
  UINT8   portScanMap2;
  UINT8   ToggleStatus;
  UINT16  i;
  SBGPPPORTCONFIG  *portCfg;


  portScanMap = 0;
  retryCounter = MAX_TRAINING_RETRY;
  ToggleStatus = 0;

  // Obtain a list of ports to be checked
  for ( portId = 0; portId < MAX_GPP_PORTS; portId++ ) {
    portCfg = &pConfig->PORTCONFIG[portId].PortCfg;
    if ( portCfg->PortPresent == TRUE && portCfg->PortDetected == FALSE ) {
      portScanMap |= 1 << portId;
    }
  }
  portScanMap2 = portScanMap;

  //
  // After training is enabled, Check LCSTATE for each port, if LCSTATE<= 4, then keep
  // polling for up to 40ms. If LCSTATE still <= 4, then assume the port to be empty.
  //
  i = 400;
  while ( --i && portScanMap2) {
    for (portId = 0; portId < MAX_GPP_PORTS; portId++) {
      portCfg = &pConfig->PORTCONFIG[portId].PortCfg;
      if (((portCfg->PortHotPlug == FALSE) || ((portCfg->PortHotPlug == TRUE) && (pConfig->S3Resume == FALSE)) ) && (portScanMap2 & (1 << portId))) {
        //
        // Get port link state (reading LC_CURRENT_STATE of PCIEIND_P)
        //
        abIndex = SB_RCINDXP_REGA5 | ((UINT32) RCINDXP << 29) | (portId << 24);
        Data32 = readAlink (abIndex) & 0x3F;
        if ((UINT8) (Data32) > 4) {
          portScanMap2 &= ~(1 << portId);       // This port is not empty
          break;
        }
        SbStall (100);                          // Delay 100us
      }
    }
  }
  portScanMap &= ~portScanMap2;                 // Mark remaining ports as empty


  while ( --retryCounter && portScanMap ) {
    for ( portId = 0; portId < MAX_GPP_PORTS; portId++ ) {
      portCfg = &pConfig->PORTCONFIG[portId].PortCfg;
      if (( portCfg->PortHotPlug == TRUE ) && ( pConfig->S3Resume )) {
        continue;
      }
      if ( portCfg->PortPresent == TRUE && portCfg->PortDetected == FALSE ) {
        //
        // Get port link state (reading LC_CURRENT_STATE of PCIEIND_P)
        //
        SbStall (1000);                          // Delay 400us
        abIndex = SB_RCINDXP_REGA5 | ((UINT32) RCINDXP << 29) | (portId << 24);
        Data32 = readAlink (abIndex) & 0x3F3F3F3F;

        if ( (UINT8) (Data32) == 0x10 ) {
          portCfg->PortDetected = TRUE;
          portScanMap &= ~(1 << portId);
        } else {
          for (i = 0; i < 4; i++) {
            //
            // Compliance mode (0x7), downgrade from Gen2 to Gen1 (*A12)
            //
            if ((UINT8) (Data32) == 0x29 || (UINT8) (Data32) == 0x2A || (UINT8) (Data32) == 0x7 ) {
              ToggleStatus |= (1 << portId);                 // A11 only: need to toggle GPP reset
              portScanMap &= ~(1 << portId);
            }
            Data32 >>= 8;
          }
        }
      }
    }
  }
  return ToggleStatus;
}


/**
 * AfterGppLinkInit
 *       - Search for display device behind each GPP port
 *       - If the port is empty AND not hotplug-capable:
 *           * Turn off link training
 *           * (optional) Power down the port
 *           * Hide the configuration space (Turn off the port)
 *
 * @param[in] pConfig Southbridge configuration structure pointer.
 *
 */
VOID
AfterGppLinkInit (
  IN       AMDSBCFG* pConfig
  )
{
  UINT32  portId;
  SBGPPPORTCONFIG  *portCfg;
  UINT32  regBusNumber;
  UINT32  abValue;
  UINT32  abIndex;
  UINT32  i;
  UINT32  Data32;
  UINT8   bValue;
  UINT8   cimGppGen2;

  cimGppGen2 = pConfig->GppGen2;
#if  SB_CIMx_PARAMETER == 0
  cimGppGen2 = cimGppGen2Default;
#endif

  bValue = GPP_EFUSE_LOCATION;
  getEfuseStatus (&bValue);
  if ( (bValue & GPP_GEN2_EFUSE_BIT) != 0  ) {
    cimGppGen2 = FALSE;
  } else {
    pConfig->CoreGen2Enable = TRUE;          // Output for platform use
  }

//GPP Gen2 Speed Change
// if ((GPP Gen2 == enabled) and (RCINDP_Reg 0xA4[0] == 0x1)) {
//   PCIe_Cfg 0x88[3:0]  = 0x2
//   RCINDP_Reg 0xA2[13] = 0x0
//   RCINDP_Reg 0xC0[15] = 0x0
//   RCINDP_Reg 0xA4[29] = 0x1
// } else {
//   PCIe_Cfg 0x88[3:0]  = 0x1
//   RCINDP_Reg 0xA4[0]  = 0x0
//   RCINDP_Reg 0xA2[13] = 0x1
//   RCINDP_Reg 0xC0[15] = 0x0
//   RCINDP_Reg 0xA4[29] = 0x1
// }
  for ( portId = 0; portId < MAX_GPP_PORTS; portId++ ) {
    portCfg = &pConfig->PORTCONFIG[portId].PortCfg;
    abValue = readAlink (SB_RCINDXP_REGA4 | portId << 24) & BIT0;
    if (( cimGppGen2 == TRUE ) && (abValue == BIT0) && (portCfg->PortDetected == TRUE))  {
      portCfg->PortIsGen2 = TRUE;            // Output for platform use
      sbGppForceGen2 (portId);
      //_asm {jmp $};
      SbStall (400);                          // Delay 400us
      i = 500;
      Data32 = 0;
      while ( --i ) {
        abIndex = SB_RCINDXP_REGA5 | ((UINT32) RCINDXP << 29) | (portId << 24);
        Data32 = readAlink (abIndex) & 0x3F;
        if ((UINT8) (Data32) == 0x10) {
          break;
        }
        SbStall (400);                          // Delay 100us
      }
      if (!( (UINT8) (Data32) == 0x10 )) {
        if (pConfig->GppCompliance == FALSE) {
          portCfg->PortIsGen2 = FALSE;       // Revert to default; output for platform use
          sbGppForceGen1 (portId);
        }
      }
    } else {
      if (pConfig->GppCompliance == FALSE) {
        sbGppForceGen1 (portId);
      }
    }
//RPR 5.9 Link Bandwidth Notification Capability Enable
//RCINDC 0xC1[0] = 1
//PCIe Cfg 0x68[10] = 0
//PCIe Cfg 0x68[11] = 0

    rwAlink (SB_RCINDXC_REGC1, 0xFFFFFFFF, BIT0);
    RWPCI (PCI_ADDRESS (0, GPP_DEV_NUM, portId, 0x68), AccWidthUint16, ~(BIT10 + BIT11), 0);
  }

//  Status = AGESA_SUCCESS;
  pConfig->GppFoundGfxDev = 0;
  abValue = readAlink (SB_ABCFG_REGC0 | ((UINT32) ABCFG << 29));

  for ( portId = 0; portId < MAX_GPP_PORTS; portId++ ) {
    portCfg = &pConfig->PORTCONFIG[portId].PortCfg;
    // Check if there is GFX device behind each GPP port
    if ( portCfg->PortDetected == TRUE ) {
      regBusNumber = (SBTEMP_BUS << 16) + (SBTEMP_BUS << 8);
      WritePCI (PCI_ADDRESS (0, GPP_DEV_NUM, portId, 0x18), AccWidthUint32, &regBusNumber);
      // *** Stall ();
      ReadPCI (PCI_ADDRESS (SBTEMP_BUS, 0, 0, 0x0B), AccWidthUint8, &bValue);
      if ( bValue == 3 ) {
        pConfig->GppFoundGfxDev |= (1 << portId);
      }
      regBusNumber = 0;
      WritePCI (PCI_ADDRESS (0, GPP_DEV_NUM, portId, 0x18), AccWidthUint32, &regBusNumber);
    }

    // Mask off non-applicable ports
    else if ( portCfg->PortPresent == FALSE ) {
      abValue &= ~(1 << (portId + 4));
    }
    // Mask off empty port if the port is not hotplug-capable
    else if ( portCfg->PortHotPlug == FALSE ) {
      abValue &= ~(1 << (portId + 4));
    }
    // Clear STRAP_BIF_DE_EMPHASIS_SEL_x_GPP bit (abcfg:0x34[0, 4, 8, C][21]=0) to make hotplug working
    if ( portCfg->PortHotPlug == TRUE ) {
      rwAlink ((SB_ABCFG_REG340 + portId * 4) | ((UINT32) ABCFG << 29), ~BIT21, 0);

// RPR5.12 Hot Plug: PCIe Native Support
// RCINDP_Reg 0x10[3] = 0x1
// PCIe_Cfg 0x5A[8] = 0x1
// PCIe_Cfg 0x6C[6] = 0x1
// RCINDP_Reg 0x20[19] = 0x0

      rwAlink ((SB_RCINDXP_REG10 | ((UINT32) RCINDXP << 29) | (portId << 24)), 0xFFFFFFFF, BIT3);
      RWPCI (PCI_ADDRESS (0, GPP_DEV_NUM, portId, 0x5b), AccWidthUint8, 0xff, BIT0);
      RWPCI (PCI_ADDRESS (0, GPP_DEV_NUM, portId, 0x6c), AccWidthUint8, 0xff, BIT6);
      rwAlink ((SB_RCINDXP_REG20 | ((UINT32) RCINDXP << 29) | (portId << 24)), ~BIT19, 0);
    }
  }
  if ( pConfig->GppUnhidePorts == FALSE ) {
    if ((abValue & 0xF0) == 0) {
      abValue = BIT8;         // if all ports are empty set GPP_RESET
    } else if ((abValue & 0xE0) != 0 && (abValue & 0x10) == 0) {
      abValue |= BIT4;        // PortA should always be visible whenever other ports are exist
    }

    // Update GPP_Portx_Enable (abcfg:0xC0[7:5])
    writeAlink (SB_ABCFG_REGC0 | ((UINT32) ABCFG << 29), abValue);
  }

  //
  // Common initialization for open GPP ports
  //
  for ( portId = 0; portId < MAX_GPP_PORTS; portId++ ) {
    ReadPCI (PCI_ADDRESS (0, GPP_DEV_NUM, portId, 0x80), AccWidthUint8, &bValue);
    if (bValue != 0xff) {
      // Set pciCfg:PCIE_DEVICE_CNTL2[3:0] = 4'h6 (0x80[3:0])
      bValue &= 0xf0;
      bValue |= 0x06;
      WritePCI (PCI_ADDRESS (0, GPP_DEV_NUM, portId, 0x80), AccWidthUint8, &bValue);

        // Set PCIEIND_P:PCIE_RX_CNTL[RX_RCB_CPL_TIMEOUT_MODE] (0x70:[19]) = 1
      abIndex = SB_RCINDXP_REG70 | ((UINT32) RCINDXP << 29) | (portId << 24);
      abValue = readAlink (abIndex) | BIT19;
      writeAlink (abIndex, abValue);

        // Set PCIEIND_P:PCIE_TX_CNTL[TX_FLUSH_TLP_DIS] (0x20:[19]) = 0
      abIndex = SB_RCINDXP_REG20 | ((UINT32) RCINDXP << 29) | (portId << 24);
      abValue = readAlink (abIndex) & ~BIT19;
      writeAlink (abIndex, abValue);

    }
  }
}


/**
 * sbPcieGppLateInit - Late PCIE initialization for SB800 GPP component
 *
 *
 * @param[in] pConfig Southbridge configuration structure pointer.
 *
 */
VOID
sbPcieGppLateInit (
  IN       AMDSBCFG* pConfig
  )
{
  UINT32  reg32Value;
  UINT8   portId;
  UINT8   busNum;
  UINT8   aspmValue;
  UINT8   reg8Value;
  UINT8   cimGppPhyPllPowerDown;

  reg8Value = 0x01;
//
// Configure ASPM
//
//  writeAlink (0xC0 | ((UINT32) RCINDXC << 29), 0x400);  // Set STRAP_F0_MSI_EN
  aspmValue = (UINT8)pConfig->GppPortAspm;
  cimGppPhyPllPowerDown = (UINT8) pConfig->GppPhyPllPowerDown;
#if  SB_CIMx_PARAMETER == 0
  aspmValue = cimGppPortAspmDefault;
  cimGppPhyPllPowerDown = cimGppPhyPllPowerDownDefault;
#endif

  for ( portId = 0; portId < MAX_GPP_PORTS; portId++ ) {
    // write pci_reg3d with 0x01 to fix yellow mark for GPP bridge under Vista
    // when native PCIE is enabled but MSI is not available
    // SB02029: SB800 BIF/GPP allowing strap STRAP_BIF_INTERRUPT_PIN_SB controlled by AB reg
    WritePCI (PCI_ADDRESS (0, 21, portId, 0x3d), AccWidthUint8, &reg8Value);
    ReadPCI (PCI_ADDRESS (0, 21, portId, 0x19), AccWidthUint8, &busNum);
    if (busNum != 0xFF) {
      ReadPCI (PCI_ADDRESS (busNum, 0, 0, 0x00), AccWidthUint32, &reg32Value);
      if (reg32Value != 0xffffffff) {
        // Set ASPM on EP side
        sbGppSetAspm (PCI_ADDRESS (busNum, 0, 0, 0), aspmValue & 0x3);
        // Set ASPM on port side
        sbGppSetAspm (PCI_ADDRESS (0, 21, portId, 0), aspmValue & 0x3);
      }
    }
    aspmValue = aspmValue >> 2;
  }

//
// Configure Lock HWInit registers
//
  reg32Value = readAlink (SB_ABCFG_REGC0 | ((UINT32) ABCFG << 29));
  if (reg32Value & 0xF0) {
    reg32Value = readAlink (SB_RCINDXC_REG10 | ((UINT32) RCINDXC << 29));
    writeAlink (SB_RCINDXC_REG10 | ((UINT32) RCINDXC << 29), reg32Value | BIT0);  // Set HWINIT_WR_LOCK

    if ( cimGppPhyPllPowerDown == TRUE ) {
//
// RPR 5.4 Power Saving Feature for GPP Lanes
//
      UINT32  abValue;
      // Set PCIE_P_CNTL in Alink PCIEIND space
      abValue = readAlink (RC_INDXC_REG40 | ((UINT32) RCINDXC << 29));
      abValue |= BIT12 + BIT3 + BIT0;
      abValue &= ~(BIT9 + BIT4);
      writeAlink (RC_INDXC_REG40 | ((UINT32) RCINDXC << 29), abValue);
    }
  }

//
// Configure Lock HWInit registers
//
  reg32Value = readAlink (SB_ABCFG_REGC0 | ((UINT32) ABCFG << 29));
//
// Disable hidden register decode and serial number capability
//
  reg32Value = readAlink (SB_ABCFG_REG330 | ((UINT32) ABCFG << 29));
  writeAlink (SB_ABCFG_REG330 | ((UINT32) ABCFG << 29), reg32Value & ~(BIT26 + BIT10));
}

/**
 * sbGppSetAspm - Set SPP ASPM
 *
 *
 * @param[in] pciAddress PCI Address.
 * @param[in] LxState    Lane State.
 *
 */
VOID
sbGppSetAspm (
  IN       UINT32    pciAddress,
  IN       UINT8     LxState
  )
{
  UINT8      pcieCapOffset;
  UINT8      value8;
  UINT8      maxFuncs;
  UINT32     devBDF;

  maxFuncs = 1;
  ReadPCI (pciAddress + 0x0E, AccWidthUint8, &value8);

  if (value8 & BIT7) {
    maxFuncs = 8;              // multi-function device
  }
  while (maxFuncs != 0) {
    devBDF = pciAddress + (UINT32) ((maxFuncs - 1) << 16);
    pcieCapOffset = sbFindPciCap (devBDF, PCIE_CAP_ID);
    if (pcieCapOffset) {
      // Read link capabilities register (0x0C[11:10] - ASPM support)
      ReadPCI (devBDF + pcieCapOffset + 0x0D, AccWidthUint8, &value8);
      if (value8 & BIT2) {
        value8 = (value8 >> 2) & (BIT1 + BIT0);
        // Set ASPM state in link control register
        RWPCI (devBDF + pcieCapOffset + 0x10, AccWidthUint8, 0xffffffff, LxState & value8);
      }
    }
  maxFuncs--;
  }
}

/**
 * sbFindPciCap - Find PCI Cap
 *
 *
 * @param[in] pciAddress     PCI Address.
 * @param[in] targetCapId    Target Cap ID.
 *
 */
UINT8
sbFindPciCap (
  IN       UINT32  pciAddress,
  IN       UINT8  targetCapId
  )
{
  UINT8       NextCapPtr;
  UINT8       CapId;

  NextCapPtr = 0x34;
  while (NextCapPtr != 0) {
    ReadPCI (pciAddress + NextCapPtr, AccWidthUint8, &NextCapPtr);
    if (NextCapPtr == 0xff) {
      return 0;
    }
    if (NextCapPtr != 0) {
      ReadPCI (pciAddress + NextCapPtr, AccWidthUint8, &CapId);
      if (CapId == targetCapId) {
        break;
      } else {
        NextCapPtr++;
      }
    }
  }
  return NextCapPtr;
}

/**
 * sbGppForceGen2 - Set SPP to GENII
 *
 *
 * @param[in] portId
 *
 */
VOID
sbGppForceGen2 (
  IN       UINT32     portId
  )
{
  RWPCI (PCI_ADDRESS (0, GPP_DEV_NUM, portId, 0x88), AccWidthUint8, 0xf0, 0x02);
  rwAlink (SB_RCINDXP_REGA2 | portId << 24, ~BIT13, 0);
  rwAlink (SB_RCINDXP_REGC0 | portId << 24, ~BIT15, 0);
  rwAlink (SB_RCINDXP_REGA4 | portId << 24, 0xFFFFFFFF, BIT29);
}

/**
 * sbGppForceGen1 - Set SPP to GENI
 *
 *
 * @param[in] portId
 *
 */
VOID
sbGppForceGen1 (
  IN       UINT32     portId
  )
{
  RWPCI (PCI_ADDRESS (0, GPP_DEV_NUM, portId, 0x88), AccWidthUint8, 0xf0, 0x01);
  rwAlink (SB_RCINDXP_REGA4 | portId << 24, ~BIT0, 0);
  rwAlink (SB_RCINDXP_REGA2 | portId << 24, 0xFFFFFFFF, BIT13);
  rwAlink (SB_RCINDXP_REGC0 | portId << 24, ~BIT15, 0);
  rwAlink (SB_RCINDXP_REGA4 | portId << 24, 0xFFFFFFFF, BIT29);
}

/**
 * sbGppDisableUnusedPadMap - Return GPP Pad Map
 *
 *
 * @param[in] pConfig
 *
 */
VOID
sbGppDisableUnusedPadMap (
  IN       AMDSBCFG* pConfig
  )
{
  UINT32  Data32;
  UINT32  HoldData32;
  SBGPPPORTCONFIG  *portCfg;
  UINT8  cimGppLaneReversal;
  UINT8  cimAlinkPhyPllPowerDown;
  UINT8  cimGppPhyPllPowerDown;

  cimAlinkPhyPllPowerDown = (UINT8) pConfig->AlinkPhyPllPowerDown;
  cimGppLaneReversal =  (UINT8) pConfig->GppLaneReversal;
  cimGppPhyPllPowerDown =  (UINT8) pConfig->GppPhyPllPowerDown;
#if  SB_CIMx_PARAMETER == 0
  cimGppLaneReversal = cimGppLaneReversalDefault;
  cimAlinkPhyPllPowerDown = cimAlinkPhyPllPowerDownDefault;
  cimGppPhyPllPowerDown = cimGppPhyPllPowerDownDefault;
#endif

  Data32 = 0;
  HoldData32 = 0;
  switch ( pConfig->GppLinkConfig ) {
  case GPP_CFGMODE_X4000:
    portCfg = &pConfig->PORTCONFIG[0].PortCfg;
    if ( portCfg->PortDetected == FALSE ) {
      Data32 |= 0x0f0f;
      HoldData32 |= 0x1000;
    }
    break;
  case GPP_CFGMODE_X2200:
    portCfg = &pConfig->PORTCONFIG[0].PortCfg;
    if ( portCfg->PortDetected == FALSE ) {
      Data32 |= ( cimGppLaneReversal )? 0x0c0c:0x0303;
      HoldData32 |= 0x1000;
    }
    portCfg = &pConfig->PORTCONFIG[1].PortCfg;
    if ( portCfg->PortDetected == FALSE ) {
      Data32 |= ( cimGppLaneReversal )? 0x0303:0x0c0c;
      HoldData32 |= 0x2000;
    }
    break;
  case GPP_CFGMODE_X2110:
    portCfg = &pConfig->PORTCONFIG[0].PortCfg;
    if ( portCfg->PortDetected == FALSE ) {
      Data32 |= ( cimGppLaneReversal )? 0x0c0c:0x0303;
      HoldData32 |= 0x1000;
    }
    portCfg = &pConfig->PORTCONFIG[1].PortCfg;
    if ( portCfg->PortDetected == FALSE ) {
      Data32 |= ( cimGppLaneReversal )? 0x0202:0x0404;
      HoldData32 |= 0x2000;
    }
    portCfg = &pConfig->PORTCONFIG[2].PortCfg;
    if ( portCfg->PortDetected == FALSE ) {
      Data32 |= ( cimGppLaneReversal )? 0x0101:0x0808;
      HoldData32 |= 0x4000;
    }
    break;
  case GPP_CFGMODE_X1111:
    portCfg = &pConfig->PORTCONFIG[0].PortCfg;
    if ( portCfg->PortDetected == FALSE ) {
      Data32 |= ( cimGppLaneReversal )? 0x0808:0x0101;
      HoldData32 |= 0x1000;
    }
    portCfg = &pConfig->PORTCONFIG[1].PortCfg;
    if ( portCfg->PortDetected == FALSE ) {
      Data32 |= ( cimGppLaneReversal )? 0x0404:0x0202;
      HoldData32 |= 0x2000;
    }
    portCfg = &pConfig->PORTCONFIG[2].PortCfg;
    if ( portCfg->PortDetected == FALSE ) {
      Data32 |= ( cimGppLaneReversal )? 0x0202:0x0404;
      HoldData32 |= 0x4000;
    }
    portCfg = &pConfig->PORTCONFIG[3].PortCfg;
    if ( portCfg->PortDetected == FALSE ) {
      Data32 |= ( cimGppLaneReversal )? 0x0101:0x0808;
      HoldData32 |= 0x8000;
    }
    break;
  default:
    break;
  }

// RPR 5.11 Power Saving With GPP Disable
// ABCFG 0xC0[8] = 0x0
// ABCFG 0xC0[15:12] = 0xF
// Enable "Power Saving Feature for A-Link Express Lanes"
// Enable "Power Saving Feature for GPP Lanes"
// ABCFG 0x90[19] = 1
// ABCFG 0x90[6] = 1
// RCINDC_Reg 0x65 [27:0] = 0xFFFFFFF
// ABCFG 0xC0[7:4] = 0x0
  if ( (Data32 & 0xf) == 0xf ) Data32 |= 0x0cff0000;
  if ( cimAlinkPhyPllPowerDown && cimGppPhyPllPowerDown ) {
    rwAlink (SB_ABCFG_REGC0 | ((UINT32) ABCFG << 29), ~BIT8, 0);
    rwAlink (SB_ABCFG_REGC0 | ((UINT32) ABCFG << 29), 0xFFFFFFFF, HoldData32);
    rwAlink (SB_AX_INDXC_REG40, ~(BIT9 + BIT4), (BIT0 + BIT3 + BIT12));
    rwAlink (RC_INDXC_REG40, ~(BIT9 + BIT4), (BIT0 + BIT3 + BIT12));
    rwAlink ((SB_ABCFG_REG90 | ((UINT32) ABCFG << 29)), 0xFFFFFFFF, (BIT6 + BIT19));
    rwAlink (RC_INDXC_REG65, 0xFFFFFFFF, Data32);
  }
}
