summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPatrick Rudolph <siro@das-labor.org>2017-06-19 19:33:12 +0200
committerMartin Roth <martinroth@google.com>2017-06-22 15:21:14 +0000
commit58d16af91862a964db24b575b9110c767a975916 (patch)
tree7b3b333dd40f40a14dbae265526156f45022ea81 /src
parentacac02d5d27c74c690353f8a62a3e3cad8947b56 (diff)
downloadcoreboot-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')
-rw-r--r--src/northbridge/intel/sandybridge/raminit_common.c39
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