nb/intel/sandybridge: Create sequence helpers

Create some functions to program commonly-used sequences.

Tested on Asus P8H61-M PRO, still boots.

Change-Id: I1b6474ab208fe5fc2bd7f1b68eff20541fdfce9b
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47503
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/src/northbridge/intel/sandybridge/raminit_common.c b/src/northbridge/intel/sandybridge/raminit_common.c
index 4f0a8da..baaf496 100644
--- a/src/northbridge/intel/sandybridge/raminit_common.c
+++ b/src/northbridge/intel/sandybridge/raminit_common.c
@@ -533,8 +533,7 @@
 	/* Choose a populated rank */
 	slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2;
 
-	const struct iosav_ssq sequence[] = ZQCS_SEQUENCE(slotrank, 3, 8, 0);
-	iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+	iosav_write_zqcs_sequence(channel, slotrank, 3, 8, 0);
 
 	/*
 	 * Execute command queue - why is bit 22 set here?!
@@ -870,8 +869,7 @@
 		/* Drain */
 		wait_for_iosav(channel);
 
-		const struct iosav_ssq zqcs_sequence[] = ZQCS_SEQUENCE(slotrank, 4, 101, 31);
-		iosav_write_sequence(channel, zqcs_sequence, ARRAY_SIZE(zqcs_sequence));
+		iosav_write_zqcs_sequence(channel, slotrank, 4, 101, 31);
 
 		/* Execute command queue */
 		iosav_run_once(channel);
@@ -1031,9 +1029,7 @@
 {
 	wait_for_iosav(channel);
 
-	const struct iosav_ssq sequence[] =
-		READ_MPR_SEQUENCE(ctrl->tMOD, 1, 3, 15, ctrl->CAS + 36);
-	iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+	iosav_write_read_mpr_sequence(channel, slotrank, ctrl->tMOD, 1, 3, 15, ctrl->CAS + 36);
 
 	/* Execute command queue */
 	iosav_run_once(channel);
@@ -1294,8 +1290,7 @@
 
 		wait_for_iosav(channel);
 
-		const struct iosav_ssq sequence[] = PREA_SEQUENCE(ctrl->tRP, 0);
-		iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+		iosav_write_prea_sequence(channel, slotrank, ctrl->tRP, 0);
 
 		/* Execute command queue */
 		iosav_run_once(channel);
@@ -1391,9 +1386,8 @@
 
 	wait_for_iosav(channel);
 
-	const struct iosav_ssq wr_sequence[] =
-		MISC_WRITE_SEQUENCE(MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1), 4, 4, 500, 18);
-	iosav_write_sequence(channel, wr_sequence, ARRAY_SIZE(wr_sequence));
+	iosav_write_misc_write_sequence(ctrl, channel, slotrank,
+		MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1), 4, 4, 500, 18);
 
 	/* Execute command queue */
 	iosav_run_once(channel);
@@ -1527,8 +1521,7 @@
 
 	wait_for_iosav(channel);
 
-	const struct iosav_ssq sequence[] = PREA_SEQUENCE(ctrl->tRP, 18);
-	iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+	iosav_write_prea_sequence(channel, slotrank, ctrl->tRP, 18);
 
 	/* Execute command queue */
 	iosav_run_once(channel);
