Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/28577
Change subject: nb/intel/x4x: Program read training results to all ranks ......................................................................
nb/intel/x4x: Program read training results to all ranks
While during the read training itself only the settings for rank 0 are used for all ranks, the controller does use the separate settings for each rank later on. It is unknown which register is responsible for this. Therefore program the results for all ranks.
TESTED: Fixes DG43GT not booting with only the second DIMM slot of a channel populated.
Change-Id: I7965a068ef4779847e62e966154764370c91302a Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/northbridge/intel/x4x/dq_dqs.c 1 file changed, 7 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/77/28577/1
diff --git a/src/northbridge/intel/x4x/dq_dqs.c b/src/northbridge/intel/x4x/dq_dqs.c index 8704d39..e4aacfa 100644 --- a/src/northbridge/intel/x4x/dq_dqs.c +++ b/src/northbridge/intel/x4x/dq_dqs.c @@ -447,7 +447,10 @@ * - use the mean between the saved succeeding and failing value * - note0: bytelanes cannot be trained independently, so the delays need to be * adjusted and tested for all of them at the same time - * - note1: this memory controller appears to have per rank registers for these + * - note1: At this stage all ranks effectively use the rank0's rt_dqs settings, + * but later on their respective setting is used (TODO where??). + * So programming the results for all ranks at the end of the training. + * - note2: this memory controller appears to have per rank registers for these * DQS rx delays, but only the one rank 0 seems to be used for all of them */ int do_read_training(struct sysinfo *s) @@ -498,6 +501,8 @@ }
printk(RAM_DEBUG, "Centered values, loop %d:\n", loop); + /* Later on separate settings for each rank are used so program + all of them */ FOR_EACH_BYTELANE(lane) { u8 center = (dqs_lower[lane] + dqs_upper[lane]) / 2; printk(RAM_DEBUG, "\t lane%d: #%d\n", lane, center); @@ -519,7 +524,7 @@ printk(BIOS_ERR, "Huh? read training overflowed!!\n"); } - FOR_EACH_POPULATED_RANK_IN_CHANNEL(s->dimms, channel, rank) + FOR_EACH_RANK_IN_CHANNEL(rank) rt_set_dqs(channel, lane, rank, &s->rt_dqs[channel][lane]); printk(BIOS_DEBUG, "\tlane%d: %d.%d\n",