HAOUAS Elyes has uploaded this change for review.

View Change

[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;
+ }
}

To view, visit change 37448. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I6c17c18171e258a70e153009e953ce898ad3baa9
Gerrit-Change-Number: 37448
Gerrit-PatchSet: 1
Gerrit-Owner: HAOUAS Elyes <ehaouas@noos.fr>
Gerrit-MessageType: newchange