summaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f14/Proc/Mem/NB/ON/mndcton.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/f14/Proc/Mem/NB/ON/mndcton.c')
-rw-r--r--src/vendorcode/amd/agesa/f14/Proc/Mem/NB/ON/mndcton.c490
1 files changed, 490 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f14/Proc/Mem/NB/ON/mndcton.c b/src/vendorcode/amd/agesa/f14/Proc/Mem/NB/ON/mndcton.c
new file mode 100644
index 0000000000..c0855b8f43
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f14/Proc/Mem/NB/ON/mndcton.c
@@ -0,0 +1,490 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mndcton.c
+ *
+ * Northbridge ON DCT supporting functions
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/NB/ON)
+ * @e \$Revision: 37169 $ @e \$Date: 2010-09-01 05:35:27 +0800 (Wed, 01 Sep 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.
+ *
+ * ***************************************************************************
+ *
+ */
+
+
+/*
+ *----------------------------------------------------------------------------
+ * MODULES USED
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+#include "AGESA.h"
+#include "amdlib.h"
+#include "Ids.h"
+#include "mm.h"
+#include "mn.h"
+#include "mt.h"
+#include "mu.h"
+#include "OptionMemory.h" // need def for MEM_FEAT_BLOCK_NB
+#include "mnon.h"
+#include "merrhdl.h"
+#include "GeneralServices.h"
+#include "cpuFamilyTranslation.h"
+#include "cpuCommonF14Utilities.h"
+#include "Filecode.h"
+#define FILECODE PROC_MEM_NB_ON_MNDCTON_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+#define UNUSED_CLK 4
+#define MAX_RD_DQS_DLY 0x1F
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+extern BUILD_OPT_CFG UserOptions;
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function programs the memory controller with configuration parameters
+ *
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ * @return TRUE - An Error value lower than AGESA_FATAL may have occurred
+ * @return FALSE - An Error value greater than or equal to AGESA_FATAL may have occurred
+ * @return NBPtr->MCTPtr->ErrCode - Contains detailed AGESA_STATUS value
+ */
+
+BOOLEAN
+MemNAutoConfigON (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ DIE_STRUCT *MCTPtr;
+ DCT_STRUCT *DCTPtr;
+ UINT8 PowerDownMode;
+
+ MCTPtr = NBPtr->MCTPtr;
+ DCTPtr = NBPtr->DCTPtr;
+ //======================================================================
+ // Build Dram Control Register Value (F2x78)
+ //======================================================================
+ //
+
+ //======================================================================
+ // Build Dram Config Lo Register Value
+ //======================================================================
+ //
+ MemNSetBitFieldNb (NBPtr, BFEnDispAutoPrecharge, 1);
+
+ MemNSetBitFieldNb (NBPtr, BFIdleCycInit, 3);
+
+ //======================================================================
+ // Build Dram Config Hi Register Value
+ //======================================================================
+ //
+
+ MemNSetBitFieldNb (NBPtr, BFMemClkFreq, MemNGetMemClkFreqIdClientNb (NBPtr, DCTPtr->Timings.Speed));
+
+ PowerDownMode = (UINT8) ((UserOptions.CfgPowerDownMode == POWER_DOWN_MODE_AUTO) ? POWER_DOWN_BY_CHIP_SELECT : UserOptions.CfgPowerDownMode);
+ PowerDownMode = (!NBPtr->IsSupported[ChannelPDMode]) ? PowerDownMode : 0;
+ IDS_OPTION_HOOK (IDS_POWERDOWN_MODE, &PowerDownMode, &(NBPtr->MemPtr->StdHeader));
+ if (PowerDownMode == 1) {
+ MemNSetBitFieldNb (NBPtr, BFPowerDownMode, 1);
+ }
+
+ MemNSetBitFieldNb (NBPtr, BFPchgPDModeSel, 1);
+
+ MemNSetBitFieldNb (NBPtr, BFDcqBypassMax, 0xE);
+
+ MemNSetBitFieldNb (NBPtr, BFDctSelBankSwap, 1);
+
+ //======================================================================
+ // Build Dram Config Misc Register Value
+ //======================================================================
+ //
+ // Max out Non-SPD timings
+ MemNSetBitFieldNb (NBPtr, BFNonSPD, 0x18FF);
+ MemNSetBitFieldNb (NBPtr, BFNonSPDHi, 0x2A);
+ MemNSetBitFieldNb (NBPtr, BFTwrrdSD, 0xA);
+ MemNSetBitFieldNb (NBPtr, BFTrdrdSD, 0x8);
+ MemNSetBitFieldNb (NBPtr, BFTwrwrSD, 0x9);
+
+ MemNSetBitFieldNb (NBPtr, BFWrOdtOnDuration, DEFAULT_WR_ODT_ON_ON);
+ MemNSetBitFieldNb (NBPtr, BFRdOdtOnDuration, DEFAULT_RD_ODT_ON_ON);
+ MemNSetBitFieldNb (NBPtr, BFWrOdtTrnOnDly, 0);
+
+ //======================================================================
+ // DRAM MRS Register, set ODT
+ //======================================================================
+ MemNSetBitFieldNb (NBPtr, BFBurstCtrl, 1);
+
+ // DrvImpCtrl: drive impedance control.01b(34 ohm driver; Ron34 = Rzq/7)
+ MemNSetBitFieldNb (NBPtr, BFDrvImpCtrl, 1);
+
+ return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL);
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sends an MRS command
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemNSendMrsCmdON (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ MemNSetASRSRTNb (NBPtr);
+ MemNSwapBitsNb (NBPtr);
+
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tCS%d MR%d %04x\n",
+ (MemNGetBitFieldNb (NBPtr, BFDramInitRegReg) >> 20) & 0xF,
+ (MemNGetBitFieldNb (NBPtr, BFDramInitRegReg) >> 16) & 0xF,
+ (MemNGetBitFieldNb (NBPtr, BFDramInitRegReg) & 0xFFFF));
+
+ // 1.Set SendMrsCmd=1
+ MemNSetBitFieldNb (NBPtr, BFSendMrsCmd, 1);
+
+ // 2.Wait for SendMrsCmd=0
+ MemNPollBitFieldNb (NBPtr, BFSendMrsCmd, 0, PCI_ACCESS_TIMEOUT, FALSE);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function combines all the memory into a contiguous map.
+ * Requires that Mask values for each bank be programmed first and that
+ * the chip-select population indicator is correctly set.
+ *
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ * @return TRUE - An Error value lower than AGESA_FATAL may have occurred
+ * @return FALSE - An Error value greater than or equal to AGESA_FATAL may have occurred
+ */
+
+BOOLEAN
+MemNStitchMemoryON (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT32 NxtCSBase;
+ UINT32 CurCSBase;
+ UINT32 CsSize;
+ UINT32 BiggestBank;
+ UINT8 p;
+ UINT8 q;
+ UINT8 BiggestDimm;
+ DIE_STRUCT *MCTPtr;
+ DCT_STRUCT *DCTPtr;
+ MCTPtr = NBPtr->MCTPtr;
+ DCTPtr = NBPtr->DCTPtr;
+
+ DCTPtr->Timings.CsEnabled = 0;
+ NxtCSBase = 0;
+ for (p = 0; p < MAX_CS_PER_CHANNEL_ON; p++) {
+ BiggestBank = 0;
+ BiggestDimm = 0;
+ for (q = 0; q < MAX_CS_PER_CHANNEL_ON; q++) {
+ if (((DCTPtr->Timings.CsPresent & ~DCTPtr->Timings.CsTestFail) & ((UINT16)1 << q)) != 0) {
+ if ((MemNGetBitFieldNb (NBPtr, BFCSBaseAddr0Reg + q) & 7) == 0) {
+ // (CSEnable|Spare==1)bank is not enabled yet
+ CsSize = MemNGetBitFieldNb (NBPtr, BFCSMask0Reg + (q >> 1));
+ if (CsSize != 0) {
+ CsSize += ((UINT32)1 << 19);
+ CsSize &= 0xFFF80000;
+ }
+ if (CsSize > BiggestBank) {
+ BiggestBank = CsSize;
+ BiggestDimm = q;
+ }
+ }
+ }
+ }
+
+ if (BiggestBank != 0) {
+ CurCSBase = NxtCSBase;
+ CurCSBase |= ((UINT32)1 << BFCSEnable);
+ NxtCSBase += BiggestBank;
+ if ((BiggestDimm & 1) != 0) {
+ if ((DCTPtr->Timings.DimmMirrorPresent & (1 << (BiggestDimm >> 1))) != 0) {
+ CurCSBase |= ((UINT32)1 << BFOnDimmMirror);
+ }
+ }
+ MemNSetBitFieldNb (NBPtr, BFCSBaseAddr0Reg + BiggestDimm, CurCSBase);
+ DCTPtr->Timings.CsEnabled |= (1 << BiggestDimm);
+ }
+ if ((DCTPtr->Timings.CsTestFail & ((UINT16)1 << p)) != 0) {
+ MemNSetBitFieldNb (NBPtr, (BFCSBaseAddr0Reg + p), (UINT32)1 << BFTestFail);
+ }
+ }
+
+ if (NxtCSBase != 0) {
+ DCTPtr->Timings.DctMemSize = NxtCSBase >> 8; // Scale base address from [39:8] to [47:16]
+ NBPtr->MCTPtr->NodeMemSize += NBPtr->DCTPtr->Timings.DctMemSize;
+ NBPtr->MCTPtr->NodeSysLimit = NBPtr->MCTPtr->NodeMemSize - 1;
+ } else {
+ PutEventLog (AGESA_FATAL, MEM_ERROR_NO_DIMM_FOUND_ON_SYSTEM, 0, 0, 0, 0, &NBPtr->MemPtr->StdHeader);
+ SetMemError (AGESA_FATAL, MCTPtr);
+ }
+
+ return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function sets the maximum round-trip latency in the system from the processor to the DRAM
+ * devices and back for Ontario.
+ *
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] MaxRcvEnDly - Maximum receiver enable delay value
+ *
+ */
+
+VOID
+MemNSetMaxLatencyON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT16 MaxRcvEnDly
+ )
+{
+ UINT32 N;
+ UINT32 T;
+ UINT32 P;
+ UINT32 Px2;
+ UINT32 MemClkPeriod;
+
+ AGESA_TESTPOINT (TpProcMemRcvrCalcLatency, &(NBPtr->MemPtr->StdHeader));
+
+ N = 0x50; // init value for MaxRdLat used in training
+
+ if (MaxRcvEnDly != 0xFFFF) {
+ T = MemNTotalSyncComponentsClientNb (NBPtr);
+
+ // P = P + CEIL(MAX (total delay in DqsRcvEn + RdDqsTime))
+ P = ((MaxRcvEnDly + MAX_RD_DQS_DLY) + 31) / 32;
+
+ // P = P + 6.5
+ // T = T + 2586 ps
+ Px2 = (P * 2) + 13;
+ T += 2586;
+
+ // N = (P/(MemClkFreq * 2) + T) * NclkFreq
+ MemClkPeriod = 1000000 / NBPtr->DCTPtr->Timings.Speed;
+ N = ((((Px2 * MemClkPeriod + 3) / 4) + T) * NBPtr->NBClkFreq + 999999) / 1000000;
+ N += 2;
+ }
+
+ NBPtr->DCTPtr->Timings.MaxRdLat = (UINT16) N;
+ ASSERT (N <= 0x3FF);
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\tMaxRdLat: %03x\n", N);
+ MemNSetBitFieldNb (NBPtr, BFMaxLatency, N);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function retrieves the Max latency parameters
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ * @param[in] *MinDlyPtr - Pointer to variable to store the Minimum Delay value
+ * @param[in] *MaxDlyPtr - Pointer to variable to store the Maximum Delay value
+ * @param[in] *DlyBiasPtr - Pointer to variable to store Delay Bias value
+ * @param[in] MaxDlyForMaxRdLat - Maximum receiver enable delay value
+ *
+ */
+
+VOID
+MemNGetMaxLatParamsClientON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT16 MaxDlyForMaxRdLat,
+ IN OUT UINT16 *MinDlyPtr,
+ IN OUT UINT16 *MaxDlyPtr,
+ IN OUT UINT16 *DlyBiasPtr
+ )
+{
+ UINT32 P;
+ UINT32 Px2;
+ UINT32 T;
+ UINT32 MemClkPeriod;
+
+ T = MemNTotalSyncComponentsClientNb (NBPtr);
+
+ // P = P + CEIL(MAX (total delay in DqsRcvEn + RdDqsTime))
+ P = (MaxDlyForMaxRdLat + 31) / 32;
+
+ // P = P + 6.5
+ // T = T + 2586 ps
+ Px2 = (P * 2) + 13;
+ T += 2586;
+
+ // N = (P/(MemClkFreq * 2) + T) * NclkFreq
+ MemClkPeriod = 1000000 / NBPtr->DCTPtr->Timings.Speed;
+
+ *MinDlyPtr = (UINT16) (((((Px2 * MemClkPeriod + 3) / 4) + T) * NBPtr->NBClkFreq + 999999) / 1000000);
+
+ if (NBPtr->NbFreqChgState == 1) {
+ *MinDlyPtr += 2;
+ } else {
+ *MinDlyPtr += 1;
+ }
+
+ *MaxDlyPtr = 100 + *MinDlyPtr; // 100 fixed iterations
+
+ // IF ((NCLK!=MEMCLK) && (NCLK!=MEMCLK/2))
+ // THEN TrainingOffset = 3
+ // ELSE TrainingOffset = 2
+ if ((NBPtr->NBClkFreq == NBPtr->DCTPtr->Timings.Speed) ||
+ (NBPtr->NBClkFreq == (UINT32) (NBPtr->DCTPtr->Timings.Speed / 2)) ||
+ (NBPtr->NBClkFreq == (UINT32) (NBPtr->DCTPtr->Timings.Speed / 2 + 1))) {
+ *DlyBiasPtr = 2;
+ } else {
+ *DlyBiasPtr = 3;
+ }
+
+ // Register settings required before MaxRdLat training
+ MemNSetBitFieldNb (NBPtr, BFForceCasToSlot0, 1);
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function is a wrapper to call a CPU routine to change NB P-state and
+ * update NB frequency.
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in] *NBPstate - NB Pstate
+ *
+ * @return TRUE - Succeed
+ * @return FALSE - Fail
+ */
+BOOLEAN
+MemNChangeNbFrequencyWrapON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN UINT32 NBPstate
+ )
+{
+ BOOLEAN Status;
+ UINT32 NBFreq;
+ UINT32 Memclk;
+ CPU_SPECIFIC_SERVICES *FamilySpecificServices;
+
+ if (NBPtr->NbFreqChgState == 0) {
+ // While in state 0, report the new memclk to the
+ // CPU module to adjust the NB P-state settings.
+ Memclk = NBPtr->DCTPtr->Timings.Speed;
+ } else {
+ // We have already adjusted for target memclk.
+ // Indicate NB P-state change only.
+ Memclk = 0;
+ }
+
+ Status = F14NbPstateInit (Memclk,
+ MemNGetMemClkFreqIdClientNb (NBPtr, NBPtr->DCTPtr->Timings.Speed),
+ NBPstate,
+ &NBFreq,
+ &(NBPtr->MemPtr->StdHeader));
+ if (Status) {
+ // When NB frequency change succeeds, TSC rate may have changed.
+ // We need to update TSC rate
+ GetCpuServicesOfCurrentCore (&FamilySpecificServices, &NBPtr->MemPtr->StdHeader);
+ FamilySpecificServices->GetTscRate (FamilySpecificServices, &NBPtr->MemPtr->TscRate, &NBPtr->MemPtr->StdHeader);
+ }
+ return Status;
+}
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ * This function sets Dqs Odt for ON
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ * @param[in,out] *OptParam - Optional parameter
+ *
+ * @return TRUE
+ */
+
+BOOLEAN
+MemNSetDqsODTON (
+ IN OUT MEM_NB_BLOCK *NBPtr,
+ IN OUT VOID *OptParam
+ )
+{
+ if ((NBPtr->DCTPtr->Timings.Speed == DDR1333_FREQUENCY) && (NBPtr->ChannelPtr->Dimms == 1)) {
+ MemNSetBitFieldNb (NBPtr, BFDQOdt03, 0x20);
+ MemNSetBitFieldNb (NBPtr, BFDQOdt47, 0x20);
+ }
+ return TRUE;
+} \ No newline at end of file