summaryrefslogtreecommitdiff
path: root/ReferenceCode/Chipset/SystemAgent/MemoryInit/Pei/MrcOemPlatform.c
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Chipset/SystemAgent/MemoryInit/Pei/MrcOemPlatform.c')
-rw-r--r--ReferenceCode/Chipset/SystemAgent/MemoryInit/Pei/MrcOemPlatform.c2780
1 files changed, 2780 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/SystemAgent/MemoryInit/Pei/MrcOemPlatform.c b/ReferenceCode/Chipset/SystemAgent/MemoryInit/Pei/MrcOemPlatform.c
new file mode 100644
index 0000000..d095c51
--- /dev/null
+++ b/ReferenceCode/Chipset/SystemAgent/MemoryInit/Pei/MrcOemPlatform.c
@@ -0,0 +1,2780 @@
+/** @file
+ This file contains platform related functions.
+
+@copyright
+ Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement.
+
+**/
+
+#ifdef MRC_MINIBIOS_BUILD
+#include "MemoryUtils.h"
+#else
+#include <Tiano.h>
+#include <EdkIIGluePeim.h>
+#include <EdkIIGlueBaseLib.h>
+#include "CpuRegs.h"
+#include "CpuPlatformLib.h"
+#ifdef SSA_FLAG
+#include "SsaCallbackPeim.h"
+extern
+VOID
+SsaBiosInitialize (
+ IN MrcParameters *MrcData
+ );
+#endif // SSA_FLAG
+#endif
+
+//
+// Include files
+//
+#ifndef AMI_OVERRIDE_FOR_MEMORY_DOWN
+#include <Token.h>
+#include "MrcSpdData.h"
+#endif // AMI_OVERRIDE_FOR_MEMORY_DOWN
+#include "MrcTypes.h"
+#include "MrcApi.h"
+#include "McAddress.h"
+#include "MrcCommon.h"
+#include "MrcGlobal.h"
+#include "MrcOem.h"
+#include "MrcOemPlatform.h"
+
+#include "PchRegsLpc.h"
+#include "MrcReset.h"
+
+
+// AMI_OVERRIDE_FOR_UPSERVER_SUPPORT
+#ifdef UPSERVER_SUPPORT
+#include "MrcOemSmbus.h"
+
+const U8 CltmThermalLookUpTable [2][2][2][5] =
+{
+ {// DRAM Density 2Gb
+ {// Frequency 1600
+ // 1 DIMM
+ {6, 6, 6, 6, 6},
+ // 2 DIMMs
+ {7, 7, 7, 6, 6}
+ },
+ {// Frequency 1333
+ // 1 DIMM
+ {5, 5, 5, 5, 5},
+ // 2 DIMMs
+ {6, 6, 6, 6, 5}
+ }
+ },
+ {// DRAM Density 4Gb
+ {// Frequency 1600
+ // 1 DIMM
+ {7, 6, 6, 6, 7},
+ // 2 DIMMs
+ {7, 7, 7, 7, 6}
+ },
+ {// Frequency 1333
+ // 1 DIMM
+ {6, 5, 5, 5, 6},
+ // 2 DIMMs
+ {7, 7, 6, 6, 6}
+ }
+ }
+};
+
+const U16 CltmPowerLookUpTable [2][2][2][8] =
+{
+ {// DRAM Density 2Gb
+ {// Frequency 1600
+ // DIMM Position 1
+
+ {4, 99, 147, 129, 6, 10, 0x18, 0x0C},
+ // DIMM Position 2
+ {3, 182, 203, 64, 3, 5, 0x1B, 0x09}
+ },
+ {// Frequency 1333
+ // DIMM Position 1
+ {4, 102, 160, 121, 7, 11, 0x15, 0x08},
+ // DIMM Position 2
+ {3, 210, 236, 60, 3, 5, 0x18, 0x0C}
+ }
+ },
+ {// DRAM Density 4Gb
+ {// Frequency 1600
+ // DIMM Position 1
+ {4, 111, 158, 132, 8, 12, 0x1B, 0x0E},
+ // DIMM Position 2
+ {3, 188, 209, 66, 4, 6, 0x1D, 0x07}
+ },
+ {// Frequency 1333
+ // DIMM Position 1
+ {4, 115, 171, 124, 9, 13, 0x17, 0x0A},
+ // DIMM Position 2
+ {3, 217, 241, 62, 4, 6, 0x1B, 0x09}
+ }
+ }
+};
+
+#endif
+// AMI_OVERRIDE_FOR_UPSERVER_SUPPORT
+
+#ifdef MRC_DEBUG_PRINT
+extern const char CcdString[];
+const char TrainEnString[] = "TrainingEnables";
+const char GdxcString[] = "Gdxc";
+const char BaseTimeString[] = "BaseTime";
+const char ThermEnString[] = "ThermalEnables";
+#endif // MRC_DEBUG_PRINT
+
+#ifdef ULT_FLAG
+
+//
+// The following section contains board-specific CMD/CTL/CLK and DQ/DQS mapping, needed for LPDDR3
+//
+
+//
+// DQByteMap[0] - ClkDQByteMap:
+// If clock is per rank, program to [0xFF, 0xFF]
+// If clock is shared by 2 ranks, program to [0xFF, 0] or [0, 0xFF]
+// If clock is shared by 2 ranks but does not go to all bytes,
+// Entry[i] defines which DQ bytes Group i services
+// DQByteMap[1] - CmdNDQByteMap: Entry[0] is CmdN/CAA and Entry[1] is CmdN/CAB
+// DQByteMap[2] - CmdSDQByteMap: Entry[0] is CmdS/CAA and Entry[1] is CmdS/CAB
+// DQByteMap[3] - CkeDQByteMap : Entry[0] is CKE /CAA and Entry[1] is CKE /CAB
+// For DDR, DQByteMap[3:1] = [0xFF, 0]
+// DQByteMap[4] - CtlDQByteMap : Always program to [0xFF, 0] since we have 1 CTL / rank
+// Variable only exists to make the code easier to use
+// DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0] since we have 1 CA Vref
+// Variable only exists to make the code easier to use
+//
+
+//
+// DQ byte mapping to CMD/CTL/CLK, from the CPU side - for Sawtooth Peak and Harris Beach
+//
+const U8 DqByteMapRvpCh0[6][2] = {
+ { 0x0F, 0xF0 }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+ { 0x00, 0xF0 }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+ { 0x0F, 0xF0 }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+ { 0x0F, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+ { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+ { 0xFF, 0x00 } // CA Vref is one for all bytes
+};
+
+const U8 DqByteMapRvpCh1[6][2] = {
+ { 0x0F, 0xF0 }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+ { 0x00, 0xF0 }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+ { 0x0F, 0xF0 }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+ { 0x0F, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+ { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+ { 0xFF, 0x00 } // CA Vref is one for all bytes
+};
+
+//
+// DQ byte mapping to CMD/CTL/CLK, from the CPU side - for Big Creek
+//
+const U8 DqByteMapSvCh0[6][2] = {
+ { 0x0F, 0xF0 }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+ { 0x00, 0xF0 }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+ { 0x0F, 0xF0 }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+ { 0x0F, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+ { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+ { 0xFF, 0x00 } // CA Vref is one for all bytes
+};
+
+const U8 DqByteMapSvCh1[6][2] = {
+ { 0xE8, 0x17 }, // CLK0 goes to package 0 - Bytes[3:0], CLK1 goes to package 1 - Bytes[7:4]
+ { 0x00, 0x17 }, // CmdN does not have CAA, CAB goes to Bytes[7:4]
+ { 0xE8, 0x17 }, // CmdS CAA goes to Bytes[3:0], CmdS CAB goes to Byte[7:4]
+ { 0xE8, 0x00 }, // CKE CAA goes to Bytes[3:0], CKE does not have CAB
+ { 0xFF, 0x00 }, // CTL (CS) goes to all bytes
+ { 0xFF, 0x00 } // CA Vref is one for all bytes
+};
+
+//
+// DQS byte swizzling between CPU and DRAM - for Sawtooth Peak and Harris Beach
+//
+const U8 DqsMapCpu2DramRvpCh0[8] = { 2, 0, 1, 3, 6, 4, 7, 5 };
+const U8 DqsMapCpu2DramRvpCh1[8] = { 1, 3, 2, 0, 5, 7, 6, 4 };
+
+//
+// DQS byte swizzling between CPU and DRAM - for Big Creek
+//
+const U8 DqsMapCpu2DramSvCh0[8] = { 0, 1, 2, 3, 5, 6, 7, 4 };
+const U8 DqsMapCpu2DramSvCh1[8] = { 7, 6, 5, 2, 4, 3, 1, 0 };
+
+//
+// DQ bit swizzling between CPU and DRAM - for Sawtooth Peak and Harris Beach
+//
+const U8 DqMapCpu2DramRvpCh0[8][8] = {
+ { 16, 21, 18, 19, 20, 17, 22, 23 }, // Byte 0
+ { 3, 6, 1, 5, 2, 7, 0, 4 }, // Byte 1
+ { 9, 8, 14, 15, 10, 11, 13, 12 }, // Byte 2
+ { 29, 28, 27, 31, 24, 25, 30, 26 }, // Byte 3
+ { 53, 49, 50, 51, 48, 52, 54, 55 }, // Byte 4
+ { 35, 38, 33, 37, 34, 39, 32, 36 }, // Byte 5
+ { 63, 59, 61, 57, 56, 60, 58, 62 }, // Byte 6
+ { 44, 45, 46, 42, 40, 41, 43, 47 } // Byte 7
+};
+const U8 DqMapCpu2DramRvpCh1[8][8] = {
+ { 15, 11, 8, 9, 10, 14, 12, 13 }, // Byte 0
+ { 24, 29, 30, 26, 28, 25, 27, 31 }, // Byte 1
+ { 16, 20, 22, 23, 17, 21, 19, 18 }, // Byte 2
+ { 6, 3, 1, 5, 2, 7, 4, 0 }, // Byte 3
+ { 47, 42, 40, 41, 43, 46, 44, 45 }, // Byte 4
+ { 57, 56, 62, 58, 61, 60, 59, 63 }, // Byte 5
+ { 51, 49, 54, 53, 48, 50, 55, 52 }, // Byte 6
+ { 38, 35, 36, 32, 34, 39, 33, 37 } // Byte 7
+};
+
+//
+// DQ bit swizzling between CPU and DRAM - for Big Creek
+//
+const U8 DqMapCpu2DramSvCh0[8][8] = {
+ { 1, 0, 2, 6, 5, 4, 3, 7 }, // Byte 0
+ { 13, 9, 14, 10, 12, 8, 15, 11 }, // Byte 1
+ { 22, 18, 21, 16, 17, 20, 19, 23 }, // Byte 2
+ { 29, 28, 26, 27, 30, 31, 24, 25 }, // Byte 3
+ { 41, 45, 46, 42, 40, 44, 43, 47 }, // Byte 4
+ { 53, 49, 54, 50, 52, 48, 55, 51 }, // Byte 5
+ { 63, 62, 61, 60, 59, 58, 57, 56 }, // Byte 6
+ { 34, 35, 37, 36, 38, 39, 33, 32 } // Byte 7
+};
+const U8 DqMapCpu2DramSvCh1[8][8] = {
+ { 58, 62, 57, 61, 59, 63, 56, 60 }, // Byte 0
+ { 54, 50, 53, 49, 55, 51, 52, 48 }, // Byte 1
+ { 46, 47, 45, 44, 43, 42, 41, 40 }, // Byte 2
+ { 22, 19, 23, 18, 16, 21, 20, 17 }, // Byte 3
+ { 38, 34, 37, 33, 39, 35, 36, 32 }, // Byte 4
+ { 26, 30, 25, 29, 27, 31, 24, 28 }, // Byte 5
+ { 15, 11, 9, 13, 14, 10, 12, 8 }, // Byte 6
+ { 6, 7, 0, 1, 4, 5, 3, 2 } // Byte 7
+};
+
+#endif // ULT_FLAG
+
+const MrcVddSelect MemoryVoltageTable[] = {
+ //
+ // MB DT MB DT
+ // Voltage // GPIO24/GPIO60 GPIO46 GPIO8/GPIO45
+ //
+ 1650, // 0 0 0
+ 1600, // 0 0 1
+ 1550, // 0 1 0
+ 1503, // 0 1 1
+ 1500, // 1 0 0
+ 1450, // 1 0 1
+ 1400, // 1 1 0
+ 1350 // 1 1 1
+};
+
+/**
+ Gets CPU ratio
+
+ @param[in] Nothing
+
+ @retval Cpu ratio.
+**/
+U32
+MrcGetCpuRatio (
+ void
+ )
+{
+ PCU_CR_PLATFORM_INFO_STRUCT Msr;
+
+ Msr.Data = AsmReadMsr64 (PCU_CR_PLATFORM_INFO);
+ return (Msr.Bits.MAX_NON_TURBO_LIM_RATIO);
+}
+
+/**
+ Gets CPU current time.
+
+ @param[in] Nothing
+
+ @retval The current CPU time in milliseconds.
+**/
+U64
+MrcGetCpuTime (
+ void
+ )
+{
+ U32 TimeBase;
+
+ TimeBase = (1000 * MRC_SYSTEM_BCLK) * MrcGetCpuRatio (); //In Millisec
+ return ((TimeBase == 0) ? 0 : MrcOemMemoryDivideU64ByU64 (AsmReadTsc (), TimeBase));
+}
+
+/**
+ Sets CpuModel and CpuStepping in MrcData based on CpuModelStep.
+
+ @param[out] MrcData - The Mrc Host data structure
+ @param[in] CpuModel - The CPU Family Model.
+ @param[in] CpuStepping - The CPU Stepping.
+
+ @retval - mrcSuccess if the model and stepping is found. Otherwise mrcFail
+**/
+MrcStatus
+MrcSetCpuInformation (
+ OUT MrcParameters *MrcData,
+ IN MrcCpuModel CpuModel,
+ IN MrcCpuStepping CpuStepping
+ )
+{
+ MrcInput *Inputs;
+ MrcDebug *Debug;
+ MrcStatus Status;
+
+ Inputs = &MrcData->SysIn.Inputs;
+ Debug = &MrcData->SysIn.Inputs.Debug;
+ Status = mrcFail;
+
+#ifdef ULT_FLAG
+ if (CpuModel == cmHSW_ULT) {
+ Inputs->CpuModel = cmHSW_ULT;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Haswell ULT:");
+
+ switch (CpuStepping) {
+ case csHswUltB0:
+ Inputs->CpuStepping = csHswUltB0;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, " Stepping B0\n");
+ break;
+
+ case csHswUltC0:
+ Inputs->CpuStepping = csHswUltC0;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, " Stepping C0\n");
+ break;
+
+ default:
+ Inputs->CpuStepping = csHswUltB0; // @todo: Update for C0.
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_WARNING,
+ "\nWARNING: Unknown CPU stepping, using MRC for last known step. Step = %Xh\n",
+ Inputs->CpuStepping
+ );
+ break;
+ }
+ Status = mrcSuccess;
+ }
+#endif // ULT_FLAG
+
+#ifdef TRAD_FLAG
+ if (CpuModel == cmHSW) {
+ Inputs->CpuModel = cmHSW;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Haswell:");
+
+ switch (CpuStepping) {
+ case csHswA0:
+ Inputs->CpuStepping = csHswA0;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, " Stepping A0\n");
+ break;
+
+ case csHswB0:
+ Inputs->CpuStepping = csHswB0;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, " Stepping B0\n");
+ break;
+
+ case csHswC0:
+ Inputs->CpuStepping = csHswC0;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, " Stepping C0\n");
+ break;
+
+ default:
+ Inputs->CpuStepping = csHswC0;
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_WARNING,
+ "\nWARNING: Unknown CPU stepping, using MRC for last known step. Step = %Xh\n",
+ Inputs->CpuStepping
+ );
+ break;
+ }
+ Status = mrcSuccess;
+ }
+
+ if (CpuModel == cmCRW) {
+ Inputs->CpuModel = cmCRW;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Crystalwell:");
+
+ switch (CpuStepping) {
+ case csCrwB0:
+ Inputs->CpuStepping = csCrwB0;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, " Stepping B0\n");
+ break;
+
+ case csCrwC0:
+ Inputs->CpuStepping = csCrwC0;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, " Stepping C0\n");
+ break;
+
+ default:
+ Inputs->CpuStepping = csCrwB0; // @todo: Update for C0
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_WARNING,
+ "\nWARNING: Unknown CPU stepping, using MRC for last known step. Step = %Xh\n",
+ Inputs->CpuStepping
+ );
+ break;
+ }
+ Status = mrcSuccess;
+ }
+#endif // TRAD_FLAG
+
+ return Status;
+}
+
+/**
+ Gets a number from the CPU's random number generator.
+
+ @param[in] Nothing
+
+ @retval Random number or zero if random number is not generated or is invalid.
+**/
+U32
+AsmGetRandomNumber (
+ void
+ )
+{
+ U32 Status;
+ U32 RandomNumber;
+
+ // Assembly instruction to read CPU's random number generator
+ // Instruction is only available 100k cycles after reset
+ // rdrand eax
+ // db 0Fh, 0C7h, 0F0h
+#if defined __GNUC__ // GCC compiler
+ __asm__ __volatile__ (
+ "\n\t .byte 0x0F, 0xC7, 0xF0"
+ "\n\t movl %%eax, %0"
+ "\n\t pushf"
+ "\n\t pop %%eax"
+ "\n\t movl %%eax, %1"
+ : "=m" (RandomNumber),
+ "=m" (Status)
+ );
+#else //MSFT compiler
+ ASM {
+ _emit 0x0F
+ _emit 0xC7
+ _emit 0xF0
+ mov RandomNumber, eax
+
+ pushfd
+ pop eax
+ mov Status, eax
+ }
+#endif
+ // If CF is cleared, return 0
+ return (((Status & 1) == 0) ? 0 : RandomNumber);
+}
+
+/**
+ Gets a random number from the CPU's random number generator.
+
+ @param[in] Nothing
+
+ @retval Random number returned by the CPU instruction or generated from real time clock data.
+**/
+U32
+MrcGetRandomNumber (
+ void
+ )
+{
+ U32 RandomNumber;
+ U32 Retry;
+ U16 Year;
+ U8 Month;
+ U8 DayOfMonth;
+ U8 Hours;
+ U8 Minutes;
+ U8 Seconds;
+
+ RandomNumber = 0;
+ for (Retry = 100000; ((Retry != 0) && (RandomNumber == 0)); --Retry) {
+ RandomNumber = AsmGetRandomNumber ();
+ }
+ if ((Retry == 0) && (RandomNumber == 0)) {
+ MrcOemGetRtcTime (&Seconds, &Minutes, &Hours, &DayOfMonth, &Month, &Year);
+ RandomNumber = Seconds + (Minutes * 60) + (Hours * 60 * 60);
+ }
+
+ return (RandomNumber);
+}
+
+/**
+ This function enables 2x Refresh through the mailbox.
+
+ @param[in] MrcData - Pointer to the MRC global data structure
+
+ @retval - Nothing.
+**/
+void
+MrcOemEnable2xRefresh (
+ IN MrcParameters *const MrcData
+ )
+{
+#ifndef MRC_MINIBIOS_BUILD
+ MrcDebug *Debug;
+ MrcMailbox2xRefresh Write2xRefreshData;
+ U32 MailboxStatus;
+
+ Debug = &MrcData->SysIn.Inputs.Debug;
+
+ MailboxRead(MAILBOX_TYPE_PCODE, READ_DDR_FORCE_2X_REFRESH, &Write2xRefreshData.Data, &MailboxStatus);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, " Read Write2xRefreshData: 0x%x\n", Write2xRefreshData.Data);
+
+
+ if (!Write2xRefreshData.Bits.Lock_Bit) {
+ Write2xRefreshData.Bits.Lock_Bit = 1;
+ Write2xRefreshData.Bits.Enable_2x_Refresh = 1;
+#ifdef ULT_FLAG
+ if (MrcData->SysOut.Outputs.DdrType == MRC_DDR_TYPE_LPDDR3) {
+ Write2xRefreshData.Bits.LPDDR_Min_MR4 = RefRate2x; // Matches the JEDEC MR4 Encoding.
+ }
+#endif
+ MailboxWrite(MAILBOX_TYPE_PCODE, WRITE_DDR_FORCE_2X_REFRESH, Write2xRefreshData.Data, &MailboxStatus);
+
+ if (MailboxStatus != PCODE_MAILBOX_CC_SUCCESS) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "WRITE_DDR_FORCE_2X_REFRESH failed. MailboxStatus = 0x%x\n", MailboxStatus);
+ } else {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Writing 0x%x to WRITE_DDR_FORCE_2X_REFRESH\n", Write2xRefreshData.Data);
+ }
+ }
+#endif
+}
+
+/**
+ This function changes the DIMM Voltage to the closest desired voltage without
+ going higher. Default wait time is the minimum value of 200us, if more time
+ is needed before deassertion of DIMM Reset#, then change the parameter.
+
+ @param[in, out] MrcData - The MRC "global data" area.
+ @param[in] VddVoltage - Selects the DDR voltage to use, in mV.
+ @param[in, out] VddSettleWaitTime - Time needed for Vdd to settle after the update
+
+ @retval TRUE if a voltage change occurred, otherwise FALSE.
+**/
+BOOL
+MrcOemVDDVoltageCheckAndSwitch (
+ IN OUT MrcParameters *MrcData,
+ IN const MrcVddSelect VddVoltage,
+ IN OUT U32 * const VddSettleWaitTime
+ )
+{
+ MrcInput *Inputs;
+ MrcOutput *Outputs;
+ BOOL Status;
+ U32 GPIOBase;
+ U32 GPIO_In_31_0;
+ U32 GPIO_In_63_32;
+ U32 GPIO_Out_31_0;
+ U32 GPIO_Out_63_32;
+ U32 Current;
+ U8 Index;
+
+ Inputs = &MrcData->SysIn.Inputs;
+ Outputs = &MrcData->SysOut.Outputs;
+ Status = FALSE;
+
+ if (((Inputs->MobilePlatform == TRUE) && (Inputs->BoardType != btUser4)) || (Inputs->MobilePlatform == FALSE)) {
+ //
+ // Read GPIO base.
+ //
+ MrcOemMmioRead (
+ MrcOemGetPcieDeviceAddress (0, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_GPIO_BASE),
+ &GPIOBase,
+ Inputs->PciEBaseAddress
+ );
+ GPIOBase &= ~MRC_BIT0;
+
+#ifdef MRC_MINIBIOS_BUILD
+ if ((Inputs->MobilePlatform == TRUE) && (Inputs->BoardType != btUser4)) {
+ //
+ // Setup GPIOs (8,24,46)
+ //
+ GPIO_In_31_0 = MrcOemInPort32 ((U16) (GPIOBase + R_PCH_GPIO_USE_SEL));
+ if ((GPIO_In_31_0 & (MRC_BIT8 | MRC_BIT24)) != (MRC_BIT8 | MRC_BIT24)) {
+ GPIO_In_31_0 |= (MRC_BIT8 | MRC_BIT24);
+ MrcOemOutPort32 ((U16) (GPIOBase + R_PCH_GPIO_USE_SEL), GPIO_In_31_0);
+ }
+
+ GPIO_In_63_32 = MrcOemInPort32 ((U16) (GPIOBase + R_PCH_GPIO_USE_SEL2));
+ if ((GPIO_In_63_32 & MRC_BIT14) != MRC_BIT14) {
+ GPIO_In_63_32 |= MRC_BIT14;
+ MrcOemOutPort32 ((U16) (GPIOBase + R_PCH_GPIO_USE_SEL2), GPIO_In_63_32);
+ }
+
+ GPIO_In_31_0 = MrcOemInPort32 ((U16) (GPIOBase + R_PCH_GPIO_IO_SEL));
+ if ((GPIO_In_31_0 & (MRC_BIT8 | MRC_BIT24)) != 0) {
+ GPIO_In_31_0 &= ~(MRC_BIT8 | MRC_BIT24);
+ MrcOemOutPort32 ((U16) (GPIOBase + R_PCH_GPIO_IO_SEL), GPIO_In_31_0);
+ }
+
+ GPIO_In_63_32 = MrcOemInPort32 ((U16) (GPIOBase + R_PCH_GPIO_IO_SEL2));
+ if ((GPIO_In_63_32 & MRC_BIT14) != 0) {
+ GPIO_In_63_32 &= ~MRC_BIT14;
+ MrcOemOutPort32 ((U16) (GPIOBase + R_PCH_GPIO_IO_SEL2), GPIO_In_63_32);
+ }
+ } else if ((Inputs->MobilePlatform == FALSE) && (Inputs->BoardType == btCRBDT)) {
+ //
+ // Setup GPIOs (45,46,60)
+ //
+ GPIO_In_63_32 = MrcOemInPort32 ((U16) (GPIOBase + R_PCH_GPIO_USE_SEL2));
+ if ((GPIO_In_63_32 & (MRC_BIT28 | MRC_BIT14 | MRC_BIT13)) != (MRC_BIT28 | MRC_BIT14 | MRC_BIT13)) {
+ GPIO_In_63_32 |= (MRC_BIT28 | MRC_BIT14 | MRC_BIT13);
+ MrcOemOutPort32 ((U16) (GPIOBase + R_PCH_GPIO_USE_SEL2), GPIO_In_63_32);
+ }
+
+ GPIO_In_63_32 = MrcOemInPort32 ((U16) (GPIOBase + R_PCH_GPIO_IO_SEL2));
+ if ((GPIO_In_63_32 & (MRC_BIT28 | MRC_BIT14 | MRC_BIT13)) != 0) {
+ GPIO_In_63_32 &= ~(MRC_BIT28 | MRC_BIT14 | MRC_BIT13);
+ MrcOemOutPort32 ((U16) (GPIOBase + R_PCH_GPIO_IO_SEL2), GPIO_In_63_32);
+ }
+ }
+#endif // MRC_MINIBIOS_BUILD
+
+ GPIO_In_31_0 = MrcOemInPort32 ((U16) (GPIOBase + R_PCH_GPIO_LVL));
+ GPIO_In_63_32 = MrcOemInPort32 ((U16) (GPIOBase + R_PCH_GPIO_LVL2));
+ GPIO_Out_31_0 = GPIO_In_31_0;
+ GPIO_Out_63_32 = GPIO_In_63_32;
+
+ for (Index = 0; Index < (sizeof (MemoryVoltageTable) / sizeof (MemoryVoltageTable[0])); Index++) {
+ if (VddVoltage >= MemoryVoltageTable[Index]) {
+ break;
+ }
+ }
+
+#ifdef EMBEDDED_FLAG
+ if (Inputs->BoardType == btCRBEMB) {
+ //
+ // Set GP24 to the required value.
+ //
+ Current = (((GPIO_Out_31_0 & MRC_BIT24) >> 22) ^ MRC_BIT2) | MRC_BIT1 | MRC_BIT0;
+ (Index & MRC_BIT1) ? (GPIO_Out_31_0 &= (~MRC_BIT24)) : (GPIO_Out_31_0 |= MRC_BIT24);
+ } else
+#endif
+
+ if ((Inputs->MobilePlatform == TRUE) && (Inputs->BoardType != btUser4)) {
+ //
+ // Set GP8, GP24, and GP46 to the required value.
+ //
+ Current = (((GPIO_Out_31_0 & MRC_BIT24) >> 22) | ((GPIO_Out_63_32 & MRC_BIT14) >> 13) | ((GPIO_Out_31_0 & MRC_BIT8) >> 8));
+ (Index & MRC_BIT2) ? (GPIO_Out_31_0 |= MRC_BIT24) : (GPIO_Out_31_0 &= (~MRC_BIT24));
+ (Index & MRC_BIT1) ? (GPIO_Out_63_32 |= MRC_BIT14) : (GPIO_Out_63_32 &= (~MRC_BIT14));
+ (Index & MRC_BIT0) ? (GPIO_Out_31_0 |= MRC_BIT8) : (GPIO_Out_31_0 &= (~MRC_BIT8));
+ } else if ((Inputs->MobilePlatform == FALSE) && (Inputs->BoardType == btCRBDT)) {
+ //
+ // Set GP45, GP46, and GP60 to the required value.
+ //
+ Current = (((GPIO_Out_63_32 & MRC_BIT28) >> 26) | ((GPIO_Out_63_32 & MRC_BIT14) >> 13) | ((GPIO_Out_63_32 & MRC_BIT13) >> 13));
+ (Index & MRC_BIT2) ? (GPIO_Out_63_32 |= MRC_BIT28) : (GPIO_Out_63_32 &= (~MRC_BIT28));
+ (Index & MRC_BIT1) ? (GPIO_Out_63_32 |= MRC_BIT14) : (GPIO_Out_63_32 &= (~MRC_BIT14));
+ (Index & MRC_BIT0) ? (GPIO_Out_63_32 |= MRC_BIT13) : (GPIO_Out_63_32 &= (~MRC_BIT13));
+ } else {
+ Current = 4;
+ }
+
+ MRC_DEBUG_MSG (&Inputs->Debug, MSG_LEVEL_NOTE, "Current VddVoltage is %u mV\n", MemoryVoltageTable[Current]);
+ if ((GPIO_In_31_0 != GPIO_Out_31_0) || (GPIO_In_63_32 != GPIO_Out_63_32)) {
+ MRC_DEBUG_MSG (&Inputs->Debug, MSG_LEVEL_NOTE, "**** VddVoltage updated to %u mV\n", VddVoltage);
+ MrcOemOutPort32 ((U16) (GPIOBase + R_PCH_GPIO_LVL), GPIO_Out_31_0);
+ MrcOemOutPort32 ((U16) (GPIOBase + R_PCH_GPIO_LVL2), GPIO_Out_63_32);
+ Status = TRUE;
+ }
+
+ //
+ // Increase the VddSettleWaitTime by the amount requested in the Input structure
+ //
+ *VddSettleWaitTime += Inputs->VddSettleWaitTime;
+
+ //
+ // Either update was already done or change is not necessary every time this is called
+ //
+ Outputs->VddVoltageDone = TRUE;
+ }
+
+ return (Status);
+}
+
+/**
+ Hook before normal mode is enabled.
+
+ @param[in, out] MrcData - The MRC "global data" area.
+
+ @retval Nothing.
+**/
+void
+MrcOemBeforeNormalModeTestMenu (
+ IN OUT MrcParameters *const MrcData
+ )
+{
+
+ return;
+}
+
+/**
+ Hook after normal mode is enabled
+
+ @param[in] MrcData - The MRC "global data" area.
+
+ @retval Nothing.
+**/
+void
+MrcOemAfterNormalModeTestMenu (
+ IN MrcParameters *MrcData
+ )
+{
+
+ MrcThermalOverwrites (MrcData);
+
+ // @todo: Add lates code DDR Thermal Management, throttling control. Also UP CLTT code
+ //
+// AMI_OVERRIDE_FOR_UPSERVER_SUPPORT
+#ifdef UPSERVER_SUPPORT
+ MrcCltmInit (MrcData);
+#endif // UPSERVER_SUPPORT
+// AMI_OVERRIDE_FOR_UPSERVER_SUPPORT
+ return;
+}
+
+/**
+ Overwrite Thermal settings
+
+ @param[in] MrcData - The MRC "global data" area.
+
+ @retval Nothing.
+**/
+void
+MrcThermalOverwrites (
+ IN MrcParameters *MrcData
+ )
+{
+ MrcInput *Inputs;
+ MrcOutput *Outputs;
+ MrcDebug *Debug;
+ MrcDdrType DdrType;
+ ThermalMngmtEn *ThermalEnables;
+ U8 Channel;
+ U32 Offset;
+ PCU_CR_DDR_PTM_CTL_PCU_STRUCT DdrPtmCtl;
+ PCU_CR_DDR_ENERGY_SCALEFACTOR_PCU_STRUCT DdrEnergyScaleFactor;
+ PCU_CR_DDR_RAPL_CHANNEL_POWER_FLOOR_PCU_STRUCT DdrRaplChannelPowerFloor;
+ PCU_CR_DDR_RAPL_LIMIT_PCU_STRUCT DdrRaplLimit;
+ PCU_CR_DDR_WARM_THRESHOLD_CH0_PCU_STRUCT DdrWarmThresholdCh0;
+ PCU_CR_DDR_WARM_THRESHOLD_CH1_PCU_STRUCT DdrWarmThresholdCh1;
+ PCU_CR_DDR_HOT_THRESHOLD_CH0_PCU_STRUCT DdrHotThresholdCh0;
+ PCU_CR_DDR_HOT_THRESHOLD_CH1_PCU_STRUCT DdrHotThresholdCh1;
+ PCU_CR_DDR_WARM_BUDGET_CH0_PCU_STRUCT DdrWarmBudgetCh0;
+ PCU_CR_DDR_WARM_BUDGET_CH1_PCU_STRUCT DdrWarmBudgetCh1;
+ PCU_CR_DDR_HOT_BUDGET_CH0_PCU_STRUCT DdrHotBudgetCh0;
+ PCU_CR_DDR_HOT_BUDGET_CH1_PCU_STRUCT DdrHotBudgetCh1;
+ MCHBAR_CH0_CR_PM_DIMM_IDLE_ENERGY_STRUCT PmDimmIdleEnergy;
+ MCHBAR_CH0_CR_PM_DIMM_PD_ENERGY_STRUCT PmDimmPdEnergy;
+ MCHBAR_CH0_CR_PM_DIMM_ACT_ENERGY_STRUCT PmDimmActEnergy;
+ MCHBAR_CH0_CR_PM_DIMM_RD_ENERGY_STRUCT PmDimmRdEnergy;
+ MCHBAR_CH0_CR_PM_DIMM_WR_ENERGY_STRUCT PmDimmWrEnergy;
+ MCHBAR_CH0_CR_PM_THRT_CKE_MIN_STRUCT PmThrtCkeMin;
+ MCDECS_CR_PM_SREF_CONFIG_MCMAIN_STRUCT PmSrefConfig;
+
+ Inputs = &MrcData->SysIn.Inputs;
+ Debug = &Inputs->Debug;
+ ThermalEnables = &Inputs->ThermalEnables;
+ Outputs = &MrcData->SysOut.Outputs;
+ DdrType = Outputs->DdrType;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "...Thermal Overwrite ...\n");
+
+ if (Inputs->ThermalEnables.UserPowerWeightsEn) {
+ //
+ // ENERGY SCALE FACTOR
+ //
+ DdrEnergyScaleFactor.Data = 0;
+ DdrEnergyScaleFactor.Bits.SCALEFACTOR = ThermalEnables->EnergyScaleFact;
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_NOTE,
+ "DDR_ENERGY_SCALEFACTOR %Xh: %Xh \n",
+ PCU_CR_DDR_ENERGY_SCALEFACTOR_PCU_REG,
+ DdrEnergyScaleFactor.Data
+ );
+ MrcWriteCR (MrcData, PCU_CR_DDR_ENERGY_SCALEFACTOR_PCU_REG, DdrEnergyScaleFactor.Data);
+
+ //
+ // RAPL POWER FLOOR
+ //
+ DdrRaplChannelPowerFloor.Data = 0;
+ DdrRaplChannelPowerFloor.Bits.CH0 = ThermalEnables->RaplPwrFl[0];
+ DdrRaplChannelPowerFloor.Bits.CH1 = ThermalEnables->RaplPwrFl[1];
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_NOTE,
+ "DDR_RAPL_CHANNEL_POWER_FLOOR %Xh: %Xh \n",
+ PCU_CR_DDR_RAPL_CHANNEL_POWER_FLOOR_PCU_REG,
+ DdrRaplChannelPowerFloor.Data
+ );
+ MrcWriteCR (MrcData, PCU_CR_DDR_RAPL_CHANNEL_POWER_FLOOR_PCU_REG, DdrRaplChannelPowerFloor.Data);
+ }
+
+ //
+ // RAPL LIMIT
+ //
+ DdrRaplLimit.Data = 0;
+ DdrRaplLimit.Bits.LIMIT1_TIME_WINDOW_X = ThermalEnables->RaplLim1WindX;
+ DdrRaplLimit.Bits.LIMIT1_TIME_WINDOW_Y = ThermalEnables->RaplLim1WindY;
+ DdrRaplLimit.Bits.LIMIT1_ENABLE = ThermalEnables->RaplLim1Ena;
+ DdrRaplLimit.Bits.LIMIT1_POWER = ThermalEnables->RaplLim1Pwr;
+ DdrRaplLimit.Bits.LOCKED = ThermalEnables->RaplLim2Lock;
+ DdrRaplLimit.Bits.LIMIT2_TIME_WINDOW_X = ThermalEnables->RaplLim2WindX;
+ DdrRaplLimit.Bits.LIMIT2_TIME_WINDOW_Y = ThermalEnables->RaplLim2WindY;
+ DdrRaplLimit.Bits.LIMIT2_ENABLE = ThermalEnables->RaplLim2Ena;
+ DdrRaplLimit.Bits.LIMIT2_POWER = ThermalEnables->RaplLim2Pwr;
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_NOTE,
+ "DDR_RAPL_LIMIT1 %Xh: %Xh \n",
+ PCU_CR_DDR_RAPL_LIMIT_PCU_REG,
+ DdrRaplLimit.Data32[0]
+ );
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_NOTE,
+ "DDR_RAPL_LIMIT2 %Xh: %Xh \n",
+ PCU_CR_DDR_RAPL_LIMIT_PCU_REG + 4,
+ DdrRaplLimit.Data32[1]
+ );
+ MrcWriteCR (MrcData, PCU_CR_DDR_RAPL_LIMIT_PCU_REG, DdrRaplLimit.Data32[0]);
+ MrcWriteCR (MrcData, PCU_CR_DDR_RAPL_LIMIT_PCU_REG + 4, DdrRaplLimit.Data32[1]);
+
+ //
+ // DDR WARM AND HOT THRESHOLD
+ //
+ DdrWarmThresholdCh0.Data = 0;
+ DdrWarmThresholdCh0.Bits.DIMM1 = ThermalEnables->WarmThreshold[0][1];
+ DdrWarmThresholdCh0.Bits.DIMM0 = ThermalEnables->WarmThreshold[0][0];
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_NOTE,
+ "DDR_WARM_THRESHOLD_CH0 %Xh: %Xh \n",
+ PCU_CR_DDR_WARM_THRESHOLD_CH0_PCU_REG,
+ DdrWarmThresholdCh0.Data
+ );
+ MrcWriteCR (MrcData, PCU_CR_DDR_WARM_THRESHOLD_CH0_PCU_REG, DdrWarmThresholdCh0.Data);
+
+ DdrWarmThresholdCh1.Data = 0;
+ DdrWarmThresholdCh1.Bits.DIMM1 = ThermalEnables->WarmThreshold[1][1];
+ DdrWarmThresholdCh1.Bits.DIMM0 = ThermalEnables->WarmThreshold[1][0];
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_NOTE,
+ "DDR_WARM_THRESHOLD_CH1 %Xh: %Xh \n",
+ PCU_CR_DDR_WARM_THRESHOLD_CH1_PCU_REG,
+ DdrWarmThresholdCh1.Data
+ );
+ MrcWriteCR (MrcData, PCU_CR_DDR_WARM_THRESHOLD_CH1_PCU_REG, DdrWarmThresholdCh1.Data);
+
+ DdrHotThresholdCh0.Data = 0;
+ DdrHotThresholdCh0.Bits.DIMM1 = ThermalEnables->HotThreshold[0][1];
+ DdrHotThresholdCh0.Bits.DIMM0 = ThermalEnables->HotThreshold[0][0];
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_NOTE,
+ "DDR_HOT_THRESHOLD_CH0 %Xh: %Xh \n",
+ PCU_CR_DDR_HOT_THRESHOLD_CH0_PCU_REG,
+ DdrHotThresholdCh0.Data
+ );
+ MrcWriteCR (MrcData, PCU_CR_DDR_HOT_THRESHOLD_CH0_PCU_REG, DdrHotThresholdCh0.Data);
+
+ DdrHotThresholdCh1.Data = 0;
+ DdrHotThresholdCh1.Bits.DIMM1 = ThermalEnables->HotThreshold[1][1];
+ DdrHotThresholdCh1.Bits.DIMM0 = ThermalEnables->HotThreshold[1][0];
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_NOTE,
+ "DDR_HOT_THRESHOLD_CH1 %Xh: %Xh \n",
+ PCU_CR_DDR_HOT_THRESHOLD_CH1_PCU_REG,
+ DdrHotThresholdCh1.Data
+ );
+ MrcWriteCR (MrcData, PCU_CR_DDR_HOT_THRESHOLD_CH1_PCU_REG, DdrHotThresholdCh1.Data);
+
+ //
+ // DDR WARM AND HOT BUDGET
+ //
+ DdrWarmBudgetCh0.Data = 0;
+ DdrWarmBudgetCh0.Bits.DIMM1 = ThermalEnables->WarmBudget[0][1];
+ DdrWarmBudgetCh0.Bits.DIMM0 = ThermalEnables->WarmBudget[0][0];
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_NOTE,
+ "DDR_WARM_BUDGET_CH0 %Xh: %Xh \n",
+ PCU_CR_DDR_WARM_BUDGET_CH0_PCU_REG,
+ DdrWarmBudgetCh0.Data
+ );
+ MrcWriteCR (MrcData, PCU_CR_DDR_WARM_BUDGET_CH0_PCU_REG, DdrWarmBudgetCh0.Data);
+
+ DdrWarmBudgetCh1.Data = 0;
+ DdrWarmBudgetCh1.Bits.DIMM1 = ThermalEnables->WarmBudget[1][1];
+ DdrWarmBudgetCh1.Bits.DIMM0 = ThermalEnables->WarmBudget[1][0];
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_NOTE,
+ "DDR_WARM_BUDGET_CH1 %Xh: %Xh \n",
+ PCU_CR_DDR_WARM_BUDGET_CH1_PCU_REG,
+ DdrWarmBudgetCh1.Data
+ );
+ MrcWriteCR (MrcData, PCU_CR_DDR_WARM_BUDGET_CH1_PCU_REG, DdrWarmBudgetCh1.Data);
+
+ DdrHotBudgetCh0.Data = 0;
+ DdrHotBudgetCh0.Bits.DIMM1 = ThermalEnables->HotBudget[0][1];
+ DdrHotBudgetCh0.Bits.DIMM0 = ThermalEnables->HotBudget[0][0];
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_NOTE,
+ "DDR_HOT_BUDGET_CH0 %Xh: %Xh \n",
+ PCU_CR_DDR_HOT_BUDGET_CH0_PCU_REG,
+ DdrHotBudgetCh0.Data
+ );
+ MrcWriteCR (MrcData, PCU_CR_DDR_HOT_BUDGET_CH0_PCU_REG, DdrHotBudgetCh0.Data);
+
+ DdrHotBudgetCh1.Data = 0;
+ DdrHotBudgetCh1.Bits.DIMM1 = ThermalEnables->HotBudget[1][1];
+ DdrHotBudgetCh1.Bits.DIMM0 = ThermalEnables->HotBudget[1][0];
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_NOTE,
+ "DDR_HOT_BUDGET_CH1 %Xh: %Xh \n",
+ PCU_CR_DDR_HOT_BUDGET_CH1_PCU_REG,
+ DdrHotBudgetCh1.Data
+ );
+ MrcWriteCR (MrcData, PCU_CR_DDR_HOT_BUDGET_CH1_PCU_REG, DdrHotBudgetCh1.Data);
+
+ for (Channel = 0; Channel < MAX_CHANNEL; Channel++) {
+ if (MrcChannelExist (Outputs, Channel)) {
+ if (Inputs->ThermalEnables.UserPowerWeightsEn) {
+ PmDimmIdleEnergy.Data = 0;
+ PmDimmIdleEnergy.Bits.DIMM1_IDLE_ENERGY = ThermalEnables->IdleEnergy[Channel][1];
+ PmDimmIdleEnergy.Bits.DIMM0_IDLE_ENERGY = ThermalEnables->IdleEnergy[Channel][0];
+ Offset = MCHBAR_CH0_CR_PM_DIMM_IDLE_ENERGY_REG +
+ (MCHBAR_CH1_CR_PM_DIMM_IDLE_ENERGY_REG - MCHBAR_CH0_CR_PM_DIMM_IDLE_ENERGY_REG) * Channel;
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_NOTE,
+ "C%u PM_DIMM_IDLE_ENERGY %Xh: %Xh \n",
+ Channel,
+ Offset,
+ PmDimmIdleEnergy.Data
+ );
+ MrcWriteCR (MrcData, Offset, PmDimmIdleEnergy.Data);
+
+ PmDimmPdEnergy.Data = 0;
+ PmDimmPdEnergy.Bits.DIMM1_PD_ENERGY = ThermalEnables->PdEnergy[Channel][1];
+ PmDimmPdEnergy.Bits.DIMM0_PD_ENERGY = ThermalEnables->PdEnergy[Channel][0];
+ Offset = MCHBAR_CH0_CR_PM_DIMM_PD_ENERGY_REG +
+ (MCHBAR_CH1_CR_PM_DIMM_PD_ENERGY_REG - MCHBAR_CH0_CR_PM_DIMM_PD_ENERGY_REG) * Channel;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "C%u PM_DIMM_PD_ENERGY %Xh: %Xh \n", Channel, Offset, PmDimmPdEnergy.Data);
+ MrcWriteCR (MrcData, Offset, PmDimmPdEnergy.Data);
+
+ PmDimmActEnergy.Data = 0;
+ PmDimmActEnergy.Bits.DIMM1_ACT_ENERGY = ThermalEnables->ActEnergy[Channel][1];
+ PmDimmActEnergy.Bits.DIMM0_ACT_ENERGY = ThermalEnables->ActEnergy[Channel][0];
+ Offset = MCHBAR_CH0_CR_PM_DIMM_ACT_ENERGY_REG +
+ (MCHBAR_CH1_CR_PM_DIMM_ACT_ENERGY_REG - MCHBAR_CH0_CR_PM_DIMM_ACT_ENERGY_REG) * Channel;
+ MRC_DEBUG_MSG (
+ Debug,
+ MSG_LEVEL_NOTE,
+ "C%u PM_DIMM_ACT_ENERGY %Xh: %Xh \n",
+ Channel,
+ Offset,
+ PmDimmActEnergy.Data
+ );
+ MrcWriteCR (MrcData, Offset, PmDimmActEnergy.Data);
+
+ PmDimmRdEnergy.Data = 0;
+ PmDimmRdEnergy.Bits.DIMM1_RD_ENERGY = ThermalEnables->RdEnergy[Channel][1];
+ PmDimmRdEnergy.Bits.DIMM0_RD_ENERGY = ThermalEnables->RdEnergy[Channel][0];
+ Offset = MCHBAR_CH0_CR_PM_DIMM_RD_ENERGY_REG +
+ (MCHBAR_CH1_CR_PM_DIMM_RD_ENERGY_REG - MCHBAR_CH0_CR_PM_DIMM_RD_ENERGY_REG) * Channel;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "C%u PM_DIMM_RD_ENERGY %Xh: %Xh \n", Channel, Offset, PmDimmRdEnergy.Data);
+ MrcWriteCR (MrcData, Offset, PmDimmRdEnergy.Data);
+
+ PmDimmWrEnergy.Data = 0;
+ PmDimmWrEnergy.Bits.DIMM1_WR_ENERGY = ThermalEnables->WrEnergy[Channel][1];
+ PmDimmWrEnergy.Bits.DIMM0_WR_ENERGY = ThermalEnables->WrEnergy[Channel][0];
+ Offset = MCHBAR_CH0_CR_PM_DIMM_WR_ENERGY_REG +
+ (MCHBAR_CH1_CR_PM_DIMM_WR_ENERGY_REG - MCHBAR_CH0_CR_PM_DIMM_WR_ENERGY_REG) * Channel;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "C%u PM_DIMM_WR_ENERGY %Xh: %Xh \n", Channel, Offset, PmDimmWrEnergy.Data);
+ MrcWriteCR (MrcData, Offset, PmDimmWrEnergy.Data);
+ }
+
+ PmThrtCkeMin.Data = 0;
+#ifdef ULT_FLAG
+ if (DdrType == MRC_DDR_TYPE_LPDDR3) {
+ PmThrtCkeMin.Bits.CKE_MIN_DEFEATURE = ThermalEnables->ThrtCkeMinDefeatLpddr;
+ PmThrtCkeMin.Bits.CKE_MIN = ThermalEnables->ThrtCkeMinTmrLpddr;
+ } else
+#endif // ULT_FLAG
+ {
+ PmThrtCkeMin.Bits.CKE_MIN_DEFEATURE = ThermalEnables->ThrtCkeMinDefeat;
+ PmThrtCkeMin.Bits.CKE_MIN = ThermalEnables->ThrtCkeMinTmr;
+ }
+ Offset = MCHBAR_CH0_CR_PM_THRT_CKE_MIN_REG +
+ (MCHBAR_CH1_CR_PM_THRT_CKE_MIN_REG - MCHBAR_CH0_CR_PM_THRT_CKE_MIN_REG) * Channel;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "C%u PM_THRT_CKE_MIN %Xh: %Xh \n", Channel, Offset, PmThrtCkeMin.Data);
+ MrcWriteCR (MrcData, Offset, PmThrtCkeMin.Data);
+ }
+ }
+
+ PmSrefConfig.Data = 0;
+ PmSrefConfig.Bits.SR_Enable = ThermalEnables->SrefCfgEna;
+ PmSrefConfig.Bits.Idle_timer = ThermalEnables->SrefCfgIdleTmr;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "PM_SREF_CONFIG %Xh: %Xh\n", MCDECS_CR_PM_SREF_CONFIG_MCMAIN_REG, PmSrefConfig.Data);
+ MrcWriteCR (MrcData, MCDECS_CR_PM_SREF_CONFIG_MCMAIN_REG, PmSrefConfig.Data);
+
+ //
+ // POWER THERMAL MANAGEMENT CONTROL
+ //
+ DdrPtmCtl.Data = MrcReadCR (MrcData, PCU_CR_DDR_PTM_CTL_PCU_REG);
+ DdrPtmCtl.Bits.OLTM_ENABLE = ThermalEnables->EnableOltm;
+ DdrPtmCtl.Bits.CLTM_ENABLE = ThermalEnables->EnableCltm;
+ DdrPtmCtl.Bits.EXTTS_ENABLE = ThermalEnables->EnableExtts;
+ DdrPtmCtl.Bits.REFRESH_2X_MODE = ThermalEnables->Refresh2X;
+#ifdef ULT_FLAG
+ if (DdrType == MRC_DDR_TYPE_LPDDR3) {
+ DdrPtmCtl.Bits.PDWN_CONFIG_CTL = ThermalEnables->EnablePwrDnLpddr;
+ //
+ // When enabling 2x Refresh for LPDDR through the Mailbox we must
+ // ensure DDR_PTM_CTL.DISABLE_DRAM_TS = 0. Thus we ignore LpddrThermalSensor.
+ //
+ if (Inputs->RefreshRate2x == FALSE) {
+ DdrPtmCtl.Bits.DISABLE_DRAM_TS = (ThermalEnables->LpddrThermalSensor == 0) ? 1 : 0;
+ } else {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Ignoring ThermalEnables->LpddrThermal Sensor as 2x Refresh is enabled\n");
+ }
+ } else
+#endif // ULT_FLAG
+ {
+ DdrPtmCtl.Bits.PDWN_CONFIG_CTL = ThermalEnables->EnablePwrDn;
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "DDR_PTM_CTL %Xh: %Xh\n", PCU_CR_DDR_PTM_CTL_PCU_REG, DdrPtmCtl.Data);
+ MrcWriteCR (MrcData, PCU_CR_DDR_PTM_CTL_PCU_REG, DdrPtmCtl.Data);
+
+ return;
+}
+
+
+/**
+ this function use by the OEM to do dedicated task during the MRC.
+
+ @param[in] MrcData - include all the MRC data
+ @param[in] OemStatusCommand - A command that indicates the task to perform.
+ @param[in] ptr - general ptr for general use.
+
+ @retval The status of the task.
+**/
+MrcStatus
+MrcOemCheckPoint (
+ IN MrcParameters *MrcData,
+ IN MRC_OemStatusCommand OemStatusCommand,
+ IN void *ptr
+ )
+{
+ MrcInput *Inputs;
+ MrcOutput *Outputs;
+ MrcStatus Status;
+ MrcDdrType DdrType;
+
+ Status = mrcSuccess;
+ Inputs = &MrcData->SysIn.Inputs;
+ Outputs = &MrcData->SysOut.Outputs;
+ DdrType = Outputs->DdrType;
+
+
+ switch (OemStatusCommand) {
+ case OemSpdProcessingRun:
+ break;
+
+ case OemPreTraining:
+ break;
+
+ case OemMcTrainingRun:
+ break;
+
+ case OemEarlyCommandTraining:
+ if (DdrType == MRC_DDR_TYPE_LPDDR3) {
+ Status = mrcSuccess; // This is required for LPDDR
+ } else if (!Inputs->TrainingEnables.ECT) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+#ifdef ULT_FLAG
+ case OemJedecInitLpddr3: // MrcJedecInitLpddr3
+ if (DdrType == MRC_DDR_TYPE_LPDDR3) {
+ Status = mrcSuccess;
+ } else {
+ Status = mrcFail; // Skip this step for non-LPDDR
+ }
+ break;
+#endif // ULT_FLAG
+
+ case OemSenseAmpTraining:
+ if (!Inputs->TrainingEnables.SOT) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemReadMprTraining:
+ if (!Inputs->TrainingEnables.RDMPRT) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemReceiveEnable:
+ if (!Inputs->TrainingEnables.RCVET) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemJedecWriteLeveling:
+ if (!Inputs->TrainingEnables.JWRL) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemWriteLeveling:
+ if (!Inputs->TrainingEnables.FWRL) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemWriteDqDqs:
+ if (!Inputs->TrainingEnables.WRTC1D) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemReadDqDqs:
+ if (!Inputs->TrainingEnables.RDTC1D) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemDimmODTTraining:
+ if (!Inputs->TrainingEnables.DIMMODTT) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemDimmRonTraining:
+ if (!Inputs->TrainingEnables.DIMMRONT) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemWriteSlewRate:
+ if (!Inputs->TrainingEnables.WRSRT) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemDimmODT1dTraining:
+ if (!Inputs->TrainingEnables.DIMMODTT1D) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemWriteDriveStrength:
+ if (!Inputs->TrainingEnables.WRDST) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemWriteEQTraining:
+ if (!Inputs->TrainingEnables.WREQT) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemReadODTTraining:
+ if (!Inputs->TrainingEnables.RDODTT) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemReadEQTraining:
+ if (!Inputs->TrainingEnables.RDEQT) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemPostTraining:
+ if (DdrType == MRC_DDR_TYPE_LPDDR3) {
+ Status = mrcFail; // Skip this training step
+ break;
+ }
+ break;
+
+ case OemReadAmplifierPower:
+ if (!Inputs->TrainingEnables.RDAPT) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemOptimizeComp:
+ break;
+
+ case OemWriteDqDqs2D:
+ if (!Inputs->TrainingEnables.WRTC2D) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemReadDqDqs2D:
+ if (!Inputs->TrainingEnables.RDTC2D) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemCmdVoltCentering:
+ if (!Inputs->TrainingEnables.CMDVC) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemWriteVoltCentering2D:
+ if (!Inputs->TrainingEnables.WRVC2D) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemReadVoltCentering2D:
+ if (!Inputs->TrainingEnables.RDVC2D) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemLateCommandTraining:
+ if (!Inputs->TrainingEnables.LCT) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemRoundTripLatency:
+ if (!Inputs->TrainingEnables.RTL) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemTurnAroundTimes:
+ //
+ // @todo: TAT has to be updated for LPDDR3, skip it for now.
+ //
+ if ((!Inputs->TrainingEnables.TAT) || (DdrType == MRC_DDR_TYPE_LPDDR3)) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+#ifdef ULT_FLAG
+ case OemRcvEnCentering1D:
+ if ((!Inputs->TrainingEnables.RCVENC1D) || (DdrType != MRC_DDR_TYPE_LPDDR3)) {
+ Status = mrcFail; // Skip this step for non-LPDDR
+ }
+ break;
+#endif // ULT_FLAG
+
+ case OemRetrainMarginCheck:
+ if (!Inputs->TrainingEnables.RMC) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+
+ case OemRmt:
+ if (!Inputs->TrainingEnables.RMT) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemMemTest:
+ if (!Inputs->TrainingEnables.MEMTST) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemAliasCheck:
+ if (!Inputs->TrainingEnables.ALIASCHK) {
+ Status = mrcFail; // Skip this training step
+ }
+ break;
+
+ case OemBeforeNormalMode:
+ MrcOemBeforeNormalModeTestMenu (MrcData);
+ break;
+
+ case OemAfterNormalMode:
+ MrcOemAfterNormalModeTestMenu (MrcData);
+ break;
+
+ case OemFrequencySetDone:
+#ifdef SSA_FLAG
+#ifndef MRC_MINIBIOS_BUILD
+ SsaBiosInitialize (MrcData);
+#endif
+#endif // SSA_FLAG
+ break;
+
+ default:
+ break;
+ }
+
+ return Status;
+}
+
+/**
+ This function display on port 80 number.
+ It can be different debug interface.
+ This function can be use for any debug ability according to OEM requirements.
+
+ @param[in] MrcData - Mrc Global Data
+ @param[in] DisplayDebugNumber - the number to display on port 80.
+
+ @retval Nothing
+**/
+void
+MrcOemDebugHook (
+ IN MrcParameters *MrcData,
+ IN U16 DisplayDebugNumber
+ )
+{
+ MrcInput *Inputs;
+ U8 temp;
+ U16 BreakCmos;
+
+ Inputs = &MrcData->SysIn.Inputs;
+ Inputs->Debug.PostCode[1] = DisplayDebugNumber;
+ MrcOemOutPort16 (0x80, DisplayDebugNumber);
+ MRC_DEBUG_MSG (&Inputs->Debug, MSG_LEVEL_NOTE, "Post Code: 0x%X\n", DisplayDebugNumber);
+
+ //
+ // Check if we should break on this post code.
+ //
+ do {
+ temp = RtcRead (MRC_POST_CODE_LOW_BYTE_ADDR);
+ BreakCmos = (RtcRead (MRC_POST_CODE_HIGH_BYTE_ADDR) << 8) | temp;
+ } while (DisplayDebugNumber == BreakCmos);
+
+#ifdef SSA_FLAG
+#ifndef MRC_MINIBIOS_BUILD
+ if ((void *) (Inputs->SsaCallbackPpi) != NULL) {
+ (((SSA_BIOS_CALLBACKS_PPI *) (Inputs->SsaCallbackPpi))->MrcCheckpoint) ((EFI_PEI_SERVICES **) (Inputs->Debug.Stream), ((SSA_BIOS_CALLBACKS_PPI *)Inputs->SsaCallbackPpi), DisplayDebugNumber, NULL);
+ }
+#endif
+#endif // SSA_FLAG
+
+ return;
+}
+
+#ifdef MRC_DEBUG_PRINT
+/**
+ Print the input parameters to the debug message output port.
+
+ @param[in] MrcData - The MRC global data.
+
+ @retval mrcSuccess
+**/
+MrcStatus
+MrcPrintInputParameters (
+ IN MrcParameters *const MrcData
+ )
+{
+ const MrcDebug *Debug;
+ const MrcInput *Inputs;
+ const MrcControllerIn *ControllerIn;
+ const MrcChannelIn *ChannelIn;
+ const MrcDimmIn *DimmIn;
+ const TrainingStepsEn *TrainingSteps;
+ U8 Controller;
+ U8 Channel;
+ U8 Dimm;
+
+ Inputs = &MrcData->SysIn.Inputs;
+ Debug = &Inputs->Debug;
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "*************************************\n");
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "*****MRC INPUT PARAMS DUMP START*****\n");
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "*************************************\n");
+ //
+ // The following are system level definitions. All memory controllers in the system are set to these values.
+ //
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Debug.Stream : %Xh\n", Inputs->Debug.Stream);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Debug.Level : %Xh\n", Inputs->Debug.Level);
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "FreqMax : %u\n", Inputs->FreqMax);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Ratio : %u\n", Inputs->Ratio);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "RefClk : %uMHz\n", (Inputs->RefClk == MRC_REF_CLOCK_100) ? 100 : 133);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "BClk : %uHz\n", Inputs->BClkFrequency);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "BoardType : %Xh\n", Inputs->BoardType);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "CpuStepping : %Xh\n", Inputs->CpuStepping);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "CpuModel : %Xh\n", Inputs->CpuModel);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "GraphicsStolenSize : %Xh\n", Inputs->GraphicsStolenSize);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "GraphicsGttSize : %Xh\n", Inputs->GraphicsGttSize);
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.Seconds : %u\n", BaseTimeString, Inputs->BaseTime.Seconds);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.Minutes : %u\n", BaseTimeString, Inputs->BaseTime.Minutes);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.Hours : %u\n", BaseTimeString, Inputs->BaseTime.Hours);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.DayOfMonth : %u\n", BaseTimeString, Inputs->BaseTime.DayOfMonth);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.Month : %u\n", BaseTimeString, Inputs->BaseTime.Month);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.Year : %u\n", BaseTimeString, Inputs->BaseTime.Year);
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Iteration : %Xh\n", Inputs->Iteration);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MrcMode : %Xh\n", Inputs->MrcMode);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "VddVoltage : %u mV\n", Inputs->VddVoltage);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MemoryProfile : %Xh\n", Inputs->MemoryProfile);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "BootMode : %Xh\n", Inputs->BootMode);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "TxtFlag : %Xh\n", Inputs->TxtFlag);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MobilePlatform : %Xh\n", Inputs->MobilePlatform);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "EccSupport : %Xh\n", Inputs->EccSupport);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "SetRxDqs32 : %Xh\n", Inputs->SetRxDqs32);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "GfxIsVersatileAcceleration : %Xh\n", Inputs->GfxIsVersatileAcceleration);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "ScramblerEnable : %Xh\n", Inputs->ScramblerEnable);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "McLock : %Xh\n", Inputs->McLock);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "RemapEnable : %Xh\n", Inputs->RemapEnable);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "PowerDownMode : %Xh\n", Inputs->PowerDownMode);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "PwdwnIdleCounter : %Xh\n", Inputs->PwdwnIdleCounter);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "RankInterleave : %Xh\n", Inputs->RankInterleave);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "EnhancedInterleave : %Xh\n", Inputs->EnhancedInterleave);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "WeaklockEn : %Xh\n", Inputs->WeaklockEn);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "EnCmdRate : %Xh\n", Inputs->EnCmdRate);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "CmdTriStateDis : %Xh\n", Inputs->CmdTriStateDis);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "RefreshRate2x : %Xh\n", Inputs->RefreshRate2x);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "BaseAddresses\n");
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, " PciE : %Xh\n", Inputs->PciEBaseAddress);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, " MchBar : %Xh\n", Inputs->MchBarBaseAddress);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, " Smbus : %Xh\n", Inputs->SmbusBaseAddress);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, " Gdxc : %Xh\n", Inputs->GdxcBaseAddress);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, " Hpet : %Xh\n\n", Inputs->HpetBaseAddress);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MeStolenSize : %Xh\n", Inputs->MeStolenSize);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MmioSize : %Xh\n", Inputs->MmioSize);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "TsegSize : %Xh\n", Inputs->TsegSize);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "IedSize : %Xh\n", Inputs->IedSize);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "DprSize : %Xh\n", Inputs->DprSize);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "VddSettleWaitTime : %Xh\n", Inputs->VddSettleWaitTime);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "VccIomV : %Xh\n", Inputs->VccIomV);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "AutoSelfRefreshSupport : %u\n", Inputs->AutoSelfRefreshSupport);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "ExtTemperatureSupport : %u\n", Inputs->ExtTemperatureSupport);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "ChHashEnable : %Xh\n", Inputs->ChHashEnable);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "ChHashMask : %Xh\n", Inputs->ChHashMask);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "ChHashInterleaveBit : %Xh\n", Inputs->ChHashInterleaveBit);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%sEnable : %Xh\n", GdxcString, Inputs->Gdxc.GdxcEnable);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%sIotSize : %Xh\n", GdxcString, Inputs->Gdxc.GdxcIotSize);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%sMotSize : %Xh\n", GdxcString, Inputs->Gdxc.GdxcMotSize);
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MemoryTrace: %u\n", Inputs->MemoryTrace);
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "*************************************\n");
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "***** MRC TRAINING STEPS *****\n");
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "*************************************\n");
+ TrainingSteps = &Inputs->TrainingEnables;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s : %Xh\n", TrainEnString, Inputs->TrainingEnables);
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.ECT : %u\n", TrainEnString, TrainingSteps->ECT);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.SOT : %u\n", TrainEnString, TrainingSteps->SOT);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RDMPRT : %u\n", TrainEnString, TrainingSteps->RDMPRT);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RCVET : %u\n", TrainEnString, TrainingSteps->RCVET);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.JWRL : %u\n", TrainEnString, TrainingSteps->JWRL);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.FWRL : %u\n", TrainEnString, TrainingSteps->FWRL);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.WRTC1D : %u\n", TrainEnString, TrainingSteps->WRTC1D);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RDTC1D : %u\n", TrainEnString, TrainingSteps->RDTC1D);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.DIMMODTT : %u\n", TrainEnString, TrainingSteps->DIMMODTT);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.WRDST : %u\n", TrainEnString, TrainingSteps->WRDST);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.WREQT : %u\n", TrainEnString, TrainingSteps->WREQT);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RDODTT : %u\n", TrainEnString, TrainingSteps->RDODTT);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RDEQT : %u\n", TrainEnString, TrainingSteps->RDEQT);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RDAPT : %u\n", TrainEnString, TrainingSteps->RDAPT);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.WRTC2D : %u\n", TrainEnString, TrainingSteps->WRTC2D);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RDTC2D : %u\n", TrainEnString, TrainingSteps->RDTC2D);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.WRVC2D : %u\n", TrainEnString, TrainingSteps->WRVC2D);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RDVC2D : %u\n", TrainEnString, TrainingSteps->RDVC2D);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.LCT : %u\n", TrainEnString, TrainingSteps->LCT);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RTL : %u\n", TrainEnString, TrainingSteps->RTL);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.TAT : %u\n", TrainEnString, TrainingSteps->TAT);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RMT : %u\n", TrainEnString, TrainingSteps->RMT);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.MEMTST : %u\n", TrainEnString, TrainingSteps->MEMTST);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.DIMMODTT1D : %u\n", TrainEnString, TrainingSteps->DIMMODTT1D);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.WRSRT : %u\n", TrainEnString, TrainingSteps->WRSRT);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.DIMMRONT : %u\n", TrainEnString, TrainingSteps->DIMMRONT);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.ALIASCHK : %u\n", TrainEnString, TrainingSteps->ALIASCHK);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RCVENC1D : %u\n", TrainEnString, TrainingSteps->RCVENC1D);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RMC : %u\n", TrainEnString, TrainingSteps->RMC);
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "*************************************\n");
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "***** MRC TIMING DATA *****\n");
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "*************************************\n");
+
+ for (Controller = 0; Controller < MAX_CONTROLLERS; Controller++) {
+ ControllerIn = &Inputs->Controller[Controller];
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Controller[%u] ChannelCount : %Xh\n", Controller, ControllerIn->ChannelCount);
+ for (Channel = 0; Channel < MAX_CHANNEL; Channel++) {
+ ChannelIn = &ControllerIn->Channel[Channel];
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel[%u].Status : %Xh\n", Channel, ChannelIn->Status);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel[%u].DimmCount : %Xh\n", Channel, ChannelIn->DimmCount);
+
+ for (Dimm = 0; Dimm < MAX_DIMMS_IN_CHANNEL; Dimm++) {
+ DimmIn = &ChannelIn->Dimm[Dimm];
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u Status : %Xh\n", CcdString, Controller, Channel, Dimm, DimmIn->Status);
+ if (Inputs->MemoryProfile == USER_PROFILE) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tCK : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tCK);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u NMode : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.NMode);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tCL : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tCL);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tCWL : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tCWL);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tFAW : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tFAW);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tRAS : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tRAS);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tRC : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tRC);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tRCD : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tRCD);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tREFI : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tREFI);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tRFC : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tRFC);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tRP : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tRP);
+#ifdef ULT_FLAG
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tRPab : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tRPab);
+#endif // ULT_FLAG
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tRRD : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tRRD);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tRTP : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tRTP);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tWR : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tWR);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u tWTR : %u\n", CcdString, Controller, Channel, Dimm, DimmIn->Timing.tWTR);
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s %u/%u/%u SpdAddress : %Xh\n", CcdString, Controller, Channel, Dimm, DimmIn->SpdAddress);
+ }
+ }
+ }
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "*************************************\n");
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "***** THERMAL OVERWRITE *******\n");
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "*************************************\n");
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.EnableExtts : %Xh\n", ThermEnString, Inputs->ThermalEnables.EnableExtts);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.EnableCltm : %Xh\n", ThermEnString, Inputs->ThermalEnables.EnableCltm);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.EnableOltm : %Xh\n", ThermEnString, Inputs->ThermalEnables.EnableOltm);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.EnablePwrDn : %Xh\n", ThermEnString, Inputs->ThermalEnables.EnablePwrDn);
+#ifdef ULT_FLAG
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.EnablePwrDnLpddr: %Xh\n", ThermEnString, Inputs->ThermalEnables.EnablePwrDnLpddr);
+#endif // ULT_FLAG
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.Refresh2X : %Xh\n", ThermEnString, Inputs->ThermalEnables.Refresh2X);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.LpddrThermalSensor: %Xh\n", ThermEnString, Inputs->ThermalEnables.LpddrThermalSensor);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.LockPTMregs : %Xh\n", ThermEnString, Inputs->ThermalEnables.LockPTMregs);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.UserPowerWeightsEn: %Xh\n", ThermEnString, Inputs->ThermalEnables.UserPowerWeightsEn);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.EnergyScaleFact : %Xh\n", ThermEnString, Inputs->ThermalEnables.EnergyScaleFact);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RaplLim2Lock : %Xh\n", ThermEnString, Inputs->ThermalEnables.RaplLim2Lock);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RaplLim2WindX : %Xh\n", ThermEnString, Inputs->ThermalEnables.RaplLim2WindX);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RaplLim2WindY : %Xh\n", ThermEnString, Inputs->ThermalEnables.RaplLim2WindY);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RaplLim2Ena : %Xh\n", ThermEnString, Inputs->ThermalEnables.RaplLim2Ena);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RaplLim2Pwr : %Xh\n", ThermEnString, Inputs->ThermalEnables.RaplLim2Pwr);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RaplLim1WindX : %Xh\n", ThermEnString, Inputs->ThermalEnables.RaplLim1WindX);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RaplLim1WindY : %Xh\n", ThermEnString, Inputs->ThermalEnables.RaplLim1WindY);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RaplLim1Ena : %Xh\n", ThermEnString, Inputs->ThermalEnables.RaplLim1Ena);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RaplLim1Pwr : %Xh\n", ThermEnString, Inputs->ThermalEnables.RaplLim1Pwr);
+ for (Channel = 0; Channel < MAX_CHANNEL; Channel++) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RaplPwrFlCh[%u] : %Xh\n", ThermEnString, Channel, Inputs->ThermalEnables.RaplPwrFl[Channel]);
+ for (Dimm = 0; Dimm < MAX_DIMMS_IN_CHANNEL; Dimm++) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.WarmThresholdCh[%u]Dimm[%u] : %Xh\n", ThermEnString, Channel, Dimm, Inputs->ThermalEnables.WarmThreshold[Channel][Dimm]);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.HotThresholdCh[%u]Dimm[%u] : %Xh\n", ThermEnString, Channel, Dimm, Inputs->ThermalEnables.HotThreshold[Channel][Dimm]);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.WarmBudgetCh[%u]Dimm[%u] : %Xh\n", ThermEnString, Channel, Dimm, Inputs->ThermalEnables.WarmBudget[Channel][Dimm]);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.HotBudgetCh[%u]Dimm[%u] : %Xh\n", ThermEnString, Channel, Dimm, Inputs->ThermalEnables.HotBudget[Channel][Dimm]);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.IdleEnergyCh[%u]Dimm[%u] : %Xh\n", ThermEnString, Channel, Dimm, Inputs->ThermalEnables.IdleEnergy[Channel][Dimm]);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.PdEnergyCh[%u]Dimm[%u] : %Xh\n", ThermEnString, Channel, Dimm, Inputs->ThermalEnables.PdEnergy[Channel][Dimm]);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.ActEnergyCh[%u]Dimm[%u] : %Xh\n", ThermEnString, Channel, Dimm, Inputs->ThermalEnables.ActEnergy[Channel][Dimm]);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.RdEnergyCh[%u]Dimm[%u] : %Xh\n", ThermEnString, Channel, Dimm, Inputs->ThermalEnables.RdEnergy[Channel][Dimm]);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.WrEnergyCh[%u]Dimm[%u] : %Xh\n", ThermEnString, Channel, Dimm, Inputs->ThermalEnables.WrEnergy[Channel][Dimm]);
+ }
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.SrefCfgEna : %Xh\n", ThermEnString, Inputs->ThermalEnables.SrefCfgEna);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.SrefCfgIdleTmr : %Xh\n", ThermEnString, Inputs->ThermalEnables.SrefCfgIdleTmr);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.ThrtCkeMinDefeat: %Xh\n", ThermEnString, Inputs->ThermalEnables.ThrtCkeMinDefeat);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.ThrtCkeMinTmr : %Xh\n", ThermEnString, Inputs->ThermalEnables.ThrtCkeMinTmr);
+#ifdef ULT_FLAG
+ if (Inputs->CpuModel == cmHSW_ULT) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.ThrtCkeMinDefeatLpddr: %Xh\n", ThermEnString, Inputs->ThermalEnables.ThrtCkeMinDefeatLpddr);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%s.ThrtCkeMinTmrLpddr : %Xh\n", ThermEnString, Inputs->ThermalEnables.ThrtCkeMinTmrLpddr);
+ }
+#endif // ULT_FLAG
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "*************************************\n");
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "*****MRC INPUT PARAMS DUMP END*******\n");
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "*************************************\n\n");
+
+ return mrcSuccess;
+}
+
+/**
+ Print the specified memory to the serial message debug port.
+
+ @param[in] Debug - Serial message debug structure.
+ @param[in] Start - The starting address to dump.
+ @param[in] Size - The amount of data in bytes to dump.
+
+ @retval Nothing.
+**/
+void
+MrcPrintMemory (
+ IN const MrcDebug *const Debug,
+ IN const U8 *const Start,
+ IN const U32 Size
+ )
+{
+ const U8 *Address;
+ const U8 *End;
+ U32 Line;
+ U32 Offset;
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, " ");
+ for (Offset = 0; Offset < 16; Offset++) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%02X ", ((U32) Start + Offset) % 16);
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "\n");
+ End = Start + Size;
+ for (Line = 0; Line < ((Size / 16) + 1); Line++) {
+ Address = Start + (Line * 16);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "% 8X: ", Address);
+ for (Offset = 0; Offset < 16; Offset++) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, ((Address + Offset) < End) ? "%02X " : " ", Address[Offset]);
+ }
+ for (Offset = 0; (Offset < 16) && ((Address + Offset) < End); Offset++) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "%c", isprint (Address[Offset]) ? Address[Offset] : '.');
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "\n");
+ }
+ return;
+}
+#endif
+
+#if (defined MEMORY_DOWN_SUPPORT && (MEMORY_DOWN_SUPPORT > 0))
+
+/******************************************************************************
+ Memory down configuration code starts here.
+ Add SPD, and channel/slot population settings here.
+
+ Even though this is a memory down configuration, the MRC needs to know how
+ the memory appears to the controller, so indicate here which channels are
+ populated. Also, the MRC needs to know which slots are valid, even though
+ there are technically no physical slots in a memory down configuration.
+ The MRC also needs a valid SPD data for the configuration.
+******************************************************************************/
+typedef enum {
+ MEMORY_ABSENT, ///< No memory down and no physical memory slot.
+ MEMORY_SLOT_ONLY, ///< No memory down and a physical memory slot.
+ MEMORY_DOWN_ONLY, ///< Memory down and not a physical memory slot.
+} MemorySlotStatus;
+
+#ifndef AMI_OVERRIDE_FOR_MEMORY_DOWN
+#if defined(NB_OEM_DIMM1_STATUS) && (NB_OEM_DIMM1_STATUS == 0x02)
+static const UINT8 Dimm1SpdTbl[] = NB_OEM_DIMM1_SPD_DATA;
+#endif
+#if defined(NB_OEM_DIMM2_STATUS) && (NB_OEM_DIMM2_STATUS == 0x02)
+static const UINT8 Dimm2SpdTbl[] = NB_OEM_DIMM2_SPD_DATA;
+#endif
+#if defined(NB_OEM_DIMM3_STATUS) && (NB_OEM_DIMM3_STATUS == 0x02)
+static const UINT8 Dimm3SpdTbl[] = NB_OEM_DIMM3_SPD_DATA;
+#endif
+#if defined(NB_OEM_DIMM4_STATUS) && (NB_OEM_DIMM4_STATUS == 0x02)
+static const UINT8 Dimm4SpdTbl[] = NB_OEM_DIMM4_SPD_DATA;
+#endif
+#endif // AMI_OVERRIDE_FOR_MEMORY_DOWN
+///
+/// Example board support
+///
+#ifdef AMI_OVERRIDE_FOR_MEMORY_DOWN
+#define EXAMPLE_BOARD_SUPPORT 0
+#else
+#if (defined MEMORY_DOWN_SUPPORT && (MEMORY_DOWN_SUPPORT == 1))
+#define EXAMPLE_BOARD_SUPPORT 1
+#else
+#define EXAMPLE_BOARD_SUPPORT 0
+#endif // MEMORY_DOWN_SUPPORT
+#endif // AMI_OVERRIDE_FOR_MEMORY_DOWN
+#if (defined EXAMPLE_BOARD_SUPPORT && (EXAMPLE_BOARD_SUPPORT > 0))
+///
+/// For this example board, we have a dual channel, single slot configuration
+/// with the same memory configuration in each channel (DDR3).
+///
+const MemorySlotStatus ExampleSlotStatus[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL] = {
+#ifndef AMI_OVERRIDE_FOR_MEMORY_DOWN
+ NB_OEM_DIMM1_STATUS, // Channel 0, Slot 0
+ NB_OEM_DIMM2_STATUS, // Channel 0, Slot 1
+ NB_OEM_DIMM3_STATUS, // Channel 1, Slot 0
+ NB_OEM_DIMM4_STATUS, // Channel 1, Slot 1
+#else
+ MEMORY_DOWN_ONLY, ///< Channel 0, Slot 0
+ MEMORY_ABSENT, ///< Channel 0, Slot 1
+ MEMORY_DOWN_ONLY, ///< Channel 1, Slot 0
+ MEMORY_ABSENT, ///< Channel 1, Slot 1
+#endif // AMI_OVERRIDE_FOR_MEMORY_DOWN
+};
+
+const U8 ExampleSpd[] = {
+ 0x92, ///< 0 Number of Serial PD Bytes Written / SPD Device Size / CRC Coverage 1, 2
+ 0x10, ///< 1 SPD Revision
+ 0x0B, ///< 2 DRAM Device Type
+ 0x03, ///< 3 Module Type
+ 0x02, ///< 4 SDRAM Density and Banks
+ 0x11, ///< 5 SDRAM Addressing
+ 0x00, ///< 6 Module Nominal Voltage
+ 0x09, ///< 7 Module Organization
+ 0x03, ///< 8 Module Memory Bus Width
+ 0x52, ///< 9 Fine Timebase (FTB) Dividend / Divisor
+ 0x01, ///< 10 Medium Timebase (MTB) Dividend
+ 0x08, ///< 11 Medium Timebase (MTB) Divisor
+ 0x0A, ///< 12 SDRAM Minimum Cycle Time (tCKmin)
+ 0x00, ///< 13 Reserved0
+ 0xFE, ///< 14 CAS Latencies Supported, Least Significant Byte
+ 0x00, ///< 15 CAS Latencies Supported, Most Significant Byte
+ 0x69, ///< 16 Minimum CAS Latency Time (tAAmin)
+ 0x78, ///< 17 Minimum Write Recovery Time (tWRmin)
+ 0x69, ///< 18 Minimum RAS# to CAS# Delay Time (tRCDmin)
+ 0x30, ///< 19 Minimum Row Active to Row Active Delay Time (tRRDmin)
+ 0x69, ///< 20 Minimum Row Precharge Delay Time (tRPmin)
+ 0x11, ///< 21 Upper Nibbles for tRAS and tRC
+ 0x18, ///< 22 Minimum Active to Precharge Delay Time (tRASmin), Least Significant Byte
+ 0x81, ///< 23 Minimum Active to Active/Refresh Delay Time (tRCmin), Least Significant Byte
+ 0x70, ///< 24 Minimum Refresh Recovery Delay Time (tRFCmin), Least Significant Byte
+ 0x03, ///< 25 Minimum Refresh Recovery Delay Time (tRFCmin), Most Significant Byte
+ 0x3C, ///< 26 Minimum Internal Write to Read Command Delay Time (tWTRmin)
+ 0x3C, ///< 27 Minimum Internal Read to Precharge Command Delay Time (tRTPmin)
+ 0x00, ///< 28 Upper Nibble for tFAW
+ 0xF0, ///< 29 Minimum Four Activate Window Delay Time (tFAWmin)
+ 0x83, ///< 30 SDRAM Optional Features
+ 0x01, ///< 31 SDRAMThermalAndRefreshOptions
+ 0x00, ///< 32 ModuleThermalSensor
+ 0x00, ///< 33 SDRAM Device Type
+ 0x00, ///< 34 Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
+ 0x00, ///< 35 Fine Offset for Minimum CAS Latency Time (tAAmin)
+ 0x00, ///< 36 Fine Offset for Minimum RAS# to CAS# Delay Time (tRCDmin)
+ 0x00, ///< 37 Fine Offset for Minimum Row Precharge Delay Time (tRPmin)
+ 0x00, ///< 38 Fine Offset for Minimum Active to Active/Refresh Delay Time (tRCmin)
+ 0x00, ///< 39
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 40 - 49
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 50 - 59
+ 0, 0, ///< 60 - 61
+ 0x45, ///< 62 Reference Raw Card Used
+ 0x00, ///< 63 Address Mapping from Edge Connector to DRAM
+ 0x00, ///< 64 ThermalHeatSpreaderSolution
+ 0, 0, 0, 0, 0, ///< 65 - 69
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 70 - 79
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 80 - 89
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 90 - 99
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ///< 100 - 109
+ 0, 0, 0, 0, 0, 0, 0, ///< 110 - 116
+ 0x80, ///< 117 Module Manufacturer ID Code, Least Significant Byte
+ 0xCE, ///< 118 Module Manufacturer ID Code, Most Significant Byte
+ 0x01, ///< 119 Module Manufacturing Location
+ 0x11, ///< 120 Module Manufacturing Date Year
+ 0x02, ///< 121 Module Manufacturing Date creation work week
+ 0x44, ///< 122 Module Serial Number A
+ 0x0A, ///< 123 Module Serial Number B
+ 0x83, ///< 124 Module Serial Number C
+ 0x0C, ///< 125 Module Serial Number D
+ 0xA5, ///< 126 CRC A
+ 0x50 ///< 127 CRC B
+};
+#endif // EXAMPLE_BOARD_SUPPORT
+
+
+/**
+ Copies information from the Memory Down SPD structure to the SPD Input structure
+ in the Host structure.
+
+ Setting the SpdBaseAddress to zero means this slot has a memory down configuration.
+ For systems that have both memory down and slots, it is recommended to have the
+ memory down in the slot position farthest from the controller.
+
+ @param[in, out] Inputs - MRC Host Input structure.
+ @param[in] SpdIn - Pointer to the Memory Down SPD structure to copy.
+ @param[in] Slot - Pointer to the Memory Down MemorySlotStatus structure.
+ @param[in] SpdSize - Size of the SPD structure to limit MemoryCpy.
+
+ @retval - Nothing.
+**/
+void
+CopyMemoryDownSpd (
+ IN OUT MrcInput *const Inputs,
+ IN const U8 *SpdIn[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL],
+ IN const MemorySlotStatus *Slot,
+ IN U16 SpdSize
+ )
+{
+ MrcDimmIn *DimmIn;
+ U8 Channel;
+ U8 Dimm;
+
+ if (SpdIn == NULL || Slot == NULL || SpdSize == 0) {
+ return;
+ }
+
+ for (Channel = 0; Channel < MAX_CHANNEL; Channel++) {
+ for (Dimm = 0; Dimm < MAX_DIMMS_IN_CHANNEL; Dimm++, Slot++) {
+ DimmIn = &Inputs->Controller[0].Channel[Channel].Dimm[Dimm];
+ switch (*Slot) {
+ case MEMORY_DOWN_ONLY:
+ DimmIn->SpdAddress = 0;
+ // Check user request to disable DIMM/rank pair.
+ if (DimmIn->Status != DIMM_DISABLED) {
+ DimmIn->Status = DIMM_ENABLED;
+ MrcOemMemoryCpy ((U8 *) &DimmIn->Spd, (U8 *) SpdIn[Channel][Dimm], SpdSize);
+ MRC_DEBUG_MSG (&Inputs->Debug, MSG_LEVEL_NOTE, "Memory down present on channel %u, dimm %u\n", Channel, Dimm);
+ } else {
+ MRC_DEBUG_MSG (&Inputs->Debug, MSG_LEVEL_NOTE, "Memory down absent on channel %u, dimm %u\n", Channel, Dimm);
+ }
+ break;
+
+ case MEMORY_ABSENT:
+ DimmIn->Status = DIMM_DISABLED;
+ DimmIn->SpdAddress = 0;
+ MRC_DEBUG_MSG (&Inputs->Debug, MSG_LEVEL_NOTE, "Memory down absent on channel %u, dimm %u\n", Channel, Dimm);
+ break;
+
+ case MEMORY_SLOT_ONLY:
+ default:
+ break;
+ }
+ }
+ }
+
+ return;
+}
+
+/**
+ Enables Memory Down support and sets SPD data for all DIMMs needing support.
+
+ @param[in] Inputs - MRC Input data structure.
+ @param[in] BoardId - The ID of the board.
+
+ @retval Nothing
+**/
+void
+EnableMemoryDown (
+ IN MrcInput *const Inputs,
+ IN U16 BoardId
+ )
+{
+ const U8 *SpdIn[MAX_CHANNEL][MAX_DIMMS_IN_CHANNEL];
+ const MemorySlotStatus *Slot;
+ U16 SpdSize;
+ U8 Channel;
+ U8 Dimm;
+#ifndef AMI_OVERRIDE_FOR_MEMORY_DOWN
+ const U8 *DimmSpdTbl = NULL;
+#endif // AMI_OVERRIDE_FOR_MEMORY_DOWN
+
+ Channel = 0;
+ Dimm = 0;
+ SpdSize = 0;
+
+ switch (BoardId) {
+#if (defined EXAMPLE_BOARD_SUPPORT && (EXAMPLE_BOARD_SUPPORT > 0))
+
+ case 0:
+ //
+ // BoardIdExample:
+ //
+ for (Channel = 0; Channel < MAX_CHANNEL; Channel++) {
+ for (Dimm = 0; Dimm < MAX_DIMMS_IN_CHANNEL; Dimm++) {
+#ifndef AMI_OVERRIDE_FOR_MEMORY_DOWN
+#if defined(NB_OEM_DIMM1_STATUS) && (NB_OEM_DIMM1_STATUS == 0x02)
+ if (Channel == 0 && Dimm == 0) {
+ DimmSpdTbl = Dimm1SpdTbl;
+ }
+#endif
+#if defined(NB_OEM_DIMM2_STATUS) && (NB_OEM_DIMM2_STATUS == 0x02)
+ if (Channel == 0 && Dimm == 1) {
+ DimmSpdTbl = Dimm2SpdTbl;
+ }
+#endif
+#if defined(NB_OEM_DIMM3_STATUS) && (NB_OEM_DIMM3_STATUS == 0x02)
+ if (Channel == 1 && Dimm == 0) {
+ DimmSpdTbl = Dimm3SpdTbl;
+ }
+#endif
+#if defined(NB_OEM_DIMM4_STATUS) && (NB_OEM_DIMM4_STATUS == 0x02)
+ if (Channel == 1 && Dimm == 1) {
+ DimmSpdTbl = Dimm4SpdTbl;
+ }
+#endif
+ SpdIn[Channel][Dimm] = DimmSpdTbl;
+ if (DimmSpdTbl != NULL) {
+ DimmSpdTbl = NULL;
+ }
+#else
+ SpdIn[Channel][Dimm] = ExampleSpd;
+#endif // AMI_OVERRIDE_FOR_MEMORY_DOWN
+ }
+ }
+
+ Slot = (const MemorySlotStatus *) &ExampleSlotStatus[0][0];
+ SpdSize = sizeof(ExampleSpd);
+ break;
+#endif // EXAMPLE_BOARD_SUPPORT
+
+
+ //
+ // Add additional boards that support memory down here.
+ //
+
+ //
+ // The default case means the board ID was not recognized. Instead
+ // we set Slot = NULL thus forcing us to read from the SPD.
+ //
+ default:
+ Slot = NULL;
+ }
+
+ CopyMemoryDownSpd (Inputs, SpdIn, Slot, SpdSize);
+
+ return;
+}
+#endif // MEMORY_DOWN_SUPPORT
+
+#ifdef ULT_FLAG
+/**
+ Initialize the board-specific CMD/CTL/CLK and DQ/DQS mapping for LPDDR3.
+
+ @param[in, out] Inputs - MRC Input data structure.
+ @param[in] BoardId - The ID of the board.
+
+ @retval none
+**/
+void
+MrcOemLpddrBoardMapping (
+ IN OUT MrcInput *Inputs,
+ IN U16 BoardId
+ )
+{
+ MrcControllerIn *ControllerIn;
+ U8 *DqByteMapCh0;
+ U8 *DqByteMapCh1;
+ U8 *DqsMapCpu2DramCh0;
+ U8 *DqsMapCpu2DramCh1;
+ U8 *DqMapCpu2DramCh0;
+ U8 *DqMapCpu2DramCh1;
+ U32 Channel;
+ U32 Byte;
+
+
+ ControllerIn = &Inputs->Controller[0];
+ DqByteMapCh0 = NULL;
+ DqByteMapCh1 = NULL;
+ DqsMapCpu2DramCh0 = NULL;
+ DqsMapCpu2DramCh1 = NULL;
+ DqMapCpu2DramCh0 = NULL;
+ DqMapCpu2DramCh1 = NULL;
+
+ //
+ // CKE to Rank mapping: CKE | 0 1 2 3
+ // (same on both channels) --------------
+ // Rank | 0 1 0 1
+ //
+ Inputs->CkeRankMapping = 0xAA;
+
+ //
+ // @todo: pass these via SaPlatformPolicy PPI
+ //
+ DqByteMapCh0 = (U8 *) DqByteMapRvpCh0;
+ DqByteMapCh1 = (U8 *) DqByteMapRvpCh1;
+ DqsMapCpu2DramCh0 = (U8 *) DqsMapCpu2DramRvpCh0;
+ DqsMapCpu2DramCh1 = (U8 *) DqsMapCpu2DramRvpCh1;
+ DqMapCpu2DramCh0 = (U8 *) DqMapCpu2DramRvpCh0;
+ DqMapCpu2DramCh1 = (U8 *) DqMapCpu2DramRvpCh1;
+
+
+ //
+ // DQ byte mapping to CMD/CTL/CLK
+ //
+ MrcOemMemoryCpy ((U8 *) ControllerIn->Channel[0].DQByteMap, DqByteMapCh0, sizeof (DqByteMapRvpCh0));
+ MrcOemMemoryCpy ((U8 *) ControllerIn->Channel[1].DQByteMap, DqByteMapCh1, sizeof (DqByteMapRvpCh1));
+
+ //
+ // DQS byte swizzling between CPU and DRAM
+ //
+ MrcOemMemoryCpy (ControllerIn->Channel[0].DqsMapCpu2Dram, DqsMapCpu2DramCh0, sizeof (DqsMapCpu2DramRvpCh0));
+ MrcOemMemoryCpy (ControllerIn->Channel[1].DqsMapCpu2Dram, DqsMapCpu2DramCh1, sizeof (DqsMapCpu2DramRvpCh1));
+
+ for (Channel = 0; Channel < MAX_CHANNEL; Channel++) {
+ MRC_DEBUG_MSG (&Inputs->Debug, MSG_LEVEL_ERROR, "Ch %d DqsMapCpu2Dram: ", Channel);
+ for (Byte = 0; Byte < 8; Byte++) {
+ MRC_DEBUG_MSG (&Inputs->Debug, MSG_LEVEL_ERROR, "%d ", ControllerIn->Channel[Channel].DqsMapCpu2Dram[Byte]);
+ }
+ MRC_DEBUG_MSG (&Inputs->Debug, MSG_LEVEL_ERROR, "\n");
+ }
+
+ //
+ // DQ bit swizzling between CPU and DRAM
+ //
+ MrcOemMemoryCpy ((U8 *) ControllerIn->Channel[0].DqMapCpu2Dram, DqMapCpu2DramCh0, sizeof (DqMapCpu2DramRvpCh0));
+ MrcOemMemoryCpy ((U8 *) ControllerIn->Channel[1].DqMapCpu2Dram, DqMapCpu2DramCh1, sizeof (DqMapCpu2DramRvpCh0));
+}
+#endif // ULT_FLAG
+// AMI_OVERRIDE_FOR_UPSERVER_SUPPORT
+#ifdef UPSERVER_SUPPORT
+void
+MrcCltmDisable (
+ MrcParameters *MrcData
+ )
+/*++
+
+Routine Description:
+
+ Disable CLTM configuration register if Outputs->CLTM_SPD_Conf = PROCESS_FAILED
+
+Arguments:
+
+ MrcData - include all the MRC data.
+
+Returns:
+ None
+
+--*/
+{
+ MrcDebug *Debug;
+ PCU_CR_DDR_PTM_CTL_PCU_STRUCT DdrPtmCtl;
+ ThermalMngmtEn *ThermalEnables;
+ MrcInput *Inputs;
+
+ Inputs = &MrcData->SysIn.Inputs;
+ Debug = &Inputs->Debug;
+ ThermalEnables = &Inputs->ThermalEnables;
+
+ DdrPtmCtl.Data = MrcReadCR (MrcData, PCU_CR_DDR_PTM_CTL_PCU_REG);
+ DdrPtmCtl.Bits.OLTM_ENABLE = ThermalEnables->EnableOltm;//Disable , 0, Not available for UP Platforms
+ DdrPtmCtl.Bits.CLTM_ENABLE = CLTM_DISABLE;//0, Disable.
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "CLTM is Disabled - Exiting.\n");
+ MrcWriteCR (MrcData, PCU_CR_DDR_PTM_CTL_PCU_REG, DdrPtmCtl.Data);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "DDR_PTM_CTL %Xh: %Xh \n", PCU_CR_DDR_PTM_CTL_PCU_REG, MrcReadCR (MrcData, PCU_CR_DDR_PTM_CTL_PCU_REG));
+}
+
+void
+MrcCltmInit (
+ MrcParameters *MrcData
+ )
+/*++
+
+Routine Description:
+
+ CLTM Initialization
+
+Arguments:
+
+ MrcData - include all the MRC data.
+
+Returns:
+ None
+
+--*/
+{
+ MrcInput *Inputs;
+ MrcOutput *Outputs;
+ MrcDebug *Debug;
+ ThermalMngmtEn *ThermalEnables;
+ U8 Controller;
+ U8 Channel, Dimm;
+ U8 OffsetDimm[2];
+ BOOL FirstValue;
+ PCU_CR_DDR_PTM_CTL_PCU_STRUCT DdrPtmCtl;
+ PCU_CR_DDR_ENERGY_SCALEFACTOR_PCU_STRUCT DdrEnergyScaleFactor;
+ PCU_CR_DDR_WARM_THRESHOLD_CH0_PCU_STRUCT DdrWarmThresholdCh0;
+ PCU_CR_DDR_WARM_THRESHOLD_CH1_PCU_STRUCT DdrWarmThresholdCh1;
+ PCU_CR_DDR_HOT_THRESHOLD_CH0_PCU_STRUCT DdrHotThresholdCh0;
+ PCU_CR_DDR_HOT_THRESHOLD_CH1_PCU_STRUCT DdrHotThresholdCh1;
+ PCU_CR_DDR_WARM_BUDGET_CH0_PCU_STRUCT DdrWarmBudgetCh0;
+ PCU_CR_DDR_WARM_BUDGET_CH1_PCU_STRUCT DdrWarmBudgetCh1;
+ PCU_CR_DDR_HOT_BUDGET_CH0_PCU_STRUCT DdrHotBudgetCh0;
+ PCU_CR_DDR_HOT_BUDGET_CH1_PCU_STRUCT DdrHotBudgetCh1;
+ MCHBAR_CH0_CR_PM_DIMM_IDLE_ENERGY_STRUCT PmDimmIdleEnergy;
+ MCHBAR_CH0_CR_PM_DIMM_PD_ENERGY_STRUCT PmDimmPdEnergy;
+ MCHBAR_CH0_CR_PM_DIMM_ACT_ENERGY_STRUCT PmDimmActEnergy;
+ MCHBAR_CH0_CR_PM_DIMM_RD_ENERGY_STRUCT PmDimmRdEnergy;
+ MCHBAR_CH0_CR_PM_DIMM_WR_ENERGY_STRUCT PmDimmWrEnergy;
+ TSOD_CONF_REGISTER_STRUCT TsodConfReg;
+
+ U8 h=0,i = 0, j = 0, k1 =2, k0=2 ; //h=2xRefreshMode i = Density , j = Frequency , k1 = Adjacent DIMM prescence in Channel 1, k0 = Adjacent DIMM prescence in Channel 0
+ U8 iprev = 2, hotThreshold = 0, warmThreshold=0;
+ U8 ControllerSave = CONTROLLER_NOT_LOADED;
+ const U16 *PwrWeight0 = NULL, *PwrWeight1 = NULL ;
+ U16 MtsData = 0, Thigh = 0, Tcrit = 0, Temp = 0;
+ U16 freq=0, density= 0;
+ Inputs = &MrcData->SysIn.Inputs;
+ Debug = &Inputs->Debug;
+ ThermalEnables = &Inputs->ThermalEnables;
+ Outputs = &MrcData->SysOut.Outputs;
+ TsodConfReg.Data =0;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MrcCltmInit - Start.\n");
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "EnableCltm %d EccSupport %d - \n", ThermalEnables->EnableCltm, Outputs->EccSupport);
+ if (ThermalEnables->EnableCltm && (Outputs->EccSupport == TRUE)) {
+ FirstValue = FALSE;
+ if(Outputs->CLTM_SPD_Conf == PROCESS_NOT_INITIALIZED) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE,"CLTM_SPD_Config = %u\n",Outputs->CLTM_SPD_Conf);
+ for (Controller = 0; Controller < MAX_CONTROLLERS; Controller++) {
+ // Check in every DIMM for CLTM capabilities
+ for (Channel = 0; Channel < MAX_CHANNEL; Channel++) {
+
+ if (Outputs->Controller[Controller].Channel[Channel].Status != CHANNEL_PRESENT) continue;
+
+ for (Dimm = 0; Dimm < MAX_DIMMS_IN_CHANNEL; Dimm++) {
+
+ if (Outputs->Controller[Controller].Channel[Channel].Dimm[Dimm].Status != DIMM_PRESENT) continue;
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d - Check for CLTM Capabilities\n", Channel, Dimm);
+
+ // CHECK CLTM RESTRICTIONS
+
+ // Check ECC support. Do not enable CLTM if not supported.
+ if (Outputs->Controller[Controller].Channel[Channel].Dimm[Dimm].EccSupport == FALSE) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "CLTM is Disable - Channel %d Dimm %d is non ECC - Exiting.\n", Channel, Dimm);
+ Outputs->CLTM_SPD_Conf = PROCESS_FAILED;
+ MrcCltmDisable(MrcData);
+ return;
+ }
+
+ // Check thermal sensor presence. Do not enable CLTM if no sensor.
+ if (Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].Spd.Ddr3.General.ModuleThermalSensor.Bits.ThermalSensorPresence == 0) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "CLTM is Disable - Channel %d Dimm %d do not have Thermal Sensor Incorporated - Exiting.\n", Channel, Dimm);
+ Outputs->CLTM_SPD_Conf = PROCESS_FAILED;
+ MrcCltmDisable(MrcData);
+ return;
+ }
+/*All dimms will be taken as Raw Card E
+ // Check Refernce Raw Card = E . Do not enable CLTM if no Raw Card.
+ if (Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].Spd.Ddr3.Module.Unbuffered.ReferenceRawCardUsed.Bits.Card != rcE) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d RAW Card is not E - CLTM disable.\n", Channel, Dimm);
+ Outputs->CLTM_SPD_Conf = PROCESS_FAILED;
+ MrcCltmDisable(MrcData);
+ return;
+ }
+*/
+ // Check if UDIMM. Do not enable CLTM if not UDIM
+ if (Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].Spd.Ddr3.General.ModuleType.Bits.ModuleType != MRC_UDIMM_TYPE_NUMBER) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Module Type is not UDIMM - CLTM disable.\n", Channel, Dimm);
+ Outputs->CLTM_SPD_Conf = PROCESS_FAILED;
+ MrcCltmDisable(MrcData);
+ return;
+ }
+ /* All dimms will be configure as Dual Rank and x8
+ // Check if Dual Rank. Do not enable CLTM if not Dual Rank
+ if (Outputs->Controller[Controller].Channel[Channel].Dimm[Dimm].RankInDIMM != 2) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d not Dual Rank - CLTM disable.\n", Channel, Dimm);
+ Outputs->CLTM_SPD_Conf = PROCESS_FAILED;
+ MrcCltmDisable(MrcData);
+ return;
+ }
+
+ // Check if x8. Do not enable CLTM if not x8
+ if (Outputs->Controller[Controller].Channel[Channel].Dimm[Dimm].SdramWidth != 8) {
+ Outputs->CLTM_SPD_Conf = PROCESS_FAILED;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Width is not x8 - CLTM disable.\n", Channel, Dimm);
+ MrcCltmDisable(MrcData);
+ return;
+ }
+*/
+ //switch (Outputs->Controller[Controller].Channel[Channel].Dimm[Dimm].DimmCapacity) {
+ switch (Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].Spd.Ddr3.General.SdramDensityAndBanks.Bits.Density) {
+ //case 2048:
+ case 3:
+ i = 0;
+ if(FirstValue == FALSE) { iprev = i; }
+ if(iprev != i) {
+ //MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Capacity is 2Gb and different from other previous DIMM - CLTM disable\n", Channel, Dimm);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Density is 2Gb and different from other previous DIMM - configure as 4Gb\n", Channel, Dimm);
+ i = 1;
+ }
+ iprev =i;
+ //MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Capacity is 2Gb\n", Channel, Dimm);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Density is 2Gb\n", Channel, Dimm);
+ break;
+ //case 4096:
+ case 4:
+ i = 1;
+ if(FirstValue == FALSE) { iprev = i; }
+ if(iprev != i) {
+ //MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Capacity is 4Gb and different from other previous DIMM\n", Channel, Dimm);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Density is 4Gb and different from other previous DIMM\n", Channel, Dimm);
+ i = 1;
+ }
+ iprev =i;
+ //MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Capacity is 4Gb\n", Channel, Dimm);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Density is 4Gb\n", Channel, Dimm);
+ break;
+ default:
+ //MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Capacity is different than 4Gb and 2GB - CLTM disable \n", Channel, Dimm);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Density is different than 4Gb and 2GB \n", Channel, Dimm);
+ i = 1;
+ iprev =i;
+ break;
+ }
+
+ if (Outputs->Controller[Controller].Channel[Channel].DimmCount > 1) {
+ if(Channel == 0) {k0 = 1;}
+ else{k1=1;}
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Adjacent DIMM next to Dimm %d in Channel %d.\n", Dimm, Channel);
+ }
+ else {
+ if(Channel == 0) {k0 = 0;}
+ else{k1=0;}
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "No adjacent DIMM next to Dimm %d in Channel %d.\n", Dimm, Channel);
+ }
+
+ // Check if DIMM supports dual refresh
+ if (((Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].Spd.Ddr3.General.ThermalAndRefreshOptions.Data & (MRC_BIT1 | MRC_BIT0)) == MRC_BIT0)) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Supports 2x Self Refresh\n", Channel, Dimm);
+ } else {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d DO NOT Support 2x Self Refresh\n", Channel, Dimm);
+ ThermalEnables->Refresh2X = DISABLE_REFRESH2X;
+
+ }
+ h = ThermalEnables->Refresh2X;
+ FirstValue = TRUE;
+ } //for (Dimm = 0; Dimm < MAX_DIMMS_IN_CHANNEL; Dimm++)
+ } //for (Channel = 0; Channel < MAX_CHANNEL; Channel++)
+ }// for Controller
+
+ //Frequency calculated from Common Memory Controller Frequency
+ switch (Outputs->Frequency) {
+ case f1600:
+ j = 0;
+ break;
+ case f1333:
+ j = 1;
+ break;
+ default:
+ j=0;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MC Frequency is other than 1600 and 1333 - CLTM configure as 1600 .\n");
+ break;
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE,"CLTM_SPD_Config check has finished for first time\n");
+ }
+
+ if((Outputs->CLTM_SPD_Conf != PROCESS_FAILED) && (Outputs->CLTM_SPD_Conf != PROCESS_NOT_INITIALIZED) )
+ {
+ h = (((Outputs->CLTM_SPD_Conf)& (0x0300))>> 8); // mask with 0000 0011 0000 0000 and shift right 8, 2xRefreshMode
+ i = (((Outputs->CLTM_SPD_Conf)& (0x00C0))>> 6); // mask with 0000 0000 1100 0000 and shift right 6, Density index
+ j = (((Outputs->CLTM_SPD_Conf)& (0x0030))>> 4); // mask with 0000 0000 0011 0000 and shift right 4, Frequency
+ k1 = (((Outputs->CLTM_SPD_Conf)& (0x000C))>> 2); //mask 0000 0000 0000 1100 and shift right 2, Adjacent DIMM prescence of channel 1
+ k0 = ((Outputs->CLTM_SPD_Conf)& 0x0003);//mask with 0000 0000 0000 0011, Adjacent DIMM prescence of channel 0
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE,"DIMM variables: 2xRefresh Support, frequency , adjacent, density has been initialized. \n ");
+ }
+ else if (Outputs->CLTM_SPD_Conf == PROCESS_FAILED)
+ {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "CLTM_SPD_Config already executed and Failed\n");
+ MrcCltmDisable(MrcData);
+ return;
+ }
+
+ Outputs->CLTM_SPD_Conf = (h << 8)+ (i << 6) + (j<<4) + (k1<<2) + k0;
+ (i == 0)? (density = 2) : (density = 4);
+ (j == 0)? (freq = 1600) : (freq = 1333);
+
+
+ if ( ((k0==0)||(k0==1)) && ((k1==0)||(k1==1)) ){
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE,"CLTM_SPD_Config interpret = \n 2xRefresh Support = %d , density = 2GB%d, frequency=%d, \n Channel 1 adjacent DIMM=%d, Channel 0 Adjacent DIMM =%d \n",h,density,freq,k1,k0);
+ }
+ else if (k1==2) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE,"CLTM_SPD_Config interpret = \n 2xRefresh Support = %d ,density index=%d, frequency=%d, \n Channel 0 Adjacent DIMM =%d \n",h,density,freq,k0);
+ }
+ else if (k0==2) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE,"CLTM_SPD_Config interpret = \n 2xRefresh Support = %d ,density index=%d, frequency =%d, \n Channel 1 Adjacent DIMM =%d \n",h,density,freq,k1);
+ }
+ else{
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE,"CLTM_SPD_Config interpret incorrectly k1=%d, or k0=%d are incorrect \n",k1,k0);
+ Outputs->CLTM_SPD_Conf = PROCESS_FAILED;
+ MrcCltmDisable(MrcData);
+ return;
+ }
+
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE,"CLTM_SPD_Config = %u\n",Outputs->CLTM_SPD_Conf);
+
+ //Configuration Register of TSOD
+ TsodConfReg.Bits.EVENT_MODE = ThermalEnables->TSOD_EventMode;//Default 1, Interrupt
+ TsodConfReg.Bits.EVENT_POLARITY = ThermalEnables->TSOD_EventPolarity;//Default 0, Low
+ TsodConfReg.Bits.CRICAL_EVENT_ONLY = ThermalEnables->TSOD_CriticalEventOnly;//Default 1, Enable
+ TsodConfReg.Bits.EVENT_OUTPUT_CONTROL = ThermalEnables->TSOD_EventOutputControl; //Default 1, Enable
+ TsodConfReg.Bits.ALARM_WINDOW_LOCK = ThermalEnables->TSOD_AlarmwindowLockBit; //Default 0, Unlock
+ TsodConfReg.Bits.CRITICAL_LOCK = ThermalEnables->TSOD_CriticaltripLockBit; //Default 0, Unlock
+ TsodConfReg.Bits.SHUTDOWNMODE = ThermalEnables->TSOD_ShutdownMode; // Default 0, TSOD Enable
+ TsodConfReg.Bits.HYST_ENABLE = HYST_DISABLE;
+
+
+ DdrWarmThresholdCh0.Data = 0;
+ DdrWarmThresholdCh1.Data = 0;
+ DdrHotThresholdCh0.Data = 0;
+ DdrHotThresholdCh1.Data = 0;
+
+ if (!ThermalEnables->UserThresholdEn) {//Configuration of warm and hot threshold depending of single or dual refresh
+ if(h != DISABLE_REFRESH2X ) {
+ warmThreshold = ( WarmThreshold_2X_MAX_TEMP );
+ hotThreshold = ( HotThreshold_2X_MAX_TEMP );
+
+ }
+ else{
+ warmThreshold = ( WarmThreshold_1X_MAX_TEMP );
+ hotThreshold = ( HotThreshold_1X_MAX_TEMP );
+
+ }
+ }
+
+ for (Controller = 0; Controller < MAX_CONTROLLERS; Controller++) {
+ for (Channel = 0; Channel < MAX_CHANNEL; Channel++) {
+
+ //OffsetChannel[Channel] = 0;
+
+ if (Outputs->Controller[Controller].Channel[Channel].Status != CHANNEL_PRESENT) continue;
+
+ for (Dimm = 0; Dimm < MAX_DIMMS_IN_CHANNEL; Dimm++) {
+
+ OffsetDimm[Dimm] = 0;
+ if (Outputs->Controller[Controller].Channel[Channel].Dimm[Dimm].Status != DIMM_PRESENT) continue;
+ ControllerSave = Controller;
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "CLTM Configuration for Channel %d Dimm %d\n", Channel, Dimm);
+
+ // Get offset temperature
+ (Channel ==0) ? (OffsetDimm[Dimm] = CltmThermalLookUpTable[i][j][k0][ThermalEnables->Altitude]): (OffsetDimm[Dimm] = CltmThermalLookUpTable[i][j][k1][ThermalEnables->Altitude]);
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Offset = %d degreeC\n", OffsetDimm[Dimm]);
+
+ if (ThermalEnables->TSOD_ManEn) {
+ Thigh = ((ThermalEnables->TSOD_ThigMax) << 4);
+ Tcrit = ((ThermalEnables->TSOD_TcritMax) << 4);
+
+ }
+ else{
+ Tcrit = (( (CRITICAL_TEMP) - OffsetDimm[Dimm]) << 4);
+ if(h != DISABLE_REFRESH2X ) {
+ Thigh = (( (THOT_2X_MAX_TEMP) - OffsetDimm[Dimm]) << 4);
+ }
+ else{
+ Thigh = (( (THOT_1X_MAX_TEMP) - OffsetDimm[Dimm]) << 4);
+ }
+
+ }
+
+ // SPD Thermal sensor registers Configurations Begin
+ //((SpdDeviceAddress & 0x0F) | THERMAL_MODULE_MASK )
+ //Thermal Sensor Information
+ // MFG ID
+ if (MrcOemSmbusRead16 (Inputs->SmbusBaseAddress, ((Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].SpdAddress & 0x0F) | THERMAL_MODULE_MASK ), MTS_MFGID, &MtsData) == mrcFail) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Error - Channel %d Dimm %d Temp Sensor NACK\n", Channel, Dimm);
+ } else {
+ Temp = (((MtsData & 0xFF00) >> 8) | ((MtsData & 0x00FF) << 8));
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Temp Sensor Mfg Id = 0x%04X\n", Channel, Dimm, Temp);
+ }
+
+ // SPD thermal sensor DEV ID
+
+ if (MrcOemSmbusRead16 (Inputs->SmbusBaseAddress, ((Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].SpdAddress & 0x0F) | THERMAL_MODULE_MASK ) , MTS_DID, &MtsData) == mrcFail) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Error - Channel %d Dimm %d Temp Sensor NACK\n", Channel, Dimm);
+ } else {
+ Temp = (((MtsData & 0xFF00) >> 8) | ((MtsData & 0x00FF) << 8));
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Channel %d Dimm %d Temp Sensor Dev/Rev Id = 0x%04X\n", Channel, Dimm, Temp);
+ }
+
+ // Configuration Register // Disabling Configuration Register
+ MtsData = 0;
+ Temp = (((MtsData & 0xFF00) >> 8) | ((MtsData & 0x00FF) << 8));
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Thermal Sensor Configuration value to be programmed into TS2002 is 0x%X\n", Temp);
+ MrcOemSmbusWrite16 (Inputs->SmbusBaseAddress, ((Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].SpdAddress & 0x0F) | THERMAL_MODULE_MASK ), MTS_CFG, Temp);
+ MrcOemSmbusRead16 (Inputs->SmbusBaseAddress, ((Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].SpdAddress & 0x0F) | THERMAL_MODULE_MASK ), MTS_CFG, &MtsData);
+ Temp = (((MtsData & 0xFF00) >> 8) | ((MtsData & 0x00FF) << 8));
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Thermal Sensor Configuration value read from TS2002 is 0x%X\n", MtsData);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Thermal Sensor Configuration value is 0x%X\n", Temp);
+
+ // THigh 0x02
+
+ Temp = (((Thigh & 0xFF00) >> 8) | ((Thigh & 0x00FF) << 8));
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "High Temp value is 0x%X = %d degreeC\n", Thigh, (Thigh >> 4));
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "High Temp value to be programmed into TS2002 is 0x%X\n", Temp);
+ MrcOemSmbusWrite16 (Inputs->SmbusBaseAddress, ((Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].SpdAddress & 0x0F) | THERMAL_MODULE_MASK ), MTS_THIGH, Temp);
+ MrcOemSmbusRead16 (Inputs->SmbusBaseAddress, ((Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].SpdAddress & 0x0F) | THERMAL_MODULE_MASK ), MTS_THIGH, &Thigh);
+ Temp = (((Thigh & 0xFF00) >> 8) | ((Thigh & 0x00FF) << 8));
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "High Temp value read from TS2002 is 0x%X\n", Thigh);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "High Temp value is 0x%X = %d degreeC\n", Temp, (Temp >> 4));
+
+
+ // TCrit 0x04
+ Temp = (((Tcrit & 0xFF00) >> 8) | ((Tcrit & 0x00FF) << 8));
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Critical Temp value is 0x%X = %d degreeC\n", Tcrit, (Tcrit >> 4));
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Critical Temp value to be programmed into TS2002 is 0x%X\n", Temp);
+ MrcOemSmbusWrite16 (Inputs->SmbusBaseAddress, ((Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].SpdAddress & 0x0F) | THERMAL_MODULE_MASK ), MTS_TCRIT, Temp);
+ MrcOemSmbusRead16 (Inputs->SmbusBaseAddress, ((Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].SpdAddress & 0x0F) | THERMAL_MODULE_MASK ), MTS_TCRIT, &Tcrit);
+ Temp = (((Tcrit & 0xFF00) >> 8) | ((Tcrit & 0x00FF) << 8));
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Critical Temp value read from TS2002 is 0x%X\n", Tcrit);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Critical Temp value is 0x%X = %d degreeC\n", Temp, (Temp >> 4));
+
+ // Configuration Register
+ MtsData = TsodConfReg.Data;
+ Temp = (((MtsData & 0xFF00) >> 8) | ((MtsData & 0x00FF) << 8));
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Thermal Sensor Configuration value is 0x%X\n", MtsData);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Thermal Sensor Configuration value to be programmed into TS2002 is 0x%X\n", Temp);
+ MrcOemSmbusWrite16 (Inputs->SmbusBaseAddress, ((Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].SpdAddress & 0x0F) | THERMAL_MODULE_MASK ), MTS_CFG, Temp);
+ MrcOemSmbusRead16 (Inputs->SmbusBaseAddress, ((Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].SpdAddress & 0x0F) | THERMAL_MODULE_MASK ), MTS_CFG, &MtsData);
+ Temp = (((MtsData & 0xFF00) >> 8) | ((MtsData & 0x00FF) << 8));
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Thermal Sensor Configuration value read from TS2002 is 0x%X\n", MtsData);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Thermal Sensor Configuration value is 0x%X\n", Temp);
+ // SPD thermal sensor registers Configurations End
+
+ //Read current temperature of the TSOD 0x05
+ MrcOemSmbusRead16 (Inputs->SmbusBaseAddress, ((Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].SpdAddress & 0x0F) | THERMAL_MODULE_MASK ), TEMPERATURE_REGISTER, &Thigh);
+ Temp = (((Thigh & 0xFF00) >> 8) | ((Thigh & 0x001F) << 8));//This will get rid of the firt three bits of the register and hold only the themperatur value
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "SMBUS base Address is 0x%X\n", Inputs->SmbusBaseAddress);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "SPD address offset 0x%X of Channel:%d DIMM:%d \n", Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].SpdAddress & 0x0F, Channel, Dimm);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Module thermal SPD address 0x%X of Channel:%d DIMM:%d\n", ((Inputs->Controller[Controller].Channel[Channel].Dimm[Dimm].SpdAddress & 0x0F) | THERMAL_MODULE_MASK ), Channel, Dimm);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Offset to temperature register 0x%X\n", TEMPERATURE_REGISTER );
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Temperature register value read from TS2002 is 0x%X\n", Thigh);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "Current TSOD Temperatur value is 0x%X = %d degreeC\n", Temp, (Temp >> 4));
+
+ //Warm and hot threshold Configuration begin
+ if(!ThermalEnables->UserThresholdEn) {
+
+ if((Channel ==0)&& (Dimm == 0) ) {
+ DdrWarmThresholdCh0.Bits.DIMM0 = warmThreshold;
+ DdrHotThresholdCh0.Bits.DIMM0 = hotThreshold;
+ }
+ if((Channel ==0)&& (Dimm == 1) ) {
+ DdrWarmThresholdCh0.Bits.DIMM1 = warmThreshold;
+ DdrHotThresholdCh0.Bits.DIMM1 = hotThreshold;
+ }
+
+ if((Channel ==1)&& (Dimm == 0) ) {
+ DdrWarmThresholdCh1.Bits.DIMM0 = warmThreshold;
+ DdrHotThresholdCh1.Bits.DIMM0 = hotThreshold;
+ }
+
+ if((Channel ==1)&& (Dimm == 1) ) {
+ DdrWarmThresholdCh1.Bits.DIMM1 = warmThreshold;
+ DdrHotThresholdCh1.Bits.DIMM1 = hotThreshold;
+ }
+
+ }//Warm and hot threshold Configuration End
+
+
+
+ } //for (Dimm = 0; Dimm < MAX_DIMMS_IN_CHANNEL; Dimm++)
+
+ } //for (Channel = 0; Channel < MAX_CHANNEL; Channel++)
+ } // for Controller
+
+ if(!ThermalEnables->UserThresholdEn) {//Warm and hot threshold Write Registers begin
+
+ MrcWriteCR (MrcData, PCU_CR_DDR_WARM_THRESHOLD_CH0_PCU_REG, DdrWarmThresholdCh0.Data);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "DDR_WARM_THRESHOLD_CH0 %Xh: %Xh \n", PCU_CR_DDR_WARM_THRESHOLD_CH0_PCU_REG, MrcReadCR (MrcData, PCU_CR_DDR_WARM_THRESHOLD_CH0_PCU_REG));
+
+ MrcWriteCR (MrcData, PCU_CR_DDR_HOT_THRESHOLD_CH0_PCU_REG, DdrHotThresholdCh0.Data);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "DDR_HOT_THRESHOLD_CH0 %Xh: %Xh \n", PCU_CR_DDR_HOT_THRESHOLD_CH0_PCU_REG, MrcReadCR (MrcData, PCU_CR_DDR_HOT_THRESHOLD_CH0_PCU_REG));
+
+ MrcWriteCR (MrcData, PCU_CR_DDR_WARM_THRESHOLD_CH1_PCU_REG, DdrWarmThresholdCh1.Data);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "DDR_WARM_THRESHOLD_CH1 %Xh: %Xh \n", PCU_CR_DDR_WARM_THRESHOLD_CH1_PCU_REG, MrcReadCR (MrcData, PCU_CR_DDR_WARM_THRESHOLD_CH1_PCU_REG));
+
+ MrcWriteCR (MrcData, PCU_CR_DDR_HOT_THRESHOLD_CH1_PCU_REG, DdrHotThresholdCh1.Data);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "DDR_HOT_THRESHOLD_CH1 %Xh: %Xh \n", PCU_CR_DDR_HOT_THRESHOLD_CH1_PCU_REG, MrcReadCR (MrcData, PCU_CR_DDR_HOT_THRESHOLD_CH1_PCU_REG));
+
+
+ }//Warm and hot threshold threshold Write Register End
+
+
+
+
+ ASSERT (ControllerSave != CONTROLLER_NOT_LOADED ); //If no controller is Save The system asserts
+
+
+ if(!ThermalEnables->UserPowerWeightsEn) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "UP Server overriding Power weight Energy registers...\n");
+ DdrEnergyScaleFactor.Data = 0;
+
+ if((k0==0)||(k0==1)) {
+ PwrWeight0 = &CltmPowerLookUpTable[i][j][k0][0];
+ ASSERT(PwrWeight0 != NULL);//If PwrWeight0 is Null the system asserts.
+ DdrEnergyScaleFactor.Bits.SCALEFACTOR = *PwrWeight0;
+ }
+ if((k1==0)||(k1==1)) {
+ PwrWeight1 = &CltmPowerLookUpTable[i][j][k1][0];
+ ASSERT(PwrWeight1 != NULL);//If PwrWeight1 is Null the system asserts.
+ DdrEnergyScaleFactor.Bits.SCALEFACTOR = *PwrWeight1;
+ }
+
+ if ( ((k0==0)||(k0==1)) && ((k1==0)||(k1==1))) {
+ (k0 >= k1) ? (DdrEnergyScaleFactor.Bits.SCALEFACTOR = *PwrWeight0) : (DdrEnergyScaleFactor.Bits.SCALEFACTOR = *PwrWeight1);
+ }
+
+
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "DDR_ENERGY_SCALEFACTOR %Xh: %Xh \n", PCU_CR_DDR_ENERGY_SCALEFACTOR_PCU_REG, DdrEnergyScaleFactor.Data);
+ MrcWriteCR (MrcData, PCU_CR_DDR_ENERGY_SCALEFACTOR_PCU_REG, DdrEnergyScaleFactor.Data);
+
+
+ if((k0==0)||(k0==1)) {PwrWeight0++;}
+ if((k1==0)||(k1==1)) {PwrWeight1++;}
+
+ PmDimmRdEnergy.Data = 0;
+
+ if ((k0==0)||(k0==1)){
+ if (Outputs->Controller[ControllerSave].Channel[0].Dimm[0].Status == DIMM_PRESENT){
+ PmDimmRdEnergy.Bits.DIMM0_RD_ENERGY = *PwrWeight0;
+ }
+ if (Outputs->Controller[ControllerSave].Channel[0].Dimm[1].Status == DIMM_PRESENT){
+ PmDimmRdEnergy.Bits.DIMM1_RD_ENERGY = *PwrWeight0;
+ }
+
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MCHBAR_CH0_CR_PM_DIMM_RD_ENERGY_REG %Xh: %Xh \n", MCHBAR_CH0_CR_PM_DIMM_RD_ENERGY_REG, PmDimmRdEnergy.Data);
+ MrcWriteCR (MrcData, MCHBAR_CH0_CR_PM_DIMM_RD_ENERGY_REG, PmDimmRdEnergy.Data);
+
+
+ PmDimmRdEnergy.Data = 0;
+
+ if ((k1==0)||(k1==1)){
+ if (Outputs->Controller[ControllerSave].Channel[1].Dimm[0].Status == DIMM_PRESENT){
+ PmDimmRdEnergy.Bits.DIMM0_RD_ENERGY = *PwrWeight1;
+
+ }
+ if (Outputs->Controller[ControllerSave].Channel[1].Dimm[1].Status == DIMM_PRESENT){
+ PmDimmRdEnergy.Bits.DIMM1_RD_ENERGY = *PwrWeight1;
+ }
+
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MCHBAR_CH1_CR_PM_DIMM_RD_ENERGY_REG %Xh: %Xh \n", MCHBAR_CH1_CR_PM_DIMM_RD_ENERGY_REG, PmDimmRdEnergy.Data);
+ MrcWriteCR (MrcData, MCHBAR_CH1_CR_PM_DIMM_RD_ENERGY_REG, PmDimmRdEnergy.Data);
+
+ if((k0==0)||(k0==1)) {PwrWeight0++;}
+ if((k1==0)||(k1==1)) {PwrWeight1++;}
+ PmDimmWrEnergy.Data = 0;
+
+ if ((k0==0)||(k0==1)){
+ if (Outputs->Controller[ControllerSave].Channel[0].Dimm[0].Status == DIMM_PRESENT){
+ PmDimmWrEnergy.Bits.DIMM0_WR_ENERGY = *PwrWeight0;
+ }
+ if (Outputs->Controller[ControllerSave].Channel[0].Dimm[1].Status == DIMM_PRESENT){
+ PmDimmWrEnergy.Bits.DIMM1_WR_ENERGY = *PwrWeight0;
+ }
+
+ }
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MCHBAR_CH0_CR_PM_DIMM_WR_ENERGY_REG %Xh: %Xh \n", MCHBAR_CH0_CR_PM_DIMM_WR_ENERGY_REG, PmDimmWrEnergy.Data);
+ MrcWriteCR (MrcData, MCHBAR_CH0_CR_PM_DIMM_WR_ENERGY_REG, PmDimmWrEnergy.Data);
+
+ PmDimmWrEnergy.Data = 0;
+
+ if ((k1==0)||(k1==1)){
+ if (Outputs->Controller[ControllerSave].Channel[1].Dimm[0].Status == DIMM_PRESENT){
+ PmDimmWrEnergy.Bits.DIMM0_WR_ENERGY = *PwrWeight1;
+
+ }
+ if (Outputs->Controller[ControllerSave].Channel[1].Dimm[1].Status == DIMM_PRESENT){
+ PmDimmWrEnergy.Bits.DIMM1_WR_ENERGY = *PwrWeight1;
+ }
+
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MCHBAR_CH1_CR_PM_DIMM_WR_ENERGY_REG %Xh: %Xh \n", MCHBAR_CH1_CR_PM_DIMM_WR_ENERGY_REG, PmDimmWrEnergy.Data);
+ MrcWriteCR (MrcData, MCHBAR_CH1_CR_PM_DIMM_WR_ENERGY_REG, PmDimmWrEnergy.Data);
+
+ if((k0==0)||(k0==1)) {PwrWeight0++;}
+ if((k1==0)||(k1==1)) {PwrWeight1++;}
+ PmDimmActEnergy.Data = 0;
+ if ((k0==0)||(k0==1)){
+ if (Outputs->Controller[ControllerSave].Channel[0].Dimm[0].Status == DIMM_PRESENT){
+ PmDimmActEnergy.Bits.DIMM0_ACT_ENERGY = *PwrWeight0;
+ }
+ if (Outputs->Controller[ControllerSave].Channel[0].Dimm[1].Status == DIMM_PRESENT){
+ PmDimmActEnergy.Bits.DIMM1_ACT_ENERGY = *PwrWeight0;
+ }
+
+ }
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MCHBAR_CH0_CR_PM_DIMM_ACT_ENERGY_REG %Xh: %Xh \n", MCHBAR_CH0_CR_PM_DIMM_ACT_ENERGY_REG, PmDimmActEnergy.Data);
+ MrcWriteCR (MrcData, MCHBAR_CH0_CR_PM_DIMM_ACT_ENERGY_REG, PmDimmActEnergy.Data);
+
+ PmDimmActEnergy.Data = 0;
+ if ((k1==0)||(k1==1)){
+ if (Outputs->Controller[ControllerSave].Channel[1].Dimm[0].Status == DIMM_PRESENT){
+ PmDimmActEnergy.Bits.DIMM0_ACT_ENERGY = *PwrWeight1;
+ }
+ if (Outputs->Controller[ControllerSave].Channel[1].Dimm[1].Status == DIMM_PRESENT){
+ PmDimmActEnergy.Bits.DIMM1_ACT_ENERGY = *PwrWeight1;
+ }
+
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MCHBAR_CH1_CR_PM_DIMM_ACT_ENERGY_REG %Xh: %Xh \n", MCHBAR_CH1_CR_PM_DIMM_ACT_ENERGY_REG, PmDimmActEnergy.Data);
+ MrcWriteCR (MrcData, MCHBAR_CH1_CR_PM_DIMM_ACT_ENERGY_REG, PmDimmActEnergy.Data);
+
+ if((k0==0)||(k0==1)) {PwrWeight0++;}
+ if((k1==0)||(k1==1)) {PwrWeight1++;}
+ PmDimmIdleEnergy.Data = 0;
+ if ((k0==0)||(k0==1)){
+ if (Outputs->Controller[ControllerSave].Channel[0].Dimm[0].Status == DIMM_PRESENT){
+ PmDimmIdleEnergy.Bits.DIMM0_IDLE_ENERGY = *PwrWeight0;
+ }
+ if (Outputs->Controller[ControllerSave].Channel[0].Dimm[1].Status == DIMM_PRESENT){
+ PmDimmIdleEnergy.Bits.DIMM1_IDLE_ENERGY = *PwrWeight0;
+ }
+
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MCHBAR_CH0_CR_PM_DIMM_IDLE_ENERGY_REG %Xh: %Xh \n", MCHBAR_CH0_CR_PM_DIMM_IDLE_ENERGY_REG, PmDimmIdleEnergy.Data);
+ MrcWriteCR (MrcData, MCHBAR_CH0_CR_PM_DIMM_IDLE_ENERGY_REG, PmDimmIdleEnergy.Data);
+
+ PmDimmIdleEnergy.Data = 0;
+ if ((k1==0)||(k1==1)){
+ if (Outputs->Controller[ControllerSave].Channel[1].Dimm[0].Status == DIMM_PRESENT){
+ PmDimmIdleEnergy.Bits.DIMM0_IDLE_ENERGY = *PwrWeight1;
+ }
+ if (Outputs->Controller[ControllerSave].Channel[1].Dimm[1].Status == DIMM_PRESENT){
+ PmDimmIdleEnergy.Bits.DIMM1_IDLE_ENERGY = *PwrWeight1;
+ }
+
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MCHBAR_CH1_CR_PM_DIMM_IDLE_ENERGY_REG %Xh: %Xh \n", MCHBAR_CH1_CR_PM_DIMM_IDLE_ENERGY_REG, PmDimmIdleEnergy.Data);
+ MrcWriteCR (MrcData, MCHBAR_CH1_CR_PM_DIMM_IDLE_ENERGY_REG, PmDimmIdleEnergy.Data);
+
+ if((k0==0)||(k0==1)) {PwrWeight0++;}
+ if((k1==0)||(k1==1)) {PwrWeight1++;}
+ PmDimmPdEnergy.Data = 0;
+ if ((k0==0)||(k0==1)){
+ if (Outputs->Controller[ControllerSave].Channel[0].Dimm[0].Status == DIMM_PRESENT){
+ PmDimmPdEnergy.Bits.DIMM0_PD_ENERGY = *PwrWeight0;
+ }
+ if (Outputs->Controller[ControllerSave].Channel[0].Dimm[1].Status == DIMM_PRESENT){
+ PmDimmPdEnergy.Bits.DIMM1_PD_ENERGY = *PwrWeight0;
+ }
+
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MCHBAR_CH0_CR_PM_DIMM_PD_ENERGY_REG %Xh: %Xh \n", MCHBAR_CH0_CR_PM_DIMM_PD_ENERGY_REG, PmDimmPdEnergy.Data);
+ MrcWriteCR (MrcData, MCHBAR_CH0_CR_PM_DIMM_PD_ENERGY_REG, PmDimmPdEnergy.Data);
+
+ PmDimmPdEnergy.Data = 0;
+ if ((k1==0)||(k1==1)){
+ if (Outputs->Controller[ControllerSave].Channel[1].Dimm[0].Status == DIMM_PRESENT){
+ PmDimmPdEnergy.Bits.DIMM0_PD_ENERGY = *PwrWeight1;
+ }
+ if (Outputs->Controller[ControllerSave].Channel[1].Dimm[1].Status == DIMM_PRESENT){
+ PmDimmPdEnergy.Bits.DIMM1_PD_ENERGY = *PwrWeight1;
+ }
+
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MCHBAR_CH1_CR_PM_DIMM_PD_ENERGY_REG %Xh: %Xh \n", MCHBAR_CH1_CR_PM_DIMM_PD_ENERGY_REG, PmDimmPdEnergy.Data);
+ MrcWriteCR (MrcData, MCHBAR_CH1_CR_PM_DIMM_PD_ENERGY_REG, PmDimmPdEnergy.Data);
+
+ }
+
+ if(!ThermalEnables->UserBudgetEn) {
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "UP Server Overriding Power budget registers...\n");
+
+ if((k0==0)||(k0==1)) {
+ PwrWeight0 = &CltmPowerLookUpTable[i][j][k0][0];
+ PwrWeight0 = PwrWeight0 + WARM_BUDGET_POSITION;
+ ASSERT(PwrWeight0 != NULL);//If PwrWeight0 is Null the system asserts.
+
+ }
+ if((k1==0)||(k1==1)) {
+ PwrWeight1 = &CltmPowerLookUpTable[i][j][k1][0];
+ PwrWeight1 = PwrWeight1 + WARM_BUDGET_POSITION;
+ ASSERT(PwrWeight1 != NULL);//If PwrWeight1 is Null the system asserts.
+
+ }
+
+ DdrWarmBudgetCh0.Data = 0;
+ if ((k0==0)||(k0==1)){
+ if (Outputs->Controller[ControllerSave].Channel[0].Dimm[0].Status == DIMM_PRESENT){
+ DdrWarmBudgetCh0.Bits.DIMM0 = *PwrWeight0;
+ }
+ if (Outputs->Controller[ControllerSave].Channel[0].Dimm[1].Status == DIMM_PRESENT){
+ DdrWarmBudgetCh0.Bits.DIMM1 = *PwrWeight0;
+ }
+
+ }
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "DDR_WARM_BUDGET_CH0 %Xh: %Xh \n", PCU_CR_DDR_WARM_BUDGET_CH0_PCU_REG, DdrWarmBudgetCh0.Data);
+ MrcWriteCR (MrcData, PCU_CR_DDR_WARM_BUDGET_CH0_PCU_REG, DdrWarmBudgetCh0.Data);
+
+ DdrWarmBudgetCh1.Data = 0;
+ if ((k1==0)||(k1==1)){
+ if (Outputs->Controller[ControllerSave].Channel[1].Dimm[0].Status == DIMM_PRESENT){
+ DdrWarmBudgetCh1.Bits.DIMM0 = *PwrWeight1;
+ }
+ if (Outputs->Controller[ControllerSave].Channel[1].Dimm[1].Status == DIMM_PRESENT){
+ DdrWarmBudgetCh1.Bits.DIMM1 = *PwrWeight1;
+ }
+
+ }
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "DDR_WARM_BUDGET_CH1 %Xh: %Xh \n", PCU_CR_DDR_WARM_BUDGET_CH1_PCU_REG, DdrWarmBudgetCh1.Data);
+ MrcWriteCR (MrcData, PCU_CR_DDR_WARM_BUDGET_CH1_PCU_REG, DdrWarmBudgetCh1.Data);
+
+ if((k0==0)||(k0==1)) {PwrWeight0++;}
+ if((k1==0)||(k1==1)) {PwrWeight1++;}
+ DdrHotBudgetCh0.Data = 0;
+ if ((k0==0)||(k0==1)){
+ if (Outputs->Controller[ControllerSave].Channel[0].Dimm[0].Status == DIMM_PRESENT){
+ DdrHotBudgetCh0.Bits.DIMM0 = *PwrWeight0;
+ }
+ if (Outputs->Controller[ControllerSave].Channel[0].Dimm[1].Status == DIMM_PRESENT){
+ DdrHotBudgetCh0.Bits.DIMM1 = *PwrWeight0;
+ }
+
+ }
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "DDR_HOT_BUDGET_CH0 %Xh: %Xh \n", PCU_CR_DDR_HOT_BUDGET_CH0_PCU_REG, DdrHotBudgetCh0.Data);
+ MrcWriteCR (MrcData, PCU_CR_DDR_HOT_BUDGET_CH0_PCU_REG, DdrHotBudgetCh0.Data);
+
+ DdrHotBudgetCh1.Data = 0;
+
+ if ((k1==0)||(k1==1)){
+ if (Outputs->Controller[ControllerSave].Channel[1].Dimm[0].Status == DIMM_PRESENT){
+ DdrHotBudgetCh1.Bits.DIMM0 = *PwrWeight1;
+ }
+ if (Outputs->Controller[ControllerSave].Channel[1].Dimm[1].Status == DIMM_PRESENT){
+ DdrHotBudgetCh1.Bits.DIMM1 = *PwrWeight1;
+ }
+
+ }
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "DDR_HOT_BUDGET_CH1 %Xh: %Xh \n", PCU_CR_DDR_HOT_BUDGET_CH1_PCU_REG, DdrHotBudgetCh1.Data);
+ MrcWriteCR (MrcData, PCU_CR_DDR_HOT_BUDGET_CH1_PCU_REG, DdrHotBudgetCh1.Data);
+
+ }
+
+
+ //
+ // POWER THERMAL MANAGEMENT CONTROL
+ //
+ DdrPtmCtl.Data = MrcReadCR (MrcData, PCU_CR_DDR_PTM_CTL_PCU_REG);
+ DdrPtmCtl.Bits.OLTM_ENABLE = ThermalEnables->EnableOltm;//Disable , 0, Not available for UP Platforms
+ DdrPtmCtl.Bits.CLTM_ENABLE = ThermalEnables->EnableCltm;//Default 1
+ DdrPtmCtl.Bits.REFRESH_2X_MODE = ThermalEnables->Refresh2X;//Default 1, REFRESH_2X_WARM_HOT if dimm do not support then equals 0
+ /*
+ DdrPtmCtl.Bits.EXTTS_ENABLE = ThermalEnables->EnableExtts;//Default 0
+ DdrPtmCtl.Bits.PDWN_CONFIG_CTL = ThermalEnables->EnablePwrDn;//Default 1, BIOS is in control of powednmodes
+
+ //DdrPtmCtl.Bits.DISABLE_DRAM_TS = !ThermalEnables->LpddrThermalSensor; //If not ULT this is disable or Value 1
+ */
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "DDR_PTM_CTL %Xh to program: %Xh \n", PCU_CR_DDR_PTM_CTL_PCU_REG, DdrPtmCtl.Data);
+ MrcWriteCR (MrcData, PCU_CR_DDR_PTM_CTL_PCU_REG, DdrPtmCtl.Data);
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "DDR_PTM_CTL %Xh: %Xh \n", PCU_CR_DDR_PTM_CTL_PCU_REG, MrcReadCR (MrcData, PCU_CR_DDR_PTM_CTL_PCU_REG));
+
+
+ } else {
+ //
+ // POWER THERMAL MANAGEMENT CONTROL
+ //
+ Outputs->CLTM_SPD_Conf = PROCESS_FAILED;
+ MrcCltmDisable(MrcData);
+ return;
+
+
+ }
+
+ MRC_DEBUG_MSG (Debug, MSG_LEVEL_NOTE, "MrcCltmInit - End.\n");
+
+}
+#endif // AMI_OVERRIDE_FOR_UPSERVER_SUPPORT