/* $NoKeywords:$ */
/**
 * @file
 *
 * Config Hudson2 AB
 *
 * Init AB bridge.
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project:     AGESA
 * @e sub-project: FCH
 * @e \$Revision: 63425 $   @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $
 *
 */
/*
*****************************************************************************
*
 * 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.
****************************************************************************
*/
#include "FchPlatform.h"
#include "Filecode.h"
#define FILECODE PROC_FCH_PCIE_FAMILY_HUDSON2_HUDSON2ABENVSERVICE_FILECODE

//
// Declaration of local functions
//
VOID AbCfgTbl (IN AB_TBL_ENTRY  *ABTbl, IN AMD_CONFIG_PARAMS *StdHeader);

/**
 * Hudson2PcieOrderRule - AB-Link Configuration Table for ablink
 * Post Pass Np Downstream/Upstream Feature
 *
 */
AB_TBL_ENTRY Hudson2PcieOrderRule[] =
{
  //
  // abPostPassNpDownStreamTbl
  //
  {ABCFG, FCH_ABCFG_REG10060, BIT31, BIT31},
  {ABCFG, FCH_ABCFG_REG1009C, BIT4 + BIT5, BIT4 + BIT5},
  {ABCFG, FCH_ABCFG_REG9C, BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7, BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7},
  {ABCFG, FCH_ABCFG_REG90, BIT21 + BIT22 + BIT23, BIT21 + BIT22 + BIT23},
  {ABCFG, FCH_ABCFG_REGF0, BIT6 + BIT5, BIT6 + BIT5},
  {AXINDC, FCH_AX_INDXC_REG02, BIT9, BIT9},
  {ABCFG, FCH_ABCFG_REG10090, BIT9 + BIT10 + BIT11 + BIT12, BIT9 + BIT10 + BIT11 + BIT12},

  //
  // abPostPassNpUpStreamTbl
  //
  {ABCFG, FCH_ABCFG_REG58, BIT10, BIT10},
  {ABCFG, FCH_ABCFG_REGF0, BIT3 + BIT4, BIT3 + BIT4},
  {ABCFG, FCH_ABCFG_REG54, BIT1, BIT1},
  { (UINT8)0xFF, (UINT8)0xFF, (UINT8)0xFF, (UINT8)0xFF},
};

/**
 * Hudson2InitEnvAbTable - AB-Link Configuration Table for Hudson2
 *
 */
AB_TBL_ENTRY Hudson2InitEnvAbTable[] =
{
  //
  // Enable downstream posted transactions to pass non-posted transactions.
  //
  {ABCFG, FCH_ABCFG_REG10090, BIT8 + BIT16, BIT8 + BIT16},

  //
  // Enable Hudson-2 to issue memory read/write requests in the upstream direction.
  //
  {AXCFG, FCH_AB_REG04, BIT2, BIT2},

  //
  // Enabling IDE/PCIB Prefetch for Performance Enhancement
  // PCIB prefetch   ABCFG 0x10060 [20] = 1   ABCFG 0x10064 [20] = 1
  //
  {ABCFG, FCH_ABCFG_REG10060, BIT20, BIT20},                                    ///  PCIB prefetch enable
  {ABCFG, FCH_ABCFG_REG10064, BIT20, BIT20},                                    ///  PCIB prefetch enable

  //
  // Controls the USB OHCI controller prefetch used for enhancing performance of ISO out devices.
  // Setting B-Link Prefetch Mode (ABCFG 0x80 [18:17] = 11)
  //
  {ABCFG, FCH_ABCFG_REG80, BIT0 + BIT17 + BIT18, BIT0 + BIT17 + BIT18},

  //
  // Enabled SMI ordering enhancement. ABCFG 0x90[21]
  // USB Delay A-Link Express L1 State. ABCFG 0x90[17]
  //
  {ABCFG, FCH_ABCFG_REG90, BIT21 + BIT17, BIT21 + BIT17},

  //
  // Disable the credit variable in the downstream arbitration equation
  // Register bit to qualify additional address bits into downstream register programming. (A12 BIT1 default is set)
  //
  {ABCFG, FCH_ABCFG_REG9C, BIT0, BIT0},

  //
  // Enabling Detection of Upstream Interrupts ABCFG 0x94 [20] = 1
  // ABCFG 0x94 [19:0] = cpu interrupt delivery address [39:20]
  //
  {ABCFG, FCH_ABCFG_REG94, BIT20, BIT20 + 0x00FEE},

  //
  // Programming cycle delay for AB and BIF clock gating
  // Enable the AB and BIF clock-gating logic.
  // Enable the A-Link int_arbiter enhancement to allow the A-Link bandwidth to be used more efficiently
  // Enable the requester ID for upstream traffic. [16]: SB/NB link [17]: GPP
  //
  {ABCFG, FCH_ABCFG_REG10054,  0x00FFFFFF, 0x010407FF},
  {ABCFG, FCH_ABCFG_REG98,  0xFFFC00FF, 0x00034700},
  {ABCFG, FCH_ABCFG_REG54,  0x00FF0000, 0x00040000},

  //
  // Non-Posted Memory Write Support
  //
  {AXINDC, FCH_AX_INDXC_REG10, BIT9, BIT9},

  //
  // UMI L1 Configuration
  //Step 1: AXINDC_Reg 0x02[0] = 0x1 Set REGS_DLP_IGNORE_IN_L1_EN to ignore DLLPs during L1 so that txclk can be turned off.
  //Step 2: AXINDP_Reg 0x02[15] = 0x1 Sets REGS_LC_ALLOW_TX_L1_CONTROL to allow TX to prevent LC from going to L1 when there are outstanding completions.
  //
  {AXINDC, FCH_AX_INDXC_REG02, BIT0, BIT0},
  {AXINDP, FCH_AX_INDXP_REG02, BIT15, BIT15},
  {ABCFG, 0, 0, (UINT8) 0xFF},                                                 /// This dummy entry is to clear ab index
  { (UINT8)0xFF, (UINT8)0xFF, (UINT8)0xFF, (UINT8)0xFF},
};

