<br><br>2011/4/1 Keith Hui <<a href="mailto:buurin@gmail.com">buurin@gmail.com</a>>:<br>> ping?<br><br><blockquote style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class="gmail_quote">
Adds support for initializing registered SDRAM modules on Intel 440BX northbridge.<br><br>Drops unneeded romcc-inspired programming tricks.<br><br>Only set nbxecc flags (see 440BX datasheet, page 3-16) when a non-ECC module has been detected<br>
in a row via SPD; also drops an unneeded intermediate variable used in setting them.<br><br>Boot tested on ASUS P2B-LS with regular and registered ECC SDRAM under Linux and memtest86+.<br><br>Signed-off-by: Keith Hui <<a href="mailto:buurin@gmail.com">buurin@gmail.com</a>><br>
<br>Index: src/northbridge/intel/i440bx/raminit.c<br>===================================================================<br>--- src/northbridge/intel/i440bx/raminit.c (revision 6460)<br>+++ src/northbridge/intel/i440bx/raminit.c (working copy)<br>
@@ -721,19 +721,23 @@<br> */<br> static void set_dram_row_attributes(void)<br> {<br>- int i, dra, drb, col, width, value, rps, edosd, ecc, nbxecc;<br>+ int i, dra, drb, col, width, value, rps;<br> u8 bpr; /* Top 8 bits of PGPOL */<br>
+ u8 nbxecc = 0; /* NBXCFG[31:24] */<br>+ u8 edo, sd, regsd; /* EDO, SDRAM, registered SDRAM */<br><br>- edosd = 0;<br>+ edo = 0;<br>+ sd = 0;<br>+ regsd = 1;<br> rps = 0;<br> drb = 0;<br> bpr = 0;<br>- nbxecc = 0xff;<br>
<br> for (i = 0; i < DIMM_SOCKETS; i++) {<br> unsigned int device;<br> device = DIMM0 + i;<br> bpr >>= 2;<br>+ nbxecc >>= 2;<br><br> /* First check if a DIMM is actually present. */<br> value = spd_read_byte(device, SPD_MEMORY_TYPE);<br>
@@ -742,13 +746,13 @@<br> || value == SPD_MEMORY_TYPE_SDRAM) {<br><br> if (value == SPD_MEMORY_TYPE_EDO) {<br>- edosd |= 0x02;<br>+ edo = 1;<br> } else if (value == SPD_MEMORY_TYPE_SDRAM) {<br></blockquote>
<div><br>Can you add a #define for SPD_MEMORY_TYPE_REGISTERED_SDRAM to src/include/spd.h as well ? If that is relevant to do, ofcourse.<br> </div><blockquote style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class="gmail_quote">
- edosd |= 0x04;<br>+ sd = 1;<br> }<br> PRINT_DEBUG("Found DIMM in slot %d\n", i);<br><br>- if (edosd == 0x06) {<br>+ if (edo && sd) {<br> print_err("Mixing EDO/SDRAM unsupported!\n");<br>
die("HALT\n");<br> }<br>@@ -764,24 +768,38 @@<br> * TODO: Other register than NBXCFG also needs this<br> * ECC information.<br> */<br>- ecc = spd_read_byte(device, SPD_DIMM_CONFIG_TYPE);<br>
+ value = spd_read_byte(device, SPD_DIMM_CONFIG_TYPE);<br><br> /* Data width */<br> width = spd_read_byte(device, SPD_MODULE_DATA_WIDTH_LSB);<br><br> /* Exclude error checking data width from page size calculations */<br>
- if (ecc) {<br>+ if (value) {<br> value = spd_read_byte(device,<br> SPD_ERROR_CHECKING_SDRAM_WIDTH);<br> width -= value;<br> /* ### ECC */<br> /* Clear top 2 bits to help set up NBXCFG. */<br>- ecc &= 0x3f;<br>
+ nbxecc &= 0x3f;<br> } else {<br> /* Without ECC, top 2 bits should be 11. */<br>- ecc |= 0xc0;<br>+ nbxecc |= 0xc0;<br> }<br><br>+ /* If any installed DIMM is *not* registered, this system cannot be<br>
+ * configured for registered SDRAM.<br>+ * By registered, only the address and control lines need to be, which<br>+ * we can tell by reading SPD byte 21, bit 1.<br>+ */<br>+ value = spd_read_byte(device, SPD_MODULE_ATTRIBUTES);<br>
+ <br>+ PRINT_DEBUG("DIMM is ");<br>+ if ((value & 0x02) == 0) {<br>+ regsd = 0;<br>+ PRINT_DEBUG("not ");<br>+ }<br>+ PRINT_DEBUG("registered\n");<br>+ <br> /* Calculate page size in bits. */<br>
value = ((1 << col) * width);<br><br>@@ -801,7 +819,6 @@<br> * Second bank of 1-bank DIMMs "doesn't have<br> * ECC" - or anything.<br> */<br>- ecc |= 0x80;<br> if (dra == 2) {<br>
dra = 0x0; /* 2KB */<br> } else if (dra == 4) {<br>@@ -878,7 +895,6 @@<br><br> /* If there's no DIMM in the slot, set dra to 0x00. */<br> dra = 0x00;<br>- ecc = 0xc0;<br> /* Still have to propagate DRB over. */<br>
drb &= 0xff;<br> drb |= (drb << 8);<br>@@ -895,7 +911,6 @@<br> drb >>= 8;<br><br> rps |= (dra & 0x0f) << (i * 4);<br>- nbxecc = (nbxecc >> 2) | (ecc & 0xc0);<br> }<br><br> /* Set paging policy register. */<br>
@@ -910,20 +925,19 @@<br> pci_write_config8(NB, NBXCFG + 3, nbxecc);<br> PRINT_DEBUG("NBXECC[31:24] has been set to 0x%02x\n", nbxecc);<br><br>- /* Set DRAMC[4:3] to proper memory type (EDO/SDRAM).<br>- * TODO: Registered SDRAM support.<br>
- */<br>- edosd &= 0x07;<br>- if (edosd & 0x02) {<br>- edosd |= 0x00;<br>- } else if (edosd & 0x04) {<br>- edosd |= 0x08;<br>+ /* Set DRAMC[4:3] to proper memory type (EDO/SDRAM/Registered SDRAM). */<br>+<br>
+ /* i will be used to set DRAMC[4:3]. */<br>+ if (regsd && sd) {<br>+ i = 0x10; // Registered SDRAM<br></blockquote><div><br>The datasheets says that this are bits: i = 0x2, not 0x10.<br><br></div><blockquote style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class="gmail_quote">
+ } else if (sd) {<br>+ i = 0x08; // SDRAM<br></blockquote><div><br>i = 0x1, not 0x8</div><div><br></div><blockquote style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class="gmail_quote">
+ } else {<br>+ i = 0; // EDO <br></blockquote><blockquote style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class="gmail_quote"> }<br>- edosd &= 0x18;<br><br>- /* edosd is now in the form needed for DRAMC[4:3]. */<br>
value = pci_read_config8(NB, DRAMC) & 0xe7;<br>- value |= edosd;<br>+ value |= i;<br> pci_write_config8(NB, DRAMC, value);<br> PRINT_DEBUG("DRAMC has been set to 0x%02x\n", value);<br> } <br></blockquote>