vc/amd/agesa/f.../Proc/Mem/Tech/DDR3: Support a custom memory profile

The ability to set up a custom memory profile is useful if you don't
like the XMP memory profiles (if they exist) of your RAM sticks, or
want to try some overclocking. Read SPD data will be overriden by your
custom values. Tested on Crucial BLT8G3D1869DT1TX0 (1866MHz 9-9-9-27).

Signed-off-by: Mike Banon <mikebdp2@gmail.com>
Change-Id: I1238ff00ef0efd11ea807794827476c30ac98065
Reviewed-on: https://review.coreboot.org/c/coreboot/+/40489
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Reviewed-by: Frans Hendriks <fhendriks@eltan.com>
This commit is contained in:
Mike Banon 2020-04-17 14:56:42 +03:00 committed by Patrick Georgi
parent 3ee9935f63
commit f7b410d409
10 changed files with 337 additions and 3 deletions

View File

@ -25,4 +25,117 @@ config CPU_AMD_AGESA_OPENSOURCE_MEM_XMP_2
help
XMP 2 memory profile. Check that it exists on ALL of your RAM sticks!
config CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM
bool "CUSTOM"
help
Custom memory profile. Use the XMP SPD values as the base, if available.
if CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM
config CUSTOM_SPD_DIVIDENT
int "[10]: Medium Timebase (MTB) Dividend"
default 1
range 1 255
config CUSTOM_SPD_DIVISOR
int "[11]: Medium Timebase (MTB) Divisor"
default 14
range 1 255
config CUSTOM_SPD_TCK
int "[12]: SDRAM Minimum Cycle Time, tCK"
default 15
range 1 255
config CUSTOM_SPD_CASLO
int "[14]: CAS Latencies Supported, Lower Byte"
default 124
range 0 255
config CUSTOM_SPD_CASHI
int "[15]: CAS Latencies Supported, Higher Byte"
default 0
range 0 255
config CUSTOM_SPD_TAA
int "[16]: Min CAS Latency Time, tAA"
default 132
range 1 255
config CUSTOM_SPD_TWR
int "[17]: Min Write Recovery Time, tWR"
default 210
range 1 255
config CUSTOM_SPD_TRCD
int "[18]: Min RAS# to CAS# Delay Time, tRCD"
default 132
range 1 255
config CUSTOM_SPD_TRRD
int "[19]: Min Row Active to Row Active Delay Time, tRRD"
default 84
range 1 255
config CUSTOM_SPD_TRP
int "[20]: Min Row Precharge Delay Time, tRP"
default 132
range 1 255
config CUSTOM_SPD_UPPER_TRC
int "[21][7:4]: Min Active to Active/Refresh Delay, UPPER tRC"
default 2
range 0 16
config CUSTOM_SPD_UPPER_TRAS
int "[21][3:0]: Min Active to Precharge Delay Time, UPPER tRAS"
default 1
range 0 16
config CUSTOM_SPD_TRAS
int "[22]: Min Active to Precharge Delay Time, LOWER tRAS"
default 138
range 1 255
config CUSTOM_SPD_TRC
int "[23]: Min Active to Active/Refresh Delay, LOWER tRC"
default 181
range 1 255
if CPU_AMD_AGESA_FAMILY16_KB
config CUSTOM_SPD_TRFC_LO
int "[24]: Min Refresh Recovery Delay Time, LOWER tRFC"
default 56
range 1 255
config CUSTOM_SPD_TRFC_HI
int "[25]: Min Refresh Recovery Delay Time, UPPER tRFC"
default 14
range 0 255
endif
config CUSTOM_SPD_TWTR
int "[26]: Min Internal Write to Read Command Delay, tWTR"
default 105
range 1 255
config CUSTOM_SPD_TRTP
int "[27]: Min Internal Read to Precharge Command Delay, tRTP"
default 105
range 1 255
config CUSTOM_SPD_UPPER_TFAW
int "[28][3:0]: Min Four Activate Window Delay, UPPER tFAW"
default 1
range 0 16
config CUSTOM_SPD_TFAW
int "[29]: Min Four Activate Window Delay Time, tFAW"
default 164
range 1 255
endif
endchoice

View File

@ -817,6 +817,11 @@ CONST UINT32 ROMDATA AmdPlatformTypeCgf = CFG_AMD_PLATFORM_TYPE;
#define CFG_DQS_TRAINING_CONTROL TRUE
#endif
#if CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM)
#undef BLDCFG_IGNORE_SPD_CHECKSUM
#define BLDCFG_IGNORE_SPD_CHECKSUM TRUE
#endif
#ifdef BLDCFG_IGNORE_SPD_CHECKSUM
#define CFG_IGNORE_SPD_CHECKSUM BLDCFG_IGNORE_SPD_CHECKSUM
#else

