Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/23087
Change subject: nb/intel/sandybridge/raminit: Add workaround for timC ......................................................................
nb/intel/sandybridge/raminit: Add workaround for timC
The initial phase between CMD and CLK can be calculated if the board does follow the design guidelines. Some do not and may have a different phase. As we don't know we have to test.
Add a loop that changes the initial phase in quarter steps to fix the issue "timC discovery failed". The additional loop is only taken on failed timC discovery and should have no influence on working boards.
Tested on Lenovo T430. Needs test on affected hardware.
Change-Id: I535ea4e320c4572bfae55ce1d0f2c1723e9c54d6 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M src/northbridge/intel/sandybridge/raminit_common.c 1 file changed, 26 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/87/23087/1
diff --git a/src/northbridge/intel/sandybridge/raminit_common.c b/src/northbridge/intel/sandybridge/raminit_common.c index eaef5f7..0d84cd6 100644 --- a/src/northbridge/intel/sandybridge/raminit_common.c +++ b/src/northbridge/intel/sandybridge/raminit_common.c @@ -2076,11 +2076,32 @@ write32(DEFAULT_MCHBAR + 0x4288 + (channel << 10), 0); }
- FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS { - err = discover_timC(ctrl, channel, slotrank); - if (err) - return err; - } + do { + FOR_ALL_CHANNELS { + FOR_ALL_POPULATED_RANKS { + err = discover_timC(ctrl, channel, slotrank); + if (err) + break; + } + if (err) + break; + } + + if (err) { + /* + * This path is rarely taken and a result of ignorance. + * In case the board doesn't follow design guidelines, + * the calculated value of reg_c14_offset doesn't work. + * As it only affects a very small amount of boards and + * the real value is discovered in a later step, just + * try to find a "good" one for now. + * Increment CLK/CMD phase offset by one quarter. + */ + ctrl->reg_c14_offset += 128 / 4; + } + } while (err && ctrl->reg_c14_offset < 128); + if (err) + return err;
FOR_ALL_POPULATED_CHANNELS program_timings(ctrl, channel);