/*
* This file is part of the coreboot project.
*
- * Copyright (C) 2007 Advanced Micro Devices, Inc.
+ * 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
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);
* 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 gaurantee that all nodes have wrapped. To do
+ * 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,
u32 dev;
u32 reg;
u32 val;
+ u16 nvbits;
mctHookBeforeECC();
OB_ChipKill = mctGet_NVbits(NV_ChipKill); /* ECC Chip-kill mode */
OF_ScrubCTL = 0; /* Scrub CTL for Dcache, L2, and dram */
- val = mctGet_NVbits(NV_DCBKScrub);
- mct_AdjustScrub_D(pDCTstatA, val);
- OF_ScrubCTL |= val << 16;
- val = mctGet_NVbits(NV_L2BKScrub);
- OF_ScrubCTL |= val << 8;
+ nvbits = mctGet_NVbits(NV_DCBKScrub);
+ mct_AdjustScrub_D(pDCTstatA, &nvbits);
+ OF_ScrubCTL |= (u32) nvbits << 16;
- val = mctGet_NVbits(NV_DramBKScrub);
- OF_ScrubCTL |= val;
+ nvbits = mctGet_NVbits(NV_L2BKScrub);
+ OF_ScrubCTL |= (u32) nvbits << 8;
+
+ nvbits = mctGet_NVbits(NV_DramBKScrub);
+ OF_ScrubCTL |= nvbits;
AllECC = 1;
MemClrECC = 0;
- print_t(" ECCInit 0 \n");
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
struct DCTStatStruc *pDCTstat;
pDCTstat = pDCTstatA + Node;
LDramECC = isDramECCEn_D(pDCTstat);
if(pDCTstat->ErrCode != SC_RunningOK) {
pDCTstat->Status &= ~(1 << SB_ECCDIMMs);
- if (OB_NBECC) {
+ if (!OB_NBECC) {
pDCTstat->ErrStatus |= (1 << SB_DramECCDis);
}
AllECC = 0;
}
} /* if Node present */
}
- print_t(" ECCInit 1 \n");
if(AllECC)
pMCTstat->GStatus |= 1<<GSB_ECCDIMMs;
else
pMCTstat->GStatus &= ~(1<<GSB_ECCDIMMs);
- print_t(" ECCInit 2 \n");
-
/* Program the Dram BKScrub CTL to the proper (user selected) value.*/
/* Reset MC4_STS. */
for (Node = 0; Node < MAX_NODES_SUPPORTED; Node++) {
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 */ /*set dram background scrubbing to setup value */
+ 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 */
}
- print_t(" ECCInit 3 \n");
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;
}
}
}
-
+#ifdef UNUSED_CODE
static u32 GetScrubAddr_D(u32 Node)
{
/* Get the current 40-bit Scrub ADDR address, scaled to 32-bits,
return val; /* ScrubAddr[39:8] */
}
-
+#endif
static u8 isDramECCEn_D(struct DCTStatStruc *pDCTstat)
{