/**
 * FchInitEnvAbLinkInit - Set ABCFG registers before PCI
 * emulation.
 *
 *
 * @param[in] FchDataPtr Fch configuration structure pointer.
 *
 */
VOID
FchInitEnvAbLinkInit (
  IN  VOID     *FchDataPtr
  )
{
  UINT32                 AbValue;
  UINT16                 AbTempVar;
  UINT8                  AbValue8;
  UINT8                  FchALinkClkGateOff;
  UINT8                  FchBLinkClkGateOff;
  UINT32                 FchResetCpuOnSyncFlood;
  AB_TBL_ENTRY           *AbTblPtr;
  FCH_DATA_BLOCK         *LocalCfgPtr;
  AMD_CONFIG_PARAMS      *StdHeader;

  LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr;
  StdHeader = LocalCfgPtr->StdHeader;

  FchALinkClkGateOff = (UINT8) LocalCfgPtr->Ab.ALinkClkGateOff;
  FchBLinkClkGateOff = (UINT8) LocalCfgPtr->Ab.BLinkClkGateOff;
  //
  // AB CFG programming
  //
  if ( LocalCfgPtr->Ab.SlowSpeedAbLinkClock ) {
    RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40, AccessWidth8, (UINT32)~BIT1, BIT1);
  } else {
    RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40, AccessWidth8, (UINT32)~BIT1, 0);
  }

  //
  // Read Arbiter address, Arbiter address is in PMIO 6Ch
  //
  ReadMem (ACPI_MMIO_BASE + PMIO_BASE + 0x6C , AccessWidth16, &AbTempVar);
  /// Write 0 to enable the arbiter
  AbValue8 = 0;
  LibAmdIoWrite (AccessWidth8, AbTempVar, &AbValue8, StdHeader);


  FchResetCpuOnSyncFlood = LocalCfgPtr->Ab.ResetCpuOnSyncFlood;

  if ( LocalCfgPtr->Ab.PcieOrderRule == 1 ) {
    AbTblPtr = (AB_TBL_ENTRY *) (&Hudson2PcieOrderRule[0]);
    AbCfgTbl (AbTblPtr, StdHeader);
  }

  if ( LocalCfgPtr->Ab.PcieOrderRule == 2 ) {
    RwAlink (FCH_ABCFG_REG10090 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x7 << 10), (UINT32) (0x7 << 10), StdHeader);
    RwAlink (FCH_ABCFG_REG58 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1F << 11), (UINT32) (0x1C << 11), StdHeader);
    RwAlink (FCH_ABCFG_REGB4 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x3 << 0), (UINT32) (0x3 << 0), StdHeader);
  }

  AbTblPtr = (AB_TBL_ENTRY *) (&Hudson2InitEnvAbTable[0]);
  AbCfgTbl (AbTblPtr, StdHeader);

  if ( FchResetCpuOnSyncFlood ) {
    RwAlink (FCH_ABCFG_REG10050 | (UINT32) (ABCFG << 29), (UINT32)~BIT2, BIT2, StdHeader);
  }

  if ( LocalCfgPtr->Ab.AbClockGating ) {
    RwAlink (FCH_ABCFG_REG10054 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16), StdHeader);
    RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16), StdHeader);
    RwAlink (FCH_ABCFG_REG10054 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 24), (UINT32) (0x1 << 24), StdHeader);
    RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 24), (UINT32) (0x1 << 24), StdHeader);
  } else {
    RwAlink (FCH_ABCFG_REG10054 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 24), (UINT32) (0x0 << 24), StdHeader);
    RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 24), (UINT32) (0x0 << 24), StdHeader);
  }


  if ( LocalCfgPtr->Ab.GppClockGating ) {
    RwAlink (FCH_ABCFG_REG98 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xF << 12), (UINT32) (0x4 << 12), StdHeader);
    RwAlink (FCH_ABCFG_REG98 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xF << 8), (UINT32) (0x7 << 8), StdHeader);
    RwAlink (FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 0), (UINT32) (0x1 << 0), StdHeader);
  } else {
    RwAlink (FCH_ABCFG_REG98 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xF << 8), (UINT32) (0x0 << 8), StdHeader);
    RwAlink (FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 0), (UINT32) (0x0 << 0), StdHeader);
  }

  if ( LocalCfgPtr->Ab.UmiL1TimerOverride ) {
    RwAlink (FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x7 << 12), (UINT32) (LocalCfgPtr->Ab.UmiL1TimerOverride  << 12), StdHeader);
    RwAlink (FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 15), (UINT32) (0x1  << 15), StdHeader);
  }

  if ( LocalCfgPtr->Ab.UmiLinkWidth ) {
//    RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16));
  }

  if ( LocalCfgPtr->Ab.UmiDynamicSpeedChange ) {
    RwAlink ((UINT32) FCH_AX_INDXP_REGA4, ~ (UINT32) (0x1 << 0), (UINT32) (0x1 << 0), StdHeader);
    RwAlink ((UINT32) FCH_AX_CFG_REG88, ~ (UINT32) (0xF << 0), (UINT32) (0x2 << 0), StdHeader);
    RwAlink ((UINT32) FCH_AX_INDXP_REGA4, ~ (UINT32) (0x1 << 18), (UINT32) (0x1 << 18), StdHeader);
  }

  if ( LocalCfgPtr->Ab.PcieRefClockOverClocking ) {
//    RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16));
  }

  if ( LocalCfgPtr->Ab.UmiGppTxDriverStrength  ) {
    RwAlink (FCH_ABCFG_REGA8 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x3 << 18), (UINT32) ((LocalCfgPtr->Ab.UmiGppTxDriverStrength - 1) << 18), StdHeader);
    RwAlink (FCH_ABCFG_REGA0 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 8), (UINT32) (0x1 << 8), StdHeader);
  }

  if ( LocalCfgPtr->Gpp.PcieAer ) {
//    RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16));
  }

  if ( LocalCfgPtr->Gpp.PcieRas ) {
//    RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16));
  }

  //
  // Ab Bridge MSI
  //
  if ( LocalCfgPtr->Ab.AbMsiEnable) {
    AbValue = ReadAlink (FCH_ABCFG_REG94 | (UINT32) (ABCFG << 29), StdHeader);
    AbValue = AbValue | BIT20;
    WriteAlink (FCH_ABCFG_REG94 | (UINT32) (ABCFG << 29), AbValue, StdHeader);
  }

  //
  // A/B Clock Gate-OFF
  //
  if ( FchALinkClkGateOff ) {
    RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x2E, AccessWidth8, 0xFE, BIT0);
  } else {
    RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x2E, AccessWidth8, 0xFE, 0x00);
  }

  if ( FchBLinkClkGateOff ) {
    //RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x2D, AccessWidth8, 0xEF, 0x10);      /// A11 Only
    RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x2E, AccessWidth8, 0xFD, BIT1);
  } else {
    RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x2E, AccessWidth8, 0xFD, 0x00);
  }
}

