aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdmct/mct/mctsrc.c
diff options
context:
space:
mode:
authorMarc Jones (marc.jones <Marc Jones (marc.jones@amd.com)>2008-04-11 03:20:28 +0000
committerMarc Jones <marc.jones@amd.com>2008-04-11 03:20:28 +0000
commite3aeb93a52d03e1b3dfcf30c66956b18f7f600d7 (patch)
tree84f5632e9d913a7c22f2ee3662704883a93fac79 /src/northbridge/amd/amdmct/mct/mctsrc.c
parent234e87f137faff67c391c4df678a82b763089119 (diff)
Bring Fam10 memory controller init up to date with the latest AMD BKDG
recomendations. Changes include the following: fix > 4GB dqs tests fix channel interleaving ecc memory scrub updates MC tristating updates debug print changes fix memory hoisting across nodes - The DRAM Hole Address Register is set via devx in each node, but the Node number <-> DRAM Base mapping and the Node number <-> DstNode mapping is set in Node 0. The memmap is setup on node0 and copied to the other nodes later. so dev, not devx. The bug was the hole was always being set on the first node. Signed-off-by: Marc Jones (marc.jones@amd.com) Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3232 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/northbridge/amd/amdmct/mct/mctsrc.c')
-rw-r--r--src/northbridge/amd/amdmct/mct/mctsrc.c66
1 files changed, 22 insertions, 44 deletions
diff --git a/src/northbridge/amd/amdmct/mct/mctsrc.c b/src/northbridge/amd/amdmct/mct/mctsrc.c
index 243467a3eb..7b5e1b4b54 100644
--- a/src/northbridge/amd/amdmct/mct/mctsrc.c
+++ b/src/northbridge/amd/amdmct/mct/mctsrc.c
@@ -1,7 +1,7 @@
/*
* 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
@@ -42,10 +42,7 @@ static void mct_SetFinalRcvrEnDly_D(struct DCTStatStruc *pDCTstat,
u8 Channel, u8 Receiver,
u32 dev, u32 index_reg,
u8 Addl_Index, u8 Pass);
-static void CalcMaxLatency_D(struct DCTStatStruc *pDCTstat,
- u8 DQSRcvrEnDly, u8 Channel);
static void mct_SetMaxLatency_D(struct DCTStatStruc *pDCTstat, u8 Channel, u8 DQSRcvEnDly);
-static void mct_SetDQSRcvEn_D(struct DCTStatStruc *pDCTstat, u32 val);
static void fenceDynTraining_D(struct MCTStatStruc *pMCTstat,
struct DCTStatStruc *pDCTstat, u8 dct);
static void mct_DisableDQSRcvEn_D(struct DCTStatStruc *pDCTstat);
@@ -766,9 +763,8 @@ static u8 mct_CompareTestPatternQW0_D(struct MCTStatStruc *pMCTstat,
u8 *test_buf;
u8 i;
u8 result;
- u8 *addr_lo_buf;
+ u8 value;
- SetUpperFSbase(addr); // needed?
if(Pass == FirstPass) {
if(pattern==1) {
@@ -780,44 +776,27 @@ static u8 mct_CompareTestPatternQW0_D(struct MCTStatStruc *pMCTstat,
test_buf = (u8 *)TestPattern2_D;
}
- addr_lo_buf = (u8 *) (addr << 8);
- result = DQS_FAIL;
+ SetUpperFSbase(addr);
+ addr <<= 8;
if((pDCTstat->Status & (1<<SB_128bitmode)) && channel ) {
- addr_lo_buf += 8; /* second channel */
+ addr += 8; /* second channel */
test_buf += 8;
}
-
-#if DQS_TRAIN_DEBUG > 4
- print_debug("\t\t\t\t\t\tQW0 : test_buf = ");
- print_debug_hex32((unsigned)test_buf);
- print_debug(": ");
+ print_debug_dqs_pair("\t\t\t\t\t\t test_buf = ", (u32)test_buf, " | addr_lo = ", addr, 4);
for (i=0; i<8; i++) {
- print_debug_hex8(test_buf[i]); print_debug(" ");
- }
- print_debug("\n");
-
- print_debug("\t\t\t\t\t\tQW0 : addr_lo_buf = ");
- print_debug_hex32((unsigned)addr_lo_buf);
- print_debug(": ");
- for (i=0; i<8; i++) {
- print_debug_hex8(addr_lo_buf[i]); print_debug(" ");
- }
- print_debug("\n");
-#endif
+ value = read32_fs(addr);
+ print_debug_dqs_pair("\t\t\t\t\t\t\t\t ", test_buf[i], " | ", value, 4);
- /* prevent speculative execution of following instructions */
- _EXECFENCE;
-
- for (i=0; i<8; i++) {
- if(addr_lo_buf[i] == test_buf[i]) {
+ if (value == test_buf[i]) {
pDCTstat->DqsRcvEn_Pass |= (1<<i);
} else {
pDCTstat->DqsRcvEn_Pass &= ~(1<<i);
}
}
+ result = DQS_FAIL;
if (Pass == FirstPass) {
/* if first pass, at least one byte lane pass
@@ -1062,7 +1041,7 @@ static void fenceDynTraining_D(struct MCTStatStruc *pMCTstat,
Set_NB32_index_wait(dev, index_reg, 0x08, val);
/* Wait 200 MEMCLKs. */
- mct_Wait_10ns (20000); /* wait 200us */
+ mct_Wait(50000); /* wait 200us */
/* Clear F2x[1,0]9C_x08[PhyFenceTrEn]=0. */
val = Get_NB32_index_wait(dev, index_reg, 0x08);
@@ -1101,21 +1080,20 @@ static void fenceDynTraining_D(struct MCTStatStruc *pMCTstat,
}
-static void mct_Wait_10ns (u32 cycles)
+static void mct_Wait(u32 cycles)
{
- u32 saved, i;
+ u32 saved;
u32 hi, lo, msr;
- /* cycles = number of 10ns cycles(or longer) to delay */
- /* FIXME: Need to calibrate to CPU/NCLK speed? */
+ /* Wait # of 50ns cycles
+ This seems like a hack to me... */
- msr = 0x10; /* TSC */
- for (i = 0; i < cycles; i++) {
- _RDMSR(msr, &lo, &hi);
- saved = lo;
+ cycles <<= 3; /* x8 (number of 1.25ns ticks) */
- do {
- _RDMSR(msr, &lo, &hi);
- } while (lo - saved < 8); /* 8 x 1.25 ns as NCLK is at 1.25ns */
- }
+ msr = 0x10; /* TSC */
+ _RDMSR(msr, &lo, &hi);
+ saved = lo;
+ do {
+ _RDMSR(msr, &lo, &hi);
+ } while (lo - saved < cycles );
}