From 337818cec631161582a2e65d73cf3e1f9a611bb7 Mon Sep 17 00:00:00 2001
From: Timothy Pearson <tpearson@raptorengineeringinc.com>
Date: Sat, 20 Jun 2015 20:02:49 -0500
Subject: [PATCH 064/143] northbridge/amd/amdmct: Clear memory before enabling
ECC
Change-Id: I992e7040520570893ba6a213138dd57bfa14733b
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
---
src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 45 ++++++++----------------
src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c | 38 +++++++++++++++++++-
2 files changed, 51 insertions(+), 32 deletions(-)
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
index f4859d0..d8a09f0 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c
@@ -51,8 +51,6 @@ static void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat,
struct DCTStatStruc *pDCTstat);
static void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat,
struct DCTStatStruc *pDCTstat);
-static void MCTMemClrSync_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA);
static u8 NodePresent_D(u8 Node);
static void SyncDCTsReady_D(struct MCTStatStruc *pMCTstat,
struct DCTStatStruc *pDCTstatA);
@@ -1500,10 +1498,11 @@ restartinit:
InterleaveChannels_D(pMCTstat, pDCTstatA);
printk(BIOS_DEBUG, "mctAutoInitMCT_D: ECCInit_D\n");
- if (ECCInit_D(pMCTstat, pDCTstatA)) { /* Setup ECC control and ECC check-bits*/
- printk(BIOS_DEBUG, "mctAutoInitMCT_D: MCTMemClr_D\n");
- MCTMemClr_D(pMCTstat,pDCTstatA);
- }
+ ECCInit_D(pMCTstat, pDCTstatA); /* Setup ECC control and ECC check-bits*/
+
+ /* mctDoWarmResetMemClr_D(); */
+ printk(BIOS_DEBUG, "mctAutoInitMCT_D: MCTMemClr_D\n");
+ MCTMemClr_D(pMCTstat,pDCTstatA);
printk(BIOS_DEBUG, "mctAutoInitMCT_D: mct_ForceNBPState0_Dis_Fam15\n");
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
@@ -2094,9 +2093,6 @@ static void DQSTiming_D(struct MCTStatStruc *pMCTstat,
/* FIXME - currently uses calculated value TrainMaxReadLatency_D(pMCTstat, pDCTstatA); */
mctHookAfterAnyTraining();
-
- /* mctDoWarmResetMemClr_D(); */
- MCTMemClr_D(pMCTstat, pDCTstatA);
}
static void LoadDQSSigTmgRegs_D(struct MCTStatStruc *pMCTstat,
@@ -2384,26 +2380,6 @@ static void DCTMemClr_Init_D(struct MCTStatStruc *pMCTstat,
}
}
-static void MCTMemClrSync_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA)
-{
- /* Ensures that memory clear has completed on all node.*/
- u8 Node;
- struct DCTStatStruc *pDCTstat;
-
- if (!mctGet_NVbits(NV_DQSTrainCTL)){
- /* callback to wrapper: mctDoWarmResetMemClr_D */
- } else { /* NV_DQSTrainCTL == 1 */
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- pDCTstat = pDCTstatA + Node;
-
- if (pDCTstat->NodePresent) {
- DCTMemClr_Sync_D(pMCTstat, pDCTstat);
- }
- }
- }
-}
-
static void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat,
struct DCTStatStruc *pDCTstat)
{
@@ -2424,9 +2400,12 @@ static void DCTMemClr_Sync_D(struct MCTStatStruc *pMCTstat,
} while (!(val & (1 << Dr_MemClrStatus)));
}
- val = 0x0FE40FC0; /* BKDG recommended */
+ if (is_fam15h())
+ val = 0x0ce00f41; /* BKDG recommended */
+ else
+ val = 0x0fe40fc0; /* BKDG recommended */
val |= MCCH_FlushWrOnStpGnt; /* Set for S3 */
- Set_NB32(dev, 0x11C, val);
+ Set_NB32(dev, 0x11c, val);
}
static u8 NodePresent_D(u8 Node)
@@ -3089,6 +3068,8 @@ static void GetPresetmaxF_D(struct MCTStatStruc *pMCTstat,
u16 proposedFreq;
u16 word;
+ printk(BIOS_DEBUG, "%s: Start\n", __func__);
+
/* Get CPU Si Revision defined limit (NPT) */
if (is_fam15h())
proposedFreq = 933;
@@ -3113,6 +3094,8 @@ static void GetPresetmaxF_D(struct MCTStatStruc *pMCTstat,
pDCTstat->PresetmaxFreq = word;
}
/* Check F3xE8[DdrMaxRate] for maximum DRAM data rate support */
+
+ printk(BIOS_DEBUG, "%s: Done\n", __func__);
}
static void SPDGetTCL_D(struct MCTStatStruc *pMCTstat,
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
index 3a9fecc..918e91e 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
@@ -88,6 +88,10 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
u32 val;
u16 nvbits;
+ uint32_t dword;
+ uint8_t sync_flood_on_dram_err[MAX_NODES_SUPPORTED];
+ uint8_t sync_flood_on_any_uc_err[MAX_NODES_SUPPORTED];
+
mctHookBeforeECC();
/* Construct these booleans, based on setup options, for easy handling
@@ -111,6 +115,25 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
nvbits = mctGet_NVbits(NV_DramBKScrub);
OF_ScrubCTL |= nvbits;
+ /* Prevent lockups on DRAM errors during ECC init */
+ for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
+ struct DCTStatStruc *pDCTstat;
+ pDCTstat = pDCTstatA + Node;
+
+ if (NodePresent_D(Node)) {
+ dword = Get_NB32(pDCTstat->dev_nbmisc, 0x44);
+ sync_flood_on_dram_err[Node] = (dword >> 30) & 0x1;
+ sync_flood_on_any_uc_err[Node] = (dword >> 21) & 0x1;
+ dword &= ~(0x1 << 30);
+ dword &= ~(0x1 << 21);
+ Set_NB32(pDCTstat->dev_nbmisc, 0x44, dword);
+
+ /* Clear the RAM before enabling ECC to prevent MCE-related lockups */
+ DCTMemClr_Init_D(pMCTstat, pDCTstat);
+ DCTMemClr_Sync_D(pMCTstat, pDCTstat);
+ }
+ }
+
AllECC = 1;
MemClrECC = 0;
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
@@ -157,7 +180,7 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
} /* Node has Dram */
if (MemClrECC) {
- MCTMemClrSync_D(pMCTstat, pDCTstatA);
+ DCTMemClr_Sync_D(pMCTstat, pDCTstat);
}
if (pDCTstat->LogicalCPUID & (AMD_DR_GT_D0 | AMD_FAM15_ALL)) {
@@ -170,6 +193,19 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
} /* if Node present */
}
+ /* Restore previous MCA error handling settings */
+ for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
+ struct DCTStatStruc *pDCTstat;
+ pDCTstat = pDCTstatA + Node;
+
+ if (NodePresent_D(Node)) {
+ dword = Get_NB32(pDCTstat->dev_nbmisc, 0x44);
+ dword |= (sync_flood_on_dram_err[Node] & 0x1) << 30;
+ dword |= (sync_flood_on_any_uc_err[Node] & 0x1) << 21;
+ Set_NB32(pDCTstat->dev_nbmisc, 0x44, dword);
+ }
+ }
+
if(AllECC)
pMCTstat->GStatus |= 1<<GSB_ECCDIMMs;
else
--
1.7.9.5