diff options
author | Patrick Rudolph <siro@das-labor.org> | 2017-06-19 19:33:12 +0200 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2017-06-22 15:21:14 +0000 |
commit | 58d16af91862a964db24b575b9110c767a975916 (patch) | |
tree | 7b3b333dd40f40a14dbae265526156f45022ea81 /src/northbridge | |
parent | acac02d5d27c74c690353f8a62a3e3cad8947b56 (diff) | |
download | coreboot-58d16af91862a964db24b575b9110c767a975916.tar.xz |
nb/intel/sandybridge/raminit: Fix dual DIMM command rate
On boards that are able to take two DIMMs per channel the
command rate should be 2T. It is possible to use 1T with
load reduced "1T" DIMMs, but it's not clear how to detect
those DIMMs. Raminit might fail for those who do not have
such DIMMS installed.
Hardcode command rate of 2T to make sure raminit works on
dual DIMM per channel boards (currently only desktop boards).
The command rate of 1T is still tested if only 1 DIMM per
channel is present.
Will decrease performance on quad slot mainboards, if two DIMMs
are installed in one channel and previously 1T have been selected.
Tested on ASRock B75 Pro3-M.
Change-Id: I029d01092fd0e11390cebcd94ca6f23bf0ee2cab
Signed-off-by: Patrick Rudolph <siro@das-labor.org>
Reviewed-on: https://review.coreboot.org/20270
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Diffstat (limited to 'src/northbridge')
-rw-r--r-- | src/northbridge/intel/sandybridge/raminit_common.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/src/northbridge/intel/sandybridge/raminit_common.c b/src/northbridge/intel/sandybridge/raminit_common.c index be0589dd8b..c6ff551fbf 100644 --- a/src/northbridge/intel/sandybridge/raminit_common.c +++ b/src/northbridge/intel/sandybridge/raminit_common.c @@ -2342,7 +2342,6 @@ static int try_cmd_stretch(ramctr_timing *ctrl, int channel, int cmd_stretch) int command_training(ramctr_timing *ctrl) { int channel; - int err; FOR_ALL_POPULATED_CHANNELS { fill_pattern5(ctrl, channel, 0); @@ -2350,17 +2349,35 @@ int command_training(ramctr_timing *ctrl) } FOR_ALL_POPULATED_CHANNELS { - /* try command rate 1T and 2T */ - err = try_cmd_stretch(ctrl, channel, 0); + int cmdrate, err; + + /* + * Dual DIMM per channel: + * Issue: While c320c discovery seems to succeed raminit + * will fail in write training. + * Workaround: Skip 1T in dual DIMM mode, that's only + * supported by a few DIMMs. + * TODO: How to detect "1T" DIMMs ? + * + * Single DIMM per channel: + * Try command rate 1T and 2T + */ + cmdrate = ((ctrl->rankmap[channel] & 0x5) == 0x5); + + for(; cmdrate < 2; cmdrate++) { + err = try_cmd_stretch(ctrl, channel, cmdrate << 1); + + if (!err) + break; + } + if (err) { - err = try_cmd_stretch(ctrl, channel, 2); - if (err) { - printk(BIOS_EMERG, "c320c discovery failed\n"); - return err; - } - printram("Using CMD rate 2T on channel %u\n", channel); - } else - printram("Using CMD rate 1T on channel %u\n", channel); + printk(BIOS_EMERG, "c320c discovery failed\n"); + return err; + } + + printram("Using CMD rate %uT on channel %u\n", + cmdrate + 1, channel); } FOR_ALL_POPULATED_CHANNELS |