northbridge/amd/amdmct: Allow override of memory settings via NVRAM

This patch allows the following memory controller settings to be overridden in NVRAM:
Memory frequency limit
ECC enable
ECC scrub rate

Change-Id: Ibfde3d888b0f81a29a14af2d142171510b87655e
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
Reviewed-on: http://review.coreboot.org/8438
Tested-by: build bot (Jenkins)
Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
This commit is contained in:
Timothy Pearson 2015-02-14 16:40:20 -06:00 committed by Alexandru Gagniuc
parent eb605d72b2
commit 068ca9c8fc
1 changed files with 42 additions and 4 deletions

View File

@ -20,9 +20,23 @@
/* Call-backs */ /* Call-backs */
#include <delay.h> #include <delay.h>
#define NVRAM_DDR2_800 0
#define NVRAM_DDR2_667 1
#define NVRAM_DDR2_533 2
#define NVRAM_DDR2_400 3
#define NVRAM_DDR3_1600 0
#define NVRAM_DDR3_1333 1
#define NVRAM_DDR3_1066 2
#define NVRAM_DDR3_800 3
static const uint16_t ddr2_limits[4] = {400, 333, 266, 200};
static const uint16_t ddr3_limits[4] = {800, 666, 533, 400};
static u16 mctGet_NVbits(u8 index) static u16 mctGet_NVbits(u8 index)
{ {
u16 val = 0; u16 val = 0;
int nvram;
switch (index) { switch (index) {
case NV_PACK_TYPE: case NV_PACK_TYPE:
@ -45,10 +59,16 @@ static u16 mctGet_NVbits(u8 index)
break; break;
case NV_MAX_MEMCLK: case NV_MAX_MEMCLK:
/* Maximum platform supported memclk */ /* Maximum platform supported memclk */
//val = 200; /* 200MHz(DDR400) */ val = MEM_MAX_LOAD_FREQ;
//val = 266; /* 266MHz(DDR533) */
//val = 333; /* 333MHz(DDR667) */ if (get_option(&nvram, "max_mem_clock") == CB_SUCCESS) {
val = MEM_MAX_LOAD_FREQ; /* 400MHz(DDR800) */ int limit = val;
if (IS_ENABLED(CONFIG_DIMM_DDR3))
limit = ddr3_limits[nvram & 3];
else if (IS_ENABLED(CONFIG_DIMM_DDR2))
limit = ddr2_limits[nvram & 3];
val = min(limit, val);
}
break; break;
case NV_ECC_CAP: case NV_ECC_CAP:
#if SYSTEM_TYPE == SERVER #if SYSTEM_TYPE == SERVER
@ -91,6 +111,9 @@ static u16 mctGet_NVbits(u8 index)
/* Bank (chip select) interleaving */ /* Bank (chip select) interleaving */
//val = 0; /* disabled */ //val = 0; /* disabled */
val = 1; /* enabled (recommended) */ val = 1; /* enabled (recommended) */
if (get_option(&nvram, "interleave_chip_selects") == CB_SUCCESS)
val = !!nvram;
break; break;
case NV_MemHole: case NV_MemHole:
//val = 0; /* Disabled */ //val = 0; /* Disabled */
@ -111,6 +134,9 @@ static u16 mctGet_NVbits(u8 index)
case NV_NodeIntlv: case NV_NodeIntlv:
val = 0; /* Disabled (recommended) */ val = 0; /* Disabled (recommended) */
//val = 1; /* Enable */ //val = 1; /* Enable */
if (get_option(&nvram, "interleave_nodes") == CB_SUCCESS)
val = !!nvram;
break; break;
case NV_BurstLen32: case NV_BurstLen32:
#if !CONFIG_GFXUMA #if !CONFIG_GFXUMA
@ -151,6 +177,9 @@ static u16 mctGet_NVbits(u8 index)
#else #else
val = 0; /* Disable */ val = 0; /* Disable */
#endif #endif
if (get_option(&nvram, "ECC_memory") == CB_SUCCESS)
val = !!nvram;
break; break;
case NV_NBECC: case NV_NBECC:
#if (SYSTEM_TYPE == SERVER) #if (SYSTEM_TYPE == SERVER)
@ -172,6 +201,9 @@ static u16 mctGet_NVbits(u8 index)
* 1: Enable * 1: Enable
*/ */
val = CONFIG_AMDMCT_ENABLE_ECC_REDIR; val = CONFIG_AMDMCT_ENABLE_ECC_REDIR;
if (get_option(&nvram, "ECC_redirection") == CB_SUCCESS)
val = !!nvram;
break; break;
case NV_DramBKScrub: case NV_DramBKScrub:
/* /*
@ -200,6 +232,9 @@ static u16 mctGet_NVbits(u8 index)
* 0x16: 84ms * 0x16: 84ms
*/ */
val = CONFIG_AMDMCT_BACKGROUND_SCRUB_RATE; val = CONFIG_AMDMCT_BACKGROUND_SCRUB_RATE;
if ((get_option(&nvram, "ecc_scrub_rate") == CB_SUCCESS) && (nvram <= 0x16))
val = nvram;
break; break;
case NV_L2BKScrub: case NV_L2BKScrub:
val = 0; /* Disabled - See L2Scrub in BKDG */ val = 0; /* Disabled - See L2Scrub in BKDG */
@ -219,6 +254,9 @@ static u16 mctGet_NVbits(u8 index)
/* channel interleave is better performance than ganged mode at this time */ /* channel interleave is better performance than ganged mode at this time */
val = 1; /* Enabled */ val = 1; /* Enabled */
//val = 0; /* Disabled */ //val = 0; /* Disabled */
if (get_option(&nvram, "interleave_memory_channels") == CB_SUCCESS)
val = !!nvram;
break; break;
case NV_ChannelIntlv: case NV_ChannelIntlv:
val = 5; /* Not currently checked in mctchi_d.c */ val = 5; /* Not currently checked in mctchi_d.c */