diff options
author | efdesign98 <efdesign98@gmail.com> | 2011-06-20 18:12:43 -0700 |
---|---|---|
committer | Marc Jones <marcj303@gmail.com> | 2011-06-22 01:35:45 +0200 |
commit | 621ca384a7a5efb2cc7597504dc17b741cd2df10 (patch) | |
tree | 01871adc6d39f48916b5625b3aa1a4b6d5ab9c92 /src/vendorcode/amd/agesa/f14/Proc/GNB/Nb/Family/0x14/F14NbLclkDpm.c | |
parent | 05a89ab922473f375820a3bd68691bb085c62448 (diff) | |
download | coreboot-621ca384a7a5efb2cc7597504dc17b741cd2df10.tar.xz |
Move existing AMD Ffamily14 code to f14 folder
This change moves the AMD Family14 cpu Agesa code to
the vendorcode/amd/agesa/f14 folder to complete the
transition to the family oriented folder structure.
Change-Id: I211e80ee04574cc713f38b4cc1b767dbb2bfaa59
Signed-off-by: Frank Vibrans <frank.vibrans@amd.com>
Signed-off-by: efdesign98 <efdesign98@gmail.com>
Reviewed-on: http://review.coreboot.org/52
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marcj303@gmail.com>
Diffstat (limited to 'src/vendorcode/amd/agesa/f14/Proc/GNB/Nb/Family/0x14/F14NbLclkDpm.c')
-rw-r--r-- | src/vendorcode/amd/agesa/f14/Proc/GNB/Nb/Family/0x14/F14NbLclkDpm.c | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f14/Proc/GNB/Nb/Family/0x14/F14NbLclkDpm.c b/src/vendorcode/amd/agesa/f14/Proc/GNB/Nb/Family/0x14/F14NbLclkDpm.c new file mode 100644 index 0000000000..3c918aa2cb --- /dev/null +++ b/src/vendorcode/amd/agesa/f14/Proc/GNB/Nb/Family/0x14/F14NbLclkDpm.c @@ -0,0 +1,348 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * LCLK DPM initialization + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 39007 $ @e \$Date: 2010-10-05 00:32:54 +0800 (Tue, 05 Oct 2010) $ + * + */ +/* + ***************************************************************************** + * + * Copyright (c) 2011, 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 "amdlib.h" +#include "Ids.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbFuseTable.h" +#include "GnbPcie.h" +#include GNB_MODULE_DEFINITIONS (GnbCommonLib) +#include GNB_MODULE_DEFINITIONS (GnbPcieConfig) +#include "GnbRegistersON.h" +#include "OptionGnb.h" +#include "GfxLib.h" +#include "NbConfigData.h" +#include "NbSmuLib.h" +#include "NbLclkDpm.h" +#include "NbFamilyServices.h" +#include "Filecode.h" + +#define FILECODE PROC_GNB_NB_FAMILY_0X14_F14NBLCLKDPM_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; +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +UINT32 LclkDpmCacTable [] = { + 0x0, + 0x0, + 0x0, + 0x0 +}; + +UINT32 LclkDpmActivityThresholdTable [] = { + 0x100, + 0x40FFFF, + 0x40FFFF, + 0x0 +}; + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Init NB LCLK DPM in Root Complex Activity mode + * + * + * + * @param[in] StdHeader Pointer to Standard configuration + * @retval Initialization 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; +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Family specific check PsppPolicy to initially enable appropriate DPM states + * + * + * @param[in] LclkDpmValid UINT32 Lclk Dpm Valid + * @param[in] StdHeader Pointer to AMD_CONFIG_PARAMS + */ +UINT32 +NbFmDpmStateBootupInit ( + IN UINT32 LclkDpmValid, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + PCIe_PLATFORM_CONFIG *Pcie; + UINT32 LclkDpmValidState; + UINT8 Dpm0ValidOffset; + + if ((LclkDpmValid & 0xFF) == 0) { + IDS_HDT_CONSOLE (NB_MISC, " No valid DPM State Bootup Init\n"); + return 0; + } + + // For ON, from DPM0(the most right non-zero bit) to highest DPM(bit 7) + Dpm0ValidOffset = LibAmdBitScanForward (LclkDpmValid & 0xFF); + // Enable DPM0 + LclkDpmValidState = 1 << Dpm0ValidOffset; + + if (PcieLocateConfigurationData (StdHeader, &Pcie) == AGESA_SUCCESS) { + switch (Pcie->PsppPolicy) { + case PsppDisabled: + case PsppPerformance: + case PsppBalanceHigh: + if ((Dpm0ValidOffset + 2) <= 7) { + // Enable DPM0 + DPM2 + LclkDpmValidState = LclkDpmValidState + (1 << (Dpm0ValidOffset + 2)); + } + break; + case PsppBalanceLow: + if ((Dpm0ValidOffset + 1) <= 7) { + // Enable DPM0 + DPM1 + LclkDpmValidState = LclkDpmValidState + (1 << (Dpm0ValidOffset + 1)); + } + break; + case PsppPowerSaving: + // Enable DPM0 + break; + default: + ASSERT (FALSE); + } + } else { + IDS_HDT_CONSOLE (NB_MISC, " DPM State Bootup Init Pcie Locate ConfigurationData Fail!! -- Enable DPM0 only\n"); + } + return LclkDpmValidState; +} + |