summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngel Pons <th3fanbus@gmail.com>2020-11-14 17:02:55 +0100
committerFelix Held <felix-coreboot@felixheld.de>2020-11-22 20:39:52 +0000
commit820bce7322d2af612a39c94c3391b317e33adfb8 (patch)
tree5d091e325614babd8bb4db24f741fa74d17e9a83
parentc6d2feaee53cfce3ca54d389b51593fc86e25576 (diff)
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>
-rw-r--r--src/northbridge/intel/sandybridge/raminit_common.c34
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");