diff options
author | Angel Pons <th3fanbus@gmail.com> | 2020-11-14 17:02:55 +0100 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2020-11-22 20:39:52 +0000 |
commit | 820bce7322d2af612a39c94c3391b317e33adfb8 (patch) | |
tree | 5d091e325614babd8bb4db24f741fa74d17e9a83 /src | |
parent | c6d2feaee53cfce3ca54d389b51593fc86e25576 (diff) | |
download | coreboot-820bce7322d2af612a39c94c3391b317e33adfb8.tar.xz |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/northbridge/intel/sandybridge/raminit_common.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/src/northbridge/intel/sandybridge/raminit_common.c b/src/northbridge/intel/sandybridge/raminit_common.c index 57c376b1aa..ef4ae455f8 100644 --- a/src/northbridge/intel/sandybridge/raminit_common.c +++ b/src/northbridge/intel/sandybridge/raminit_common.c @@ -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 statistics[NUM_LANES][128]; @@ -1767,14 +1767,12 @@ static int discover_timB(ramctr_timing *ctrl, int channel, int slotrank) return 0; } -static int get_timB_high_adjust(u64 val) +static int get_dqs_flyby_adjust(u64 val) { int i; - /* DQS is good enough */ if (val == 0xffffffffffffffffLL) return 0; - if (val >= 0xf000000000000000LL) { /* DQS is late, needs negative adjustment */ 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)); res |= ((u64) MCHBAR32(lane_base[lane] + GDCRTRAININGRESULT2(channel))) << 32; + old = 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("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 * lanes (DQ). */ -int write_training(ramctr_timing *ctrl) +static int jedec_write_leveling(ramctr_timing *ctrl) { - int channel, slotrank, lane; - int err; - - FOR_ALL_POPULATED_CHANNELS - MCHBAR32_OR(TC_RWP_ch(channel), 1 << 27); + int channel, slotrank; disable_refresh_machine(ctrl); @@ -1971,7 +1966,7 @@ int write_training(ramctr_timing *ctrl) /* Set any valid value for timB, it gets corrected later */ FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS { - err = discover_timB(ctrl, channel, slotrank); + const int err = write_level_rank(ctrl, channel, slotrank); if (err) return err; } @@ -2003,6 +1998,21 @@ int write_training(ramctr_timing *ctrl) 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"); precharge(ctrl); printram("CPF\n"); |