diff options
author | Nico Huber <nico.huber@secunet.com> | 2013-05-14 11:58:44 +0200 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2013-05-22 18:04:11 +0200 |
commit | 08bee23f7eb31cce4746c51cfde3a7017e0e8b8e (patch) | |
tree | 53d1e22e71ec63ae1e888cc2312f1ac53b8c3508 /src | |
parent | 35e45c078054a7bd64ba54b8b84b07602e8dd4ff (diff) | |
download | coreboot-08bee23f7eb31cce4746c51cfde3a7017e0e8b8e.tar.xz |
intel/gm45: Refactor DDR3 write training
Split some code in individual functions. It's the refactoring part of
a bigger change, following...
Change-Id: Id19be4588ad8984935040d9bcba4d7c5f2e1114f
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: http://review.coreboot.org/3255
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/northbridge/intel/gm45/raminit_read_write_training.c | 85 |
1 files changed, 54 insertions, 31 deletions
diff --git a/src/northbridge/intel/gm45/raminit_read_write_training.c b/src/northbridge/intel/gm45/raminit_read_write_training.c index f13cde8e93..72c83a7275 100644 --- a/src/northbridge/intel/gm45/raminit_read_write_training.c +++ b/src/northbridge/intel/gm45/raminit_read_write_training.c @@ -426,6 +426,46 @@ _bad_timing_out: return ret; } +static void write_training_find_lower(const int ch, const int group, + const address_bunch_t *const addresses, + const u32 masks[][2], const int memclk1067, + write_timing_t *const lower) +{ + program_write_timing(ch, group, lower, memclk1067); + /* Coarse search for good t. */ + while (!write_training_test(addresses, masks[group])) { + ++lower->t; + program_write_timing(ch, group, lower, memclk1067); + } + /* Fine search for good p. */ + --lower->t; + program_write_timing(ch, group, lower, memclk1067); + while (!write_training_test(addresses, masks[group])) { + ++lower->p; + program_write_timing(ch, group, lower, memclk1067); + } +} +static void write_training_find_upper(const int ch, const int group, + const address_bunch_t *const addresses, + const u32 masks[][2], const int memclk1067, + write_timing_t *const upper) +{ + program_write_timing(ch, group, upper, memclk1067); + if (!write_training_test(addresses, masks[group])) + die("Write training failed; limits too narrow.\n"); + /* Coarse search for good t. */ + while (write_training_test(addresses, masks[group])) { + ++upper->t; + program_write_timing(ch, group, upper, memclk1067); + } + /* Fine search for good p. */ + --upper->t; + program_write_timing(ch, group, upper, memclk1067); + while (write_training_test(addresses, masks[group])) { + ++upper->p; + program_write_timing(ch, group, upper, memclk1067); + } +} static void write_training_per_group(const int ch, const int group, const address_bunch_t *const addresses, const u32 masks[][2], const int memclk1067) @@ -434,46 +474,29 @@ static void write_training_per_group(const int ch, const int group, write_timing_t lower = { 0, 0, t_bound, 0 }, upper = { 0, 0, t_bound, 0 }; - /* Search lower bound. */ + /*** Search lower bound. ***/ + + /* Start at -1f from current values. */ const u32 reg = MCHBAR32(CxWRTy_MCHBAR(ch, group)); lower.t = (reg >> 12) & 0xf; lower.p = (reg >> 8) & 0x7; lower.f = ((reg >> 2) & 0x3) - 1; - program_write_timing(ch, group, &lower, memclk1067); - /* Coarse search for good t. */ - while (!write_training_test(addresses, masks[group])) { - ++lower.t; - program_write_timing(ch, group, &lower, memclk1067); - } - /* Fine search for good p. */ - --lower.t; - program_write_timing(ch, group, &lower, memclk1067); - while (!write_training_test(addresses, masks[group])) { - ++lower.p; - program_write_timing(ch, group, &lower, memclk1067); - } - /* Search upper bound. */ + write_training_find_lower(ch, group, addresses, + masks, memclk1067, &lower); + + /*** Search upper bound. ***/ + + /* Start at lower + 3t. */ upper.t = lower.t + 3; upper.p = lower.p; upper.f = lower.f; - program_write_timing(ch, group, &upper, memclk1067); - if (!write_training_test(addresses, masks[group])) - die("Write training failed; limits too narrow.\n"); - /* Coarse search for good t. */ - while (write_training_test(addresses, masks[group])) { - ++upper.t; - program_write_timing(ch, group, &upper, memclk1067); - } - /* Fine search for good p. */ - --upper.t; - program_write_timing(ch, group, &upper, memclk1067); - while (write_training_test(addresses, masks[group])) { - ++upper.p; - program_write_timing(ch, group, &upper, memclk1067); - } - /* Calculate and program mean value. */ + write_training_find_upper(ch, group, addresses, + masks, memclk1067, &upper); + + /*** Calculate and program mean value. ***/ + lower.t += lower.f * lower.t_bound; lower.p += lower.t << WRITE_TIMING_P_SHIFT; upper.t += upper.f * upper.t_bound; |