blob: 626f33d3aa5e4b7d5f4d1800e9d70bb69344d4e8 [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 2008 - 2012 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
*
* AMD is granting you permission to use this software (the Materials)
* pursuant to the terms and conditions of your Software License Agreement
* with AMD. This header does *NOT* give you permission to use the Materials
* or any rights under AMD's intellectual property. Your use of any portion
* of these Materials shall constitute your acceptance of those terms and
* conditions. If you do not agree to the terms and conditions of the Software
* License Agreement, please do not use any portion of these Materials.
*
* CONFIDENTIALITY: The Materials and all other information, identified as
* confidential and provided to you by AMD shall be kept confidential in
* accordance with the terms and conditions of the Software License Agreement.
*
* LIMITATION OF LIABILITY: THE MATERIALS AND ANY OTHER RELATED INFORMATION
* PROVIDED TO YOU BY AMD ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
* MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE,
* OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR USAGE OF TRADE.
* IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER
* (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS
* INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF AMD'S NEGLIGENCE,
* GROSS NEGLIGENCE, THE USE OF OR INABILITY TO USE THE MATERIALS OR ANY OTHER
* RELATED INFORMATION PROVIDED TO YOU BY AMD, EVEN IF AMD HAS BEEN ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE
* EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES,
* THE ABOVE LIMITATION MAY NOT APPLY TO YOU.
*
* AMD does not assume any responsibility for any errors which may appear in
* the Materials or any other related information provided to you by AMD, or
* result from use of the Materials or any related information.
*
* You agree that you will not reverse engineer or decompile the Materials.
*
* NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any
* further information, software, technical information, know-how, or show-how
* available to you. Additionally, AMD retains the right to modify the
* Materials at any time, without notice, and is not obligated to provide such
* modified Materials to you.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with
* "RESTRICTED RIGHTS." Use, duplication, or disclosure by the Government is
* subject to the restrictions as set forth in FAR 52.227-14 and
* DFAR252.227-7013, et seq., or its successor. Use of the Materials by the
* Government constitutes acknowledgement of AMD's proprietary rights in them.
*
* EXPORT ASSURANCE: You agree and certify that neither the Materials, nor any
* direct product thereof will be exported directly or indirectly, into any
* country prohibited by the United States Export Administration Act and the
* regulations thereunder, without the required authorization from the U.S.
* government nor will be used for any purpose prohibited by the same.
* ***************************************************************************
*
*/
/*----------------------------------------------------------------------------------------
* 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;
}