nb/intel/sandybridge/raminit: add additional fallbacks

Add the following fallbacks:
* Try decreasing clock frequency.
   In case of DDR1600 the next possible value of DDR1333 is being used.
* Try decreasing clock frequency.
   In case of DDR1333 the next possible value of DDR1066 is being used.
* Disable failing channel.
   The system may be able to boot with a single channel enabled.

The fallbacks are untested.

Change-Id: I3be7034ad25312b3ebf47a54f335a3893f8d7cc1
Signed-off-by: Patrick Rudolph <siro@das-labor.org>
Reviewed-on: https://review.coreboot.org/14173
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
Patrick Rudolph 2016-03-26 12:16:29 +01:00 committed by Martin Roth
parent 1e302cbd09
commit 2ccb74b6e9
1 changed files with 44 additions and 0 deletions

View File

@ -201,6 +201,7 @@ typedef struct ramctr_timing_st {
#define MAX_TIMA 127 #define MAX_TIMA 127
#define MAKE_ERR ((channel<<16)|(slotrank<<8)|1) #define MAKE_ERR ((channel<<16)|(slotrank<<8)|1)
#define GET_ERR_CHANNEL(x) (x>>16)
static void program_timings(ramctr_timing * ctrl, int channel); static void program_timings(ramctr_timing * ctrl, int channel);
@ -240,6 +241,18 @@ static void toggle_io_reset(void) {
udelay(1); udelay(1);
} }
/*
* 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. * Fill cbmem with information for SMBIOS type 17.
*/ */
@ -4252,6 +4265,37 @@ void init_dram_ddr3(spd_raw_data *spds, int mobile, int min_tck,
err = try_init_dram_ddr3(&ctrl, fast_boot, s3resume, me_uma_size); err = try_init_dram_ddr3(&ctrl, fast_boot, s3resume, me_uma_size);
} }
if (err && (ctrl.tCK < TCK_400MHZ)) {
/* 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, s3resume, me_uma_size);
}
if (err && (ctrl.tCK < TCK_400MHZ)) {
/* 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, s3resume, me_uma_size);
}
if (err) {
/* 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, s3resume, me_uma_size);
}
if (err) if (err)
die("raminit failed"); die("raminit failed");