<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>