nb/intel/x4x: Refactor sync DLL programming (part 1)

Extract some common code patterns into functions.

Change-Id: I5f8d40bb55d4b4f0639e0287881ae0ecde298590
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/51905
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
diff --git a/src/northbridge/intel/x4x/raminit_ddr23.c b/src/northbridge/intel/x4x/raminit_ddr23.c
index b3321d5..99c07f5 100644
--- a/src/northbridge/intel/x4x/raminit_ddr23.c
+++ b/src/northbridge/intel/x4x/raminit_ddr23.c
@@ -663,6 +663,30 @@
 	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 @@
 	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 @@
 	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 @@
 			}
 		}
 		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 @@
 			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) {