this patch calculates BUFF_SC according to set of rules guessed out of
some various results i came up with different DIMM setups.
looking into this patch reveals it is just begging for optimization, so role
up
your sleeves, kick out those old optimization shoes, and see how you handle
this better 8-) (uwe suggested using a table, and no argue there...)
Signed-off-by: Elia Yehuda <[EMAIL PROTECTED]>
Index: coreboot-v2/src/northbridge/intel/i82810/raminit.c
===================================================================
--- coreboot-v2/src/northbridge/intel/i82810/raminit.c (revision 3761)
+++ coreboot-v2/src/northbridge/intel/i82810/raminit.c (working copy)
@@ -220,28 +220,186 @@
* Common results (tested on actual hardware) are:
*
* (DRP: c = 128MB dual sided, d = 128MB single sided, f = 256MB dual sided)
+ * (DIMMx: DS = Dual-sided, SS = Single-sided
*
- * BUFF_SC TOM DRP DIMM0 DIMM1
+ * BUFF_SC BUFF_SC in binary TOM DRP DIMM0 DIMM1
* ----------------------------------------------------------------------------
- * 0x3356 128MB 0x0c 128MB dual-sided -
- * 0xcc56 128MB 0xc0 - 128MB dual-sided
- * 0x77da 128MB 0x0d 128MB single-sided -
- * 0xddda 128MB 0xd0 - 128MB single-sided
- * 0x0001 256MB 0xcc 128MB dual-sided 128MB dual-sided
- * 0x55c6 256MB 0xdd 128MB single-sided 128MB single-sided
- * 0x4445 256MB 0xcd 128MB single-sided 128MB dual-sided
- * 0x1145 256MB 0xdc 128MB dual-sided 128MB single-sided
- * 0x3356 256MB 0x0f 256MB dual-sided -
- * 0xcc56 256MB 0xf0 - 256MB dual-sided
- * 0x0001 384MB 0xcf 256MB dual-sided 128MB dual-sided
- * 0x0001 384MB 0xfc 128MB dual-sided 256MB dual-sided
- * 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
+ * 0x3356 0 0 1 1 00 11 01 01 01 10 128MB 0x0c 128MB DS -
+ * 0xcc56 1 1 0 0 11 00 01 01 01 10 128MB 0xc0 - 128MB DS
+ * 0x77da 0 1 1 1 01 11 11 01 10 10 128MB 0x0d 128MB SS -
+ * 0xddda 1 1 0 1 11 01 11 01 10 10 128MB 0xd0 - 128MB SS
+ * 0x0001 0 0 0 0 00 00 00 00 00 01 256MB 0xcc 128MB DS 128MB DS
+ * 0x55c6 0 1 0 1 01 01 11 00 01 10 256MB 0xdd 128MB SS 128MB SS
+ * 0x4445 0 1 0 0 01 00 01 00 01 01 256MB 0xcd 128MB SS 128MB DS
+ * 0x1145 0 0 0 1 00 01 01 00 01 01 256MB 0xdc 128MB DS 128MB SS
+ * 0x3356 0 0 1 1 00 11 01 01 01 10 256MB 0x0f 256MB DS -
+ * 0xcc56 1 1 0 0 11 00 01 01 01 10 256MB 0xf0 - 256MB DS
+ * 0x0001 0 0 0 0 00 00 00 00 00 01 384MB 0xcf 256MB DS 128MB DS
+ * 0x0001 0 0 0 0 00 00 00 00 00 01 384MB 0xfc 128MB DS 256MB DS
+ * 0x1145 0 0 0 1 00 01 01 00 01 01 384MB 0xdf 256MB DS 128MB SS
+ * 0x4445 0 1 0 0 01 00 01 00 01 01 384MB 0xfd 128MB SS 256MB DS
+ * 0x0001 0 0 0 0 00 00 00 00 00 01 512MB 0xff 256MB DS 256MB DS
+ *
+ * Here is some rough reverse engineering of those codes :
+ *
+ * 0:1 00 = 0 DIMMs
+ * 01 = 2 dual
+ * 1 dual + 1 single
+ * 1 single + 1 dual
+ * 10 = 1 DIMM only
+ * 2 single
+ * 2:3 00 = 2 dual sided
+ * 01 = 1 dual sided only
+ * 2 single sided
+ * 1 dual + 1 single
+ * 1 single + 1 dual
+ * 10 = 1 single sided only
+ * 4:5 00 = 2 DIMMs
+ * 01 = 1 DIMM only
+ * 6:7 00 = 2 dual
+ * 01 = 1 dual only
+ * 1 dual + 1 single
+ * 1 single + 1 dual
+ * 11 = 1 single
+ * 2 single
+ * 8:9 00 = 2 dual
+ * 1 single + 1 dual
+ * 1 dual only in slot #1
+ * 01 = 1 single only in slot #1
+ * 1 dual + 1 single
+ * 2 single
+ * 11 = no dimm in slot #1
+ * 10:11 00 = 1 dual only in slot #0
+ * 2 dual
+ * 1 dual + 1 single
+ * 01 = 1 single only in slot #0
+ * 2 single
+ * 1 single + 1 dual
+ * 11 = no dimm in slot #0
+ * 12 0 = 1 dual only in slot #1
+ * 2 dual
+ * 1 single + 1 dual
+ * 1 = no dimm in slot #1
+ * 1 single
+ * 2 single
+ * 1 dual + 1 single
+ * 13 0 = any in slot #1
+ * 1 = no dimm in slot #1
+ * 14 0 = 1 dual only in slot #0
+ * 2 dual
+ * 1 dual + 1 single
+ * 1 = no dimm in slot #0
+ * 1 single only in slot #0
+ * 2 single
+ * 1 single + 1 dual
+ * 15 0 = no dimm in slot #1
+ * 2 DIMMs
+ * 1 = no dimm in slot #0
+ *
*/
static void set_dram_buffer_strength(const struct mem_controller *ctrl)
{
- pci_write_config16(ctrl->d0, BUFF_SC, 0x77da);
+ struct dimm_info dimm0, dimm1;
+ u16 buff_sc;
+
+ /* check 1st slot */
+ if (smbus_read_byte(ctrl->channel0[0], 2) == 4) {
+ dimm0.size = smbus_read_byte(ctrl->channel0[0], 31);
+ dimm0.dual = (smbus_read_byte(ctrl->channel0[0], 5) > 1);
+ dimm0.single = !dimm0.dual;
+ } else {
+ dimm0.size = dimm0.dual = dimm0.single = 0;
+ }
+
+ /* check 2nd slot */
+ if (smbus_read_byte(ctrl->channel0[1], 2) == 4) {
+ dimm1.size = smbus_read_byte(ctrl->channel0[1], 31);
+ dimm1.dual = (smbus_read_byte(ctrl->channel0[1], 5) > 1);
+ dimm1.single = !dimm1.dual;
+ } else {
+ dimm1.size = dimm1.dual = dimm1.single = 0;
+ }
+
+ buff_sc = 0;
+ /* tame the beast... */
+ if ( (dimm0.dual && dimm1.dual) ||
+ (dimm0.dual && dimm1.single) ||
+ (dimm0.single && dimm1.dual) ) {
+ buff_sc |= 1;
+ }
+ if ( (dimm0.size && !dimm1.size) ||
+ (!dimm0.size && dimm1.size) ||
+ (dimm0.single && dimm1.single) ) {
+ buff_sc |= 1 << 1;
+ }
+ if ( (dimm0.dual && !dimm1.size) ||
+ (!dimm0.size && dimm1.dual) ||
+ (dimm0.single && dimm1.single) ||
+ (dimm0.dual && dimm1.single) ||
+ (dimm0.single && dimm1.dual) ) {
+ buff_sc |= 1 << 2;
+ }
+ if ( (dimm0.single && !dimm1.size) ||
+ (!dimm0.size && dimm1.single) ) {
+ buff_sc |= 1 << 3;
+ }
+ if ( (dimm0.size && !dimm1.size) ||
+ (!dimm0.size && dimm1.size) ) {
+ buff_sc |= 1 << 4;
+ }
+ if ( (dimm0.dual && !dimm1.size) ||
+ (!dimm0.size && dimm1.dual) ||
+ (dimm0.dual && dimm1.single) ||
+ (dimm0.single && dimm1.dual) ) {
+ buff_sc |= 1 << 6;
+ }
+ if ( (dimm0.single && !dimm1.size) ||
+ (!dimm0.size && dimm1.single) ||
+ (dimm0.single && dimm1.single) ) {
+ buff_sc |= 3 << 6;
+ }
+ if ( (!dimm0.size && dimm1.single) ||
+ (dimm0.dual && dimm1.single) ||
+ (dimm0.single && dimm1.single) ) {
+ buff_sc |= 1 << 8;
+ }
+ if (dimm0.size && !dimm1.size) {
+ buff_sc |= 3 << 8;
+ }
+ if ( (dimm0.single && !dimm1.size) ||
+ (dimm0.single && dimm1.single) ||
+ (dimm0.single && dimm1.dual) ) {
+ buff_sc |= 1 << 10;
+ }
+ if (!dimm0.size && dimm1.size) {
+ buff_sc |= 3 << 10;
+ }
+ if ( (dimm0.size && !dimm1.size) ||
+ (dimm0.single && !dimm1.size) ||
+ (!dimm0.size && dimm1.single) ||
+ (dimm0.single && dimm1.single) ||
+ (dimm0.dual && dimm1.single) ) {
+ buff_sc |= 1 << 12;
+ }
+ if (dimm0.size && !dimm1.size) {
+ buff_sc |= 1 << 13;
+ }
+ if ( (!dimm0.size && dimm1.size) ||
+ (dimm0.single && !dimm1.size) ||
+ (dimm0.single && dimm1.single) ||
+ (dimm0.single && dimm1.dual) ) {
+ buff_sc |= 1 << 14;
+ }
+ if (!dimm0.size && dimm1.size) {
+ buff_sc |= 1 << 15;
+ }
+
+ print_debug("BUFF_SC calculated to 0x");
+ print_debug_hex16(buff_sc);
+ print_debug("\r\n");
+
+ /* go a head and set the BUFF_SC */
+ pci_write_config16(ctrl->d0, BUFF_SC, buff_sc);
}
/*-----------------------------------------------------------------------------
--
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot