nb/intel/x4x/raminit: Rework receive enable calibration

Moves receive enable calibration to a separate file to lighten
raminit.c a bit.

Receive enable calibration is quite similar to gm45 so it reuses some
of its function names.

The functional changes are:
* the minimum coarse is now reset for each channel;
* on the second fine search for DQS high, TAP overflow is handled by
  increasing medium;
* start coarse at CAS + 1 instead of CAS - 1. Other Intel northbridges
  do the same and the results are more in line with register dumps
  from vendor bios.
These might improve stability.

TESTED on ga-g41m-es2l

Change-Id: I0c970455e609d3ce96a262cbf110336a2079da4d
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/18692
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
diff --git a/src/northbridge/intel/x4x/raminit_ddr2.c b/src/northbridge/intel/x4x/raminit_ddr2.c
index bc012d2..9c13fc1 100644
--- a/src/northbridge/intel/x4x/raminit_ddr2.c
+++ b/src/northbridge/intel/x4x/raminit_ddr2.c
@@ -31,11 +31,6 @@
 
 #define ME_UMA_SIZEMB 0
 
-static inline void barrier(void)
-{
-	asm volatile("mfence":::);
-}
-
 static u32 fsb2mhz(u32 speed)
 {
 	return (speed * 267) + 800;
@@ -1161,282 +1156,6 @@
 	printk(BIOS_DEBUG, "MRS done\n");
 }
 
-static u8 sampledqs(u16 mchloc, u32 addr, u8 hilow, u8 repeat)
-{
-	u8 dqsmatch = 1;
-	volatile u32 strobe;
-
-	while (repeat-- > 0) {
-		MCHBAR8(0x5d8) = MCHBAR8(0x5d8) & ~0x2;
-		udelay(2);
-		MCHBAR8(0x5d8) = MCHBAR8(0x5d8) | 0x2;
-		udelay(2);
-		MCHBAR8(0x9d8) = MCHBAR8(0x9d8) & ~0x2;
-		udelay(2);
-		MCHBAR8(0x9d8) = MCHBAR8(0x9d8) | 0x2;
-		udelay(2);
-		barrier();
-		strobe = read32((u32 *)addr);
-		barrier();
-		if (((MCHBAR32(mchloc) & 0x40) >> 6) != hilow)
-			dqsmatch = 0;
-	}
-	return dqsmatch;
-}
-
-static void rcven_ddr2(struct sysinfo *s)
-{
-	u8 i, reg8, ch, lane;
-	u32 addr;
-	u8 tap = 0;
-	u8 savecc, savemedium, savetap, coarsecommon, medium;
-	u8 lanecoarse[8] = {0};
-	u8 mincoarse = 0xff;
-	u8 pitap[2][8];
-	u16 coarsectrl[2];
-	u16 coarsedelay[2];
-	u16 mediumphase[2];
-	u16 readdelay[2];
-	u16 mchbar;
-	MCHBAR8(0x5d8) = MCHBAR8(0x5d8) & ~0xc;
-	MCHBAR8(0x9d8) = MCHBAR8(0x9d8) & ~0xc;
-	MCHBAR8(0x5dc) = MCHBAR8(0x5dc) & ~0x80;
-
-	FOR_EACH_POPULATED_CHANNEL(s->dimms, ch) {
-		addr = (ch << 29);
-		for (i = 0; !RANK_IS_POPULATED(s->dimms, ch, i); i++)
-			addr += 128*1024*1024;
-
-		for (lane = 0; lane < 8; lane++) {
-			printk(BIOS_DEBUG, "Channel %d, Lane %d addr=0x%08x\n", ch, lane, addr);
-			coarsecommon = (s->selected_timings.CAS - 1);
-			switch (lane) {
-			case 0: case 1:
-				medium = 0;
-				break;
-			case 2: case 3:
-				medium = 1;
-				break;
-			case 4: case 5:
-				medium = 2;
-				break;
-			case 6: case 7:
-				medium = 3;
-				break;
-			default:
-				medium = 0;
-				break;
-			}
-			mchbar = 0x400*ch + 0x561 + (lane << 2);
-			tap = 0;
-			MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & ~0xf0000) |
-				(coarsecommon << 16);
-			MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & ~(3 << (lane*2))) |
-				(medium << (lane*2));
-			MCHBAR8(0x400*ch + 0x560 + lane*4) = MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0xf;
-			MCHBAR8(0x400*ch + 0x560 + lane*4) = MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0x70;
-			savecc = coarsecommon;
-			savemedium = medium;
-			savetap = 0;
-
-			MCHBAR16(0x400*ch + 0x588) = (MCHBAR16(0x400*ch + 0x588) & ~(3 << (lane*2))) |
-				(1 << (lane*2));
-
-			printk(BIOS_DEBUG, "rcven 0.1 coarse=%d\n", coarsecommon);
-			while (sampledqs(mchbar, addr, 1, 1) == 1) {
-				if (medium < 3) {
-					medium++;
-					MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
-						~(3 << (lane*2))) | (medium << (lane*2));
-				} else {
-					medium = 0;
-					coarsecommon++;
-					MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) &
-						~0xf0000) | (coarsecommon << 16);
-					MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
-						~(3 << (lane*2))) | (medium << (lane*2));
-				}
-				if (coarsecommon > 16) {
-					die("Coarse > 16: DQS tuning failed, halt\n");
-					break;
-				}
-			}
-			printk(BIOS_DEBUG, "  GOT IT (high -> low transition) coarse=%d medium=%d\n", coarsecommon, medium);
-
-			savemedium = medium;
-			savecc = coarsecommon;
-			if (medium < 3) {
-				medium++;
-				MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
-					~(3 << (lane*2))) | (medium << (lane*2));
-			} else {
-				medium = 0;
-				coarsecommon++;
-
-				MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & ~0xf0000) |
-					(coarsecommon << 16);
-				MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & ~(3 << (lane*2))) |
-					(medium << (lane*2));
-			}
-
-			printk(BIOS_DEBUG, "rcven 0.2\n");
-			while (sampledqs(mchbar, addr, 0, 1) == 1) {
-				savemedium = medium;
-				savecc = coarsecommon;
-				if (medium < 3) {
-					medium++;
-					MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
-						~(3 << (lane*2))) | (medium << (lane*2));
-				} else {
-					medium = 0;
-					coarsecommon++;
-					MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) &
-						~0xf0000) | (coarsecommon << 16);
-					MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
-						~(3 << (lane*2))) | (medium << (lane*2));
-				}
-				if (coarsecommon > 16) {
-					die("Coarse DQS tuning 2 failed, halt\n");
-					break;
-				}
-			}
-			printk(BIOS_DEBUG, "  GOT IT (low -> high transition) coarse=%d medium=%d\n", coarsecommon, medium);
-
-
-			coarsecommon = savecc;
-			medium = savemedium;
-			MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) &
-				~0xf0000) | (coarsecommon << 16);
-			MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
-				~(3 << (lane*2))) | (medium << (lane*2));
-
-			printk(BIOS_DEBUG, "rcven 0.3\n");
-			tap = 0;
-			while (sampledqs(mchbar, addr, 1, 1) == 0) {
-				savetap = tap;
-				tap++;
-				if (tap > 14)
-					break;
-				MCHBAR8(0x400*ch + 0x560 + (lane*4)) =
-					(MCHBAR8(0x400*ch + 0x560 + (lane*4)) & ~0xf) | tap;
-			}
-
-			tap = savetap;
-			MCHBAR8(0x400*ch + 0x560 + (lane*4)) =
-				(MCHBAR8(0x400*ch + 0x560 + (lane*4)) & ~0xf) | tap;
-			MCHBAR8(0x400*ch + 0x560 + (lane*4)) =
-				(MCHBAR8(0x400*ch + 0x560 + (lane*4)) & ~0x70) | 0x30;
-			if (medium < 3) {
-				medium++;
-				MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
-					~(3 << (lane*2))) | (medium << (lane*2));
-			} else {
-				medium = 0;
-				coarsecommon++;
-				MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) &
-					~0xf0000) | (coarsecommon << 16);
-				MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
-					~(3 << (lane*2))) | (medium << (lane*2));
-			}
-			if (sampledqs(mchbar, addr, 1, 1) == 0)
-				die("Not at DQS high, doh\n");
-
-			printk(BIOS_DEBUG, "rcven 0.4\n");
-			while (sampledqs(mchbar, addr, 1, 1) == 1) {
-				coarsecommon--;
-				MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) &
-					~0xf0000) | (coarsecommon << 16);
-				if (coarsecommon == 0) {
-					die("Couldn't find DQS-high 0 indicator, halt\n");
-					break;
-				}
-			}
-			printk(BIOS_DEBUG, "  GOT IT (high -> low transition) coarse=%d medium=%d\n", coarsecommon, medium);
-
-			printk(BIOS_DEBUG, "rcven 0.5\n");
-			while (sampledqs(mchbar, addr, 0, 1) == 1) {
-				savemedium = medium;
-				savecc = coarsecommon;
-				if (medium < 3) {
-					medium++;
-					MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
-						~(3 << (lane*2))) | (medium << (lane*2));
-				} else {
-					medium = 0;
-					coarsecommon++;
-					MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) &
-						~0xf0000) | (coarsecommon << 16);
-					MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
-						~(3 << (lane*2))) | (medium << (lane*2));
-				}
-				if (coarsecommon > 16) {
-					die("Coarse DQS tuning 5 failed, halt\n");
-					break;
-				}
-			}
-			printk(BIOS_DEBUG, "  GOT IT (low -> high transition) coarse=%d medium=%d\n", coarsecommon, medium);
-
-			printk(BIOS_DEBUG, "rcven 0.6\n");
-			coarsecommon = savecc;
-			medium = savemedium;
-			MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) &
-				~0xf0000) | (coarsecommon << 16);
-			MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
-				~(3 << (lane*2))) | (medium << (lane*2));
-			while (sampledqs(mchbar, addr, 1, 1) == 0) {
-				savetap = tap;
-				tap++;
-				if (tap > 14)
-					break;
-				MCHBAR8(0x400*ch + 0x560 + lane*4) =
-					(MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0xf) | tap;
-			}
-			tap = savetap;
-			MCHBAR8(0x400*ch + 0x560 + lane*4) =
-				(MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0xf) | tap;
-			MCHBAR8(0x400*ch + 0x560 + lane*4) =
-				(MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0x70) | 0x70;
-
-			pitap[ch][lane] = 0x70 | tap;
-
-			MCHBAR16(0x400*ch + 0x588) = MCHBAR16(0x400*ch + 0x588) & ~(3 << (lane*2));
-			lanecoarse[lane] = coarsecommon;
-			printk(BIOS_DEBUG, "rcven 0.7\n");
-		} // END EACH LANE
-
-		// Find minimum coarse value
-		for (lane = 0; lane < 8; lane++) {
-			if (mincoarse > lanecoarse[lane])
-				mincoarse = lanecoarse[lane];
-		}
-
-		printk(BIOS_DEBUG, "Found min coarse value = %d\n", mincoarse);
-
-		for (lane = 0; lane < 8; lane++) {
-			reg8 = (lanecoarse[lane] == 0) ? 0 : lanecoarse[lane] - mincoarse;
-			MCHBAR16(0x400*ch + 0x5fa) = (MCHBAR16(0x400*ch + 0x5fa) & ~(3 << (lane*2))) |
-				(reg8 << (lane*2));
-		}
-		MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & ~0xf0000) | (mincoarse << 16);
-		coarsectrl[ch] = mincoarse;
-		coarsedelay[ch] = MCHBAR16(0x400*ch + 0x5fa);
-		mediumphase[ch] = MCHBAR16(0x400*ch + 0x58c);
-		readdelay[ch] = MCHBAR16(0x400*ch + 0x588);
-	} // END EACH POPULATED CHANNEL
-
-	FOR_EACH_CHANNEL(ch) {
-		for (lane = 0; lane < 8; lane++) {
-			MCHBAR8(0x400*ch + 0x560 + (lane*4)) =
-				(MCHBAR8(0x400*ch + 0x560 + (lane*4)) & ~0xf) | pitap[ch][lane];
-		}
-		MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & ~0xf0000) |
-			(coarsectrl[ch] << 16);
-		MCHBAR16(0x400*ch + 0x5fa) = coarsedelay[ch];
-		MCHBAR16(0x400*ch + 0x58c) = mediumphase[ch];
-	}
-	printk(BIOS_DEBUG, "End rcven\n");
-}
-
 static void sdram_save_receive_enable(void)
 {
 	int i = 0;
@@ -1505,7 +1224,7 @@
 		|| (s->boot_path == BOOT_PATH_RESUME)) {
 		sdram_recover_receive_enable();
 	} else {
-		rcven_ddr2(s);
+		rcven(s);
 		sdram_save_receive_enable();
 	}
 }