aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f12/Proc/GNB/Nb/Family/LN/F12NbLclkDpm.c
diff options
context:
space:
mode:
authorefdesign98 <efdesign98@gmail.com>2011-06-16 16:35:54 -0700
committerMarc Jones <marcj303@gmail.com>2011-06-21 22:37:51 +0200
commitb0969d65e675f7c7a3004fc3f6fc154f22e73d44 (patch)
tree7e11f186e900ce6fc77603515b85c2a4154c6849 /src/vendorcode/amd/agesa/f12/Proc/GNB/Nb/Family/LN/F12NbLclkDpm.c
parentd1cb0eecd130cb4259ce9fedb32ebcd9ada0d4b7 (diff)
Add AMD Family 12 cpu Agesa code
This is the addition of the AMD Family 12 cpu code. Change-Id: I3febc81e192b4e86bbd3e8d6e1da62a28598fa8c Signed-off-by: Frank Vibrans<frank.vibrans@amd.com> Signed-off-by: efdesign98 <efdesign98@gmail.com> Reviewed-on: http://review.coreboot.org/40 Tested-by: build bot (Jenkins) Reviewed-by: Marc Jones <marcj303@gmail.com>
Diffstat (limited to 'src/vendorcode/amd/agesa/f12/Proc/GNB/Nb/Family/LN/F12NbLclkDpm.c')
-rwxr-xr-xsrc/vendorcode/amd/agesa/f12/Proc/GNB/Nb/Family/LN/F12NbLclkDpm.c347
1 files changed, 347 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Nb/Family/LN/F12NbLclkDpm.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Nb/Family/LN/F12NbLclkDpm.c
new file mode 100755
index 0000000000..a6783ba0f3
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Nb/Family/LN/F12NbLclkDpm.c
@@ -0,0 +1,347 @@
+/* $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 "GnbCommonLib.h"
+#include "GnbPcieConfig.h"
+#include "GnbRegistersLN.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_LN_F12NBLCLKDPM_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 F12 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
+ );
+ // Set CAC Credits
+ NbSmuRcuRegisterWrite (
+ SMUx0B_x84AC_ADDRESS,
+ &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 F12 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 LN, 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;
+}