/** * Enable Cpu Cache Flush On Halt Function * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in,out] PciAddress Pointer to Pci address struct. * @param[in,out] AndMask Pointer to AND mask bits. * @param[in,out] OrMask Pointer to Or mask bits. * @param[in] StdHeader Handle of Header for calling lib functions and services. */ STATIC VOID GetF10CacheFlushOnHaltRegister ( IN CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices, IN OUT PCI_ADDR *PciAddress, IN OUT UINT32 *AndMask, IN OUT UINT32 *OrMask, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 CoreCount; CPU_LOGICAL_ID LogicalId; // // F3xDC[25:19] = 28h // F3xDC[18:16] = 111b // PciAddress->Address.Function = FUNC_3; PciAddress->Address.Register = CLOCK_POWER_TIMING_CTRL2_REG; *AndMask = 0xFC00FFFF; *OrMask = 0x01470000; GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); if ((LogicalId.Revision & AMD_F10_C2) != 0) { // //For F10_C2 single Core, F3xDC[18:16] = 0 // GetActiveCoresInCurrentSocket (&CoreCount, StdHeader); if (CoreCount == 1) { *OrMask = 0x01400000; } } }
/** * Enable DA-C Cpu Cache Flush On Halt Function * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] EntryPoint Timepoint designator. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] StdHeader Config Handle for library, services. */ VOID SetF10DaCacheFlushOnHaltRegister ( IN CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices, IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 CoreCount; UINT32 AndMask; UINT32 OrMask; PCI_ADDR PciAddress; CPU_LOGICAL_ID LogicalId; if ((EntryPoint & CPU_FEAT_AFTER_POST_MTRR_SYNC) != 0) { // F3xDC[25:19] = 04h // F3xDC[18:16] = 111b PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = CLOCK_POWER_TIMING_CTRL2_REG; AndMask = 0xFC00FFFF; OrMask = 0x00270000; GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); if (LogicalId.Revision == AMD_F10_DA_C2) { //For DA_C2 single Core, F3xDC[18:16] = 0 GetActiveCoresInCurrentSocket (&CoreCount, StdHeader); if (CoreCount == 1) { OrMask = 0x00200000; } } IDS_OPTION_HOOK (IDS_CACHE_FLUSH_HLT, &OrMask, StdHeader); OptionMultiSocketConfiguration.ModifyCurrSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3xDC } }
/** * Family specific call to check if Pstate PSD is dependent. * * @param[in] PstateCpuServices Pstate CPU services. * @param[in,out] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] StdHeader Config Handle for library, services. * * @retval TRUE PSD is dependent. * @retval FALSE PSD is independent. * */ BOOLEAN STATIC F10IsPstatePsdDependent ( IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, IN OUT PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { CPU_LOGICAL_ID CpuLogicalId; PLATFORM_FEATS Features; // Initialize the union Features.PlatformValue = 0; GetLogicalIdOfCurrentCore (&CpuLogicalId, StdHeader); GetPlatformFeatures (&Features, PlatformConfig, StdHeader); // // RevC and later Single link has PSD option, default is dependent. // If multi-link, always return independent. // if ((Features.PlatformFeatures.PlatformSingleLink) && ((CpuLogicalId.Revision & AMD_F10_GT_Bx) != 0)) { if (PlatformConfig->ForcePstateIndependent) { return FALSE; } return TRUE; } return FALSE; }
/** * Family 14h model 0 - 0xF core 0 entry point for programming registers for lower * power consumption. * * Set up D18F6x94[CpuPstateThrEn, CpuPstateThr], and D18F4x134[IntRateCC6DecrRate * according to the BKDG. * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] CpuEarlyParams Service parameters * @param[in] StdHeader Config handle for library and services. * */ VOID F14OptimizeForLowPowerInit ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 NumBoostStates; UINT32 LocalPciRegister; BOOLEAN OptimizeForLowPower; BOOLEAN IsRevC; PCI_ADDR PciAddress; CPU_LOGICAL_ID CpuFamilyRevision; PciAddress.AddressValue = PRODUCT_INFO_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); if ((((PRODUCT_INFO_REGISTER *) &LocalPciRegister)->LowPowerDefault == 1) && (CpuEarlyParams->PlatformConfig.PlatformProfile.PlatformPowerPolicy == BatteryLife)) { OptimizeForLowPower = TRUE; } else { OptimizeForLowPower = FALSE; } // Get F4x15C [4:2] NumBoostStates // Get IsRevC NumBoostStates = 0; IsRevC = FALSE; GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); if ((CpuFamilyRevision.Revision & AMD_F14_ON_Cx) != 0) { IsRevC = TRUE; PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); NumBoostStates = (UINT8) ((CPB_CTRL_REGISTER *) &LocalPciRegister)->NumBoostStates; } // F6x94[2:0] CpuPstateThr PciAddress.AddressValue = NB_PSTATE_CFG_HIGH_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); if (OptimizeForLowPower) { ((NB_PSTATE_CFG_HIGH_REGISTER *) &LocalPciRegister)->CpuPstateThr = 0; } else { if (NumBoostStates == 0) { ((NB_PSTATE_CFG_HIGH_REGISTER *) &LocalPciRegister)->CpuPstateThr = 1; } else { ((NB_PSTATE_CFG_HIGH_REGISTER *) &LocalPciRegister)->CpuPstateThr = 2; } } // F6x94[3] CpuPstateThrEn = 1 ((NB_PSTATE_CFG_HIGH_REGISTER *) &LocalPciRegister)->CpuPstateThrEn = 1; LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // F4x134[31:27] IntRateCC6DecrRate PciAddress.AddressValue = CSTATE_MON_CTRL3_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); ((CSTATE_MON_CTRL3_REGISTER *) &LocalPciRegister)->IntRateCC6DecrRate = (OptimizeForLowPower || IsRevC) ? 0x18 : 0x8; LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); }
/** * Should hardware C1e be enabled * * @param[in] HwC1eServices Pointer to this CPU's HW C1e family services. * @param[in] StdHeader Config Handle for library, services. * * @retval TRUE HW C1e is supported. * */ BOOLEAN STATIC F10IsHwC1eSupported ( IN HW_C1E_FAMILY_SERVICES *HwC1eServices, IN AMD_CONFIG_PARAMS *StdHeader ) { CPU_LOGICAL_ID LogicalId; GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); if (((LogicalId.Revision & AMD_F10_RB_ALL) & ~(AMD_F10_RB_C3)) != 0) { return FALSE; } return TRUE; }
BOOLEAN GnbCableSafeIsSupported ( IN AMD_CONFIG_PARAMS *StdHeader ) { BOOLEAN Result; CPU_LOGICAL_ID LogicalId; SMU_FIRMWARE_REV FirmwareRev; Result = FALSE; GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); FirmwareRev = NbSmuFirmwareRevision (StdHeader); if (SMI_FIRMWARE_REVISION (FirmwareRev) >= 0x010904 && LogicalId.Revision > AMD_F12_LN_A1) { Result = TRUE; } return Result; }
/** * Ids code for parse IDS feat table. * * Feat table in IDS is used to decribe the IDS support feat and its according family,handler. * * @param[in] PIdsFeatTbl point to Ids Feat table * @param[in] IdsOption IDS indicator value, see @ref AGESA_IDS_OPTION * @param[in,out] DataPtr Data pointer. * @param[in] IdsNvPtr Ids Nvram pointer. * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. * * @retval IDS_SUCCESS Backend function is called successfully. * @retval IDS_UNSUPPORTED No Backend function is found. **/ IDS_STATUS IdsParseFeatTbl ( IN AGESA_IDS_OPTION IdsOption, IN CONST IDS_FEAT_STRUCT * PIdsFeatTbl[], IN OUT VOID *DataPtr, IN IDS_NV_ITEM *IdsNvPtr, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { UINT16 i; AGESA_STATUS Tmpsts; CPU_LOGICAL_ID CpuLogicalId; BOOLEAN No_Check_Bsp; CONST IDS_FEAT_STRUCT *PIdsFeat; IDS_STATUS ReturnFlag; IDS_STATUS status; status = IDS_SUCCESS; ReturnFlag = IDS_SUCCESS; for (i = 0; PIdsFeatTbl[i] != NULL; i++) { PIdsFeat = PIdsFeatTbl[i]; //Does specified IdsOption reached if (PIdsFeat->IdsOption == IdsOption) { //check if bsp only if (PIdsFeat->IsBsp) { No_Check_Bsp = 0; } else { No_Check_Bsp = 1; } if (No_Check_Bsp || IsBsp (StdHeader, &Tmpsts)) { //Does Family Match required GetLogicalIdOfCurrentCore (&CpuLogicalId, StdHeader); if ((CpuLogicalId.Family) & (PIdsFeat->CpuFamily)) { //Excute the code for specific Ids Feat status = PIdsFeat->pf_idsoption (DataPtr, StdHeader, IdsNvPtr); if (status != IDS_SUCCESS) { ReturnFlag = status; } } } } } return ReturnFlag; }
/** * Enable BL-C Cpu Cache Flush On Halt Function * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] EntryPoint Timepoint designator. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] StdHeader Config Handle for library, services. */ VOID SetF10BlCacheFlushOnHaltRegister ( IN CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices, IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 AndMask; UINT32 OrMask; UINT32 CoreCount; PCI_ADDR PciAddress; CPU_LOGICAL_ID CpuFamilyRevision; if ((EntryPoint & CPU_FEAT_AFTER_POST_MTRR_SYNC) != 0) { GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = CLOCK_POWER_TIMING_CTRL2_REG; if (CpuFamilyRevision.Revision == AMD_F10_BL_C3) { // F3xDC[25:19] = 04h // F3xDC[18:16] = 111b AndMask = 0xFC00FFFF; OrMask = 0x00270000; } else { // F3xDC[25:19] = 28h // F3xDC[18:16] = 111b AndMask = 0xFC00FFFF; OrMask = 0x01470000; //For BL_C2 single Core, F3xDC[18:16] = 0 GetActiveCoresInCurrentSocket (&CoreCount, StdHeader); if (CoreCount == 1) { if (CpuFamilyRevision.Revision == AMD_F10_BL_C2) { OrMask = 0x01400000; } } } // Get the Or Mask value from IDS IDS_OPTION_HOOK (IDS_CACHE_FLUSH_HLT, &OrMask, StdHeader); ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3xDC } }
/** * Performs CPU related initialization at the recovery entry point * * This function processes the MSR and PCI register tables. * * @param[in] CpuRecoveryParams Required input parameters for recovery CPU * initialization. * * @retval AGESA_SUCCESS Always succeeds. * */ AGESA_STATUS AmdCpuRecovery ( IN AMD_CPU_RECOVERY_PARAMS *CpuRecoveryParams ) { UINT8 i; CPU_LOGICAL_ID CpuLogicalId; CPU_SPECIFIC_SERVICES *FamilySpecificServices; REGISTER_TABLE **RegisterTableList[2]; REGISTER_TABLE **RegisterTable; TABLE_CORE_SELECTOR Selector; REGISTER_TABLE **TableHandle; GetLogicalIdOfCurrentCore (&CpuLogicalId, &CpuRecoveryParams->StdHeader); GetCpuServicesFromLogicalId (&CpuLogicalId, &FamilySpecificServices, &CpuRecoveryParams->StdHeader); RegisterTableList[0] = FamilySpecificServices->RegisterTableListBeforeApLaunch; RegisterTableList[1] = FamilySpecificServices->RegisterTableListAfterApLaunch; for (i = 0; i < 2; i++) { for (Selector = AllCores; Selector < TableCoreSelectorMax; Selector++) { if (IsCoreSelector (Selector, &CpuRecoveryParams->StdHeader)) { // If the current core is the selected type of core, work the table list for tables for that type of core. TableHandle = NULL; RegisterTable = GetNextRegisterTable (Selector, RegisterTableList[i], &TableHandle, &CpuRecoveryParams->StdHeader); while (*RegisterTable != NULL) { SetRegistersFromTable (&CpuRecoveryParams->PlatformConfig, RegisterTable, &CpuRecoveryParams->StdHeader); RegisterTable = GetNextRegisterTable (Selector, RegisterTableList[i], &TableHandle, &CpuRecoveryParams->StdHeader); } } else { // Once a selector does not match the current core, quit looking. break; } } } LoadMicrocodePatch (&CpuRecoveryParams->StdHeader); return (AGESA_SUCCESS); }
AGESA_STATUS GnbLibDispatchFeatures ( IN OPTION_GNB_CONFIGURATION *ConfigTable, IN AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS Status; AGESA_STATUS AgesaStatus; CPU_LOGICAL_ID LogicalId; AgesaStatus = AGESA_SUCCESS; GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); while (ConfigTable->GnbFeature != NULL) { if ((ConfigTable->Type & LogicalId.Family) != 0) { Status = ConfigTable->GnbFeature (StdHeader); AGESA_STATUS_UPDATE (Status, AgesaStatus); } ConfigTable++; } return AgesaStatus; }
/** * BSC entry point for checking whether or not CPB is supported. * * @param[in] CpbServices The current CPU's family services. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] Socket Zero based socket number to check. * @param[in] StdHeader Config handle for library and services. * * @retval TRUE CPB is supported. * @retval FALSE CPB is not supported. * */ BOOLEAN STATIC F14OnIsCpbSupported ( IN CPB_FAMILY_SERVICES *CpbServices, IN PLATFORM_CONFIGURATION *PlatformConfig, IN UINT32 Socket, IN AMD_CONFIG_PARAMS *StdHeader ) { PCI_ADDR PciAddress; CPB_CTRL_REGISTER CpbControl; CPU_LOGICAL_ID CpuFamilyRevision; GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); if ((CpuFamilyRevision.Revision & (AMD_F14_ON_Ax | AMD_F14_ON_Bx)) != 0) { return FALSE; } else { PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &CpbControl, StdHeader); return (BOOLEAN) (CpbControl.NumBoostStates != 0); } }
/** * Production Erratum for Family14h ON. * * This function implements production errata for Family14h ON. * routine at AmdInitEarly. * * @param[in] FamilyServices The current Family Specific Services. * @param[in] EarlyParams Service parameters. * @param[in] StdHeader Config handle for library and services. * */ VOID F14OnProductionErrataAtEarly ( IN CPU_SPECIFIC_SERVICES *FamilyServices, IN AMD_CPU_EARLY_PARAMS *EarlyParams, IN AMD_CONFIG_PARAMS *StdHeader ) { CPU_LOGICAL_ID LogicalId; PCI_ADDR PciAddr; UINT32 PciData; UINT64 MsrValue; GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); PciAddr.AddressValue = MAKE_SBDFO (0, 0, 24, FUNC_4, D18F4x164_ADDRESS); LibAmdPciRead (AccessWidth32, PciAddr, &PciData, StdHeader); if (((PciData & D18F4x164_FixedErrata_0_MASK) == 1) && ((LogicalId.Revision & ~(AMD_F14_ON_Ax | AMD_F14_UNKNOWN)) != 0)) { // Program MSRC001_1020[18] = 1 only when D18F4x164[0] == 1 on ON B0 and later parts. LibAmdMsrRead (MSR_LS_CFG, &MsrValue, StdHeader); MsrValue = MsrValue | BIT18; LibAmdMsrWrite (MSR_LS_CFG, &MsrValue, StdHeader); } }
/** * Initializer routine that may be invoked at AmdCpuEarly to return the steps * appropriate for the executing Rev D core. * * @CpuServiceMethod{::F_GET_EARLY_INIT_TABLE}. * * @param[in] FamilyServices The current Family Specific Services. * @param[out] Table Table of appropriate init steps for the executing core. * @param[in] EarlyParams Service Interface structure to initialize. * @param[in] StdHeader Opaque handle to standard config header. * */ VOID GetF10HyEarlyInitOnCoreTable ( IN CPU_SPECIFIC_SERVICES *FamilyServices, OUT CONST S_PERFORM_EARLY_INIT_ON_CORE **Table, IN AMD_CPU_EARLY_PARAMS *EarlyParams, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 ProcessorPackageType; CPU_LOGICAL_ID LogicalId; GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); ProcessorPackageType = LibAmdGetPackageType (StdHeader); // Check if this CPU is affected by erratum 419. if (((LogicalId.Revision & AMD_F10_HY_SCM_D0) != 0) && ((ProcessorPackageType & (PACKAGE_TYPE_G34 | PACKAGE_TYPE_FR2_FR5_FR6)) == 0)) { // Return initialization steps such that the microcode patch is applied before // brand string determination is performed. *Table = F10HyC32D0EarlyInitOnCoreTable; } else { // No workaround is necessary. Return the standard table. GetF10EarlyInitOnCoreTable (FamilyServices, Table, EarlyParams, StdHeader); } }
/** * Family specific fuse table patch * Is's correct behavior if we would have 4 states, it would be * PP_FUSE_ARRAY->LclkDpmDid[0] - Goes to State 5 * PP_FUSE_ARRAY->LclkDpmDid[1] - Goes to State 6 * PP_FUSE_ARRAY->LclkDpmDid[2] - Goes to State 7 * If we would have 4 states it would be * PP_FUSE_ARRAY->LclkDpmDid[0] - Goes to State 4 * PP_FUSE_ARRAY->LclkDpmDid[1] - Goes to State 5 * PP_FUSE_ARRAY->LclkDpmDid[2] - Goes to State 6 * PP_FUSE_ARRAY->LclkDpmDid[3] - Goes to State 7 * * @param[in] PpFuseArray Pointer to PP_FUSE_ARRAY * @param[in] StdHeader Pointer to AMD_CONFIG_PARAMS */ VOID NbFmFuseAdjustFuseTablePatch ( IN OUT PP_FUSE_ARRAY *PpFuseArray, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 LclkDpmMode; UINT8 SwSatateIndex; UINT8 MaxSclkIndex; UINT8 DpmStateIndex; UINT8 CurrentSclkDpmDid; CPU_LOGICAL_ID LogicalId; D18F3x15C_STRUCT D18F3x15C; LclkDpmMode = GnbBuildOptions.LclkDpmEn ? LclkDpmRcActivity : LclkDpmDisabled; GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); if ((LogicalId.Revision & (AMD_F12_LN_A0 | AMD_F12_LN_A1)) != 0) { LclkDpmMode = LclkDpmDisabled; } IDS_OPTION_HOOK (IDS_GNB_LCLK_DPM_EN, &LclkDpmMode, StdHeader); // Read Sclk VID GnbLibPciRead ( MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3x15C_ADDRESS), AccessWidth32, &D18F3x15C.Value, StdHeader ); PpFuseArray->SclkVid[0] = (UINT8) (D18F3x15C.Field.SclkVidLevel0); PpFuseArray->SclkVid[1] = (UINT8) (D18F3x15C.Field.SclkVidLevel1); PpFuseArray->SclkVid[2] = (UINT8) (D18F3x15C.Field.SclkVidLevel2); PpFuseArray->SclkVid[3] = (UINT8) (D18F3x15C.Field.SclkVidLevel3); //For all CPU rev LclkDpmValid[3] = 0 PpFuseArray->LclkDpmValid[3] = 0; PpFuseArray->LclkDpmVid[3] = 0; PpFuseArray->LclkDpmDid[3] = 0; // For LCLKDPM set LclkDpmVid[0] = 0, no matter if LCLK DMP enable or disable. PpFuseArray->LclkDpmVid[0] = 0; if (LclkDpmMode != LclkDpmRcActivity) { //If LCLK DPM disable (LclkDpmMode != LclkDpmRcActivity) // - LclkDpmDid[1,2] = LclkDpmDid [0], LclkDpmVid[1,2] = LclkDpmVid[0] // - Execute LCLK DPM init PpFuseArray->LclkDpmVid[1] = PpFuseArray->LclkDpmVid[0]; PpFuseArray->LclkDpmVid[2] = PpFuseArray->LclkDpmVid[0]; PpFuseArray->LclkDpmDid[1] = PpFuseArray->LclkDpmDid[0]; PpFuseArray->LclkDpmDid[2] = PpFuseArray->LclkDpmDid[0]; IDS_HDT_CONSOLE (NB_MISC, " F12 LCLK DPM Mode Disable -- use DPM0 fusing\n"); } else { // If LCLK DPM enabled // - use fused values for LclkDpmDid[0,1,2] and appropriate voltage // - Execute LCLK DPM init PpFuseArray->LclkDpmVid[2] = PpFuseArray->PcieGen2Vid; if (GfxLibIsControllerPresent (StdHeader)) { //VID index = VID index associated with highest SCLK DPM state in the Powerplay state where Label_Performance=1 // This would ignore the UVD case (where Label_Performance would be 0). for (SwSatateIndex = 0 ; SwSatateIndex < PP_FUSE_MAX_NUM_SW_STATE; SwSatateIndex++) { if (PpFuseArray->PolicyLabel[SwSatateIndex] == POLICY_LABEL_PERFORMANCE) { break; } } MaxSclkIndex = 0; CurrentSclkDpmDid = 0xff; ASSERT (PpFuseArray->SclkDpmValid[SwSatateIndex] != 0); for (DpmStateIndex = 0; DpmStateIndex < PP_FUSE_MAX_NUM_DPM_STATE; DpmStateIndex++) { if ((PpFuseArray->SclkDpmValid[SwSatateIndex] & (1 << DpmStateIndex)) != 0) { if (PpFuseArray->SclkDpmDid[DpmStateIndex] < CurrentSclkDpmDid) { CurrentSclkDpmDid = PpFuseArray->SclkDpmDid[DpmStateIndex]; MaxSclkIndex = DpmStateIndex; } } } PpFuseArray->LclkDpmVid[1] = PpFuseArray->SclkDpmVid[MaxSclkIndex]; } else { PpFuseArray->LclkDpmVid[1] = PpFuseArray->LclkDpmVid[0]; PpFuseArray->LclkDpmDid[1] = PpFuseArray->LclkDpmDid[0]; } // - use fused values for LclkDpmDid[0,1,2] and appropriate voltage //Keep using actual fusing IDS_HDT_CONSOLE (NB_MISC, " LCLK DPM use actual fusing.\n"); } //Patch SclkThermDid to 200Mhz if not fused if (PpFuseArray->SclkThermDid == 0) { PpFuseArray->SclkThermDid = GfxLibCalculateDid (200 * 100, GfxLibGetMainPllFreq (StdHeader) * 100); } }
/** * This function initializes the heap for each CPU core. * * Check for already initialized. If not, determine offset of local heap in CAS and * setup initial heap markers and bookkeeping status. Also create an initial event log. * * @param[in] StdHeader Handle of Header for calling lib functions and services. * * @retval AGESA_SUCCESS This core's heap is initialized * @retval AGESA_FATAL This core's heap cannot be initialized due to any reasons below: * - current processor family cannot be identified. * */ AGESA_STATUS HeapManagerInit ( IN AMD_CONFIG_PARAMS *StdHeader ) { // First Time Initialization // Note: First 16 bytes of buffer is reserved for Heap Manager use UINT16 HeapAlreadyInitSizeDword; UINT32 HeapAlreadyRead; UINT8 L2LineSize; UINT8 *HeapBufferPtr; UINT8 *HeapInitPtr; UINT32 *HeapDataPtr; UINT64 MsrData; UINT64 MsrMask; UINT8 Ignored; CPUID_DATA CpuId; BUFFER_NODE *FreeSpaceNode; CACHE_INFO *CacheInfoPtr; CPU_SPECIFIC_SERVICES *FamilySpecificServices; CPU_LOGICAL_ID CpuFamilyRevision; // Check whether this is a known processor family. GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); if ((CpuFamilyRevision.Family == 0) && (CpuFamilyRevision.Revision == 0)) { IDS_ERROR_TRAP; return AGESA_FATAL; } GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); FamilySpecificServices->GetCacheInfo (FamilySpecificServices, (CONST VOID **) &CacheInfoPtr, &Ignored, StdHeader); HeapBufferPtr = (UINT8 *) StdHeader->HeapBasePtr; // Check whether the heap manager is already initialized LibAmdMsrRead (AMD_MTRR_VARIABLE_HEAP_MASK, &MsrData, StdHeader); if (!IsSecureS3 (StdHeader)) { if (MsrData == (CacheInfoPtr->VariableMtrrMask & AMD_HEAP_MTRR_MASK)) { LibAmdMsrRead (AMD_MTRR_VARIABLE_HEAP_BASE, &MsrData, StdHeader); if ((MsrData & CacheInfoPtr->HeapBaseMask) == ((UINT64) (UINTN) HeapBufferPtr & CacheInfoPtr->HeapBaseMask)) { if (((HEAP_MANAGER *) HeapBufferPtr)->Signature == HEAP_SIGNATURE_VALID) { // This is not a bug, there are multiple premem basic entry points, // and each will call heap init to make sure create struct will succeed. // If that is later deemed a problem, there needs to be a reasonable test // for the calling code to make to determine if it needs to init heap or not. // In the mean time, add this to the event log PutEventLog (AGESA_SUCCESS, CPU_ERROR_HEAP_IS_ALREADY_INITIALIZED, 0, 0, 0, 0, StdHeader); return AGESA_SUCCESS; } } } // Set variable MTRR base and mask MsrData = ((UINT64) (UINTN) HeapBufferPtr & CacheInfoPtr->HeapBaseMask); MsrMask = CacheInfoPtr->VariableMtrrHeapMask & AMD_HEAP_MTRR_MASK; MsrData |= 0x06; LibAmdMsrWrite (AMD_MTRR_VARIABLE_HEAP_BASE, &MsrData, StdHeader); LibAmdMsrWrite (AMD_MTRR_VARIABLE_HEAP_MASK, &MsrMask, StdHeader); // Set top of memory to a temp value LibAmdMsrRead (TOP_MEM, &MsrData, StdHeader); if (AMD_TEMP_TOM > MsrData) { MsrData = (UINT64) (AMD_TEMP_TOM); LibAmdMsrWrite (TOP_MEM, &MsrData, StdHeader); } } // Enable variable MTTRs LibAmdMsrRead (SYS_CFG, &MsrData, StdHeader); MsrData |= AMD_VAR_MTRR_ENABLE_BIT; LibAmdMsrWrite (SYS_CFG, &MsrData, StdHeader); // Initialize Heap Space // BIOS may store to a line only after it has been allocated by a load LibAmdCpuidRead (AMD_CPUID_L2L3Cache_L2TLB, &CpuId, StdHeader); L2LineSize = (UINT8) (CpuId.ECX_Reg); HeapInitPtr = HeapBufferPtr ; for (HeapAlreadyRead = 0; HeapAlreadyRead < AMD_HEAP_SIZE_PER_CORE; (HeapAlreadyRead = HeapAlreadyRead + L2LineSize)) { Ignored = *HeapInitPtr; HeapInitPtr += L2LineSize; } HeapDataPtr = (UINT32 *) HeapBufferPtr; for (HeapAlreadyInitSizeDword = 0; HeapAlreadyInitSizeDword < AMD_HEAP_SIZE_DWORD_PER_CORE; HeapAlreadyInitSizeDword++) { *HeapDataPtr = 0; HeapDataPtr++; } // Note: We are reserving the first 16 bytes for Heap Manager use // UsedSize indicates the size of heap spaced is used for HEAP_MANAGER, BUFFER_NODE, // Pad for 16-byte alignment, buffer data, and IDS SENTINEL. // FirstActiveBufferOffset is initalized as invalid heap offset, AMD_HEAP_INVALID_HEAP_OFFSET. // FirstFreeSpaceOffset is initalized as the byte right after HEAP_MANAGER header. // Then we set Signature of HEAP_MANAGER header as valid, HEAP_SIGNATURE_VALID. ((HEAP_MANAGER*) HeapBufferPtr)->UsedSize = sizeof (HEAP_MANAGER); ((HEAP_MANAGER*) HeapBufferPtr)->FirstActiveBufferOffset = AMD_HEAP_INVALID_HEAP_OFFSET; ((HEAP_MANAGER*) HeapBufferPtr)->FirstFreeSpaceOffset = sizeof (HEAP_MANAGER); ((HEAP_MANAGER*) HeapBufferPtr)->Signature = HEAP_SIGNATURE_VALID; // Create free space link FreeSpaceNode = (BUFFER_NODE *) (HeapBufferPtr + sizeof (HEAP_MANAGER)); FreeSpaceNode->BufferSize = AMD_HEAP_SIZE_PER_CORE - sizeof (HEAP_MANAGER) - sizeof (BUFFER_NODE); FreeSpaceNode->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET; StdHeader->HeapStatus = HEAP_LOCAL_CACHE; EventLogInitialization (StdHeader); return AGESA_SUCCESS; }
/** * Family 10h core 0 entry point for performing power plane initialization. * * The steps are as follows: * 1. If single plane, program lower VID code of CpuVid & NbVid for all * enabled P-States. * 2. Configure F3xA0[SlamMode] & F3xD8[VsRampTime & VsSlamTime] based on * platform requirements. * 3. Configure F3xD4[PowerStepUp & PowerStepDown] * 4. Optionally configure F3xA0[PsiVidEn & PsiVid] * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] CpuEarlyParams Service parameters * @param[in] StdHeader Config handle for library and services. * */ VOID F10CpuAmdPmPwrPlaneInit ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, IN AMD_CONFIG_PARAMS *StdHeader ) { BOOLEAN PviModeFlag; PCI_ADDR PciAddress; UINT16 PowerStepTime; UINT32 PowerStepEncoded; UINT32 PciRegister; UINT32 VsSlamTime; UINT32 Socket; UINT32 Module; UINT32 Core; UINT32 NumOfCores; UINT32 LowCore; UINT32 AndMask; UINT32 OrMask; UINT64 MsrRegister; AP_TASK TaskPtr; AGESA_STATUS IgnoredSts; PLATFORM_FEATS Features; CPU_LOGICAL_ID LogicalId; // Initialize the union Features.PlatformValue = 0; GetPlatformFeatures (&Features, &CpuEarlyParams->PlatformConfig, StdHeader); IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); ASSERT (Core == 0); GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); // Set SlamVidMode PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = PW_CTL_MISC_REG; LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); AndMask = 0xFFFFFFFF; OrMask = 0x00000000; if (((POWER_CTRL_MISC_REGISTER *) &PciRegister)->PviMode == 1) { PviModeFlag = TRUE; ((POWER_CTRL_MISC_REGISTER *) &AndMask)->SlamVidMode = 0; // Have all single plane cores adjust their NB and CPU VID fields TaskPtr.FuncAddress.PfApTask = F10PmPwrPlaneInitPviCore; TaskPtr.DataTransfer.DataSizeInDwords = 0; TaskPtr.ExeFlags = WAIT_FOR_CORE; ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParams); } else { PviModeFlag = FALSE; ((POWER_CTRL_MISC_REGISTER *) &OrMask)->SlamVidMode = 1; } ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); F10ProgramVSSlamTimeOnSocket (&PciAddress, CpuEarlyParams, StdHeader); // Configure PowerStepUp/PowerStepDown PciAddress.Address.Register = CPTC0_REG; if ((Features.PlatformFeatures.PlatformSingleLink == 1) || (Features.PlatformFeatures.PlatformUma == 1) || (Features.PlatformFeatures.PlatformUmaIfcm == 1) || (Features.PlatformFeatures.PlatformIfcm == 1) || (Features.PlatformFeatures.PlatformIommu == 1)) { PowerStepEncoded = 0x8; } else { GetGivenModuleCoreRange ((UINT32) Socket, (UINT32) Module, &LowCore, &NumOfCores, StdHeader); NumOfCores = ((NumOfCores - LowCore) + 1); PowerStepTime = (UINT16) (400 / NumOfCores); for (PowerStepEncoded = 0xF; PowerStepEncoded > 0; PowerStepEncoded--) { if (PowerStepTime <= PowerStepEncodings[PowerStepEncoded]) { break; } } } AndMask = 0xFFFFFFFF; ((CLK_PWR_TIMING_CTRL_REGISTER *) &AndMask)->PowerStepUp = 0; ((CLK_PWR_TIMING_CTRL_REGISTER *) &AndMask)->PowerStepDown = 0; OrMask = 0x00000000; ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->PowerStepUp = PowerStepEncoded; ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->PowerStepDown = PowerStepEncoded; ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); if ((LogicalId.Revision & AMD_F10_C3) != 0) { // Set up Pop up P-state register PciAddress.Address.Register = CPTC2_REG; LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); AndMask = 0xFFFFFFFF; ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupPstate = 0; ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupCpuVid = 0; ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupCpuFid = 0; ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupCpuDid = 0; OrMask = 0x00000000; ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupEn = 0; ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupPstate = ((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->PstateMaxVal; LibAmdMsrRead ((((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->PstateMaxVal + PS_REG_BASE), &MsrRegister, StdHeader); ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupCpuVid = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuVid; ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupCpuFid = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuFid; ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupCpuDid = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuDid; PciAddress.Address.Register = POPUP_PSTATE_REG; ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // Set AltVidStart PciAddress.Address.Register = CPTC1_REG; AndMask = 0xFFFFFFFF; ((CLK_PWR_TIMING_CTRL1_REGISTER *) &AndMask)->AltVidStart = 0; OrMask = 0x00000000; ((CLK_PWR_TIMING_CTRL1_REGISTER *) &OrMask)->AltVidStart = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuVid; ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // Set up Altvid slam time PciAddress.Address.Register = CPTC2_REG; VsSlamTime = F10CalculateAltvidVSSlamTimeOnCore (PviModeFlag, &PciAddress, CpuEarlyParams, StdHeader); AndMask = 0xFFFFFFFF; ((CLK_PWR_TIMING_CTRL2_REGISTER *) &AndMask)->AltvidVSSlamTime = 0; ((CLK_PWR_TIMING_CTRL2_REGISTER *) &AndMask)->SlamTimeMode = 0; OrMask = 0x00000000; ((CLK_PWR_TIMING_CTRL2_REGISTER *) &OrMask)->AltvidVSSlamTime = VsSlamTime; ((CLK_PWR_TIMING_CTRL2_REGISTER *) &OrMask)->SlamTimeMode = 2; ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); } if (IsWarmReset (StdHeader) && !PviModeFlag) { // Configure PsiVid F10PmVrmLowPowerModeEnable (FamilySpecificServices, CpuEarlyParams, StdHeader); } }
AGESA_STATUS GnbLoadBuildOptionDataML ( IN AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS Status; GNB_HANDLE *GnbHandle; GNB_BUILD_OPTIONS_ML *GnbBuildOptionData; UINT32 D0F0xBC_xC01040D0; CPU_LOGICAL_ID LogicalCpuid; D18F3xA0_STRUCT D18F3xA0; Status = AGESA_SUCCESS; GnbBuildOptionData = (GNB_BUILD_OPTIONS_ML *) GnbAllocateHeapBuffer (AMD_GNB_BUILD_OPTIONS_HANDLE, sizeof (GNB_BUILD_OPTIONS_ML), StdHeader); ASSERT (GnbBuildOptionData != NULL); GnbHandle = GnbGetHandle (StdHeader); GnbBuildOptionData->GnbCommonOptions.CfgScsSupport = GnbBuildOptionsML.GnbCommonOptions.CfgScsSupport; GnbBuildOptionData->GnbCommonOptions.CfgUmaSteering = GnbBuildOptionsML.GnbCommonOptions.CfgUmaSteering; GnbBuildOptionData->GnbCommonOptions.GmcPowerGating = GnbBuildOptionsML.GnbCommonOptions.GmcPowerGating; GnbBuildOptionData->GnbCommonOptions.CfgGmcClockGating = GnbBuildOptionsML.GnbCommonOptions.CfgGmcClockGating; GnbBuildOptionData->GnbCommonOptions.CfgOrbDynWakeEnable = GnbBuildOptionsML.GnbCommonOptions.CfgOrbDynWakeEnable; GnbBuildOptionData->GnbCommonOptions.CfgOrbClockGatingEnable = GnbBuildOptionsML.GnbCommonOptions.CfgOrbClockGatingEnable; GnbBuildOptionData->GnbCommonOptions.CfgIommuL1ClockGatingEnable = GnbBuildOptionsML.GnbCommonOptions.CfgIommuL1ClockGatingEnable; GnbBuildOptionData->GnbCommonOptions.CfgIommuL2ClockGatingEnable = GnbBuildOptionsML.GnbCommonOptions.CfgIommuL2ClockGatingEnable; GnbBuildOptionData->GnbCommonOptions.LclkDeepSleepEn = GnbBuildOptionsML.GnbCommonOptions.LclkDeepSleepEn; GnbBuildOptionData->GnbCommonOptions.LclkDpmEn = GnbBuildOptionsML.GnbCommonOptions.LclkDpmEn; GnbBuildOptionData->GnbCommonOptions.CfgIocLclkClockGatingEnable = GnbBuildOptionsML.GnbCommonOptions.CfgIocLclkClockGatingEnable; GnbBuildOptionData->GnbCommonOptions.CfgBapmSupport = GnbBuildOptionsML.GnbCommonOptions.CfgBapmSupport; GnbBuildOptionData->GnbCommonOptions.CfgDcTdpEnable = GnbBuildOptionsML.GnbCommonOptions.CfgDcTdpEnable; GnbBuildOptionData->CfgLhtcSupport = GnbBuildOptionsML.CfgLhtcSupport; GnbBuildOptionData->CfgSviRevision = GnbBuildOptionsML.CfgSviRevision; GnbBuildOptionData->CfgSamuPatchEnabled = GnbBuildOptionsML.CfgSamuPatchEnabled; GnbBuildOptionData->CfgTdcSupport = GnbBuildOptionsML.CfgTdcSupport; GnbBuildOptionData->CfgNativeGen1PLL = GnbBuildOptionsML.CfgNativeGen1PLL; GnbBuildOptionData->CfgPciePhyIsolationEnable = GnbBuildOptionsML.CfgPciePhyIsolationEnable; GnbBuildOptionData->CfgLinkBwNotificationEn = GnbBuildOptionsML.CfgLinkBwNotificationEn; GnbBuildOptionData->CfgBatteryBoostEn = UserOptions.CfgBatteryBoostEn; GnbBuildOptionData->CfgSpgClockGatingEnable = GnbBuildOptionsML.CfgSpgClockGatingEnable; GnbBuildOptionData->CfgPspDpmEn = GnbBuildOptionsML.CfgPspDpmEn; GnbBuildOptionData->CfgSMUServiceEnablementBitMap = GnbBuildOptionsML.CfgSMUServiceEnablementBitMap; GnbBuildOptionData->CfgUseSMUServices = GnbBuildOptionsML.CfgUseSMUServices; // Check for BAPM capability GnbRegisterReadML (GnbHandle, D18F3xA0_TYPE, D18F3xA0_ADDRESS, &D18F3xA0, 0, StdHeader); GetLogicalIdOfCurrentCore (&LogicalCpuid, StdHeader); if (((LogicalCpuid.Family & AMD_FAMILY_16_ML) != 0) && ((LogicalCpuid.Revision & AMD_F16_ML_A0) != 0) && (D18F3xA0.Field.ConfigId < 35)) { // BAPM is not supported on A0 ES1 config IDs // Reduce SMU service enablement to supported services GnbBuildOptionData->CfgSMUServiceEnablementBitMap = 0x003C0040ul; } IDS_HDT_CONSOLE (GNB_TRACE, "SMUServiceEnablementBitMap = 0x%x\n", GnbBuildOptionData->CfgSMUServiceEnablementBitMap); IDS_OPTION_HOOK (IDS_GNB_LOAD_BUILD_OPTIONS, GnbBuildOptionData, StdHeader); // Check fuse state of BBB feature. GnbRegisterReadML (GnbHandle, D0F0xBC_xC01040D0_TYPE, D0F0xBC_xC01040D0_ADDRESS, &D0F0xBC_xC01040D0, 0, StdHeader); if ((D0F0xBC_xC01040D0 & BIT15) == 0) { GnbBuildOptionData->CfgBatteryBoostEn = FALSE; } GnbDumpBuildOptionDataML (GnbBuildOptionData); return Status; }
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); }
/** * Support routine for F10PmAfterReset to perform MSR initialization on all * cores of a family 10h socket. * * This function implements steps 2 - 24 on each core. * * @param[in] StdHeader Config handle for library and services. * */ VOID STATIC F10PmAfterResetCore ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Socket; UINT32 Module; UINT32 Ignored; UINT32 PsMaxVal; UINT32 LocalPciRegister; UINT64 LocalMsrRegister; UINT64 SavedMsr; UINT64 CurrentLimitMsr; PCI_ADDR PciAddress; GO_TO_STEP GoToStep; AGESA_STATUS IgnoredSts; CPU_LOGICAL_ID LogicalId; CPU_SPECIFIC_SERVICES *FamilySpecificServices; // Step 2 If MSR C001_0071[CurNbDid] = 0, set MSR C001_001F[GfxNbPstateDis] GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); GetCpuServicesFromLogicalId (&LogicalId, &FamilySpecificServices, StdHeader); if ((LogicalId.Revision & (AMD_F10_C3 | AMD_F10_DA_C2)) != 0) { LibAmdMsrRead (MSR_COFVID_STS, &LocalMsrRegister, StdHeader); if (((COFVID_STS_MSR *) &LocalMsrRegister)->CurNbDid == 0) { LibAmdMsrRead (NB_CFG, &LocalMsrRegister, StdHeader); LocalMsrRegister |= BIT62; LibAmdMsrWrite (NB_CFG, &LocalMsrRegister, StdHeader); } } GoToStep = EXIT_SEQUENCE; LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &CurrentLimitMsr, StdHeader); PsMaxVal = (UINT32) (((PSTATE_CURLIM_MSR *) &CurrentLimitMsr)->PstateMaxVal); // Step 3 If MSRC001_0071[CurPstate] != F3xDC[PstateMaxVal], go to step 20 LibAmdMsrRead (MSR_COFVID_STS, &LocalMsrRegister, StdHeader); if (((COFVID_STS_MSR *) &LocalMsrRegister)->CurPstate != ((PSTATE_CURLIM_MSR *) &CurrentLimitMsr)->PstateMaxVal) { GoToStep = STEP20; } else { // Step 4 If F3xDC[PstateMaxVal] = 0 || F3xDC[PstateMaxVal] != 4, go to step 7 if ((PsMaxVal == 0) || (PsMaxVal != 4)) { GoToStep = STEP7; } else { // Step 5 If MSRC001_0061[CurPstateLimit] <= F3xDC[PstateMaxVal]-1, go to step 17 if (((PSTATE_CURLIM_MSR *) &CurrentLimitMsr)->CurPstateLimit <= (((PSTATE_CURLIM_MSR *) &CurrentLimitMsr)->PstateMaxVal - 1)) { GoToStep = STEP17; } } } switch (GoToStep) { default: case EXIT_SEQUENCE: // Step 6 Exit the sequence break; case STEP7: // Workaround for S3 ----Save the value of [The PState[4:0] Registers] MSRC001_00[68:64] // pointed to by F3xDC[PstateMaxVal] + 1 LibAmdMsrRead ((MSR_PSTATE_0 + (PsMaxVal + 1)), &SavedMsr, StdHeader); // Step 7 Copy the P-state register pointed to by F3xDC[PstateMaxVal] to the P-state // register pointed to by F3xDC[PstateMaxVal]+1 LibAmdMsrRead ((MSR_PSTATE_0 + PsMaxVal), &LocalMsrRegister, StdHeader); LibAmdMsrWrite ((MSR_PSTATE_0 + (PsMaxVal + 1)), &LocalMsrRegister, StdHeader); // Step 8 Write F3xDC[PstateMaxVal]+1 to F3xDC[PstateMaxVal] IdentifyCore (StdHeader, &Socket, &Module, &Ignored, &IgnoredSts); GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = CPTC2_REG; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); ((CLK_PWR_TIMING_CTRL2_REGISTER *) &LocalPciRegister)->PstateMaxVal = PsMaxVal + 1; LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // Step 9 Write (the new) F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd] FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) (PsMaxVal + 1), (BOOLEAN) FALSE, StdHeader); // Step 10 Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state // register pointed to by (the new) F3xDC[PstateMaxVal] WaitForCpuFidAndDidToMatch ((UINT32) (PsMaxVal + 1), StdHeader); // Step 11 Copy (the new) F3xDC[PstateMaxVal]-1 to MSRC001_0062[PstateCmd] FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) PsMaxVal, (BOOLEAN) FALSE, StdHeader); // Step 12 Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state // register pointed to by (the new) F3xDC[PstateMaxVal]-1 WaitForCpuFidAndDidToMatch (PsMaxVal, StdHeader); // Step 13 If MSRC001_0071[CurNbDid] = 1, set MSRC001_001F[GfxNbPstateDis] if ((LogicalId.Revision & (AMD_F10_C3 | AMD_F10_DA_C2)) != 0) { LibAmdMsrRead (MSR_COFVID_STS, &LocalMsrRegister, StdHeader); if (((COFVID_STS_MSR *) &LocalMsrRegister)->CurNbDid == 1) { LibAmdMsrRead (NB_CFG, &LocalMsrRegister, StdHeader); LocalMsrRegister |= BIT62; LibAmdMsrWrite (NB_CFG, &LocalMsrRegister, StdHeader); } } // Step 14 If required, transition the NB COF and VID to the NbDid and NbVid from the // P-state register pointed to by MSRC001_0061[CurPstateLimit] using the NB COF // and VID transition sequence after a warm reset // Step 15 Write 0 to PstateEn of the P-state register pointed to by (the new) F3xDC[PstateMaxVal] // Workaround for S3----Restore the value of [The PState[4:0] Registers] MSRC001_00[68:64] // pointed to by F3xDC[PstateMaxVal] + 1 ((PSTATE_MSR *) &SavedMsr)->PsEnable = 0; LibAmdMsrWrite ((MSR_PSTATE_0 + (PsMaxVal + 1)), &SavedMsr, StdHeader); // Step 16 Write (the new) F3xDC[PstateMaxVal]-1 to F3xDC[PstateMaxVal] LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); ((CLK_PWR_TIMING_CTRL2_REGISTER *) &LocalPciRegister)->PstateMaxVal = PsMaxVal; LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); break; case STEP17: // Step 17 Copy F3xDC[PstateMaxVal]-1 to MSRC001_0062[PstateCmd] FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) (PsMaxVal - 1), (BOOLEAN) FALSE, StdHeader); // Step 18 Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state // register pointed to by F3xDC[PstateMaxVal]-1 WaitForCpuFidAndDidToMatch ((UINT32) (PsMaxVal - 1), StdHeader); // Step 19 If MSR C001_0071[CurNbDid] = 0, set MSR C001_001F[GfxNbPstateDis] if ((LogicalId.Revision & (AMD_F10_C3 | AMD_F10_DA_C2)) != 0) { LibAmdMsrRead (MSR_COFVID_STS, &LocalMsrRegister, StdHeader); if (((COFVID_STS_MSR *) &LocalMsrRegister)->CurNbDid == 0) { LibAmdMsrRead (NB_CFG, &LocalMsrRegister, StdHeader); LocalMsrRegister |= BIT62; LibAmdMsrWrite (NB_CFG, &LocalMsrRegister, StdHeader); } } // Fall through from step 19 to step 20 case STEP20: // Step 20 Copy F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd] FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) PsMaxVal, (BOOLEAN) FALSE, StdHeader); // Step 21 Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state // register pointed to by F3xDC[PstateMaxVal] WaitForCpuFidAndDidToMatch (PsMaxVal, StdHeader); // Step 22 If MSR C001_0071[CurNbDid] = 1, set MSR C001_001F[GfxNbPstateDis] and exit // the sequence if ((LogicalId.Revision & (AMD_F10_C3 | AMD_F10_DA_C2)) != 0) { LibAmdMsrRead (MSR_COFVID_STS, &LocalMsrRegister, StdHeader); if (((COFVID_STS_MSR *) &LocalMsrRegister)->CurNbDid == 1) { LibAmdMsrRead (NB_CFG, &LocalMsrRegister, StdHeader); LocalMsrRegister |= BIT62; LibAmdMsrWrite (NB_CFG, &LocalMsrRegister, StdHeader); break; } } // Step 23 Issue an LDTSTOP and exit the sequence // Step 24 If required, transition the NB COF and VID to the NbDid and NbVid from the // P-state register pointed to by F3xDC[PstateMaxVal] using the NB COF and VID // transition sequence after a warm reset break; } }