VOID STATIC PcieMidPortInitCallbackKV ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { DxFxx68_STRUCT DxFxx68; D0F0xE4_PIF_0012_STRUCT D0F0xE4_PIF_0012; PCIe_SUBLINK_INFO *SublinkInfo; PCIe_WRAPPER_INFO *WrapperInfo; PCIe_WRAPPER_CONFIG *Wrapper; CPU_LOGICAL_ID LogicalId; UINT8 Count; UINT8 Nibble; PciePortProgramRegisterTable (PortInitMidTableKV.Table, PortInitMidTableKV.Length, Engine, TRUE, Pcie); if (PcieConfigCheckPortStatus (Engine, INIT_STATUS_PCIE_TRAINING_SUCCESS) || Engine->Type.Port.PortData.LinkHotplug != HotplugDisabled) { PcieEnableSlotPowerLimitV5 (Engine, Pcie); if (GnbFmCheckIommuPresent ((GNB_HANDLE*) PcieConfigGetParentSilicon (Engine), GnbLibGetHeader (Pcie))) { PcieInitPortForIommuV4 (Engine, Pcie); } // After GFX link is trained up and before ASPM is enabled, AGESA needs to check link width, // if it equals to x16, then apply the following change to GFX port: // Per port register 0xA1 - PCIE LC TRAINING CONTROL, bit16 - LC_EXTEND_WAIT_FOR_SKP = 1 GnbLibPciRead ( Engine->Type.Port.Address.AddressValue | DxFxx68_ADDRESS, AccessWidth32, &DxFxx68, GnbLibGetHeader (Pcie) ); if (DxFxx68.Field.NegotiatedLinkWidth == 16) { PciePortRegisterRMW ( Engine, DxFxxE4_xA1_ADDRESS, DxFxxE4_xA1_LcExtendWaitForSkp_MASK, (1 << DxFxxE4_xA1_LcExtendWaitForSkp_OFFSET), TRUE, Pcie ); } } Wrapper = PcieConfigGetParentWrapper (Engine); SublinkInfo = &(((PCIe_INFO_BUFFER *)Buffer)->SublinkInfo[MIN (Engine->EngineData.StartLane, Engine->EngineData.EndLane) / 4]); WrapperInfo = &(((PCIe_INFO_BUFFER *)Buffer)->WrapperInfo[Wrapper->WrapId]); GetLogicalIdOfCurrentCore (&LogicalId, (AMD_CONFIG_PARAMS *)Pcie->StdHeader); // Check if this CPU is KV A0 // UBTS468566 if ((LogicalId.Revision & AMD_F15_KV_A0) != 0) { Count = SublinkInfo->GppPortCount; IDS_HDT_CONSOLE (GNB_TRACE, "x1x2 PortCount = %02x\n", Count); if (Count == 2) { // If number of GPP ports under the same sublink is 2, Delay L1 Exit (prolong minimum time spent in L1) PciePortRegisterRMW ( Engine, DxFxxE4_xA0_ADDRESS, DxFxxE4_xA0_LcDelayCount_MASK | DxFxxE4_xA0_LcDelayL1Exit_MASK, (0 << DxFxxE4_xA0_LcDelayCount_OFFSET) | (1 << DxFxxE4_xA0_LcDelayL1Exit_OFFSET), TRUE, Pcie ); } else if (Count > 2) { // If number of GPP ports > 2 if (SublinkInfo->MaxGenCapability > Gen1) { // If at least 1 GPP is Gen2 capable, Disable PLL Power down feature Wrapper = PcieConfigGetParentWrapper (Engine); Nibble = (UINT8) ((MIN (Engine->EngineData.StartLane, Engine->EngineData.EndLane) % 8) / 4); // Only PSD and PPD can have x1/x2 links, so we assume that PIF number is always 0 D0F0xE4_PIF_0012.Value = PcieRegisterRead ( Wrapper, PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS + Nibble), Pcie ); D0F0xE4_PIF_0012.Field.PllPowerStateInOff = PifPowerStateL0; D0F0xE4_PIF_0012.Field.PllPowerStateInTxs2 = PifPowerStateL0; PcieRegisterWrite ( Wrapper, PIF_SPACE (Wrapper->WrapId, 0, D0F0xE4_PIF_0012_ADDRESS + Nibble), D0F0xE4_PIF_0012.Value, TRUE, Pcie ); } else { // All ports are only Gen1 PciePortRegisterRMW ( Engine, DxFxxE4_xC0_ADDRESS, DxFxxE4_xC0_StrapMedyTSxCount_MASK, 0x2 << DxFxxE4_xC0_StrapMedyTSxCount_OFFSET, TRUE, Pcie ); } } } PcieRegisterRMW ( Wrapper, WRAP_SPACE (Wrapper->WrapId, D0F0xE4_WRAP_0802_ADDRESS + (0x100 * Engine->Type.Port.PortId)), D0F0xE4_WRAP_0802_StrapBifL1ExitLatency_MASK, (WrapperInfo->L1ExitLatencyValue << D0F0xE4_WRAP_0802_StrapBifL1ExitLatency_OFFSET), TRUE, Pcie ); if (WrapperInfo->DisableL1OnWrapper == TRUE) { Engine->Type.Port.PortData.LinkAspm &= ~(AspmL1); } PcieEnableAspm (Engine, Pcie); }
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; }