northbridge/amd/amdfam10: Fold back memory frequency based on MCT load
K10 processors cannot operate at full memory speeds when more than a certain number of DIMMs are installed on a specific channel. The allowed DIMM numbers and speeds are listed in the BKDG; this patch implements the appropriate frequency reduction to ensure stability. Change-Id: I8ac5b508915e423d262ad36c49de1fe696df2ecd Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> Reviewed-on: http://review.coreboot.org/8435 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
This commit is contained in:
parent
a70093611f
commit
3c206781f2
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the coreboot project.
|
* This file is part of the coreboot project.
|
||||||
*
|
*
|
||||||
|
* Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
|
||||||
* Copyright (C) 2007 Advanced Micro Devices, Inc.
|
* Copyright (C) 2007 Advanced Micro Devices, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -34,6 +35,42 @@ static void print_t(const char *strval)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_tf(const char *func, const char *strval)
|
||||||
|
{
|
||||||
|
#if CONFIG_DEBUG_RAM_SETUP
|
||||||
|
printk(BIOS_DEBUG, "%s: %s", func, strval);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t mct_MaxLoadFreq(uint8_t count, uint16_t freq)
|
||||||
|
{
|
||||||
|
/* Return limited maximum RAM frequency */
|
||||||
|
if (IS_ENABLED(CONFIG_DIMM_DDR2)) {
|
||||||
|
if (IS_ENABLED(CONFIG_DIMM_REGISTERED)) {
|
||||||
|
/* K10 BKDG Rev. 3.62 Table 53 */
|
||||||
|
if (count > 2) {
|
||||||
|
/* Limit to DDR2-533 */
|
||||||
|
if (freq > 266) {
|
||||||
|
freq = 266;
|
||||||
|
print_tf(__func__, ": More than 2 DIMMs on channel; limiting to DDR2-533\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* K10 BKDG Rev. 3.62 Table 52 */
|
||||||
|
if (count > 1) {
|
||||||
|
/* Limit to DDR2-800 */
|
||||||
|
if (freq > 400) {
|
||||||
|
freq = 400;
|
||||||
|
print_tf(__func__, ": More than 1 DIMM on channel; limiting to DDR2-800\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return freq;
|
||||||
|
}
|
||||||
|
|
||||||
#if (CONFIG_DIMM_SUPPORT & 0x000F)==0x0005 /* AMD_FAM10_DDR3 */
|
#if (CONFIG_DIMM_SUPPORT & 0x000F)==0x0005 /* AMD_FAM10_DDR3 */
|
||||||
#include "amdfam10.h"
|
#include "amdfam10.h"
|
||||||
#include "../amdmct/wrappers/mcti.h"
|
#include "../amdmct/wrappers/mcti.h"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the coreboot project.
|
* This file is part of the coreboot project.
|
||||||
*
|
*
|
||||||
|
* Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
|
||||||
* Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
|
* Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -281,7 +282,25 @@ static void mctHookAfterDIMMpre(void)
|
||||||
|
|
||||||
static void mctGet_MaxLoadFreq(struct DCTStatStruc *pDCTstat)
|
static void mctGet_MaxLoadFreq(struct DCTStatStruc *pDCTstat)
|
||||||
{
|
{
|
||||||
pDCTstat->PresetmaxFreq = MEM_MAX_LOAD_FREQ;
|
pDCTstat->PresetmaxFreq = mctGet_NVbits(NV_MAX_MEMCLK);
|
||||||
|
|
||||||
|
/* Determine the number of installed DIMMs */
|
||||||
|
int ch1_count = 0;
|
||||||
|
int ch2_count = 0;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 15; i = i + 2) {
|
||||||
|
if (pDCTstat->DIMMValid & (1 << i))
|
||||||
|
ch1_count++;
|
||||||
|
if (pDCTstat->DIMMValid & (1 << (i + 1)))
|
||||||
|
ch2_count++;
|
||||||
|
}
|
||||||
|
if (IS_ENABLED(CONFIG_DEBUG_RAM_SETUP)) {
|
||||||
|
printk(BIOS_DEBUG, "mctGet_MaxLoadFreq: Channel 1: %d DIMM(s) detected\n", ch1_count);
|
||||||
|
printk(BIOS_DEBUG, "mctGet_MaxLoadFreq: Channel 2: %d DIMM(s) detected\n", ch2_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set limits if needed */
|
||||||
|
pDCTstat->PresetmaxFreq = mct_MaxLoadFreq(max(ch1_count, ch2_count), pDCTstat->PresetmaxFreq);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNUSED_CODE
|
#ifdef UNUSED_CODE
|
||||||
|
|
Loading…
Reference in New Issue