Angel Pons has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/47624 )
Change subject: [WIP] nb/intel/sandybridge: Derive initial timC from timB ......................................................................
[WIP] nb/intel/sandybridge: Derive initial timC from timB
The mysterious timB and timC values correspond to TxDQS and TxDQ PIs, respectively. TxDQS can be determined using JEDEC write leveling, but TxDQ needs another training step. However, the ideal skew between these two signals is 32 PI ticks, so we can apply this offset to uniformize all lanes.
Change-Id: I3795a7f83280d538660fd1bb852435ab02e1f27c Signed-off-by: Angel Pons th3fanbus@gmail.com --- M src/northbridge/intel/sandybridge/raminit_common.c 1 file changed, 16 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/24/47624/1
diff --git a/src/northbridge/intel/sandybridge/raminit_common.c b/src/northbridge/intel/sandybridge/raminit_common.c index 14f7dad..3ea4ff2 100644 --- a/src/northbridge/intel/sandybridge/raminit_common.c +++ b/src/northbridge/intel/sandybridge/raminit_common.c @@ -1592,6 +1592,7 @@
static int discover_timC(ramctr_timing *ctrl, int channel, int slotrank) { + int start[NUM_LANES]; int timC; int stats[NUM_LANES][MAX_TIMC + 1]; int lane; @@ -1603,8 +1604,17 @@ /* Execute command queue */ iosav_run_once(channel);
+ FOR_ALL_LANES { + /* 32 ticks for ideal centering */ + start[lane] = (ctrl->timings[channel][slotrank].lanes[lane].timB + 32) % 128; + } + for (timC = 0; timC <= MAX_TIMC; timC++) { - FOR_ALL_LANES ctrl->timings[channel][slotrank].lanes[lane].timC = timC; + FOR_ALL_LANES { + ctrl->timings[channel][slotrank].lanes[lane].timC = + (start[lane] + timC) % 128; + } + program_timings(ctrl, channel);
test_timC(ctrl, channel, slotrank); @@ -1642,7 +1652,11 @@ return MAKE_ERR; } } - ctrl->timings[channel][slotrank].lanes[lane].timC = rn.middle; + rn.start += start[lane]; + rn.middle += start[lane]; + rn.end += start[lane]; + ctrl->timings[channel][slotrank].lanes[lane].timC = rn.middle % 128; + printram("timC: %d, %d, %d: 0x%02x-0x%02x-0x%02x\n", channel, slotrank, lane, rn.start, rn.middle, rn.end); }