/** * BSC entry point for for enabling Core Performance Boost. * * Set up D18F4x15C[BoostSrc] and start the PDMs according to the BKDG. * * @param[in] CpbServices The current CPU's family services. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] EntryPoint Current CPU feature dispatch point. * @param[in] Socket Zero based socket number to check. * @param[in] StdHeader Config handle for library and services. * * @retval AGESA_SUCCESS Always succeeds. * */ AGESA_STATUS STATIC F12InitializeCpb ( IN CPB_FAMILY_SERVICES *CpbServices, IN PLATFORM_CONFIGURATION *PlatformConfig, IN UINT64 EntryPoint, IN UINT32 Socket, IN AMD_CONFIG_PARAMS *StdHeader ) { PCI_ADDR PciAddress; D18F4x15C_STRUCT CpbControl; SMUx0B_x8580_STRUCT SMUx0Bx8580; if ((EntryPoint & CPU_FEAT_BEFORE_PM_INIT) != 0) { // F12EarlySampleCpbSupport.F12CpbInitHook (StdHeader); PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &CpbControl.Value, StdHeader); CpbControl.Field.BoostSrc = 1; IDS_OPTION_HOOK (IDS_CPB_CTRL, &CpbControl.Value, StdHeader); LibAmdPciWrite (AccessWidth32, PciAddress, &CpbControl.Value, StdHeader); } else if ((EntryPoint & CPU_FEAT_INIT_LATE_END) != 0) { // Ensure that the recommended settings have been programmed into SMUx0B_x8580, then // interrupt the SMU with service index 12h. SMUx0Bx8580.Value = 0; SMUx0Bx8580.Field.PdmPeriod = 0x1388; SMUx0Bx8580.Field.PdmUnit = 1; SMUx0Bx8580.Field.PdmCacEn = 1; SMUx0Bx8580.Field.PdmEn = 1; NbSmuRcuRegisterWrite (SMUx0B_x8580_ADDRESS, &SMUx0Bx8580.Value, 1, TRUE, StdHeader); NbSmuServiceRequest (0x12, TRUE, StdHeader); } return AGESA_SUCCESS; }
/** * Execute/clean up reconfiguration for Gen 1 native mode * * * * @param[in] Pcie Pointer to global PCIe configuration */ VOID PcieFmExecuteNativeGen1Reconfig ( IN PCIe_PLATFORM_CONFIG *Pcie ) { IDS_HDT_CONSOLE (GNB_TRACE, "PcieFmExecuteNativeGen1Reconfig Enter\n"); NbSmuServiceRequest (19, FALSE, GnbLibGetHeader (Pcie)); IDS_HDT_CONSOLE (GNB_TRACE, "PcieFmExecuteNativeGen1Reconfig Enter\n"); }
AGESA_STATUS GnbCableSafeEntry ( IN AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS Status; PCIe_PLATFORM_CONFIG *Pcie; PCIe_ENGINE_CONFIG *DdiEngineList [MaxHdp]; UINT8 HdpIndex; UINT8 CurrentIndex; GNB_CABLE_SAFE_DATA CableSafeData; IDS_HDT_CONSOLE (GNB_TRACE, "GnbCableSafeEntry Enter\n"); Status = AGESA_SUCCESS; if (GnbCableSafeIsSupported (StdHeader)) { if (PcieLocateConfigurationData (StdHeader, &Pcie) == AGESA_SUCCESS) { for (HdpIndex = 0; HdpIndex < MaxHdp; HdpIndex++) { DdiEngineList[HdpIndex] = NULL; } LibAmdMemFill (&CableSafeData, 0, sizeof (CableSafeData), StdHeader); PcieConfigRunProcForAllEngines ( DESCRIPTOR_ALLOCATED | DESCRIPTOR_DDI_ENGINE, GnbCableSafeGetConnectorInfoArrayCallback, DdiEngineList, Pcie ); CurrentIndex = 0; for (HdpIndex = 0; HdpIndex < MaxHdp; HdpIndex++) { if (DdiEngineList [HdpIndex] != NULL) { CableSafeData.Data[HdpIndexTranslationTable[CurrentIndex]] = HdpIndex + 1; CableSafeData.Data[AuxIndexTranslationTable[CurrentIndex]] = AuxDataTranslationTable [(DdiEngineList [HdpIndex])->Type.Ddi.DdiData.AuxIndex]; IDS_HDT_CONSOLE (NB_MISC, " Index [%d] HDP 0x%02x AUX 0x%02x\n", CurrentIndex, HdpIndex, (DdiEngineList [HdpIndex])->Type.Ddi.DdiData.AuxIndex); CurrentIndex++; } } CableSafeData.Config.Enable = 0x1; CableSafeData.Config.DebounceFilter = 0x2; CableSafeData.Config.SoftPeriod = 0x4; CableSafeData.Config.Unit = 0x1; CableSafeData.Config.Period = 0xf424; NbSmuRcuRegisterWrite ( SMUx0B_x85D0_ADDRESS, (UINT32*) &CableSafeData, sizeof (CableSafeData) / sizeof (UINT32), TRUE, StdHeader ); NbSmuServiceRequest (0x05, TRUE, StdHeader); } else { Status = AGESA_ERROR; } } IDS_HDT_CONSOLE (GNB_TRACE, "GnbCableSafeEntry Exit [Status = 0x%04x]\n", Status); return Status; }
/** * BSC entry point for enabling Core Performance Boost. * * Set up D18F4x15C[BoostSrc] and start the PDMs according to the BKDG. * * @param[in] CpbServices The current CPU's family services. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] EntryPoint Current CPU feature dispatch point. * @param[in] Socket Zero based socket number to check. * @param[in] StdHeader Config handle for library and services. * * @retval AGESA_SUCCESS Always succeeds. * */ AGESA_STATUS STATIC F14OnInitializeCpb ( IN CPB_FAMILY_SERVICES *CpbServices, IN PLATFORM_CONFIGURATION *PlatformConfig, IN UINT64 EntryPoint, IN UINT32 Socket, IN AMD_CONFIG_PARAMS *StdHeader ) { PCI_ADDR PciAddress; CPB_CTRL_REGISTER CpbControl; LPMV_SCALAR2_REGISTER LpmvScalar2; SMUx0B_x8580_STRUCT SMUx0Bx8580; if ((EntryPoint & CPU_FEAT_BEFORE_PM_INIT) != 0) { // F4x14C [25:24] ApmCstExtPol = 1 PciAddress.AddressValue = LPMV_SCALAR2_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &LpmvScalar2, StdHeader); LpmvScalar2.ApmCstExtPol = 1; LibAmdPciWrite (AccessWidth32, PciAddress, &LpmvScalar2, StdHeader); // F4x15C [1:0] BoostSrc = 1 // F4x15C [29] BoostEnAllCores = 1 PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &CpbControl, StdHeader); CpbControl.BoostSrc = 1; CpbControl.BoostEnAllCores = 1; IDS_OPTION_HOOK (IDS_CPB_CTRL, &CpbControl, StdHeader); LibAmdPciWrite (AccessWidth32, PciAddress, &CpbControl, StdHeader); } else if ((EntryPoint & CPU_FEAT_INIT_LATE_END) != 0) { // Ensure that the recommended settings have been programmed into SMUx0B_x8580, then // interrupt the SMU with service index 12h. NbSmuRcuRegisterRead (SMUx0B_x8580_ADDRESS, &SMUx0Bx8580.Value, 1, StdHeader); SMUx0Bx8580.Field.PdmPeriod = 0x1388; SMUx0Bx8580.Field.PdmParamLoc = 0; SMUx0Bx8580.Field.PdmCacEn = 1; SMUx0Bx8580.Field.PdmUnit = 1; SMUx0Bx8580.Field.PdmEn = 1; NbSmuRcuRegisterWrite (SMUx0B_x8580_ADDRESS, &SMUx0Bx8580.Value, 1, TRUE, StdHeader); NbSmuServiceRequest (0x12, TRUE, StdHeader); } return AGESA_SUCCESS; }
AGESA_STATUS GnbCableSafeEntry ( IN AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS Status; PCIe_PLATFORM_CONFIG *Pcie; PCIe_ENGINE_CONFIG *DdiEngineList [MaxHdp]; UINT8 HdpIndex; UINT8 CurrentIndex; GNB_CABLE_SAFE_DATA CableSafeData; BOOLEAN ForceCableSafeOff; IDS_HDT_CONSOLE (GNB_TRACE, "GnbCableSafeEntry Enter\n"); Status = AGESA_SUCCESS; ForceCableSafeOff = GnbBuildOptions.CfgForceCableSafeOff; IDS_OPTION_HOOK (IDS_GNB_FORCE_CABLESAFE, &ForceCableSafeOff, StdHeader); if (GnbCableSafeIsSupported (StdHeader)) { if (PcieLocateConfigurationData (StdHeader, &Pcie) == AGESA_SUCCESS) { for (HdpIndex = 0; HdpIndex < MaxHdp; HdpIndex++) { DdiEngineList[HdpIndex] = NULL; } LibAmdMemFill (&CableSafeData, 0, sizeof (CableSafeData), StdHeader); if (!ForceCableSafeOff) { PcieConfigRunProcForAllEngines ( DESCRIPTOR_ALLOCATED | DESCRIPTOR_DDI_ENGINE, GnbCableSafeGetConnectorInfoArrayCallback, DdiEngineList, Pcie ); CurrentIndex = 0; for (HdpIndex = 0; HdpIndex < MaxHdp; HdpIndex++) { if (DdiEngineList [HdpIndex] != NULL) { CableSafeData.Data[HdpIndexTranslationTable[CurrentIndex]] = HdpIndex + 1; CableSafeData.Data[AuxIndexTranslationTable[CurrentIndex]] = AuxDataTranslationTable [(DdiEngineList [HdpIndex])->Type.Ddi.DdiData.AuxIndex]; IDS_HDT_CONSOLE (NB_MISC, " Index [%d] HDP 0x%02x AUX 0x%02x\n", CurrentIndex, HdpIndex, (DdiEngineList [HdpIndex])->Type.Ddi.DdiData.AuxIndex); CurrentIndex++; } } } else { GMMx6124_STRUCT GMMx6124; GMMx6124.Value = 0x3F; NbSmuSrbmRegisterWrite (SMU_GMM_TO_FCR (GMMx6124_ADDRESS), &GMMx6124.Value, TRUE, GnbLibGetHeader (Pcie)); GnbLibPciRMW ( MAKE_SBDFO (0, 0, 0x18, 6, D18F6x80_ADDRESS), AccessWidth32, 0xffffffff, (7 << D18F6x80_CableSafeDisAux_3_1_OFFSET) | (7 << D18F6x80_CableSafeDisAux_6_4_OFFSET), GnbLibGetHeader (Pcie) ); } CableSafeData.Config.Enable = 0x1; CableSafeData.Config.DebounceFilter = 0; CableSafeData.Config.SoftPeriod = 0x4; CableSafeData.Config.Unit = 0x1; CableSafeData.Config.Period = 0xf424; NbSmuRcuRegisterWrite ( SMUx0B_x85D0_ADDRESS, (UINT32*) &CableSafeData, sizeof (CableSafeData) / sizeof (UINT32), TRUE, StdHeader ); NbSmuServiceRequest (0x05, TRUE, StdHeader); } else { Status = AGESA_ERROR; } } IDS_HDT_CONSOLE (GNB_TRACE, "GnbCableSafeEntry Exit [Status = 0x%04x]\n", Status); return Status; }
AGESA_STATUS NbFmInitLclkDpmRcActivity ( IN AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS Status; PP_FUSE_ARRAY *PpFuseArray; INT8 Index; UINTN LclkState; Status = AGESA_SUCCESS; IDS_HDT_CONSOLE (GNB_TRACE, "NbFmInitLclkDpmRcActivity F14 Enter\n"); PpFuseArray = GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, StdHeader); if (PpFuseArray != NULL) { UINT32 ActivityThreshold [8]; UINT16 SamplingPeriod [10]; UINT8 LclkScalingDid [4]; UINT8 LclkScalingVid [4]; UINT32 LclkDpmValid; UINT32 MainPllVcoKHz; LibAmdMemFill (&ActivityThreshold[0], 0, sizeof (ActivityThreshold), StdHeader); LibAmdMemFill (&SamplingPeriod[0], 0, sizeof (SamplingPeriod), StdHeader); MainPllVcoKHz = GfxLibGetMainPllFreq (StdHeader) * 100; LclkDpmValid = 0; LclkState = 7; for (Index = 3; Index >= 0; Index--) { if (PpFuseArray->LclkDpmValid [Index] != 0) { // Set valid DPM state LclkDpmValid |= (1 << (LclkState)); // Set LCLK scaling DID LclkScalingDid [7 - LclkState] = PpFuseArray->LclkDpmDid [Index]; // Set LCLK scaling VID LclkScalingVid [7 - LclkState] = PpFuseArray->LclkDpmVid [Index]; // Set sampling period SamplingPeriod [LclkState] = 0xC350; // Changed from 0xC350 to 0x1388 for DPM 0 if (Index == 0) { SamplingPeriod [LclkState] = 0x1388; } // Set activity threshold from BKDG: // Raising -- ActivityThreshold [LclkState] = ((102 * (GfxLibCalculateClk (LclkScalingDid [7 - LclkState], MainPllVcoKHz) / 100)) - 10) / 10; // Lowering -- ActivityThreshold [LclkState] |= (((407 * (GfxLibCalculateClk (LclkScalingDid [7 - LclkState], MainPllVcoKHz) / 100)) + 99) / 10) << 16; // For ON specific enable LCLK DPM : ActivityThreshold [LclkState] = LclkDpmActivityThresholdTable [Index]; IDS_HDT_CONSOLE (GNB_TRACE, "Fused State Index:%d LCLK DPM State [%d]: LclkScalingDid - 0x%x, ActivityThreshold - 0x%x, SamplingPeriod - 0x%x\n", Index, LclkState, LclkScalingDid [7 - LclkState], ActivityThreshold [LclkState], SamplingPeriod [LclkState] ); LclkState--; } } if (LclkState != 7) { SMUx33_STRUCT SMUx33; SMUx0B_x8434_STRUCT SMUx0B_x8434; FCRxFF30_01E4_STRUCT FCRxFF30_01E4; UINT8 CurrentUnit; UINT16 FinalUnit; UINT16 FinalPeriod; UINT32 Freq; UINT32 FreqDelta; UINT32 Value; ASSERT (LclkScalingDid [0] != 0); FreqDelta = 0xffffffff; FinalPeriod = 0; FinalUnit = 0; Freq = (65535 * 100 * 100) / GfxLibCalculateClk (LclkScalingDid [0], MainPllVcoKHz); for (CurrentUnit = 0; CurrentUnit < 16; CurrentUnit++) { UINT32 CurrentFreqDelta; UINT32 CurrentPeriod; UINT32 Temp; Temp = GnbLibPowerOf (4, CurrentUnit); CurrentPeriod = Freq / Temp; if (CurrentPeriod <= 0xFFFF) { CurrentFreqDelta = Freq - Temp * CurrentPeriod; if (FreqDelta > CurrentFreqDelta) { FinalUnit = CurrentUnit; FinalPeriod = (UINT16) CurrentPeriod; FreqDelta = CurrentFreqDelta; } } } //Process to enablement LCLK DPM States NbSmuIndirectRead (SMUx33_ADDRESS, AccessWidth32, &SMUx33.Value, StdHeader); SMUx33.Field.BusyCntSel = 0x3; SMUx33.Field.LclkActMonUnt = FinalUnit; SMUx33.Field.LclkActMonPrd = FinalPeriod; NbSmuIndirectWrite (SMUx33_ADDRESS, AccessS3SaveWidth32, &SMUx33.Value, StdHeader); SMUx0B_x8434.Value = 0; SMUx0B_x8434.Field.LclkDpmType = 0x1; SMUx0B_x8434.Field.LclkDpmEn = 0x1; SMUx0B_x8434.Field.LclkTimerPeriod = 0x0C350; SMUx0B_x8434.Field.LclkTimerPrescalar = 0x1; NbSmuRcuRegisterWrite ( SMUx0B_x8434_ADDRESS, &SMUx0B_x8434.Value, 1, TRUE, StdHeader ); NbSmuRcuRegisterWrite ( 0x84AC, &LclkDpmCacTable[0], sizeof (LclkDpmCacTable) / sizeof (UINT32), TRUE, StdHeader ); // Program activity threshold IDS_HDT_CONSOLE (GNB_TRACE, "ActivityThreshold[4] - 0x%x ActivityThreshold[5] - 0x%x ActivityThreshold[6] - 0x%x ActivityThreshold[7] - 0x%x\n", ActivityThreshold[4], ActivityThreshold[5], ActivityThreshold[6], ActivityThreshold [7] ); NbSmuRcuRegisterWrite ( SMUx0B_x8470_ADDRESS, &ActivityThreshold[4], 4, TRUE, StdHeader ); // Program sampling period for (Index = 0; Index < (sizeof (SamplingPeriod) / sizeof (SamplingPeriod[0])); Index = Index + 2) { UINT16 Temp; Temp = SamplingPeriod[Index]; SamplingPeriod[Index] = SamplingPeriod[Index + 1]; SamplingPeriod[Index + 1] = Temp; } IDS_HDT_CONSOLE (GNB_TRACE, "SamplingPeriod[4] - 0x%x SamplingPeriod[5] - 0x%x SamplingPeriod[6] - 0x%x SamplingPeriod[7] - 0x%x \n", SamplingPeriod[4], SamplingPeriod[5], SamplingPeriod[6], SamplingPeriod[7] ); NbSmuRcuRegisterWrite ( SMUx0B_x8440_ADDRESS, (UINT32*) &SamplingPeriod[4], 2, TRUE, StdHeader ); // Program LCK scaling DID NbSmuRcuRegisterWrite ( SMUx0B_x848C_ADDRESS, (UINT32*) &LclkScalingDid[0], 1, TRUE, StdHeader ); // Program LCK scaling VID NbSmuRcuRegisterWrite ( SMUx0B_x8498_ADDRESS, (UINT32*) &LclkScalingVid[0], 1, TRUE, StdHeader ); // Program valid LCLK DPM states LclkDpmValid = NbFmDpmStateBootupInit (LclkDpmValid, StdHeader); NbSmuRcuRegisterWrite ( SMUx0B_x8490_ADDRESS, &LclkDpmValid, 1, TRUE, StdHeader ); //Setup Activity Monitor Coefficients Value = (0x24 << SMUx35_DownTrendCoef_OFFSET) | (0x24 << SMUx35_UpTrendCoef_OFFSET); NbSmuIndirectWrite (SMUx35_ADDRESS, AccessS3SaveWidth32, &Value, StdHeader); Value = (0x22 << SMUx35_DownTrendCoef_OFFSET) | (0x22 << SMUx35_UpTrendCoef_OFFSET); for (Index = SMUx37_ADDRESS; Index <= SMUx51_ADDRESS; Index = Index + 2) { NbSmuIndirectWrite (Index, AccessS3SaveWidth32, &Value, StdHeader); } // Enable LCLK DPM as voltage client NbSmuSrbmRegisterRead (FCRxFF30_01E4_ADDRESS, &FCRxFF30_01E4.Value, StdHeader); FCRxFF30_01E4.Field.VoltageChangeEn = 0x1; NbSmuSrbmRegisterWrite (FCRxFF30_01E4_ADDRESS, &FCRxFF30_01E4.Value, TRUE, StdHeader); // Start LCLK service NbSmuServiceRequest (0x8, TRUE, StdHeader); } } else { IDS_HDT_CONSOLE (GNB_TRACE, " ERROR! Cannot locate fuse table\n"); Status = AGESA_ERROR; } IDS_HDT_CONSOLE (GNB_TRACE, "NbFmInitLclkDpmRcActivity F14 Exit [0x%x]\n", Status); return Status; }