summaryrefslogtreecommitdiff
path: root/src/northbridge
diff options
context:
space:
mode:
authorTimothy Pearson <tpearson@raptorengineeringinc.com>2016-04-06 16:10:38 -0500
committerTimothy Pearson <tpearson@raptorengineeringinc.com>2016-04-08 16:43:11 +0200
commitc5c3d76127c0a3766f9f37710a4b6756e16497de (patch)
tree16927f3e4072625ce909f6398a4554a83ec02bfc /src/northbridge
parent3503b3f73052e8a0bc069995d16c30aab3782d9a (diff)
nb/amd/mct_ddr3: Cache whether ECC is allowed at the platform level
Certain AMD platforms, such as those using the SP5100 southbridge, contain a very poorly documented bug related to LPC ROM access, which is triggered by repeated (hundreds or more) rapid calls to get_option(). This bug manifests as a complete system deadlock in ramstage device configuration, requiring standby power to be removed from the system to release the deadlock. Cache the platform ECC status to avoid repeated calls to get_option() in the lane count detection logic. Change-Id: I8b48c523218ccc8c113319957d6eca2d15e1070f Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> Reviewed-on: https://review.coreboot.org/14273 Tested-by: build bot (Jenkins) Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com> Reviewed-by: Felix Held <felix-coreboot@felixheld.de> Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/northbridge')
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mct_d.c11
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mct_d.h1
2 files changed, 9 insertions, 3 deletions
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
index 0b8833124e..f31fb3c7e6 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
@@ -336,9 +336,8 @@ uint8_t is_ecc_enabled(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTs
{
uint8_t ecc_enabled = 1;
- if (!mctGet_NVbits(NV_ECC_CAP) || !mctGet_NVbits(NV_ECC)) {
- return 0;
- }
+ if (!pMCTstat->try_ecc)
+ ecc_enabled = 0;
if (pDCTstat->NodePresent && pDCTstat->DIMMValid) {
if (!(pDCTstat->Status & (1 << SB_ECCDIMMs))) {
@@ -2659,6 +2658,12 @@ static void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat,
uint8_t s3resume = acpi_is_wakeup_s3();
restartinit:
+
+ if (!mctGet_NVbits(NV_ECC_CAP) || !mctGet_NVbits(NV_ECC))
+ pMCTstat->try_ecc = 0;
+ else
+ pMCTstat->try_ecc = 1;
+
mctInitMemGPIOs_A_D(); /* Set any required GPIOs*/
if (s3resume) {
printk(BIOS_DEBUG, "mctAutoInitMCT_D: mct_ForceNBPState0_En_Fam15\n");
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h
index 67eb2b4869..a3a94393ad 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h
@@ -300,6 +300,7 @@ struct MCTStatStruc {
u32 SysLimit; /* LIMIT[39:8] (system address)*/
uint32_t TSCFreq;
uint16_t nvram_checksum;
+ uint8_t try_ecc;
} __attribute__((packed));
/*=============================================================================