/* $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; }