@@ -1637,9 +1630,8 @@
 		FOR_ALL_POPULATED_RANKS {
 			wait_for_iosav(channel);
 
-			const struct iosav_ssq sequence[] =
-				READ_MPR_SEQUENCE(ctrl->tMOD, 3, 4, 1, ctrl->CAS + 8);
-			iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+			iosav_write_read_mpr_sequence(
+				channel, slotrank, ctrl->tMOD, 3, 4, 1, ctrl->CAS + 8);
 
 			/* Execute command queue */
 			iosav_run_once(channel);
@@ -1657,9 +1649,8 @@
 		FOR_ALL_POPULATED_RANKS {
 			wait_for_iosav(channel);
 
-			const struct iosav_ssq sequence[] =
-				READ_MPR_SEQUENCE(ctrl->tMOD, 3, 4, 1, ctrl->CAS + 8);
-			iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+			iosav_write_read_mpr_sequence(
+				channel, slotrank, ctrl->tMOD, 3, 4, 1, ctrl->CAS + 8);
 
 			/* Execute command queue */
 			iosav_run_once(channel);
@@ -1814,8 +1805,7 @@
 
 		wait_for_iosav(channel);
 
-		const struct iosav_ssq wr_sequence[] = MISC_WRITE_SEQUENCE(3, 1, 3, 3, 31);
-		iosav_write_sequence(channel, wr_sequence, ARRAY_SIZE(wr_sequence));
+		iosav_write_misc_write_sequence(ctrl, channel, slotrank, 3, 1, 3, 3, 31);
 
 		/* Execute command queue */
 		iosav_run_once(channel);
@@ -1917,8 +1907,7 @@
 	/* choose an existing rank.  */
 	slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
 
-	const struct iosav_ssq sequence[] = ZQCS_SEQUENCE(slotrank, 4, 4, 31);
-	iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+	iosav_write_zqcs_sequence(channel, slotrank, 4, 4, 31);
 
 	/* Execute command queue */
 	iosav_run_once(channel);
@@ -1992,8 +1981,7 @@
 		MCHBAR32(IOSAV_STATUS_ch(channel));
 		wait_for_iosav(channel);
 
-		const struct iosav_ssq sequence[] = ZQCS_SEQUENCE(0, 4, 101, 31);
-		iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+		iosav_write_zqcs_sequence(channel, 0, 4, 101, 31);
 
 		/* Execute command queue */
 		iosav_run_once(channel);
@@ -2059,8 +2047,7 @@
 
 		wait_for_iosav(channel);
 
-		const struct iosav_ssq sequence[] = COMMAND_TRAINING_SEQUENCE(ctr);
-		iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+		iosav_write_command_training_sequence(ctrl, channel, slotrank, ctr);
 
 		/* Program LFSR for the RD/WR subsequences */
 		MCHBAR32(IOSAV_n_ADDRESS_LFSR_ch(channel, 1)) = 0x389abcd;
@@ -2128,8 +2115,7 @@
 		/* Choose an existing rank */
 		slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
 
-		const struct iosav_ssq sequence[] = ZQCS_SEQUENCE(slotrank, 4, 4, 31);
-		iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+		iosav_write_zqcs_sequence(channel, slotrank, 4, 4, 31);
 
 		/* Execute command queue */
 		iosav_run_once(channel);
@@ -2146,8 +2132,7 @@
 		/* choose an existing rank.  */
 		slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;
 
-		const struct iosav_ssq sequence[] = ZQCS_SEQUENCE(slotrank, 4, 4, 31);
-		iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+		iosav_write_zqcs_sequence(channel, slotrank, 4, 4, 31);
 
 		/* Execute command queue */
 		iosav_run_once(channel);
@@ -2308,9 +2293,8 @@
 
 		wait_for_iosav(channel);
 
-		const struct iosav_ssq sequence[] =
-			READ_MPR_SEQUENCE(ctrl->tMOD, 500, 4, 1, ctrl->CAS + 8);
-		iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+		iosav_write_read_mpr_sequence(
+			channel, slotrank, ctrl->tMOD, 500, 4, 1, ctrl->CAS + 8);
 
 		/* Execute command queue */
 		iosav_run_once(channel);
@@ -2367,9 +2351,8 @@
 		FOR_ALL_POPULATED_RANKS {
 			wait_for_iosav(channel);
 
-			const struct iosav_ssq sequence[] =
-				READ_MPR_SEQUENCE(ctrl->tMOD, 3, 4, 1, ctrl->CAS + 8);
-			iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+			iosav_write_read_mpr_sequence(
+				channel, slotrank, ctrl->tMOD, 3, 4, 1, ctrl->CAS + 8);
 
 			/* Execute command queue */
 			iosav_run_once(channel);
@@ -2389,9 +2372,8 @@
 		FOR_ALL_POPULATED_RANKS {
 			wait_for_iosav(channel);
 
-			const struct iosav_ssq sequence[] =
-				READ_MPR_SEQUENCE(ctrl->tMOD, 3, 4, 1, ctrl->CAS + 8);
-			iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+			iosav_write_read_mpr_sequence(
+				channel, slotrank, ctrl->tMOD, 3, 4, 1, ctrl->CAS + 8);
 
 			/* Execute command queue */
 			iosav_run_once(channel);
@@ -2491,8 +2473,7 @@
 				}
 				wait_for_iosav(channel);
 
-				const struct iosav_ssq sequence[] = WRITE_DATA_SEQUENCE;
-				iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+				iosav_write_data_write_sequence(ctrl, channel, slotrank);
 
 				/* Execute command queue */
 				iosav_run_once(channel);
@@ -2590,8 +2571,7 @@
 {
 	wait_for_iosav(channel);
 
-	const struct iosav_ssq sequence[] = AGGRESSIVE_WRITE_READ_SEQUENCE;
-	iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+	iosav_write_aggressive_write_read_sequence(ctrl, channel, slotrank);
 
 	/* Execute command queue */
 	iosav_run_once(channel);
@@ -2767,8 +2747,7 @@
 		}
 		wait_for_iosav(channel);
 
-		const struct iosav_ssq sequence[] = MEMORY_TEST_SEQUENCE;
-		iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+		iosav_write_memory_test_sequence(ctrl, channel, slotrank);
 
 		/* Execute command queue */
 		iosav_run_once(channel);
diff --git a/src/northbridge/intel/sandybridge/raminit_common.h b/src/northbridge/intel/sandybridge/raminit_common.h
index 3937f41..67ae966 100644
--- a/src/northbridge/intel/sandybridge/raminit_common.h
+++ b/src/northbridge/intel/sandybridge/raminit_common.h
@@ -710,11 +710,25 @@
 		},									\
 	}
 
+typedef struct ramctr_timing_st ramctr_timing;
+
 void iosav_write_sequence(const int ch, const struct iosav_ssq *seq, const unsigned int length);
 void iosav_run_queue(const int ch, const u8 loops, const u8 as_timer);
 void iosav_run_once(const int ch);
 void wait_for_iosav(int channel);
 
+void iosav_write_zqcs_sequence(int channel, int slotrank, u32 gap, u32 post, u32 wrap);
+void iosav_write_prea_sequence(int channel, int slotrank, u32 post, u32 wrap);
+void iosav_write_read_mpr_sequence(
+	int channel, int slotrank, u32 tMOD, u32 loops, u32 gap, u32 loops2, u32 post2);
+void iosav_write_misc_write_sequence(ramctr_timing *ctrl, int channel, int slotrank,
+				     u32 gap0, u32 loops0, u32 gap1, u32 loops2, u32 wrap2);
+void iosav_write_command_training_sequence(
+	ramctr_timing *ctrl, int channel, int slotrank, unsigned int address);
+void iosav_write_data_write_sequence(ramctr_timing *ctrl, int channel, int slotrank);
+void iosav_write_aggressive_write_read_sequence(ramctr_timing *ctrl, int channel, int slotrank);
+void iosav_write_memory_test_sequence(ramctr_timing *ctrl, int channel, int slotrank);
+
 /* FIXME: Vendor BIOS uses 64 but our algorithms are less
    performant and even 1 seems to be enough in practice.  */
 #define NUM_PATTERNS	4
diff --git a/src/northbridge/intel/sandybridge/raminit_iosav.c b/src/northbridge/intel/sandybridge/raminit_iosav.c
index d56ab7a..4e37444 100644
--- a/src/northbridge/intel/sandybridge/raminit_iosav.c
+++ b/src/northbridge/intel/sandybridge/raminit_iosav.c
@@ -48,3 +48,55 @@
 			return;
 	}
 }
