nb/intel/sandybridge: Encapsulate JEDEC write leveling

Create and rename a few functions to contain the entire JEDEC write
leveling algorithm. Not all write training is JEDEC write leveling.

Tested on Asus P8H61-M PRO, still boots.

Change-Id: Ie9c6315340164029e30354723b4103d906633602
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47617
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
This commit is contained in:
Angel Pons 2020-11-14 17:02:55 +01:00 committed by Felix Held
parent c6d2feaee5
commit 820bce7322
1 changed files with 22 additions and 12 deletions

View File

@ -1696,7 +1696,7 @@ static void precharge(ramctr_timing *ctrl)
} }
} }
static int discover_timB(ramctr_timing *ctrl, int channel, int slotrank) static int write_level_rank(ramctr_timing *ctrl, int channel, int slotrank)
{ {
int timB; int timB;
int statistics[NUM_LANES][128]; int statistics[NUM_LANES][128];
@ -1767,14 +1767,12 @@ static int discover_timB(ramctr_timing *ctrl, int channel, int slotrank)
return 0; return 0;
} }
static int get_timB_high_adjust(u64 val) static int get_dqs_flyby_adjust(u64 val)
{ {
int i; int i;
/* DQS is good enough */ /* DQS is good enough */
if (val == 0xffffffffffffffffLL) if (val == 0xffffffffffffffffLL)
return 0; return 0;
if (val >= 0xf000000000000000LL) { if (val >= 0xf000000000000000LL) {
/* DQS is late, needs negative adjustment */ /* DQS is late, needs negative adjustment */
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
@ -1889,9 +1887,10 @@ static void train_write_flyby(ramctr_timing *ctrl)
u64 res = MCHBAR32(lane_base[lane] + GDCRTRAININGRESULT1(channel)); u64 res = MCHBAR32(lane_base[lane] + GDCRTRAININGRESULT1(channel));
res |= ((u64) MCHBAR32(lane_base[lane] + res |= ((u64) MCHBAR32(lane_base[lane] +
GDCRTRAININGRESULT2(channel))) << 32; GDCRTRAININGRESULT2(channel))) << 32;
old = ctrl->timings[channel][slotrank].lanes[lane].timB; old = ctrl->timings[channel][slotrank].lanes[lane].timB;
ctrl->timings[channel][slotrank].lanes[lane].timB += ctrl->timings[channel][slotrank].lanes[lane].timB +=
get_timB_high_adjust(res) * 64; get_dqs_flyby_adjust(res) * 64;
printram("High adjust %d:%016llx\n", lane, res); printram("High adjust %d:%016llx\n", lane, res);
printram("Bval+: %d, %d, %d, %x -> %x\n", channel, slotrank, lane, printram("Bval+: %d, %d, %d, %x -> %x\n", channel, slotrank, lane,
@ -1942,13 +1941,9 @@ static void disable_refresh_machine(ramctr_timing *ctrl)
* the DRAM-chip samples the CLK on every DQS edge and feeds back the sampled value on the data * the DRAM-chip samples the CLK on every DQS edge and feeds back the sampled value on the data
* lanes (DQ). * lanes (DQ).
*/ */
int write_training(ramctr_timing *ctrl) static int jedec_write_leveling(ramctr_timing *ctrl)
{ {
int channel, slotrank, lane; int channel, slotrank;
int err;
FOR_ALL_POPULATED_CHANNELS
MCHBAR32_OR(TC_RWP_ch(channel), 1 << 27);
disable_refresh_machine(ctrl); disable_refresh_machine(ctrl);
@ -1971,7 +1966,7 @@ int write_training(ramctr_timing *ctrl)
/* Set any valid value for timB, it gets corrected later */ /* Set any valid value for timB, it gets corrected later */
FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS { FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
err = discover_timB(ctrl, channel, slotrank); const int err = write_level_rank(ctrl, channel, slotrank);
if (err) if (err)
return err; return err;
} }
@ -2003,6 +1998,21 @@ int write_training(ramctr_timing *ctrl)
toggle_io_reset(); toggle_io_reset();
return 0;
}
int write_training(ramctr_timing *ctrl)
{
int channel, slotrank, lane;
int err;
FOR_ALL_POPULATED_CHANNELS
MCHBAR32_OR(TC_RWP_ch(channel), 1 << 27);
err = jedec_write_leveling(ctrl);
if (err)
return err;
printram("CPE\n"); printram("CPE\n");
precharge(ctrl); precharge(ctrl);
printram("CPF\n"); printram("CPF\n");