HAOUAS Elyes has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/37448 )
Change subject: [test] nb/i945: Write CxWL1REOST ......................................................................
[test] nb/i945: Write CxWL1REOST
Got the error: "Could not find rising edge" if channel 0 is not populated.
Change-Id: I6c17c18171e258a70e153009e953ce898ad3baa9 Signed-off-by: Elyes HAOUAS ehaouas@noos.fr --- M src/northbridge/intel/i945/rcven.c 1 file changed, 68 insertions(+), 47 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/48/37448/1
diff --git a/src/northbridge/intel/i945/rcven.c b/src/northbridge/intel/i945/rcven.c index 5a90807..1faf71e 100644 --- a/src/northbridge/intel/i945/rcven.c +++ b/src/northbridge/intel/i945/rcven.c @@ -21,11 +21,14 @@ /** * sample the strobes signal */ -static u32 sample_strobes(int channel_offset, struct sys_info *sysinfo) +static u32 sample_strobes(int dimm, struct sys_info *sysinfo) { u32 reg32, addr; int i; + int channel_offset = 0;
+ if (dimm >> 1) + channel_offset = 0x80; MCHBAR32(C0DRC1 + channel_offset) |= (1 << 6);
MCHBAR32(C0DRC1 + channel_offset) &= ~(1 << 6); @@ -60,10 +63,13 @@ * This function sets receive enable coarse and medium timing parameters */
-static void set_receive_enable(int channel_offset, u8 medium, u8 coarse) +static void set_receive_enable(int dimm, u8 medium, u8 coarse) { u32 reg32; + int channel_offset = 0;
+ if (dimm >> 1) + channel_offset = 0x80; printk(BIOS_SPEW, " set_receive_enable() medium=0x%x, coarse=0x%x\n", medium, coarse);
reg32 = MCHBAR32(C0DRT1 + channel_offset); @@ -97,8 +103,13 @@
}
-static int normalize(int channel_offset, u8 *mediumcoarse, u8 *fine) +static int normalize(int dimm, u8 *mediumcoarse, u8 *fine) { + int channel_offset = 0; + + if (dimm >> 1) + channel_offset = 0x80; + printk(BIOS_SPEW, " normalize()\n");
if (*fine < 0x80) @@ -112,19 +123,23 @@ return -1; }
- set_receive_enable(channel_offset, *mediumcoarse & 3, + set_receive_enable(dimm, *mediumcoarse & 3, *mediumcoarse >> 2);
- MCHBAR8(C0WL0REOST + channel_offset) = *fine; + MCHBAR8(C0WL0REOST + (dimm >> 1) + channel_offset) = *fine;
return 0; }
-static int find_preamble(int channel_offset, u8 *mediumcoarse, +static int find_preamble(int dimm, u8 *mediumcoarse, struct sys_info *sysinfo) { /* find start of the data phase */ u32 reg32; + int channel_offset = 0; + + if (dimm >> 1) + channel_offset = 0x80;
printk(BIOS_SPEW, " find_preamble()\n");
@@ -135,10 +150,10 @@ } *mediumcoarse -= 4;
- set_receive_enable(channel_offset, *mediumcoarse & 3, + set_receive_enable(dimm, *mediumcoarse & 3, *mediumcoarse >> 2);
- reg32 = sample_strobes(channel_offset, sysinfo); + reg32 = sample_strobes(dimm, sysinfo);
} while (reg32 & (1 << 19));
@@ -154,8 +169,13 @@ * add a quarter clock to the current receive enable settings */
-static int add_quarter_clock(int channel_offset, u8 *mediumcoarse, u8 *fine) +static int add_quarter_clock(int dimm, u8 *mediumcoarse, u8 *fine) { + int channel_offset = 0; + + if (dimm >> 1) + channel_offset = 0x80; + printk(BIOS_SPEW, " add_quarter_clock() mediumcoarse=%02x fine=%02x\n", *mediumcoarse, *fine); if (*fine >= 0x80) { @@ -167,31 +187,34 @@ return -1; }
- set_receive_enable(channel_offset, *mediumcoarse & 3, + set_receive_enable(dimm, *mediumcoarse & 3, *mediumcoarse >> 2); } else { *fine += 0x80; }
- MCHBAR8(C0WL0REOST + channel_offset) = *fine; + MCHBAR8(C0WL0REOST + (dimm >> 1) + channel_offset) = *fine;
return 0; }
-static int find_strobes_low(int channel_offset, u8 *mediumcoarse, u8 *fine, +static int find_strobes_low(int dimm, u8 *mediumcoarse, u8 *fine, struct sys_info *sysinfo) { u32 rcvenmt; + int channel_offset = 0; + if (dimm >> 1) + channel_offset = 0x80;
printk(BIOS_SPEW, " find_strobes_low()\n");
for (;;) { - MCHBAR8(C0WL0REOST + channel_offset) = *fine; + MCHBAR8(C0WL0REOST + (dimm >> 1) + channel_offset) = *fine;
- set_receive_enable(channel_offset, *mediumcoarse & 3, + set_receive_enable(dimm, *mediumcoarse & 3, *mediumcoarse >> 2);
- rcvenmt = sample_strobes(channel_offset, sysinfo); + rcvenmt = sample_strobes(dimm, sysinfo);
if (((rcvenmt & (1 << 18)) != 0)) return 0; @@ -212,22 +235,26 @@ return 0; }
-static int find_strobes_edge(int channel_offset, u8 *mediumcoarse, u8 *fine, +static int find_strobes_edge(int dimm, u8 *mediumcoarse, u8 *fine, struct sys_info *sysinfo) {
int counter; u32 rcvenmt; + int channel_offset = 0; + + if (dimm >> 1) + channel_offset = 0x80;
printk(BIOS_SPEW, " find_strobes_edge()\n");
counter = 8; - set_receive_enable(channel_offset, *mediumcoarse & 3, + set_receive_enable(dimm, *mediumcoarse & 3, *mediumcoarse >> 2);
for (;;) { - MCHBAR8(C0WL0REOST + channel_offset) = *fine; - rcvenmt = sample_strobes(channel_offset, sysinfo); + MCHBAR8(C0WL0REOST + (dimm >> 1) + channel_offset) = *fine; + rcvenmt = sample_strobes(dimm, sysinfo);
if ((rcvenmt & (1 << 19)) == 0) { counter = 8; @@ -249,7 +276,7 @@ *fine = 0; *mediumcoarse += 2; if (*mediumcoarse <= 0x40) { - set_receive_enable(channel_offset, *mediumcoarse & 3, + set_receive_enable(dimm, *mediumcoarse & 3, *mediumcoarse >> 2); continue; } @@ -261,57 +288,55 @@ *fine -= 7; if (*fine >= 0xf9) { *mediumcoarse -= 2; - set_receive_enable(channel_offset, *mediumcoarse & 3, + set_receive_enable(dimm, *mediumcoarse & 3, *mediumcoarse >> 2); }
*fine &= ~(1 << 3); - MCHBAR8(C0WL0REOST + channel_offset) = *fine; + MCHBAR8(C0WL0REOST + (dimm >> 1) + channel_offset) = *fine;
return 0; }
-/** - * Here we use a trick. The RCVEN channel 0 registers are all at an - * offset of 0x80 to the channel 0 registers. We don't want to waste - * a lot of if ()s so let's just pass 0 or 0x80 for the channel offset. - */ - -static int receive_enable_autoconfig(int channel_offset, +static int receive_enable_autoconfig(int dimm, struct sys_info *sysinfo) { + int channel_offset; u8 mediumcoarse; u8 fine;
+ if (dimm >> 1) /* Channel 1 */ + channel_offset = 0x80; + printk(BIOS_SPEW, "receive_enable_autoconfig() for channel %d\n", - channel_offset ? 1 : 0); + dimm >> 1);
/* Set initial values */ mediumcoarse = (sysinfo->cas << 2) | 3; fine = 0;
- if (find_strobes_low(channel_offset, &mediumcoarse, &fine, sysinfo)) + if (find_strobes_low(dimm, &mediumcoarse, &fine, sysinfo)) return -1;
- if (find_strobes_edge(channel_offset, &mediumcoarse, &fine, sysinfo)) + if (find_strobes_edge(dimm, &mediumcoarse, &fine, sysinfo)) return -1;
- if (add_quarter_clock(channel_offset, &mediumcoarse, &fine)) + if (add_quarter_clock(dimm, &mediumcoarse, &fine)) return -1;
- if (find_preamble(channel_offset, &mediumcoarse, sysinfo)) + if (find_preamble(dimm, &mediumcoarse, sysinfo)) return -1;
- if (add_quarter_clock(channel_offset, &mediumcoarse, &fine)) + if (add_quarter_clock(dimm, &mediumcoarse, &fine)) return -1;
- if (normalize(channel_offset, &mediumcoarse, &fine)) + if (normalize(dimm, &mediumcoarse, &fine)) return -1;
/* This is a debug check to see if the rcven code is fully working. * It can be removed when the output message is not printed anymore */ - if (MCHBAR8(C0WL0REOST + channel_offset) == 0) + if (MCHBAR8(C0WL0REOST + (dimm >> 1) + channel_offset) == 0) printk(BIOS_DEBUG, "Weird. No C%sWL0REOST\n", channel_offset?"1":"0");
return 0; @@ -319,15 +344,11 @@
void receive_enable_adjust(struct sys_info *sysinfo) { - /* Is channel 0 populated? */ - if (sysinfo->dimm[0] != SYSINFO_DIMM_NOT_POPULATED - || sysinfo->dimm[1] != SYSINFO_DIMM_NOT_POPULATED) - if (receive_enable_autoconfig(0, sysinfo)) - return; + int i;
- /* Is channel 1 populated? */ - if (sysinfo->dimm[2] != SYSINFO_DIMM_NOT_POPULATED - || sysinfo->dimm[3] != SYSINFO_DIMM_NOT_POPULATED) - if (receive_enable_autoconfig(0x80, sysinfo)) - return; + for (i = 0; i < (2 * DIMM_SOCKETS); i++) { + if (sysinfo->dimm[i] != SYSINFO_DIMM_NOT_POPULATED) + if (receive_enable_autoconfig(i, sysinfo)) + return; + } }