[coreboot] [PATCH] Heterogenous dual channel support, part 2
Carl-Daniel Hailfinger
c-d.hailfinger.devel.2006 at gmx.net
Fri Jan 16 05:17:02 CET 2009
The check for compatible tCL and associated timing after the parameters
have already been determined makes sure we don't drive any DIMM with
incorrect settings.
In a heterogenous dual channel setup, each DIMM must be checked for that
criterion.
Factor out the check to prepare for per-DIMM checks.
I'd appreciate a thorough review, especially the flow of error and
default paths of the code. They should be identical.
Once this is applied, a roughly 10-line change is sufficient to use
DIMMS with compatible, but not identical tCL timings.
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>
Index: LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c
===================================================================
--- LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c (Revision 3867)
+++ LinuxBIOSv2-asus_m2a-vm/src/northbridge/amd/amdk8/raminit_f.c (Arbeitskopie)
@@ -1792,6 +1792,51 @@
return 0;
}
+int check_spd_latency_available(u32 spd_device, unsigned min_cycle_time, unsigned min_latency)
+{
+ int latencies;
+ int latency;
+ int index;
+ int value;
+
+ latencies = spd_read_byte(spd_device, SPD_CAS_LAT);
+ if (latencies < 0)
+ return -1;
+ if (latencies == 0)
+ return 1;
+
+ /* Compute the lowest cas latency supported */
+ latency = log2(latencies) -2;
+
+ /* Walk through searching for the selected latency */
+ for (index = 0; index < 3; index++, latency++) {
+ if (!(latencies & (1 << latency))) {
+ continue;
+ }
+ if (latency == min_latency)
+ break;
+ }
+ /* If I can't find the latency or my index is bad error */
+ if ((latency != min_latency) || (index >= 3)) {
+ return -2;
+ }
+
+ /* Read the min_cycle_time for this latency */
+ value = spd_read_byte(spd_device, latency_indicies[index]);
+ if (value < 0)
+ return -1;
+
+ value = convert_to_linear(value);
+ /* All is good if the selected clock speed
+ * is what I need or slower.
+ */
+ if (value <= min_cycle_time)
+ return 1;
+
+ /* That didn't work out... */
+ return -2;
+}
+
static struct spd_set_memclk_result spd_set_memclk(const struct mem_controller *ctrl, struct mem_info *meminfo)
{
/* Compute the minimum cycle time for these dimms */
@@ -1862,10 +1907,6 @@
printk_raminit("3 min_latency: %08x\n", min_latency);
for (i = 0; (i < DIMM_SOCKETS); i++) {
- int latencies;
- int latency;
- int index;
- int value;
u32 spd_device = ctrl->channel0[i];
if (!(meminfo->dimm_mask & (1 << i))) {
@@ -1876,42 +1917,17 @@
}
}
- latencies = spd_read_byte(spd_device, SPD_CAS_LAT);
- if (latencies < 0) goto hw_error;
- if (latencies == 0) {
+ switch (check_spd_latency_available(spd_device, min_cycle_time, min_latency)) {
+ case -2:
+ /* We have an error, disable the dimm */
+ meminfo->dimm_mask = disable_dimm(ctrl, i, meminfo);
+ break;
+ case -1:
+ goto hw_error;
+ break;
+ case 1:
continue;
}
-
- /* Compute the lowest cas latency supported */
- latency = log2(latencies) -2;
-
- /* Walk through searching for the selected latency */
- for (index = 0; index < 3; index++, latency++) {
- if (!(latencies & (1 << latency))) {
- continue;
- }
- if (latency == min_latency)
- break;
- }
- /* If I can't find the latency or my index is bad error */
- if ((latency != min_latency) || (index >= 3)) {
- goto dimm_err;
- }
-
- /* Read the min_cycle_time for this latency */
- value = spd_read_byte(spd_device, latency_indicies[index]);
- if (value < 0) goto hw_error;
-
- value = convert_to_linear(value);
- /* All is good if the selected clock speed
- * is what I need or slower.
- */
- if (value <= min_cycle_time) {
- continue;
- }
- /* Otherwise I have an error, disable the dimm */
- dimm_err:
- meminfo->dimm_mask = disable_dimm(ctrl, i, meminfo);
}
printk_raminit("4 min_cycle_time: %08x\n", min_cycle_time);
--
http://www.hailfinger.org/
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: linuxbios_k8_raminit_splitout_cl_recheck.diff
URL: <http://www.coreboot.org/pipermail/coreboot/attachments/20090116/8475997a/attachment.ksh>
More information about the coreboot
mailing list