[coreboot-gerrit] New patch to review for coreboot: nb/intel/sandybridge/raminit: add additional fallbacks

Patrick Rudolph (siro@das-labor.org) gerrit at coreboot.org
Sat Mar 26 15:29:16 CET 2016


Patrick Rudolph (siro at das-labor.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14173

-gerrit

commit 4294b0975421608aff72793fa6f6ea156692160f
Author: Patrick Rudolph <siro at das-labor.org>
Date:   Sat Mar 26 12:16:29 2016 +0100

    nb/intel/sandybridge/raminit: add additional fallbacks
    
    Try decreasing clock frequency twice.
    
    Disable failing channel. The system may be able to boot with
    a single channel enabled.
    
    Change-Id: I3be7034ad25312b3ebf47a54f335a3893f8d7cc1
    Signed-off-by: Patrick Rudolph <siro at das-labor.org>
---
 src/northbridge/intel/sandybridge/raminit.c | 50 +++++++++++++++++++++++++++--
 1 file changed, 48 insertions(+), 2 deletions(-)

diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c
index 3bfb900..d370da4 100644
--- a/src/northbridge/intel/sandybridge/raminit.c
+++ b/src/northbridge/intel/sandybridge/raminit.c
@@ -201,6 +201,7 @@ typedef struct ramctr_timing_st {
 #define MAX_TIMA 127
 
 #define MAKE_ERR ((channel<<16)|(slotrank<<8)|1)
+#define GET_ERR_CHANNEL(x) (x>>16)
 
 static void program_timings(ramctr_timing * ctrl, int channel);
 
@@ -241,6 +242,18 @@ static void toggle_io_reset(void) {
 }
 
 /*
+ * Disable a channel in ramctr_timing.
+ */
+static void disable_channel(ramctr_timing *ctrl, int channel) {
+	ctrl->rankmap[channel] = 0;
+	memset(&ctrl->rank_mirror[channel][0], 0, sizeof(ctrl->rank_mirror[0]));
+	ctrl->channel_size_mb[channel] = 0;
+	ctrl->cmd_stretch[channel] = 0;
+	ctrl->mad_dimm[channel] = 0;
+	memset(&ctrl->timings[channel][0], 0, sizeof(ctrl->timings[0]));
+}
+
+/*
  * Fill cbmem with information for SMBIOS type 17.
  */
 static void fill_smbios17(ramctr_timing *ctrl)
@@ -4042,6 +4055,8 @@ static int try_init_dram_ddr3(ramctr_timing *ctrl, int fast_boot,
 {
 	int err;
 
+	printk(BIOS_DEBUG, "Starting RAM training.\n");
+
 	if (!fast_boot) {
 		/* Find fastest common supported parameters */
 		dram_find_common_params(ctrl);
@@ -4233,16 +4248,47 @@ void init_dram_ddr3(spd_raw_data *spds, int mobile, int min_tck,
 		ctrl.mobile = mobile;
 		ctrl.tCK = min_tck;
 
-		printk(BIOS_DEBUG, "Starting RAM training.\n");
-
 		/* Get DDR3 SPD data */
 		dram_find_spds_ddr3(spds, &ctrl);
 	}
 
 	err = try_init_dram_ddr3(&ctrl, fast_boot, me_uma_size);
+	if (!err)
+		goto done;
+
+	/* fallback: lower clock frequency */
+	printk(BIOS_ERR, "RAM training failed, trying fallback.\n");
+	printram("Decreasing clock frequency.\n");
+	ctrl.tCK++;
+
+	err = try_init_dram_ddr3(&ctrl, fast_boot, me_uma_size);
+	if (!err)
+		goto done;
+
+	/* fallback: lower clock frequency */
+	printk(BIOS_ERR, "RAM training failed, trying fallback.\n");
+	printram("Decreasing clock frequency.\n");
+	ctrl.tCK++;
+
+	err = try_init_dram_ddr3(&ctrl, fast_boot, me_uma_size);
+	if (!err)
+		goto done;
+
+	/* fallback: disable failing channel */
+	printk(BIOS_ERR, "RAM training failed, trying fallback.\n");
+	printram("Disable failing channel.\n");
+
+	/* Reset DDR3 frequency */
+	dram_find_spds_ddr3(spds, &ctrl);
+
+	/* disable failing channel */
+	disable_channel(&ctrl, GET_ERR_CHANNEL(err));
+
+	err = try_init_dram_ddr3(&ctrl, fast_boot, me_uma_size);
 	if (err)
 		die("raminit failed");
 
+done:
 	/* FIXME: should be hardware revision-dependent.  */
 	write32(DEFAULT_MCHBAR + 0x5024, 0x00a030ce);
 



More information about the coreboot-gerrit mailing list