aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnotkb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnotkb.c')
-rw-r--r--src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnotkb.c268
1 files changed, 268 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnotkb.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnotkb.c
new file mode 100644
index 0000000000..1b5350ad01
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/NB/KB/mnotkb.c
@@ -0,0 +1,268 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * mnotkb.c
+ *
+ * Northbridge Non-SPD timings for KB
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: (Mem/NB/KB)
+ * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $
+ *
+ **/
+/*****************************************************************************
+*
+ * Copyright (c) 2008 - 2013, 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 "Ids.h"
+#include "mm.h"
+#include "mn.h"
+#include "OptionMemory.h"
+#include "mnkb.h"
+#include "mu.h"
+#include "Filecode.h"
+CODE_GROUP (G3_DXE)
+RDATA_GROUP (G3_DXE)
+
+#define FILECODE PROC_MEM_NB_KB_MNOTKB_FILECODE
+/*----------------------------------------------------------------------------
+ * DEFINITIONS AND MACROS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * TYPEDEFS AND STRUCTURES
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------
+ * PROTOTYPES OF LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+
+
+/*----------------------------------------------------------------------------
+ * EXPORTED FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+extern BUILD_OPT_CFG UserOptions;
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function sets the non-SPD timings
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ * @return TRUE - No fatal error occurs.
+ * @return FALSE - Fatal error occurs.
+ */
+
+BOOLEAN
+MemNOtherTimingKB (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ UINT8 Dct;
+ IDS_HDT_CONSOLE (MEM_STATUS, "\nStart Programming of Non-SPD Timings.\n");
+ for (Dct = 0; Dct < MAX_DCTS_PER_NODE_KB; Dct++) {
+ IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct);
+ MemNSwitchDCTNb (NBPtr, Dct);
+ if (NBPtr->DCTPtr->Timings.DctDimmValid > 0) {
+ MemNSetOtherTimingKB (NBPtr);
+ }
+ }
+ return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL);
+}
+
+/*----------------------------------------------------------------------------
+ * LOCAL FUNCTIONS
+ *
+ *----------------------------------------------------------------------------
+ */
+
+/* -----------------------------------------------------------------------------*/
+/**
+ *
+ *
+ * This function sets the non-SPD timings in PCI registers
+ *
+ * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
+ *
+ */
+
+VOID
+MemNSetOtherTimingKB (
+ IN OUT MEM_NB_BLOCK *NBPtr
+ )
+{
+ INT8 ROD;
+ INT8 WOD;
+ INT8 LD;
+ INT8 WrEarlyx2;
+ INT8 CDDTrdrdSdDc;
+ INT8 CDDTrdrdDd;
+ INT8 CDDTwrwrDd;
+ INT8 CDDTwrwrSdDc;
+ INT8 CDDTrwtTO;
+ INT8 CDDTwrrd;
+ UINT8 TrdrdSdDc;
+ UINT8 TrdrdDd;
+ UINT8 TwrwrSdDc;
+ UINT8 TwrwrDd;
+ UINT8 TrdrdSdSc;
+ UINT8 TwrwrSdSc;
+ UINT8 Twrrd;
+ UINT8 TrwtTO;
+ BOOLEAN PerRankTimingEn;
+
+ CH_DEF_STRUCT *ChannelPtr;
+ ChannelPtr = NBPtr->ChannelPtr;
+
+ PerRankTimingEn = (BOOLEAN) (MemNGetBitFieldNb (NBPtr, BFPerRankTimingEn));
+ //
+ // Latency Difference (LD) = Tcl - Tcwl
+ //
+ LD = (INT8) (MemNGetBitFieldNb (NBPtr, BFTcl)) - (INT8) (MemNGetBitFieldNb (NBPtr, BFTcwl));
+
+ //
+ // Read ODT Delay (ROD) = MAX ( 0, (RdOdtOnDuration - 6))
+ //
+ ROD = MAX (0, (INT8) (MemNGetBitFieldNb (NBPtr, BFRdOdtOnDuration) - 6));
+ //
+ // Write ODT Delay (WOD) = MAX (0, (WrOdtOnDuration - 6))
+ //
+ WOD = MAX (0, (INT8) (MemNGetBitFieldNb (NBPtr, BFWrOdtOnDuration) - 6));
+ //
+ // WrEarly = ABS (WrDqDqsEarly) / 2
+ //
+ WrEarlyx2 = (INT8) MemNGetBitFieldNb (NBPtr, BFWrDqDqsEarly);
+
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\tLD: %d ROD: %d WOD: %d WrEarlyx2: %d\n\n", LD, ROD, WOD, WrEarlyx2);
+ //
+ // Read to Read Timing (TrdrdSdSc, TrdrdScDc, TrdrdDd)
+ //
+ // TrdrdSdSc = 1.
+ // TrdrdSdDc (in MEMCLKs) = MAX(TrdrdSdSc, 3 + (IF (D18F2xA8_dct[0][PerRankTimingEn])
+ // THEN CEIL(CDDTrdrdSdDc / 2 + 0.5) ELSE 0 ENDIF)).
+ // TrdrdDd (in MEMCLKs) = MAX(TrdrdSdDc, ROD + 3, CEIL(CDDTrdrdDd/2 + 3.5)).
+ //
+ TrdrdSdSc = 1;
+
+ CDDTrdrdSdDc = (INT8) MemNCalcCDDNb (NBPtr, AccessRcvEnDly, AccessRcvEnDly, TRUE, FALSE);
+ TrdrdSdDc = MAX (TrdrdSdSc, PerRankTimingEn ? (3 + (CDDTrdrdSdDc + 1 + 1) / 2) : 3);
+
+ CDDTrdrdDd = (INT8) MemNCalcCDDNb (NBPtr, AccessRcvEnDly, AccessRcvEnDly, FALSE, TRUE);
+ TrdrdDd = MAX (ROD + 3, (CDDTrdrdDd + 7 + 1) / 2);
+ TrdrdDd = MAX (TrdrdSdDc, TrdrdDd);
+
+ MemNSetBitFieldNb (NBPtr, BFTrdrdDd, (UINT32) TrdrdDd);
+ MemNSetBitFieldNb (NBPtr, BFTrdrdSdDc, (UINT32) TrdrdSdDc);
+ MemNSetBitFieldNb (NBPtr, BFTrdrdSdSc, (UINT32) TrdrdSdSc);
+ //
+ // Write to Write Timing (TwrwrSdSc, TwrwrScDc, TwrwrDd)
+ //
+ // TwrwrSdSc (in MEMCLKs) = 1.
+ // TwrwrSdDc (in MEMCLKs) = MAX(TwrwrSdSc, WOD + 3, 3 + (IF (D18F2xA8_dct[0][PerRank-TimingEn])
+ // THEN CEIL(CDDTwrwrSdDc / 2 + 0.5) ELSE 0 ENDIF)).
+ //
+ // TwrwrDd (in MEMCLKs) = MAX(TwrwrSdDc, WOD + 3, CEIL(CDDTwrwrDd / 2 + 3.5)).
+ //
+ TwrwrSdSc = 1;
+
+ CDDTwrwrSdDc = (INT8) MemNCalcCDDNb (NBPtr, AccessWrDqsDly, AccessWrDqsDly, TRUE, FALSE);
+ TwrwrSdDc = (UINT8) MAX ((UINT8) (WOD + 3), (3 + (PerRankTimingEn ? ((CDDTwrwrSdDc + 1 + 1) / 2) : 0)));
+ TwrwrSdDc = MAX (TwrwrSdSc, TwrwrSdDc);
+
+ CDDTwrwrDd = (INT8) MemNCalcCDDNb (NBPtr, AccessWrDqsDly, AccessWrDqsDly, FALSE, TRUE);
+ TwrwrDd = (UINT8) MAX ((UINT8) (WOD + 3), (CDDTwrwrDd + 7 + 1) / 2);
+ TwrwrDd = MAX (TwrwrSdDc, TwrwrDd);
+
+ MemNSetBitFieldNb (NBPtr, BFTwrwrDd, (UINT32) TwrwrDd);
+ MemNSetBitFieldNb (NBPtr, BFTwrwrSdDc, (UINT32) TwrwrSdDc);
+ MemNSetBitFieldNb (NBPtr, BFTwrwrSdSc, (UINT32) TwrwrSdSc);
+ //
+ // Write to Read DIMM Termination Turn-around
+ //
+ // Twrrd (in MEMCLKs) = MAX(1, MAX(WOD, CEIL(CDDTwrrd / 2 + 2 - WrEarly)) - LD + 3).
+ //
+ CDDTwrrd = (INT8) MemNCalcCDDNb (NBPtr, AccessWrDqsDly, AccessRcvEnDly, FALSE, TRUE);
+ Twrrd = MAX (1, MAX (WOD, (CDDTwrrd + 1 + 4 - WrEarlyx2) / 2) - LD + 3);
+
+ MemNSetBitFieldNb (NBPtr, BFTwrrd, (UINT32) Twrrd);
+ //
+ // Read to Write Turnaround for Data, DQS Contention
+ //
+ // TrwtTO (in MEMCLKs) = MAX(ROD, CEIL(CDDTrwtTO / 2 + WrEarly)) + LD + 3
+ // If 1 DIMM/ch, substitute ROD = 0 in the above equation.
+ //
+ CDDTrwtTO = (INT8) MemNCalcCDDNb (NBPtr, AccessRcvEnDly, AccessWrDqsDly, TRUE, TRUE);
+
+ TrwtTO = MAX ((ChannelPtr->Dimms == 1 ? 0 : ROD) , (CDDTrwtTO + WrEarlyx2 + 1) / 2) + LD + 3;
+
+ MemNSetBitFieldNb (NBPtr, BFTrwtTO, (UINT32) TrwtTO);
+ //
+ // Read to Write Turnaround for opportunistic Write Bursting
+ //
+ // TrwtWB = TrwtTO + 1
+ //
+ MemNSetBitFieldNb (NBPtr, BFTrwtWB, (UINT32) TrwtTO + 1);
+
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\t TrdrdSdSc : %02x\n", TrdrdSdSc);
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTrdrdSdDc : %02x TrdrdSdDc : %02x\n", CDDTrdrdSdDc, TrdrdSdDc);
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTrdrdDd : %02x TrdrdDd : %02x\n\n", CDDTrdrdDd, TrdrdDd);
+
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\t TwrwrSdSc : %02x\n", TwrwrSdSc);
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTwrwrSdDc : %02x TwrwrSdDc : %02x\n", CDDTwrwrSdDc, TwrwrSdDc );
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTwrwrDd : %02x TwrwrDd : %02x\n\n", CDDTwrwrDd, TwrwrDd);
+
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\t TrwtWB : %02x\n", TrwtTO + 1);
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTwrrd : %02x Twrrd : %02x\n", (UINT8) CDDTwrrd, (UINT8) Twrrd );
+ IDS_HDT_CONSOLE (MEM_FLOW, "\t\tCDDTrwtTO : %02x TrwtTO : %02x\n\n", (UINT8) CDDTrwtTO, (UINT8) TrwtTO );
+}
+