diff options
Diffstat (limited to 'src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c')
-rw-r--r-- | src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c | 110 |
1 files changed, 48 insertions, 62 deletions
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c index 1be46b1351..be63149daf 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctecc_d.c @@ -88,13 +88,8 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) uint8_t sync_flood_on_dram_err[MAX_NODES_SUPPORTED]; uint8_t sync_flood_on_any_uc_err[MAX_NODES_SUPPORTED]; - uint8_t redirect_ecc_scrub = 0; - mctHookBeforeECC(); - if ((pMCTstat->GStatus & 1 << GSB_ECCDIMMs) && mctGet_NVbits(NV_ECCRedir)) - redirect_ecc_scrub = 1; - /* 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 */ @@ -113,8 +108,11 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) OF_ScrubCTL |= (u32) nvbits << 8; } + nvbits = mctGet_NVbits(NV_L3BKScrub); + OF_ScrubCTL |= (nvbits & 0x1f) << 24; /* L3Scrub = NV_L3BKScrub */ + nvbits = mctGet_NVbits(NV_DramBKScrub); - OF_ScrubCTL |= nvbits; + OF_ScrubCTL |= nvbits; /* DramScrub = NV_DramBKScrub */ /* Prevent lockups on DRAM errors during ECC init */ for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) { @@ -129,6 +127,10 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) dword &= ~(0x1 << 21); Set_NB32(pDCTstat->dev_nbmisc, 0x44, dword); + /* Clear MC4 error status */ + pci_write_config32(pDCTstat->dev_nbmisc, 0x48, 0x0); + pci_write_config32(pDCTstat->dev_nbmisc, 0x4c, 0x0); + /* Clear the RAM before enabling ECC to prevent MCE-related lockups */ DCTMemClr_Init_D(pMCTstat, pDCTstat); DCTMemClr_Sync_D(pMCTstat, pDCTstat); @@ -166,6 +168,9 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) if(LDramECC) { /* if ECC is enabled on this dram */ if (OB_NBECC) { mct_EnableDatIntlv_D(pMCTstat, pDCTstat); + val = Get_NB32(pDCTstat->dev_dct, 0x110); + val |= 1 << 5; /* DctDatIntLv = 1 */ + Set_NB32(pDCTstat->dev_dct, 0x110, val); dev = pDCTstat->dev_nbmisc; reg = 0x44; /* MCA NB Configuration */ val = Get_NB32(dev, reg); @@ -176,37 +181,16 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) printk(BIOS_DEBUG, " ECC enabled on node: %02x\n", Node); } } /* this node has ECC enabled dram */ + + if (MemClrECC) { + DCTMemClr_Sync_D(pMCTstat, pDCTstat); + } } else { LDramECC = 0; } /* Node has Dram */ - - if (MemClrECC) { - DCTMemClr_Sync_D(pMCTstat, pDCTstat); - } - - if (pDCTstat->LogicalCPUID & (AMD_DR_GT_D0 | AMD_FAM15_ALL)) { - /* Set up message triggered C1E */ - val = pci_read_config32(pDCTstat->dev_nbmisc, 0xd4); - val &= ~(0x1 << 15); /* StutterScrubEn = DRAM scrub enabled */ - val |= (mctGet_NVbits(NV_DramBKScrub)?1:0) << 15; - pci_write_config32(pDCTstat->dev_nbmisc, 0xd4, val); - } } /* 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 @@ -225,19 +209,26 @@ 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) { - val |= (1<<0); /* enable redirection */ + val |= (1 << 0); /* Enable redirection */ } Set_NB32(dev, 0x5c, val); /* Dram Scrub Addr Low */ - val = curBase>>24; + val = curBase >> 24; Set_NB32(dev, 0x60, val); /* Dram Scrub Addr High */ - Set_NB32(dev, 0x58, OF_ScrubCTL); /*Scrub Control */ + + /* Set scrub rate controls */ + if (is_fam15h()) { + /* Erratum 505 */ + fam15h_switch_dct(pDCTstat->dev_map, 0); + } + Set_NB32(dev, 0x58, OF_ScrubCTL); /* Scrub Control */ + if (is_fam15h()) { + fam15h_switch_dct(pDCTstat->dev_map, 1); /* Erratum 505 */ + Set_NB32(dev, 0x58, OF_ScrubCTL); /* Scrub Control */ + fam15h_switch_dct(pDCTstat->dev_map, 0); /* Erratum 505 */ + } if (!is_fam15h()) { /* Divisor should not be set deeper than @@ -254,36 +245,31 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) } } - if (is_fam15h()) { - uint8_t dct; - - /* Disable training mode - * See fam15EnableTrainingMode for the non-ECC training mode tear-down code - */ - for (dct = 0; dct < 2; dct++) { - /* NOTE: Reads use DCT 0 and writes use the current DCT per Erratum 505 */ - dword = Get_NB32_DCT(pDCTstat->dev_nbmisc, 0, 0x58); /* Scrub Rate Control */ - dword &= ~(0x1f << 24); /* L3Scrub = NV_L3BKScrub */ - dword |= (mctGet_NVbits(NV_L3BKScrub) & 0x1f) << 24; - dword &= ~(0x1f); /* DramScrub = NV_DramBKScrub */ - dword |= mctGet_NVbits(NV_DramBKScrub) & 0x1f; - Set_NB32_DCT(pDCTstat->dev_nbmisc, dct, 0x58, dword); /* Scrub Rate Control */ - - dword = Get_NB32_DCT(pDCTstat->dev_nbmisc, dct, 0x5c); /* DRAM Scrub Address Low */ - dword &= ~(0x1); /* ScrubReDirEn = redirect_ecc_scrub */ - dword |= redirect_ecc_scrub & 0x1; - Set_NB32_DCT(pDCTstat->dev_nbmisc, dct, 0x5c, dword); /* DRAM Scrub Address Low */ - - dword = Get_NB32_DCT(pDCTstat->dev_nbmisc, dct, 0x1b8); /* L3 Control 1 */ - dword &= ~(0x1 << 4); /* L3ScrbRedirDis = 0 */ - Set_NB32_DCT(pDCTstat->dev_nbmisc, dct, 0x1b8, dword); /* L3 Control 1 */ - } + if (pDCTstat->LogicalCPUID & (AMD_DR_GT_D0 | AMD_FAM15_ALL)) { + /* Set up message triggered C1E */ + val = pci_read_config32(pDCTstat->dev_nbmisc, 0xd4); + val &= ~(0x1 << 15); /* StutterScrubEn = DRAM scrub enabled */ + val |= (mctGet_NVbits(NV_DramBKScrub)?1:0) << 15; + pci_write_config32(pDCTstat->dev_nbmisc, 0xd4, val); } } /* this node has ECC enabled dram */ } /*Node has Dram */ } /*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(mctGet_NVbits(NV_SyncOnUnEccEn)) setSyncOnUnEccEn_D(pMCTstat, pDCTstatA); |