[LinuxBIOS] Opteron memclk speed/loading fix

Tao Liu liutao1980 at gmail.com
Sat Apr 30 11:01:49 CEST 2005


Hello,

the following patch fixes memclk selection on different loadings for opteron,
it is useful if you have more than 4dimms for one opteron cpu. 

Tao

--- freebios2-orig/src/northbridge/amd/amdk8/raminit.c	2005-04-30
16:04:13.000000000 +0800
+++ freebios2/src/northbridge/amd/amdk8/raminit.c	2005-04-30
16:14:59.000000000 +0800
@@ -1227,8 +1227,8 @@
 {
 	/* Compute the minimum cycle time for these dimms */
 	struct spd_set_memclk_result result;
-	unsigned min_cycle_time, min_latency, bios_cycle_time;
-	int i;
+	unsigned min_cycle_time, min_latency, fix_cycle_time;
+	int i, dimm_count, double_rank;
 	uint32_t value;
 
 	static const int latency_indicies[] = { 26, 23, 9 };
@@ -1240,12 +1240,50 @@
 	};
 
 
+	dimm_count = 0;
+	double_rank = 0;
+	for (i = 0; i < DIMM_SOCKETS; i++) {
+		if (dimm_mask & (1 << i)) {
+			dimm_count++;
+			if (spd_read_byte(ctrl->channel0[i], 5) > 1)
+				double_rank++;
+		}
+		if (dimm_mask & (1 << (i + DIMM_SOCKETS))) {
+			dimm_count++;
+			if (spd_read_byte(ctrl->channel1[i], 5) > 1)
+				double_rank++;
+		}
+	}
+
 	value = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
 	min_cycle_time = min_cycle_times[(value >> NBCAP_MEMCLK_SHIFT) &
NBCAP_MEMCLK_MASK];
-	bios_cycle_time = min_cycle_times[
+	/* DDR speed/loading fix */
+	fix_cycle_time = 0x50;
+	if (is_dual_channel(ctrl)) {
+		if (dimm_count > 4) {
+			if (is_cpu_pre_c0())
+				fix_cycle_time = 0x75;
+			else
+				fix_cycle_time = 0x60;
+		} else {
+			if (double_rank > 2)
+				fix_cycle_time = 0x60;
+		}
+	} else {
+		if (dimm_count > 2) {
+			fix_cycle_time = 0x60;
+		} else {
+			if (double_rank > 1)
+				fix_cycle_time = 0x60;
+		}
+	}
+	if (fix_cycle_time > min_cycle_time)
+		min_cycle_time = fix_cycle_time;
+	/* BIOS settings fix */
+	fix_cycle_time = min_cycle_times[
 		read_option(CMOS_VSTART_max_mem_clock, CMOS_VLEN_max_mem_clock, 0)];
-	if (bios_cycle_time > min_cycle_time) {
-		min_cycle_time = bios_cycle_time;
+	if (fix_cycle_time > min_cycle_time) {
+		min_cycle_time = fix_cycle_time;
 	}
 	min_latency = 2;




More information about the coreboot mailing list