intel/gm45: Add more debug output to read/write training
Add debug output for the timing values of the edges found during read and write training. Now, output for one DIMM of DDR3-1066 in a roda/rk9 looks like: [...] Lower bound for byte lane 0 on channel 0: 0.0 Upper bound for byte lane 0 on channel 0: 8.4 Final timings for byte lane 0 on channel 0: 4.2 Lower bound for byte lane 1 on channel 0: 0.0 Upper bound for byte lane 1 on channel 0: 10.2 Final timings for byte lane 1 on channel 0: 5.1 Lower bound for byte lane 2 on channel 0: 0.0 Upper bound for byte lane 2 on channel 0: 7.5 Final timings for byte lane 2 on channel 0: 3.6 Lower bound for byte lane 3 on channel 0: 0.0 Upper bound for byte lane 3 on channel 0: 11.4 Final timings for byte lane 3 on channel 0: 5.6 Lower bound for byte lane 4 on channel 0: 0.0 Upper bound for byte lane 4 on channel 0: 9.4 Final timings for byte lane 4 on channel 0: 4.6 Lower bound for byte lane 5 on channel 0: 0.0 Upper bound for byte lane 5 on channel 0: 11.2 Final timings for byte lane 5 on channel 0: 5.5 Lower bound for byte lane 6 on channel 0: 0.0 Upper bound for byte lane 6 on channel 0: 8.4 Final timings for byte lane 6 on channel 0: 4.2 Lower bound for byte lane 7 on channel 0: 0.0 Upper bound for byte lane 7 on channel 0: 10.4 Final timings for byte lane 7 on channel 0: 5.2 Lower bound for group 0 on channel 0: 1.7.5 Upper bound for group 0 on channel 0: 2.2.2 Final timings for group 0 on channel 0: 1.10.7 Lower bound for group 1 on channel 0: 1.6.1 Upper bound for group 1 on channel 0: 2.0.2 Final timings for group 1 on channel 0: 1.9.1 Lower bound for group 2 on channel 0: 2.0.7 Upper bound for group 2 on channel 0: 2.8.1 Final timings for group 2 on channel 0: 2.4.4 Lower bound for group 3 on channel 0: 2.4.7 Upper bound for group 3 on channel 0: 3.0.0 Final timings for group 3 on channel 0: 2.8.3 [...] Final timings are always the average of the two bounds. The last dots separate eights (not decimals) and the middles are elenvenths or twelfths depending on the clock speed (twelfths in this case). Change-Id: Idb7c84b514716c7265b94890c39b7225de7800dc Signed-off-by: Nico Huber <nico.huber@secunet.com> Reviewed-on: http://review.coreboot.org/3257 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
12276acfd7
commit
393619b9a6
|
@ -56,6 +56,14 @@ typedef struct {
|
||||||
int t;
|
int t;
|
||||||
int p;
|
int p;
|
||||||
} read_timing_t;
|
} read_timing_t;
|
||||||
|
static void print_read_timing(const int msg_lvl, const char *const msg,
|
||||||
|
const int lane, const int channel,
|
||||||
|
const read_timing_t *const timing)
|
||||||
|
{
|
||||||
|
printk(msg_lvl, "%s for byte lane %d on channel %d: %d.%d\n",
|
||||||
|
msg, lane, channel, timing->t, timing->p);
|
||||||
|
}
|
||||||
|
|
||||||
static int normalize_read_timing(read_timing_t *const timing)
|
static int normalize_read_timing(read_timing_t *const timing)
|
||||||
{
|
{
|
||||||
while (timing->p >= READ_TIMING_P_BOUND) {
|
while (timing->p >= READ_TIMING_P_BOUND) {
|
||||||
|
@ -183,6 +191,7 @@ static void read_training_per_lane(const int channel, const int lane,
|
||||||
lower.p = 0;
|
lower.p = 0;
|
||||||
if (read_training_find_lower(channel, lane, addresses, &lower) < 0)
|
if (read_training_find_lower(channel, lane, addresses, &lower) < 0)
|
||||||
die("Read training failure: lower bound.\n");
|
die("Read training failure: lower bound.\n");
|
||||||
|
print_read_timing(BIOS_SPEW, "Lower bound", lane, channel, &lower);
|
||||||
|
|
||||||
/*** Search upper bound. ***/
|
/*** Search upper bound. ***/
|
||||||
|
|
||||||
|
@ -192,6 +201,7 @@ static void read_training_per_lane(const int channel, const int lane,
|
||||||
if (read_training_find_upper(channel, lane, addresses, &upper) < 0)
|
if (read_training_find_upper(channel, lane, addresses, &upper) < 0)
|
||||||
/* Overflow on upper edge is not fatal. */
|
/* Overflow on upper edge is not fatal. */
|
||||||
printk(BIOS_WARNING, "Read training failure: upper bound.\n");
|
printk(BIOS_WARNING, "Read training failure: upper bound.\n");
|
||||||
|
print_read_timing(BIOS_SPEW, "Upper bound", lane, channel, &upper);
|
||||||
|
|
||||||
/*** Calculate and program mean value. ***/
|
/*** Calculate and program mean value. ***/
|
||||||
|
|
||||||
|
@ -202,8 +212,7 @@ static void read_training_per_lane(const int channel, const int lane,
|
||||||
lower.t = mean_p >> READ_TIMING_P_SHIFT;
|
lower.t = mean_p >> READ_TIMING_P_SHIFT;
|
||||||
lower.p = mean_p & (READ_TIMING_P_BOUND - 1);
|
lower.p = mean_p & (READ_TIMING_P_BOUND - 1);
|
||||||
program_read_timing(channel, lane, &lower);
|
program_read_timing(channel, lane, &lower);
|
||||||
printk(BIOS_DEBUG, "Final timings for byte lane %d on channel %d: "
|
print_read_timing(BIOS_DEBUG, "Final timings", lane, channel, &lower);
|
||||||
"%d.%d\n", lane, channel, lower.t, lower.p);
|
|
||||||
}
|
}
|
||||||
static void perform_read_training(const dimminfo_t *const dimms)
|
static void perform_read_training(const dimminfo_t *const dimms)
|
||||||
{
|
{
|
||||||
|
@ -342,6 +351,14 @@ typedef struct {
|
||||||
const int t_bound;
|
const int t_bound;
|
||||||
int p;
|
int p;
|
||||||
} write_timing_t;
|
} write_timing_t;
|
||||||
|
static void print_write_timing(const int msg_lvl, const char *const msg,
|
||||||
|
const int group, const int channel,
|
||||||
|
const write_timing_t *const timing)
|
||||||
|
{
|
||||||
|
printk(msg_lvl, "%s for group %d on channel %d: %d.%d.%d\n",
|
||||||
|
msg, group, channel, timing->f, timing->t, timing->p);
|
||||||
|
}
|
||||||
|
|
||||||
static int normalize_write_timing(write_timing_t *const timing)
|
static int normalize_write_timing(write_timing_t *const timing)
|
||||||
{
|
{
|
||||||
while (timing->p >= WRITE_TIMING_P_BOUND) {
|
while (timing->p >= WRITE_TIMING_P_BOUND) {
|
||||||
|
@ -518,6 +535,7 @@ static void write_training_per_group(const int ch, const int group,
|
||||||
if (write_training_find_lower(ch, group, addresses,
|
if (write_training_find_lower(ch, group, addresses,
|
||||||
masks, memclk1067, &lower) < 0)
|
masks, memclk1067, &lower) < 0)
|
||||||
die("Write training failure: lower bound.\n");
|
die("Write training failure: lower bound.\n");
|
||||||
|
print_write_timing(BIOS_SPEW, "Lower bound", group, ch, &lower);
|
||||||
|
|
||||||
/*** Search upper bound. ***/
|
/*** Search upper bound. ***/
|
||||||
|
|
||||||
|
@ -529,6 +547,7 @@ static void write_training_per_group(const int ch, const int group,
|
||||||
if (write_training_find_upper(ch, group, addresses,
|
if (write_training_find_upper(ch, group, addresses,
|
||||||
masks, memclk1067, &upper) < 0)
|
masks, memclk1067, &upper) < 0)
|
||||||
printk(BIOS_WARNING, "Write training failure: upper bound.\n");
|
printk(BIOS_WARNING, "Write training failure: upper bound.\n");
|
||||||
|
print_write_timing(BIOS_SPEW, "Upper bound", group, ch, &upper);
|
||||||
|
|
||||||
/*** Calculate and program mean value. ***/
|
/*** Calculate and program mean value. ***/
|
||||||
|
|
||||||
|
@ -542,10 +561,7 @@ static void write_training_per_group(const int ch, const int group,
|
||||||
lower.t = (mean_p >> WRITE_TIMING_P_SHIFT) % lower.t_bound;
|
lower.t = (mean_p >> WRITE_TIMING_P_SHIFT) % lower.t_bound;
|
||||||
lower.p = mean_p & (WRITE_TIMING_P_BOUND - 1);
|
lower.p = mean_p & (WRITE_TIMING_P_BOUND - 1);
|
||||||
program_write_timing(ch, group, &lower, memclk1067);
|
program_write_timing(ch, group, &lower, memclk1067);
|
||||||
|
print_write_timing(BIOS_DEBUG, "Final timings", group, ch, &lower);
|
||||||
printk(BIOS_DEBUG, "Final timings for group %d"
|
|
||||||
" on channel %d: %d.%d.%d\n",
|
|
||||||
group, ch, lower.f, lower.t, lower.p);
|
|
||||||
}
|
}
|
||||||
static void perform_write_training(const int memclk1067,
|
static void perform_write_training(const int memclk1067,
|
||||||
const dimminfo_t *const dimms)
|
const dimminfo_t *const dimms)
|
||||||
|
|
Loading…
Reference in New Issue