aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdmct/mct/mctecc_d.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/amd/amdmct/mct/mctecc_d.c')
-rw-r--r--src/northbridge/amd/amdmct/mct/mctecc_d.c314
1 files changed, 0 insertions, 314 deletions
diff --git a/src/northbridge/amd/amdmct/mct/mctecc_d.c b/src/northbridge/amd/amdmct/mct/mctecc_d.c
deleted file mode 100644
index 8eb7bf54b7..0000000000
--- a/src/northbridge/amd/amdmct/mct/mctecc_d.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
- *
- * 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
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-
-#include "mct_d.h"
-
-static void setSyncOnUnEccEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA);
-#ifdef UNUSED_CODE
-static u32 GetScrubAddr_D(u32 Node);
-#endif
-static u8 isDramECCEn_D(struct DCTStatStruc *pDCTstat);
-
-
-/* Initialize ECC modes of Integrated Dram+Memory Controllers of a network of
- * Hammer processors. Use Dram background scrubber to fast initialize ECC bits
- * of all dram.
- *
- * Notes:
- *
- * Order that items are set:
- * 1. eccen bit in NB
- * 2. Scrub Base
- * 3. Temp Node Base
- * 4. Temp Node Limit
- * 5. Redir bit in NB
- * 6. Scrub CTL
- *
- * Conditions for setting background scrubber.
- * 1. node is present
- * 2. node has dram functioning (WE = RE = 1)
- * 3. all eccdimms (or bit 17 of offset 90,fn 2)
- * 4. no chip-select gap exists
- *
- * The dram background scrubber is used under very controlled circumstances to
- * initialize all the ECC bits on the DIMMs of the entire dram address map
- * (including hidden or lost dram and dram above 4GB). We will turn the scrub
- * rate up to maximum, which should clear 4GB of dram in about 2.7 seconds.
- * We will activate the scrubbers of all nodes with ecc dram and let them run in
- * parallel, thereby reducing even further the time required to condition dram.
- * Finally, we will go through each node and either disable background scrubber,
- * or set the scrub rate to the user setup specified rate.
- *
- * To allow the NB to scrub, we need to wait a time period long enough to
- * guarantee that the NB scrubs the entire dram on its node. Do do this, we
- * simply sample the scrub ADDR once, for an initial value, then we sample and poll until the polled value of scrub ADDR
- * has wrapped around at least once: Scrub ADDRi+1 < Scrub ADDRi. Since we let all
- * Nodes run in parallel, we need to guarantee that all nodes have wrapped. To do
- * this efficiently, we need only to sample one of the nodes, the node with the
- * largest ammount of dram populated is the one which will take the longest amount
- * of time (the scrub rate is set to max, the same rate, on all nodes). So,
- * during setup of scrub Base, we determine how much memory and which node has
- * the largest memory installed.
- *
- * Scrubbing should not ordinarily be enabled on a Node with a chip-select gap
- * (aka SW memhole, cs hoisting, etc..).To init ECC memory on this node, the
- * scrubber is used in two steps. First, the Dram Limit for the node is adjusted
- * down to the bottom of the gap, and that ECC dram is initialized. Second, the
- * original Limit is restored, the Scrub base is set to 4GB, and scrubber is
- * allowed to run until the Scrub Addr wraps around to zero.
- */
-u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
-{
- u8 Node;
- u8 AllECC;
- u16 OB_NBECC;
- u32 curBase;
- u16 OB_ECCRedir;
- u32 LDramECC;
- u32 OF_ScrubCTL;
- u8 MemClrECC;
-
- u32 dev;
- u32 reg;
- u32 val;
- u16 nvbits;
-
- mctHookBeforeECC();
-
- /* 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_ECCRedir = mctGet_NVbits(NV_ECCRedir); /* ECC Redirection */
-
- mctGet_NVbits(NV_ChipKill); /* ECC Chip-kill mode */
-
- OF_ScrubCTL = 0; /* Scrub CTL for Dcache, L2, and dram */
- nvbits = mctGet_NVbits(NV_DCBKScrub);
- mct_AdjustScrub_D(pDCTstatA, &nvbits);
- OF_ScrubCTL |= (u32) nvbits << 16;
-
- nvbits = mctGet_NVbits(NV_L2BKScrub);
- OF_ScrubCTL |= (u32) nvbits << 8;
-
- nvbits = mctGet_NVbits(NV_DramBKScrub);
- OF_ScrubCTL |= nvbits;
-
- AllECC = 1;
- MemClrECC = 0;
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
- LDramECC = 0;
- if (NodePresent_D(Node)) { /*If Node is present */
- dev = pDCTstat->dev_map;
- reg = 0x40+(Node << 3); /* Dram Base Node 0 + index */
- val = Get_NB32(dev, reg);
-
- /* WE/RE is checked */
- if ((val & 3) == 3) { /* Node has dram populated */
- /* Negate 'all nodes/dimms ECC' flag if non ecc
- memory populated */
- if (pDCTstat->Status & (1 << SB_ECCDIMMs)) {
- LDramECC = isDramECCEn_D(pDCTstat);
- if (pDCTstat->ErrCode != SC_RunningOK) {
- pDCTstat->Status &= ~(1 << SB_ECCDIMMs);
- if (!OB_NBECC) {
- pDCTstat->ErrStatus |= (1 << SB_DramECCDis);
- }
- AllECC = 0;
- LDramECC =0;
- }
- } else {
- AllECC = 0;
- }
- if (LDramECC) { /* if ECC is enabled on this dram */
- if (OB_NBECC) {
- mct_EnableDatIntlv_D(pMCTstat, pDCTstat);
- dev = pDCTstat->dev_nbmisc;
- reg =0x44; /* MCA NB Configuration */
- val = Get_NB32(dev, reg);
- val |= 1 << 22; /* EccEn */
- Set_NB32(dev, reg, val);
- DCTMemClr_Init_D(pMCTstat, pDCTstat);
- MemClrECC = 1;
- print_tx(" ECC enabled on node: ", Node);
- }
- } /* this node has ECC enabled dram */
- } else {
- LDramECC = 0;
- } /* Node has Dram */
-
- if (MemClrECC) {
- MCTMemClrSync_D(pMCTstat, pDCTstatA);
- }
- } /* if Node present */
- }
-
- if (AllECC)
- pMCTstat->GStatus |= 1 << GSB_ECCDIMMs;
- else
- pMCTstat->GStatus &= ~(1 << GSB_ECCDIMMs);
-
- /* Program the Dram BKScrub CTL to the proper (user selected) value.*/
- /* Reset MC4_STS. */
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
- LDramECC = 0;
- if (NodePresent_D(Node)) { /* If Node is present */
- reg = 0x40+(Node << 3); /* Dram Base Node 0 + index */
- val = Get_NB32(pDCTstat->dev_map, reg);
- curBase = val & 0xffff0000;
- /*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 */
- dev = pDCTstat->dev_nbmisc;
- val = curBase << 8;
- if (OB_ECCRedir) {
- val |= (1<<0); /* enable redirection */
- }
- Set_NB32(dev, 0x5C, val); /* Dram Scrub Addr Low */
- val = curBase >> 24;
- 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);
- }
- }
- } /* this node has ECC enabled dram */
- } /*Node has Dram */
- } /*if Node present */
- }
-
- if (mctGet_NVbits(NV_SyncOnUnEccEn))
- setSyncOnUnEccEn_D(pMCTstat, pDCTstatA);
-
- mctHookAfterECC();
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
- if (NodePresent_D(Node)) {
- print_tx("ECCInit: Node ", Node);
- print_tx("ECCInit: Status ", pDCTstat->Status);
- print_tx("ECCInit: ErrStatus ", pDCTstat->ErrStatus);
- print_tx("ECCInit: ErrCode ", pDCTstat->ErrCode);
- print_t("ECCInit: Done\n");
- }
- }
- return MemClrECC;
-}
-
-
-static void setSyncOnUnEccEn_D(struct MCTStatStruc *pMCTstat,
- struct DCTStatStruc *pDCTstatA)
-{
- u32 Node;
- u32 reg;
- u32 dev;
- u32 val;
-
- for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
- struct DCTStatStruc *pDCTstat;
- pDCTstat = pDCTstatA + Node;
- if (NodePresent_D(Node)) { /* If Node is present*/
- reg = 0x40+(Node << 3); /* Dram Base Node 0 + index*/
- val = Get_NB32(pDCTstat->dev_map, reg);
- /*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*/
- dev = pDCTstat->dev_nbmisc;
- reg = 0x44; /* MCA NB Configuration*/
- val = Get_NB32(dev, reg);
- val |= (1 << SyncOnUcEccEn);
- Set_NB32(dev, reg, val);
- }
- } /* Node has Dram*/
- } /* if Node present*/
- }
-}
-
-#ifdef UNUSED_CODE
-static u32 GetScrubAddr_D(u32 Node)
-{
- /* Get the current 40-bit Scrub ADDR address, scaled to 32-bits,
- * of the specified Node.
- */
-
- u32 reg;
- u32 regx;
- u32 lo, hi;
- u32 val;
- u32 dev = PA_NBMISC(Node);
-
-
- reg = 0x60; /* Scrub Addr High */
- hi = Get_NB32(dev, reg);
-
- regx = 0x5C; /* Scrub Addr Low */
- lo = Get_NB32(dev, regx);
- /* Scrub Addr High again, detect 32-bit wrap */
- val = Get_NB32(dev, reg);
- if (val != hi) {
- hi = val; /* Scrub Addr Low again, if wrap occurred */
- lo = Get_NB32(dev, regx);
- }
-
- val = hi << 24;
- val |= lo >> 8;
-
- return val; /* ScrubAddr[39:8] */
-}
-#endif
-
-static u8 isDramECCEn_D(struct DCTStatStruc *pDCTstat)
-{
- u32 reg;
- u32 val;
- u8 i;
- u32 dev = pDCTstat->dev_dct;
- u8 ch_end;
- u8 isDimmECCEn = 0;
-
- if (pDCTstat->GangedMode) {
- ch_end = 1;
- } else {
- ch_end = 2;
- }
- for (i = 0; i < ch_end; i++) {
- if (pDCTstat->DIMMValidDCT[i] > 0) {
- reg = 0x90 + i * 0x100; /* Dram Config Low */
- val = Get_NB32(dev, reg);
- if (val & (1 << DimmEcEn)) {
- /* set local flag 'dram ecc capable' */
- isDimmECCEn = 1;
- break;
- }
- }
- }
- return isDimmECCEn;
-}