View File

@ -64,6 +64,7 @@
#include "mm.h"
#include "mn.h"
#include "mt.h"
#include "mtspd3.h"
#include "mu.h"
#include "heapManager.h"
#include "Filecode.h"
@ -101,6 +102,16 @@ MemSPDDataProcess (
IN OUT MEM_DATA_STRUCT *MemPtr
);
#if (CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM))
VOID
STATIC
AgesaCustomMemoryProfileSPD (
IN OUT UINT8 *Buffer
);
#endif
/*----------------------------------------------------------------------------
* EXPORTED FUNCTIONS
*
@ -293,6 +304,60 @@ AmdMemAuto (
return Retval;
}
#if (CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM))
/* -----------------------------------------------------------------------------*/
/**
*
*
* This function modifies a SPD buffer with the custom SPD values set up in coreboot's config.
*
* @param[in,out] *Buffer - Pointer to the UINT8
*
*/
VOID
STATIC
AgesaCustomMemoryProfileSPD (
IN OUT UINT8 *Buffer
)
{
UINT16 Offset;
//
// Modify a SPD buffer.
//
Buffer[SPD_DIVIDENT] = CONFIG_CUSTOM_SPD_DIVIDENT;
Buffer[SPD_DIVISOR] = CONFIG_CUSTOM_SPD_DIVISOR;
Buffer[SPD_TCK] = CONFIG_CUSTOM_SPD_TCK;
Buffer[SPD_CASLO] = CONFIG_CUSTOM_SPD_CASLO;
Buffer[SPD_CASHI] = CONFIG_CUSTOM_SPD_CASHI;
Buffer[SPD_TAA] = CONFIG_CUSTOM_SPD_TAA;
Buffer[SPD_TWR] = CONFIG_CUSTOM_SPD_TWR;
Buffer[SPD_TRCD] = CONFIG_CUSTOM_SPD_TRCD;
Buffer[SPD_TRRD] = CONFIG_CUSTOM_SPD_TRRD;
Buffer[SPD_TRP] = CONFIG_CUSTOM_SPD_TRP;
//
// SPD_UPPER_TRC and SPD_UPPER_TRAS are the same index but different bits:
// SPD_UPPER_TRC - [7:4], SPD_UPPER_TRAS - [3:0].
//
Buffer[SPD_UPPER_TRAS] = (CONFIG_CUSTOM_SPD_UPPER_TRC << 4) + CONFIG_CUSTOM_SPD_UPPER_TRAS;
Buffer[SPD_TRAS] = CONFIG_CUSTOM_SPD_TRAS;
Buffer[SPD_TRC] = CONFIG_CUSTOM_SPD_TRC;
Buffer[SPD_TWTR] = CONFIG_CUSTOM_SPD_TWTR;
Buffer[SPD_TRTP] = CONFIG_CUSTOM_SPD_TRTP;
Buffer[SPD_UPPER_TFAW] = CONFIG_CUSTOM_SPD_UPPER_TFAW;
Buffer[SPD_TFAW] = CONFIG_CUSTOM_SPD_TFAW;
//
// Print a SPD buffer.
//
printk(BIOS_SPEW, "***** SPD BUFFER *****\n");
for (Offset = 0; Offset < 256; Offset++) {
printk(BIOS_SPEW, "Buffer[%d] = 0x%02X\n", Offset, Buffer[Offset]);
}
printk(BIOS_SPEW, "**********************\n");
}
#endif
/* -----------------------------------------------------------------------------*/
/**
@ -369,6 +434,9 @@ MemSPDDataProcess (
if (AgesaStatus == AGESA_SUCCESS) {
DimmSPDPtr->DimmPresent = TRUE;
IDS_HDT_CONSOLE (MEM_FLOW, "SPD Socket %d Channel %d Dimm %d: %08x\n", Socket, Channel, Dimm, SpdParam.Buffer);
#if (CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM))
AgesaCustomMemoryProfileSPD(SpdParam.Buffer);
#endif
} else {
DimmSPDPtr->DimmPresent = FALSE;
}

View File

@ -95,7 +95,7 @@
#define SPD_FTB 9
#if CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_JEDEC)
#if CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_JEDEC) || CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM)
#define SPD_DIVIDENT 10
#define SPD_DIVISOR 11

View File

@ -2047,6 +2047,11 @@ CONST UINT32 ROMDATA AmdPlatformTypeCgf = CFG_AMD_PLATFORM_TYPE;
#define CFG_DQS_TRAINING_CONTROL TRUE
#endif
#if CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM)
#undef BLDCFG_IGNORE_SPD_CHECKSUM
#define BLDCFG_IGNORE_SPD_CHECKSUM TRUE
#endif
#ifdef BLDCFG_IGNORE_SPD_CHECKSUM
#define CFG_IGNORE_SPD_CHECKSUM BLDCFG_IGNORE_SPD_CHECKSUM
#else

View File

@ -62,6 +62,7 @@
#include "mm.h"
#include "mn.h"
#include "mt.h"
#include "mtspd3.h"
#include "mu.h"
#include "heapManager.h"
#include "Filecode.h"
@ -99,6 +100,16 @@ MemSPDDataProcess (
IN OUT MEM_DATA_STRUCT *MemPtr
);
#if (CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM))
VOID
STATIC
AgesaCustomMemoryProfileSPD (
IN OUT UINT8 *Buffer
);
#endif
/*----------------------------------------------------------------------------
* EXPORTED FUNCTIONS
*
@ -302,6 +313,60 @@ AmdMemAuto (
return Retval;
}
#if (CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM))
/* -----------------------------------------------------------------------------*/
/**
*
*
* This function modifies a SPD buffer with the custom SPD values set up in coreboot's config.
*
* @param[in,out] *Buffer - Pointer to the UINT8
*
*/
VOID
STATIC
AgesaCustomMemoryProfileSPD (
IN OUT UINT8 *Buffer
)
{
UINT16 Offset;
//
// Modify a SPD buffer.
//
Buffer[SPD_DIVIDENT] = CONFIG_CUSTOM_SPD_DIVIDENT;
Buffer[SPD_DIVISOR] = CONFIG_CUSTOM_SPD_DIVISOR;
Buffer[SPD_TCK] = CONFIG_CUSTOM_SPD_TCK;
Buffer[SPD_CASLO] = CONFIG_CUSTOM_SPD_CASLO;
Buffer[SPD_CASHI] = CONFIG_CUSTOM_SPD_CASHI;
Buffer[SPD_TAA] = CONFIG_CUSTOM_SPD_TAA;
Buffer[SPD_TWR] = CONFIG_CUSTOM_SPD_TWR;
Buffer[SPD_TRCD] = CONFIG_CUSTOM_SPD_TRCD;
Buffer[SPD_TRRD] = CONFIG_CUSTOM_SPD_TRRD;
Buffer[SPD_TRP] = CONFIG_CUSTOM_SPD_TRP;
//
// SPD_UPPER_TRC and SPD_UPPER_TRAS are the same index but different bits:
// SPD_UPPER_TRC - [7:4], SPD_UPPER_TRAS - [3:0].
//
Buffer[SPD_UPPER_TRAS] = (CONFIG_CUSTOM_SPD_UPPER_TRC << 4) + CONFIG_CUSTOM_SPD_UPPER_TRAS;
Buffer[SPD_TRAS] = CONFIG_CUSTOM_SPD_TRAS;
Buffer[SPD_TRC] = CONFIG_CUSTOM_SPD_TRC;
Buffer[SPD_TWTR] = CONFIG_CUSTOM_SPD_TWTR;
Buffer[SPD_TRTP] = CONFIG_CUSTOM_SPD_TRTP;
Buffer[SPD_UPPER_TFAW] = CONFIG_CUSTOM_SPD_UPPER_TFAW;
Buffer[SPD_TFAW] = CONFIG_CUSTOM_SPD_TFAW;
//
// Print a SPD buffer.
//
printk(BIOS_SPEW, "***** SPD BUFFER *****\n");
for (Offset = 0; Offset < 256; Offset++) {
printk(BIOS_SPEW, "Buffer[%d] = 0x%02X\n", Offset, Buffer[Offset]);
}
printk(BIOS_SPEW, "**********************\n");
}
#endif
/* -----------------------------------------------------------------------------*/
/**
@ -378,6 +443,9 @@ MemSPDDataProcess (
if (AgesaStatus == AGESA_SUCCESS) {
DimmSPDPtr->DimmPresent = TRUE;
IDS_HDT_CONSOLE (MEM_FLOW, "SPD Socket %d Channel %d Dimm %d: %08x\n", Socket, Channel, Dimm, SpdParam.Buffer);
#if (CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM))
AgesaCustomMemoryProfileSPD(SpdParam.Buffer);
#endif
} else {
DimmSPDPtr->DimmPresent = FALSE;
}

View File

@ -94,7 +94,7 @@
#define SPD_FTB 9
#if CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_JEDEC)
#if CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_JEDEC) || CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM)
#define SPD_DIVIDENT 10
#define SPD_DIVISOR 11

View File

@ -1016,6 +1016,11 @@ CONST UINT32 ROMDATA AmdPlatformTypeCgf = CFG_AMD_PLATFORM_TYPE;
#define CFG_DQS_TRAINING_CONTROL TRUE
#endif
#if CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM)
#undef BLDCFG_IGNORE_SPD_CHECKSUM
#define BLDCFG_IGNORE_SPD_CHECKSUM TRUE
#endif
#ifdef BLDCFG_IGNORE_SPD_CHECKSUM
#define CFG_IGNORE_SPD_CHECKSUM BLDCFG_IGNORE_SPD_CHECKSUM
#else

View File

@ -62,6 +62,7 @@
#include "mm.h"
#include "mn.h"
#include "mt.h"
#include "mtspd3.h"
#include "mu.h"
#include "heapManager.h"
#include "Filecode.h"
@ -99,6 +100,16 @@ MemSPDDataProcess (
IN OUT MEM_DATA_STRUCT *MemPtr
);
#if (CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM))
VOID
STATIC
AgesaCustomMemoryProfileSPD (
IN OUT UINT8 *Buffer
);
#endif
/*----------------------------------------------------------------------------
* EXPORTED FUNCTIONS
*
@ -314,6 +325,62 @@ AmdMemAuto (
return Retval;
}
#if (CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM))
/* -----------------------------------------------------------------------------*/
/**
*
*
* This function modifies a SPD buffer with the custom SPD values set up in coreboot's config.
*
* @param[in,out] *Buffer - Pointer to the UINT8
*
*/
VOID
STATIC
AgesaCustomMemoryProfileSPD (
IN OUT UINT8 *Buffer
)
{
UINT16 Offset;
//
// Modify a SPD buffer.
//
Buffer[SPD_DIVIDENT] = CONFIG_CUSTOM_SPD_DIVIDENT;
Buffer[SPD_DIVISOR] = CONFIG_CUSTOM_SPD_DIVISOR;
Buffer[SPD_TCK] = CONFIG_CUSTOM_SPD_TCK;
Buffer[SPD_CASLO] = CONFIG_CUSTOM_SPD_CASLO;
Buffer[SPD_CASHI] = CONFIG_CUSTOM_SPD_CASHI;
Buffer[SPD_TAA] = CONFIG_CUSTOM_SPD_TAA;
Buffer[SPD_TWR] = CONFIG_CUSTOM_SPD_TWR;
Buffer[SPD_TRCD] = CONFIG_CUSTOM_SPD_TRCD;
Buffer[SPD_TRRD] = CONFIG_CUSTOM_SPD_TRRD;
Buffer[SPD_TRP] = CONFIG_CUSTOM_SPD_TRP;
//
// SPD_UPPER_TRC and SPD_UPPER_TRAS are the same index but different bits:
// SPD_UPPER_TRC - [7:4], SPD_UPPER_TRAS - [3:0].
//
Buffer[SPD_UPPER_TRAS] = (CONFIG_CUSTOM_SPD_UPPER_TRC << 4) + CONFIG_CUSTOM_SPD_UPPER_TRAS;
Buffer[SPD_TRAS] = CONFIG_CUSTOM_SPD_TRAS;
Buffer[SPD_TRC] = CONFIG_CUSTOM_SPD_TRC;
Buffer[SPD_TRFC_LO] = CONFIG_CUSTOM_SPD_TRFC_LO;
Buffer[SPD_TRFC_HI] = CONFIG_CUSTOM_SPD_TRFC_HI;
Buffer[SPD_TWTR] = CONFIG_CUSTOM_SPD_TWTR;
Buffer[SPD_TRTP] = CONFIG_CUSTOM_SPD_TRTP;
Buffer[SPD_UPPER_TFAW] = CONFIG_CUSTOM_SPD_UPPER_TFAW;
Buffer[SPD_TFAW] = CONFIG_CUSTOM_SPD_TFAW;
//
// Print a SPD buffer.
//
printk(BIOS_SPEW, "***** SPD BUFFER *****\n");
for (Offset = 0; Offset < 256; Offset++) {
printk(BIOS_SPEW, "Buffer[%d] = 0x%02X\n", Offset, Buffer[Offset]);
}
printk(BIOS_SPEW, "**********************\n");
}
#endif
/* -----------------------------------------------------------------------------*/
/**
@ -390,6 +457,9 @@ MemSPDDataProcess (
if (AgesaStatus == AGESA_SUCCESS) {
DimmSPDPtr->DimmPresent = TRUE;
IDS_HDT_CONSOLE (MEM_FLOW, "SPD Socket %d Channel %d Dimm %d: %08x\n", Socket, Channel, Dimm, SpdParam.Buffer);
#if (CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM))
AgesaCustomMemoryProfileSPD(SpdParam.Buffer);
#endif
} else {
DimmSPDPtr->DimmPresent = FALSE;
}

View File

@ -95,7 +95,7 @@
#define SPD_FTB 9
#if CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_JEDEC)
#if CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_JEDEC) || CONFIG(CPU_AMD_AGESA_OPENSOURCE_MEM_CUSTOM)
#define SPD_DIVIDENT 10
#define SPD_DIVISOR 11