+
+void iosav_write_zqcs_sequence(int channel, int slotrank, u32 gap, u32 post, u32 wrap)
+{
+	const struct iosav_ssq sequence[] = ZQCS_SEQUENCE(slotrank, gap, post, wrap);
+	iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+}
+
+void iosav_write_prea_sequence(int channel, int slotrank, u32 post, u32 wrap)
+{
+	const struct iosav_ssq sequence[] = PREA_SEQUENCE(post, wrap);
+	iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+}
+
+void iosav_write_read_mpr_sequence(
+	int channel, int slotrank, u32 tMOD, u32 loops, u32 gap, u32 loops2, u32 post2)
+{
+	const struct iosav_ssq sequence[] = READ_MPR_SEQUENCE(tMOD, loops, gap, loops2, post2);
+	iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+}
+
+void iosav_write_misc_write_sequence(ramctr_timing *ctrl, int channel, int slotrank,
+				     u32 gap0, u32 loops0, u32 gap1, u32 loops2, u32 wrap2)
+{
+	const struct iosav_ssq sequence[] =
+		MISC_WRITE_SEQUENCE(gap0, loops0, gap1, loops2, wrap2);
+	iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+}
+
+void iosav_write_command_training_sequence(
+	ramctr_timing *ctrl, int channel, int slotrank, unsigned int address)
+{
+	const struct iosav_ssq sequence[] = COMMAND_TRAINING_SEQUENCE(address);
+	iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+}
+
+void iosav_write_data_write_sequence(ramctr_timing *ctrl, int channel, int slotrank)
+{
+	const struct iosav_ssq sequence[] = WRITE_DATA_SEQUENCE;
+	iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+}
+
+void iosav_write_aggressive_write_read_sequence(ramctr_timing *ctrl, int channel, int slotrank)
+{
+	const struct iosav_ssq sequence[] = AGGRESSIVE_WRITE_READ_SEQUENCE;
+	iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+}
+
+void iosav_write_memory_test_sequence(ramctr_timing *ctrl, int channel, int slotrank)
+{
+	const struct iosav_ssq sequence[] = MEMORY_TEST_SEQUENCE;
+	iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));
+}