summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/northbridge/intel/x4x/raminit_ddr23.c62
1 files changed, 32 insertions, 30 deletions
diff --git a/src/northbridge/intel/x4x/raminit_ddr23.c b/src/northbridge/intel/x4x/raminit_ddr23.c
index b3321d5bf2..99c07f5970 100644
--- a/src/northbridge/intel/x4x/raminit_ddr23.c
+++ b/src/northbridge/intel/x4x/raminit_ddr23.c
@@ -663,6 +663,30 @@ static void program_timings(struct sysinfo *s)
mchbar_clrsetbits8(0x6c4, 0x7, 0x2);
}
+const unsigned int sync_dll_max_taps = 16;
+
+static void sync_dll_load_tap(unsigned int tap)
+{
+ mchbar_clrsetbits8(0x1c8, 0x1f, tap & 0x1f);
+ mchbar_setbits8(0x180, 1 << 4);
+ do {} while (mchbar_read8(0x180) & (1 << 4));
+}
+
+static bool sync_dll_test_tap(unsigned int tap, uint32_t val)
+{
+ if (tap >= sync_dll_max_taps)
+ return false;
+ sync_dll_load_tap(tap);
+ return mchbar_read32(0x184) == val;
+}
+
+static void sync_dll_search_tap(uint8_t *tap, uint32_t val)
+{
+ for (; *tap < sync_dll_max_taps; ++*tap)
+ if (sync_dll_test_tap(*tap, val))
+ return;
+}
+
static void program_dll(struct sysinfo *s)
{
u8 i, j, r, reg8, clk, async = 0;
@@ -821,12 +845,8 @@ static void program_dll(struct sysinfo *s)
mchbar_clrbits16(0x180, 1 << 15 | 1 << 9);
mchbar_setbits8(0x180, 1 << 2);
j = 0;
- for (i = 0; i < 16; i++) {
- mchbar_clrsetbits8(0x1c8, 0x1f, i);
- mchbar_setbits8(0x180, 1 << 4);
- while (mchbar_read8(0x180) & (1 << 4))
- ;
- if (mchbar_read32(0x184) == 0xffffffff) {
+ for (i = 0; i < sync_dll_max_taps; i++) {
+ if (sync_dll_test_tap(i, 0xffffffff)) {
j++;
if (j >= 2)
break;
@@ -842,22 +862,10 @@ static void program_dll(struct sysinfo *s)
if (i == 1 || ((i == 0) && s->selected_timings.mem_clk == MEM_CLOCK_667MHz)) {
j = 0;
i++;
- for (; i < 16; i++) {
- mchbar_clrsetbits8(0x1c8, 0x1f, i);
- mchbar_setbits8(0x180, 1 << 4);
- while (mchbar_read8(0x180) & (1 << 4))
- ;
- if (mchbar_read32(0x184) == 0) {
- i++;
- break;
- }
- }
- for (; i < 16; i++) {
- mchbar_clrsetbits8(0x1c8, 0x1f, i);
- mchbar_setbits8(0x180, 1 << 4);
- while (mchbar_read8(0x180) & (1 << 4))
- ;
- if (mchbar_read32(0x184) == 0xffffffff) {
+ sync_dll_search_tap(&i, 0);
+ i++;
+ for (; i < sync_dll_max_taps; i++) {
+ if (sync_dll_test_tap(i, 0xffffffff)) {
j++;
if (j >= 2)
break;
@@ -866,10 +874,7 @@ static void program_dll(struct sysinfo *s)
}
}
if (j < 2) {
- mchbar_clrsetbits8(0x1c8, 0x1f, 0);
- mchbar_setbits8(0x180, 1 << 4);
- while (mchbar_read8(0x180) & (1 << 4))
- ;
+ sync_dll_load_tap(0);
j = 2;
}
}
@@ -890,10 +895,7 @@ static void program_dll(struct sysinfo *s)
i = (i + 10) % 14;
else /* DDR3 */
i = (i + 3) % 12;
- mchbar_clrsetbits8(0x1c8, 0x1f, i);
- mchbar_setbits8(0x180, 1 << 4);
- while (mchbar_read8(0x180) & (1 << 4))
- ;
+ sync_dll_load_tap(i);
}
switch (s->selected_timings.mem_clk) {