blob: 1f80537e0f41714bc0f3bdc2906f3d08b54d0678 [file] [log] [blame]
/* $NoKeywords:$ */
/**
* @file
*
* PCIe late post initialization.
*
*
*
* @xrefitem bom "File Content Label" "Release Content"
* @e project: AGESA
* @e sub-project: GNB
* @e \$Revision: 64352 $ @e \$Date: 2012-01-19 03:54:04 -0600 (Thu, 19 Jan 2012) $
*
*/
/*
*****************************************************************************
*
* 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.
* ***************************************************************************
*
*/
/*----------------------------------------------------------------------------------------
* M O D U L E S U S E D
*----------------------------------------------------------------------------------------
*/
#include "AGESA.h"
#include "Ids.h"
#include "amdlib.h"
#include "Gnb.h"
#include "GnbPcie.h"
#include "GnbFuseTable.h"
#include "heapManager.h"
#include "GnbCommonLib.h"
#include "GnbPcieConfig.h"
#include "GnbNbInitLibV1.h"
#include "GnbNbInitLibV4.h"
#include "GnbGfxInitLibV1.h"
#include "GnbGfxConfig.h"
#include "GnbTable.h"
#include "GnbRegisterAccTN.h"
#include "GnbRegistersTN.h"
#include "OptionGnb.h"
#include "GfxLibTN.h"
#include "GnbFamServices.h"
#include "GnbGfxFamServices.h"
#include "GnbBapmCoeffCalcTN.h"
#include "PcieComplexDataTN.h"
#include "Filecode.h"
#define FILECODE PROC_GNB_MODULES_GNBINITTN_GNBMIDINITTN_FILECODE
/*----------------------------------------------------------------------------------------
* D E F I N I T I O N S A N D M A C R O S
*----------------------------------------------------------------------------------------
*/
extern GNB_BUILD_OPTIONS GnbBuildOptions;
extern GNB_TABLE ROMDATA GnbMidInitTableTN[];
/*----------------------------------------------------------------------------------------
* T Y P E D E F S A N D S T R U C T U R E S
*----------------------------------------------------------------------------------------
*/
#define NUM_DPM_STATES 8
/*----------------------------------------------------------------------------------------
* P R O T O T Y P E S O F L O C A L F U N C T I O N S
*----------------------------------------------------------------------------------------
*/
AGESA_STATUS
GnbMidInterfaceTN (
IN AMD_CONFIG_PARAMS *StdHeader
);
/*----------------------------------------------------------------------------------------*/
/**
* Registers needs to be set if no GFX PCIe ports beeing us
*
*
*
* @param[in] Pcie Pointer to PCIe_PLATFORM_CONFIG
*/
VOID
STATIC
GnbIommuMidInitCheckGfxPciePorts (
IN PCIe_PLATFORM_CONFIG *Pcie
)
{
PCIe_WRAPPER_CONFIG *WrapperList;
BOOLEAN GfxPciePortUsed;
D0F2xF4_x57_STRUCT D0F2xF4_x57;
IDS_HDT_CONSOLE (GNB_TRACE, "GnbIommuMidInitCheckGfxPciePorts Enter\n");
GfxPciePortUsed = FALSE;
WrapperList = PcieConfigGetChildWrapper (Pcie);
ASSERT (WrapperList != NULL);
if (WrapperList->WrapId == GFX_WRAP_ID) {
PCIe_ENGINE_CONFIG *EngineList;
EngineList = PcieConfigGetChildEngine (WrapperList);
while (EngineList != NULL) {
if (PcieConfigIsPcieEngine (EngineList)) {
IDS_HDT_CONSOLE (GNB_TRACE, "Checking Gfx ports device number %x\n", EngineList->Type.Port.NativeDevNumber);
if (PcieConfigCheckPortStatus (EngineList, INIT_STATUS_PCIE_TRAINING_SUCCESS) ||
((EngineList->Type.Port.PortData.LinkHotplug != HotplugDisabled) && (EngineList->Type.Port.PortData.LinkHotplug != HotplugInboard))) {
// GFX PCIe ports beeing used
GfxPciePortUsed = TRUE;
IDS_HDT_CONSOLE (GNB_TRACE, "GFX PCIe ports beeing used\n");
break;
}
}
EngineList = PcieLibGetNextDescriptor (EngineList);
}
}
if (!GfxPciePortUsed) {
//D0F2xF4_x57.Field.L1ImuPcieGfxDis needs to be set
GnbRegisterReadTN (D0F2xF4_x57_TYPE, D0F2xF4_x57_ADDRESS, &D0F2xF4_x57.Value, 0, GnbLibGetHeader (Pcie));
D0F2xF4_x57.Field.L1ImuPcieGfxDis = 1;
GnbRegisterWriteTN (D0F2xF4_x57_TYPE, D0F2xF4_x57_ADDRESS, &D0F2xF4_x57.Value, GNB_REG_ACC_FLAG_S3SAVE, GnbLibGetHeader (Pcie));
}
IDS_HDT_CONSOLE (GNB_TRACE, "GnbIommuMidInitCheckGfxPciePorts Exit\n");
}
/*----------------------------------------------------------------------------------------*/
/**
* Callback to for each PCIe port
*
*
*
*
* @param[in] Engine Pointer to engine config descriptor
* @param[in, out] Buffer Not used
* @param[in] Pcie Pointer to global PCIe configuration
*
*/
VOID
STATIC
GnbIommuMidInitOnPortCallback (
IN PCIe_ENGINE_CONFIG *Engine,
IN OUT VOID *Buffer,
IN PCIe_PLATFORM_CONFIG *Pcie
)
{
GNB_TOPOLOGY_INFO TopologyInfo;
D0F2xFC_x07_L1_STRUCT D0F2xFC_x07_L1;
D0F2xFC_x0D_L1_STRUCT D0F2xFC_x0D_L1;
UINT8 L1cfgSel;
TopologyInfo.PhantomFunction = FALSE;
TopologyInfo.PcieToPciexBridge = FALSE;
if (Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled) {
TopologyInfo.PhantomFunction = TRUE;
TopologyInfo.PcieToPciexBridge = TRUE;
} else {
if (PcieConfigIsSbPcieEngine (Engine)) {
PCI_ADDR StartSbPcieDev;
PCI_ADDR EndSbPcieDev;
StartSbPcieDev.AddressValue = MAKE_SBDFO (0, 0, 0x15, 0, 0);
EndSbPcieDev.AddressValue = MAKE_SBDFO (0, 0, 0x15, 7, 0);
GnbGetTopologyInfoV4 (StartSbPcieDev, EndSbPcieDev, &TopologyInfo, GnbLibGetHeader (Pcie));
} else {
GnbGetTopologyInfoV4 (Engine->Type.Port.Address, Engine->Type.Port.Address, &TopologyInfo, GnbLibGetHeader (Pcie));
}
}
L1cfgSel = (Engine->Type.Port.CoreId == 1) ? 1 : 0;
if (TopologyInfo.PhantomFunction) {
GnbRegisterReadTN (
D0F2xFC_x07_L1_TYPE,
D0F2xFC_x07_L1_ADDRESS (L1cfgSel),
&D0F2xFC_x07_L1.Value,
0,
GnbLibGetHeader (Pcie)
);
D0F2xFC_x07_L1.Value |= BIT0;
GnbRegisterWriteTN (
D0F2xFC_x07_L1_TYPE,
D0F2xFC_x07_L1_ADDRESS (L1cfgSel),
&D0F2xFC_x07_L1.Value,
GNB_REG_ACC_FLAG_S3SAVE,
GnbLibGetHeader (Pcie)
);
}
if (TopologyInfo.PcieToPciexBridge) {
GnbRegisterReadTN (
D0F2xFC_x0D_L1_TYPE,
D0F2xFC_x0D_L1_ADDRESS (L1cfgSel),
&D0F2xFC_x0D_L1.Value,
0,
GnbLibGetHeader (Pcie)
);
D0F2xFC_x0D_L1.Field.VOQPortBits = 0x7;
GnbRegisterWriteTN (
D0F2xFC_x0D_L1_TYPE,
D0F2xFC_x0D_L1_ADDRESS (L1cfgSel),
&D0F2xFC_x0D_L1.Value,
GNB_REG_ACC_FLAG_S3SAVE,
GnbLibGetHeader (Pcie)
);
}
}
/*----------------------------------------------------------------------------------------*/
/**
* Orb/Ioc Cgtt Override setting
*
*
* @param[in] Property Property
* @param[in] StdHeader Standard configuration header
*/
VOID
STATIC
GnbCgttOverrideTN (
IN UINT32 Property,
IN AMD_CONFIG_PARAMS *StdHeader
)
{
UINT32 CGINDx0_Value;
UINT32 CGINDx1_Value;
GFX_PLATFORM_CONFIG *Gfx;
AGESA_STATUS Status;
D0F0x64_x23_STRUCT D0F0x64_x23;
IDS_HDT_CONSOLE (GNB_TRACE, "GnbCgttOverrideTN Enter\n");
CGINDx0_Value = 0xFFFFFFFF;
//When orb clock gating is enabled in the BIOS clear CG_ORB_cgtt_lclk_override - bit 13
CGINDx1_Value = 0xFFFFFFFF;
if ((Property & TABLE_PROPERTY_ORB_CLK_GATING) == TABLE_PROPERTY_ORB_CLK_GATING) {
CGINDx1_Value &= 0xFFFFDFFF;
}
//When ioc clock gating is enabled in the BIOS clear CG_IOC_cgtt_lclk_override - bit 15
if ((Property & TABLE_PROPERTY_IOC_LCLK_CLOCK_GATING) == TABLE_PROPERTY_IOC_LCLK_CLOCK_GATING) {
CGINDx1_Value &= 0xFFFF7FFF;
if ((Property & TABLE_PROPERTY_IOMMU_DISABLED) != TABLE_PROPERTY_IOMMU_DISABLED) {
//only IOMMU enabled and IOC clock gating enable
GnbRegisterReadTN (D0F0x64_x23_TYPE, D0F0x64_x23_ADDRESS, &D0F0x64_x23.Value, 0, StdHeader);
D0F0x64_x23.Field.SoftOverrideClk0 = 1;
D0F0x64_x23.Field.SoftOverrideClk1 = 1;
D0F0x64_x23.Field.SoftOverrideClk3 = 1;
D0F0x64_x23.Field.SoftOverrideClk4 = 1;
GnbRegisterWriteTN (D0F0x64_x23_TYPE, D0F0x64_x23_ADDRESS, &D0F0x64_x23.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader);
}
}
//When smu sclk clock gating is enabled in the BIOS clear CG_IOC_cgtt_lclk_override - bit 18
if ((Property & TABLE_PROPERTY_SMU_SCLK_CLOCK_GATING) == TABLE_PROPERTY_SMU_SCLK_CLOCK_GATING) {
CGINDx1_Value &= 0xFFFBFFFF;
}
Status = GfxLocateConfigData (StdHeader, &Gfx);
if (Status != AGESA_FATAL) {
if (Gfx->GmcClockGating) {
//In addition to above registers it is necessary to reset override bits for VMC, MCB, and MCD blocks
// CGINDx0, clear bit 27, bit 28
CGINDx0_Value &= 0xE7FFFFFF;
GnbRegisterWriteTN (TYPE_CGIND, 0x0, &CGINDx0_Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader);
// CGINDx1, clear bit 11
CGINDx1_Value &= 0xFFFFF7FF;
}
}
if (CGINDx1_Value != 0xFFFFFFFF) {
GnbRegisterWriteTN (TYPE_CGIND, 0x1, &CGINDx1_Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader);
}
IDS_HDT_CONSOLE (GNB_TRACE, "GnbCgttOverrideTN Exit\n");
}
/*----------------------------------------------------------------------------------------*/
/**
* IOMMU Mid Init
*
*
*
* @param[in] StdHeader Standard configuration header
* @retval AGESA_STATUS
*/
STATIC AGESA_STATUS
GnbIommuMidInit (
IN AMD_CONFIG_PARAMS *StdHeader
)
{
AGESA_STATUS Status;
PCIe_PLATFORM_CONFIG *Pcie;
IDS_HDT_CONSOLE (GNB_TRACE, "GnbIommuMidInit Enter\n");
Status = PcieLocateConfigurationData (StdHeader, &Pcie);
if (Status == AGESA_SUCCESS) {
PcieConfigRunProcForAllEngines (
DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE,
GnbIommuMidInitOnPortCallback,
NULL,
Pcie
);
}
GnbIommuMidInitCheckGfxPciePorts (Pcie);
IDS_HDT_CONSOLE (GNB_TRACE, "GnbIommuMidInit Exit [0x%x]\n", Status);
return Status;
}
/*----------------------------------------------------------------------------------------*/
/**
* IOMMU Mid Init
*
*
*
* @param[in] StdHeader Standard configuration header
* @retval AGESA_STATUS
*/
STATIC AGESA_STATUS
GnbLclkDpmInitTN (
IN AMD_CONFIG_PARAMS *StdHeader
)
{
AGESA_STATUS Status;
PCIe_PLATFORM_CONFIG *Pcie;
PP_FUSE_ARRAY *PpFuseArray;
PCI_ADDR GnbPciAddress;
UINT32 Index;
UINT8 LclkDpmMode;
D0F0xBC_x1F200_STRUCT D0F0xBC_x1F200[NUM_DPM_STATES];
D0F0xBC_x1F208_STRUCT D0F0xBC_x1F208[NUM_DPM_STATES];
D0F0xBC_x1F210_STRUCT D0F0xBC_x1F210[NUM_DPM_STATES];
D0F0xBC_x1F300_STRUCT D0F0xBC_x1F300;
ex1003_STRUCT ex1003 [NUM_DPM_STATES];
DOUBLE PcieCacLut;
ex1072_STRUCT ex1072 ;
D0F0xBC_x1FE00_STRUCT D0F0xBC_x1FE00;
D0F0xBC_x1F30C_STRUCT D0F0xBC_x1F30C;
D18F3x64_STRUCT D18F3x64;
IDS_HDT_CONSOLE (GNB_TRACE, "GnbLclkDpmInitTN Enter\n");
Status = AGESA_SUCCESS;
LclkDpmMode = GnbBuildOptions.LclkDpmEn ? LclkDpmRcActivity : LclkDpmDisabled;
IDS_OPTION_HOOK (IDS_GNB_LCLK_DPM_EN, &LclkDpmMode, StdHeader);
if (LclkDpmMode == LclkDpmRcActivity) {
PpFuseArray = GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, StdHeader);
if (PpFuseArray != NULL) {
Status = PcieLocateConfigurationData (StdHeader, &Pcie);
if (Status == AGESA_SUCCESS) {
GnbPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0);
//Clear DPM_EN bit in LCLK_DPM_CNTL register
//Call BIOS service SMC_MSG_CONFIG_LCLK_DPM to disable LCLK DPM
GnbRegisterReadTN (D0F0xBC_x1F300_TYPE, D0F0xBC_x1F300_ADDRESS, &D0F0xBC_x1F300.Value, 0, StdHeader);
D0F0xBC_x1F300.Field.LclkDpmEn = 0x0;
GnbRegisterWriteTN (D0F0xBC_x1F300_TYPE, D0F0xBC_x1F300_ADDRESS, &D0F0xBC_x1F300.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader);
GnbSmuServiceRequestV4 (
GnbPciAddress,
SMC_MSG_CONFIG_LCLK_DPM,
GNB_REG_ACC_FLAG_S3SAVE,
StdHeader
);
//Initialize LCLK states
LibAmdMemFill (D0F0xBC_x1F200, 0x00, sizeof (D0F0xBC_x1F200), StdHeader);
LibAmdMemFill (D0F0xBC_x1F208, 0x00, sizeof (D0F0xBC_x1F208), StdHeader);
LibAmdMemFill (ex1003, 0x00, sizeof (D0F0xBC_x1F208), StdHeader);
D0F0xBC_x1F200[0].Field.LclkDivider = PpFuseArray->LclkDpmDid[0];
D0F0xBC_x1F200[0].Field.VID = PpFuseArray->SclkVid[PpFuseArray->LclkDpmVid[0]];
D0F0xBC_x1F200[0].Field.LowVoltageReqThreshold = 0xa;
D0F0xBC_x1F210[0].Field.ActivityThreshold = 0xf;
D0F0xBC_x1F200[5].Field.LclkDivider = PpFuseArray->LclkDpmDid[1];
D0F0xBC_x1F200[5].Field.VID = PpFuseArray->SclkVid[PpFuseArray->LclkDpmVid[1]];
D0F0xBC_x1F200[5].Field.LowVoltageReqThreshold = 0xa;
D0F0xBC_x1F210[5].Field.ActivityThreshold = 0x32;
D0F0xBC_x1F200[5].Field.StateValid = 0x1;
D0F0xBC_x1F200[6].Field.LclkDivider = PpFuseArray->LclkDpmDid[2];
D0F0xBC_x1F200[6].Field.VID = PpFuseArray->SclkVid[PpFuseArray->LclkDpmVid[2]];
D0F0xBC_x1F200[6].Field.LowVoltageReqThreshold = 0xa;
D0F0xBC_x1F210[6].Field.ActivityThreshold = 0x32;
D0F0xBC_x1F200[6].Field.StateValid = 0x1;
GnbRegisterReadTN (TYPE_D0F0xBC , 0x1f920 , &ex1072.Value, 0, StdHeader);
PcieCacLut = 0.0000057028 * (1 << ex1072.Field.ex1072_0 );
IDS_HDT_CONSOLE (GNB_TRACE, "LCLK DPM1 10khz %x (%d)\n", GfxFmCalculateClock (PpFuseArray->LclkDpmDid[1], StdHeader), GfxFmCalculateClock (PpFuseArray->LclkDpmDid[1], StdHeader));
D0F0xBC_x1FE00.Field.Data = (UINT32) GnbFpLibDoubleToInt32 (PcieCacLut * GfxFmCalculateClock (PpFuseArray->LclkDpmDid[1], StdHeader));
GnbRegisterWriteTN (D0F0xBC_x1FE00_TYPE, D0F0xBC_x1FE00_ADDRESS, &D0F0xBC_x1FE00.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader);
PcieCacLut = 0.00000540239329 * (1 << ex1072.Field.ex1072_0 );
ex1003[6].Field.ex1003_0 = (UINT32) GnbFpLibDoubleToInt32 (PcieCacLut * GfxFmCalculateClock (PpFuseArray->LclkDpmDid[2], StdHeader));
IDS_HDT_CONSOLE (GNB_TRACE, "LCLK DPM2 10khz %x (%d)\n", GfxFmCalculateClock (PpFuseArray->LclkDpmDid[2], StdHeader), GfxFmCalculateClock (PpFuseArray->LclkDpmDid[2], StdHeader));
for (Index = 0; Index < NUM_DPM_STATES; ++Index) {
GnbRegisterWriteTN (
D0F0xBC_x1F200_TYPE,
D0F0xBC_x1F200_ADDRESS + Index * 0x20,
&D0F0xBC_x1F200[Index].Value,
GNB_REG_ACC_FLAG_S3SAVE,
StdHeader
);
GnbRegisterWriteTN (
D0F0xBC_x1F208_TYPE,
D0F0xBC_x1F208_ADDRESS + Index * 0x20,
&D0F0xBC_x1F208[Index].Value,
GNB_REG_ACC_FLAG_S3SAVE,
StdHeader
);
GnbRegisterWriteTN (
D0F0xBC_x1F210_TYPE,
D0F0xBC_x1F210_ADDRESS + Index * 0x20,
&D0F0xBC_x1F210[Index].Value,
GNB_REG_ACC_FLAG_S3SAVE,
StdHeader
);
GnbRegisterWriteTN (
TYPE_D0F0xBC ,
0x1f940 + Index * 4,
&ex1003[Index].Value,
GNB_REG_ACC_FLAG_S3SAVE,
StdHeader
);
}
//Enable LCLK DPM Voltage Scaling
GnbRegisterReadTN (D0F0xBC_x1F300_TYPE, D0F0xBC_x1F300_ADDRESS, &D0F0xBC_x1F300.Value, 0, StdHeader);
D0F0xBC_x1F300.Field.VoltageChgEn = 0x1;
D0F0xBC_x1F300.Field.LclkDpmEn = 0x1;
D0F0xBC_x1F300.Field.LclkDpmBootState = 0x5;
GnbRegisterWriteTN (D0F0xBC_x1F300_TYPE, D0F0xBC_x1F300_ADDRESS, &D0F0xBC_x1F300.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader);
//Programming Lclk Thermal Throttling Threshold
GnbRegisterReadTN (D18F3x64_TYPE, D18F3x64_ADDRESS, &D18F3x64.Value, 0, StdHeader);
GnbRegisterReadTN (D0F0xBC_x1F30C_TYPE, D0F0xBC_x1F30C_ADDRESS, &D0F0xBC_x1F30C.Value, 0, StdHeader);
D0F0xBC_x1F30C.Field.LowThreshold = (UINT16) (((D18F3x64.Field.HtcTmpLmt / 2 + 52) - 1 + 49) * 8);
D0F0xBC_x1F30C.Field.HighThreshold = (UINT16) (((D18F3x64.Field.HtcTmpLmt / 2 + 52) + 49) * 8);
GnbRegisterWriteTN (D0F0xBC_x1F30C_TYPE, D0F0xBC_x1F30C_ADDRESS, &D0F0xBC_x1F30C.Value, GNB_REG_ACC_FLAG_S3SAVE, StdHeader);
GnbSmuServiceRequestV4 (
GnbPciAddress,
SMC_MSG_CONFIG_LCLK_DPM,
GNB_REG_ACC_FLAG_S3SAVE,
StdHeader
);
}
} else {
Status = AGESA_ERROR;
}
}
IDS_HDT_CONSOLE (GNB_TRACE, "GnbLclkDpmInitTN Exit [0x%x]\n", Status);
return Status;
}
/*----------------------------------------------------------------------------------------*/
/**
* PCIe Mid Post Init
*
*
*
* @param[in] StdHeader Standard configuration header
* @retval AGESA_STATUS
*/
AGESA_STATUS
GnbMidInterfaceTN (
IN AMD_CONFIG_PARAMS *StdHeader
)
{
AGESA_STATUS Status;
UINT32 Property;
AGESA_STATUS AgesaStatus;
GNB_HANDLE *GnbHandle;
UINT8 SclkDid;
AgesaStatus = AGESA_SUCCESS;
IDS_HDT_CONSOLE (GNB_TRACE, "GnbMidInterfaceTN Enter\n");
GnbHandle = GnbGetHandle (StdHeader);
ASSERT (GnbHandle != NULL);
Property = TABLE_PROPERTY_DEAFULT;
Property |= GfxLibIsControllerPresent (StdHeader) ? 0 : TABLE_PROPERTY_IGFX_DISABLED;
Property |= GnbBuildOptions.LclkDeepSleepEn ? TABLE_PROPERTY_LCLK_DEEP_SLEEP : 0;
Property |= GnbBuildOptions.CfgOrbClockGatingEnable ? TABLE_PROPERTY_ORB_CLK_GATING : 0;
Property |= GnbBuildOptions.CfgIocLclkClockGatingEnable ? TABLE_PROPERTY_IOC_LCLK_CLOCK_GATING : 0;
Property |= GnbBuildOptions.CfgIocSclkClockGatingEnable ? TABLE_PROPERTY_IOC_SCLK_CLOCK_GATING : 0;
Property |= GnbFmCheckIommuPresent (GnbHandle, StdHeader) ? 0: TABLE_PROPERTY_IOMMU_DISABLED;
Property |= GnbBuildOptions.SmuSclkClockGatingEnable ? TABLE_PROPERTY_SMU_SCLK_CLOCK_GATING : 0;
IDS_OPTION_HOOK (IDS_GNB_PROPERTY, &Property, StdHeader);
if ((Property & TABLE_PROPERTY_IOMMU_DISABLED) == 0) {
Status = GnbEnableIommuMmioV4 (GnbHandle, StdHeader);
AGESA_STATUS_UPDATE (Status, AgesaStatus);
Status = GnbIommuMidInit (StdHeader);
AGESA_STATUS_UPDATE (Status, AgesaStatus);
}
//
// Set sclk to 100Mhz
//
SclkDid = GfxRequestSclkTNS3Save (
GfxLibCalculateDidTN (98 * 100, StdHeader),
StdHeader
);
Status = GnbProcessTable (
GnbHandle,
GnbMidInitTableTN,
Property,
GNB_TABLE_FLAGS_FORCE_S3_SAVE,
StdHeader
);
AGESA_STATUS_UPDATE (Status, AgesaStatus);
//
// Restore Sclk
//
GfxRequestSclkTNS3Save (
SclkDid,
StdHeader
);
GnbCgttOverrideTN (Property, StdHeader);
Status = GnbLclkDpmInitTN (StdHeader);
AGESA_STATUS_UPDATE (Status, AgesaStatus);
IDS_HDT_CONSOLE (GNB_TRACE, "GnbMidInterfaceTN Exit [0x%x]\n", AgesaStatus);
return AgesaStatus;
}