/**
 * AbCfgTbl - Program ABCFG by input table.
 *
 *
 * @param[in] ABTbl  ABCFG config table.
 * @param[in] StdHeader
 *
 */
VOID
AbCfgTbl (
  IN  AB_TBL_ENTRY     *ABTbl,
  IN AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32   AbValue;

  while ( (ABTbl->RegType) != 0xFF ) {
    if ( ABTbl->RegType == AXINDC ) {
      AbValue = 0x30 | (ABTbl->RegType << 29);
      WriteAlink (AbValue, (ABTbl->RegIndex & 0x00FFFFFF), StdHeader);
      AbValue = 0x34 | (ABTbl->RegType << 29);
      WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader);
    } else if ( ABTbl->RegType == AXINDP ) {
      AbValue = 0x38 | (ABTbl->RegType << 29);
      WriteAlink (AbValue, (ABTbl->RegIndex & 0x00FFFFFF), StdHeader);
      AbValue = 0x3C | (ABTbl->RegType << 29);
      WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader);
    } else {
      AbValue = ABTbl->RegIndex | (ABTbl->RegType << 29);
      WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader);
    }

    ++ABTbl;
  }

  //
  //Clear ALink Access Index
  //
  AbValue = 0;
  LibAmdIoWrite (AccessWidth32, ALINK_ACCESS_INDEX, &AbValue, StdHeader);
}

/**
 * Is UMI One Lane GEN1 Mode?
 *
 *
 * @retval  TRUE or FALSE
 *
 */
BOOLEAN
IsUmiOneLaneGen1Mode (
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32   AbValue;

  AbValue = ReadAlink ((UINT32) (FCH_AX_CFG_REG68), StdHeader);
  AbValue >>= 16;
  if (((AbValue & 0x0f) == 1) && ((AbValue & 0x03f0) == 0x0010)) {
    return (TRUE);
  } else {
    return (FALSE);
  }
}
