summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/northbridge/intel/i82810/raminit.c75
1 files changed, 74 insertions, 1 deletions
diff --git a/src/northbridge/intel/i82810/raminit.c b/src/northbridge/intel/i82810/raminit.c
index 0b3e965192..d5b4864104 100644
--- a/src/northbridge/intel/i82810/raminit.c
+++ b/src/northbridge/intel/i82810/raminit.c
@@ -72,6 +72,12 @@ static const u8 translate_i82810_to_bank[] = {
/* MB */0, 0, 0, 8, 0, 16, 16, 0, 32, 32, 0, 64, 64, 0, 128, 128,
};
+struct dimm_info {
+ u8 ds; /* dual-sided */
+ u8 ss; /* single-sided */
+ u8 size;
+};
+
/*-----------------------------------------------------------------------------
SDRAM configuration functions.
-----------------------------------------------------------------------------*/
@@ -275,10 +281,77 @@ static void set_dram_timing(void)
* 0x1145 384MB 0xdf 256MB dual-sided 128MB single-sided
* 0x4445 384MB 0xfd 128MB single-sided 256MB dual-sided
* 0x0001 512MB 0xff 256MB dual-sided 256MB dual-sided
+ *
+ * See also:
+ * http://www.coreboot.org/pipermail/coreboot/2009-May/047966.html
*/
static void set_dram_buffer_strength(void)
{
- pci_write_config16(PCI_DEV(0, 0, 0), BUFF_SC, 0x77da);
+ struct dimm_info d0, d1;
+ u16 buff_sc;
+
+ /* Check first slot. */
+ d0.size = d0.ds = d0.ss = 0;
+ if (smbus_read_byte(DIMM_SPD_BASE, SPD_MEMORY_TYPE)
+ == SPD_MEMORY_TYPE_SDRAM) {
+ d0.size = smbus_read_byte(DIMM_SPD_BASE, SPD_BANK_DENSITY);
+ d0.ds = smbus_read_byte(DIMM_SPD_BASE, SPD_NUM_DIMM_BANKS) > 1;
+ d0.ss = !d0.ds;
+ }
+
+ /* Check second slot. */
+ d1.size = d1.ds = d1.ss = 0;
+ if (smbus_read_byte(DIMM_SPD_BASE + 1, SPD_MEMORY_TYPE)
+ == SPD_MEMORY_TYPE_SDRAM) {
+ d1.size = smbus_read_byte(DIMM_SPD_BASE + 1, SPD_BANK_DENSITY);
+ d1.ds = smbus_read_byte(DIMM_SPD_BASE + 1,
+ SPD_NUM_DIMM_BANKS) > 1;
+ d1.ss = !d1.ds;
+ }
+
+ buff_sc = 0;
+
+ /* Tame the beast... */
+ if ((d0.ds && d1.ds) || (d0.ds && d1.ss) || (d0.ss && d1.ds))
+ buff_sc |= 1;
+ if ((d0.size && !d1.size) || (!d0.size && d1.size) || (d0.ss && d1.ss))
+ buff_sc |= 1 << 1;
+ if ((d0.ds && !d1.size) || (!d0.size && d1.ds) || (d0.ss && d1.ss)
+ || (d0.ds && d1.ss) || (d0.ss && d1.ds))
+ buff_sc |= 1 << 2;
+ if ((d0.ss && !d1.size) || (!d0.size && d1.ss))
+ buff_sc |= 1 << 3;
+ if ((d0.size && !d1.size) || (!d0.size && d1.size))
+ buff_sc |= 1 << 4;
+ if ((d0.ds && !d1.size) || (!d0.size && d1.ds) || (d0.ds && d1.ss)
+ || (d0.ss && d1.ds))
+ buff_sc |= 1 << 6;
+ if ((d0.ss && !d1.size) || (!d0.size && d1.ss) || (d0.ss && d1.ss))
+ buff_sc |= 3 << 6;
+ if ((!d0.size && d1.ss) || (d0.ds && d1.ss) || (d0.ss && d1.ss))
+ buff_sc |= 1 << 8;
+ if (d0.size && !d1.size)
+ buff_sc |= 3 << 8;
+ if ((d0.ss && !d1.size) || (d0.ss && d1.ss) || (d0.ss && d1.ds))
+ buff_sc |= 1 << 10;
+ if (!d0.size && d1.size)
+ buff_sc |= 3 << 10;
+ if ((d0.size && !d1.size) || (d0.ss && !d1.size) || (!d0.size && d1.ss)
+ || (d0.ss && d1.ss) || (d0.ds && d1.ss))
+ buff_sc |= 1 << 12;
+ if (d0.size && !d1.size)
+ buff_sc |= 1 << 13;
+ if ((!d0.size && d1.size) || (d0.ss && !d1.size) || (d0.ss && d1.ss)
+ || (d0.ss && d1.ds))
+ buff_sc |= 1 << 14;
+ if (!d0.size && d1.size)
+ buff_sc |= 1 << 15;
+
+ print_debug("BUFF_SC calculated to 0x");
+ print_debug_hex16(buff_sc);
+ print_debug("\r\n");
+
+ pci_write_config16(PCI_DEV(0, 0, 0), BUFF_SC, buff_sc);
}
/*-----------------------------------------------------------------------------