aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
diff options
context:
space:
mode:
authorTimothy Pearson <tpearson@raptorengineeringinc.com>2015-10-16 13:51:51 -0500
committerMartin Roth <martinroth@google.com>2015-11-02 23:45:19 +0100
commit730a043fb6cb4dd3cb5af8f8640365727b598648 (patch)
tree59afe45caca1a8e1682939c7e44e95344104533e /src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
parentd150006c4a4584bc9933c2d8ff580a54c4f0cc2a (diff)
cpu/amd: Add initial AMD Family 15h support
TEST: Booted ASUS KGPE-D16 with single Opteron 6380 * Unbuffered DDR3 DIMMs tested and working * Suspend to RAM (S3) tested and working Change-Id: Idffd2ce36ce183fbfa087e5ba69a9148f084b45e Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> Reviewed-on: http://review.coreboot.org/11966 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c')
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c55
1 files changed, 32 insertions, 23 deletions
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
index 625fe7ddc4..0a51b1a228 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c
@@ -2,6 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2010 Advanced Micro Devices, Inc.
+ * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -87,19 +88,21 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
/* Construct these booleans, based on setup options, for easy handling
later in this procedure */
- OB_NBECC = mctGet_NVbits(NV_NBECC); /* MCA ECC (MCE) enable bit */
+ OB_NBECC = mctGet_NVbits(NV_NBECC); /* MCA ECC (MCE) enable bit */
- OB_ECCRedir = mctGet_NVbits(NV_ECCRedir); /* ECC Redirection */
+ OB_ECCRedir = mctGet_NVbits(NV_ECCRedir); /* ECC Redirection */
- OB_ChipKill = mctGet_NVbits(NV_ChipKill); /* ECC Chip-kill mode */
+ OB_ChipKill = mctGet_NVbits(NV_ChipKill); /* ECC Chip-kill mode */
+ OF_ScrubCTL = 0; /* Scrub CTL for Dcache, L2, and dram */
- OF_ScrubCTL = 0; /* Scrub CTL for Dcache, L2, and dram */
- nvbits = mctGet_NVbits(NV_DCBKScrub);
- /* mct_AdjustScrub_D(pDCTstatA, &nvbits); */ /* Need not adjust */
- OF_ScrubCTL |= (u32) nvbits << 16;
+ if (!is_fam15h()) {
+ nvbits = mctGet_NVbits(NV_DCBKScrub);
+ /* mct_AdjustScrub_D(pDCTstatA, &nvbits); */ /* Need not adjust */
+ OF_ScrubCTL |= (u32) nvbits << 16;
- nvbits = mctGet_NVbits(NV_L2BKScrub);
- OF_ScrubCTL |= (u32) nvbits << 8;
+ nvbits = mctGet_NVbits(NV_L2BKScrub);
+ OF_ScrubCTL |= (u32) nvbits << 8;
+ }
nvbits = mctGet_NVbits(NV_DramBKScrub);
OF_ScrubCTL |= nvbits;
@@ -127,7 +130,7 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
pDCTstat->ErrStatus |= (1 << SB_DramECCDis);
}
AllECC = 0;
- LDramECC =0;
+ LDramECC = 0;
}
} else {
AllECC = 0;
@@ -136,7 +139,7 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
if (OB_NBECC) {
mct_EnableDatIntlv_D(pMCTstat, pDCTstat);
dev = pDCTstat->dev_nbmisc;
- reg =0x44; /* MCA NB Configuration */
+ reg = 0x44; /* MCA NB Configuration */
val = Get_NB32(dev, reg);
val |= 1 << 22; /* EccEn */
Set_NB32(dev, reg, val);
@@ -173,6 +176,10 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
/*WE/RE is checked because memory config may have been */
if((val & 3)==3) { /* Node has dram populated */
if (isDramECCEn_D(pDCTstat)) { /* if ECC is enabled on this dram */
+ if (is_fam15h()) {
+ /* Erratum 505 */
+ fam15h_switch_dct(pDCTstat->dev_map, 0);
+ }
dev = pDCTstat->dev_nbmisc;
val = curBase << 8;
if(OB_ECCRedir) {
@@ -183,16 +190,18 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
Set_NB32(dev, 0x60, val); /* Dram Scrub Addr High */
Set_NB32(dev, 0x58, OF_ScrubCTL); /*Scrub Control */
- /* Divisor should not be set deeper than
- * divide by 16 when Dcache scrubber or
- * L2 scrubber is enabled.
- */
- if ((OF_ScrubCTL & (0x1F << 16)) || (OF_ScrubCTL & (0x1F << 8))) {
- val = Get_NB32(dev, 0x84);
- if ((val & 0xE0000000) > 0x80000000) { /* Get F3x84h[31:29]ClkDivisor for C1 */
- val &= 0x1FFFFFFF; /* If ClkDivisor is deeper than divide-by-16 */
- val |= 0x80000000; /* set it to divide-by-16 */
- Set_NB32(dev, 0x84, val);
+ if (!is_fam15h()) {
+ /* Divisor should not be set deeper than
+ * divide by 16 when Dcache scrubber or
+ * L2 scrubber is enabled.
+ */
+ if ((OF_ScrubCTL & (0x1F << 16)) || (OF_ScrubCTL & (0x1F << 8))) {
+ val = Get_NB32(dev, 0x84);
+ if ((val & 0xE0000000) > 0x80000000) { /* Get F3x84h[31:29]ClkDivisor for C1 */
+ val &= 0x1FFFFFFF; /* If ClkDivisor is deeper than divide-by-16 */
+ val |= 0x80000000; /* set it to divide-by-16 */
+ Set_NB32(dev, 0x84, val);
+ }
}
}
} /* this node has ECC enabled dram */
@@ -263,8 +272,8 @@ static u8 isDramECCEn_D(struct DCTStatStruc *pDCTstat)
}
for(i=0; i<ch_end; i++) {
if(pDCTstat->DIMMValidDCT[i] > 0){
- reg = 0x90 + i * 0x100; /* Dram Config Low */
- val = Get_NB32(dev, reg);
+ reg = 0x90; /* Dram Config Low */
+ val = Get_NB32_DCT(dev, i, reg);
if(val & (1<<DimmEcEn)) {
/* set local flag 'dram ecc capable' */
isDimmECCEn = 1;