nb/intel/sandybridge: Use bitfield for GDCRTRAININGMOD register

Tested on Asus P8H61-M PRO, still boots.

Change-Id: Ie4b5777dd3789d4cd818ee66bdf3074ad055c818
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47572
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/northbridge/intel/sandybridge/raminit_common.c b/src/northbridge/intel/sandybridge/raminit_common.c
index 60f9e1f..5aaafdd 100644
--- a/src/northbridge/intel/sandybridge/raminit_common.c
+++ b/src/northbridge/intel/sandybridge/raminit_common.c
@@ -1351,7 +1351,12 @@
 		/* Execute command queue */
 		iosav_run_once(channel);
 
-		MCHBAR32(GDCRTRAININGMOD) = (slotrank << 2) | 0x8001;
+		const union gdcr_training_mod_reg training_mod = {
+			.receive_enable_mode = 1,
+			.training_rank_sel   = slotrank,
+			.odt_always_on       = 1,
+		};
+		MCHBAR32(GDCRTRAININGMOD) = training_mod.raw;
 
 		ctrl->timings[channel][slotrank].io_latency = 4;
 		ctrl->timings[channel][slotrank].roundtrip_latency = 55;
@@ -1814,7 +1819,14 @@
 	int statistics[NUM_LANES][128];
 	int lane;
 
-	MCHBAR32(GDCRTRAININGMOD) = 0x108052 | (slotrank << 2);
+	const union gdcr_training_mod_reg training_mod = {
+		.write_leveling_mode = 1,
+		.training_rank_sel   = slotrank,
+		.enable_dqs_wl       = 5,
+		.odt_always_on       = 1,
+		.force_drive_enable  = 1,
+	};
+	MCHBAR32(GDCRTRAININGMOD) = training_mod.raw;
 
 	for (timB = 0; timB < 128; timB++) {
 		FOR_ALL_LANES {
@@ -1884,7 +1896,12 @@
 static void train_write_flyby(ramctr_timing *ctrl)
 {
 	int channel, slotrank, lane, old;
-	MCHBAR32(GDCRTRAININGMOD) = 0x200;
+
+	const union gdcr_training_mod_reg training_mod = {
+		.dq_dqs_training_res = 1,
+	};
+	MCHBAR32(GDCRTRAININGMOD) = training_mod.raw;
+
 	FOR_ALL_POPULATED_CHANNELS {
 		fill_pattern1(ctrl, channel);
 	}
@@ -2046,7 +2063,13 @@
 		write_mrreg(ctrl, channel, slotrank, 1,
 				make_mr1(ctrl, slotrank, channel) | 1 << 12 | 1 << 7);
 
-	MCHBAR32(GDCRTRAININGMOD) = 0x108052;
+	const union gdcr_training_mod_reg training_mod = {
+		.write_leveling_mode = 1,
+		.enable_dqs_wl       = 5,
+		.odt_always_on       = 1,
+		.force_drive_enable  = 1,
+	};
+	MCHBAR32(GDCRTRAININGMOD) = training_mod.raw;
 
 	toggle_io_reset();
 
@@ -2522,8 +2545,11 @@
 	}
 
 	for (i = 0; i < 3; i++) {
-		MCHBAR32(GDCRTRAININGMOD_ch(channel)) = reg3000b24[i] << 24;
-		printram("[%x] = 0x%08x\n", GDCRTRAININGMOD_ch(channel), reg3000b24[i] << 24);
+		const union gdcr_training_mod_reg training_mod = {
+			.vref_gen_ctl = reg3000b24[i],
+		};
+		MCHBAR32(GDCRTRAININGMOD_ch(channel)) = training_mod.raw;
+		printram("[%x] = 0x%08x\n", GDCRTRAININGMOD_ch(channel), training_mod.raw);
 
 		for (pat = 0; pat < NUM_PATTERNS; pat++) {
 			fill_pattern5(ctrl, channel, pat);
diff --git a/src/northbridge/intel/sandybridge/raminit_common.h b/src/northbridge/intel/sandybridge/raminit_common.h
index 798b482..4a7e806 100644
--- a/src/northbridge/intel/sandybridge/raminit_common.h
+++ b/src/northbridge/intel/sandybridge/raminit_common.h
@@ -117,6 +117,29 @@
 	u32 raw;
 };
 
+union gdcr_training_mod_reg {
+	struct {
+		u32 receive_enable_mode : 1; /* [ 0.. 0] */
+		u32 write_leveling_mode : 1; /* [ 1.. 1] */
+		u32 training_rank_sel   : 2; /* [ 3.. 2] */
+		u32 enable_dqs_wl       : 4; /* [ 7.. 4] */
+		u32 dqs_logic_delay_wl  : 1; /* [ 8.. 8] */
+		u32 dq_dqs_training_res : 1; /* [ 9.. 9] */
+		u32                     : 4;
+		u32 delay_dq            : 1; /* [14..14] */
+		u32 odt_always_on       : 1; /* [15..15] */
+		u32                     : 4;
+		u32 force_drive_enable  : 1; /* [20..20] */
+		u32 dft_tx_pi_clk_view  : 1; /* [21..21] */
+		u32 dft_tx_pi_clk_swap  : 1; /* [22..22] */
+		u32 early_odt_en        : 1; /* [23..23] */
+		u32 vref_gen_ctl        : 6; /* [29..24] */
+		u32 ext_vref_sel        : 1; /* [30..30] */
+		u32 tx_fifo_always_on   : 1; /* [31..31] */
+	};
+	u32 raw;
+};
+
 union tc_dbp_reg {
 	struct {
 		u32 tRCD : 4; /* [ 3.. 0] */