nb/intel/sandybridge: Program MR2 shadow register

This register must be programmed if Self-Refresh Temperature range is
enabled in MR2 (bit 7). Because the memory controller needs to reprogram
MR2 when entering Self-Refresh, it needs a copy of the MR2 settings. It
also needs to know about mirrored ranks to correctly issue MRS commands.

Tested on Asus P8H61-M PRO, still boots.

Change-Id: I2e459ac7907ead75826c7d2ded42328286eb9377
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/47567
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 d3b71d5..4d478a0 100644
--- a/src/northbridge/intel/sandybridge/raminit_common.c
+++ b/src/northbridge/intel/sandybridge/raminit_common.c
@@ -775,6 +775,22 @@
 	mr2reg |= (odt.rttwr / 60) << 9;
 
 	write_mrreg(ctrl, channel, rank, 2, mr2reg);
+
+	/* Program MR2 shadow */
+	u32 reg32 = MCHBAR32(TC_MR2_SHADOW_ch(channel));
+
+	reg32 &= 3 << 14 | 3 << 6;
+
+	reg32 |= mr2reg & ~(3 << 6);
+
+	if (rank & 1) {
+		if (srt)
+			reg32 |= 1 << (rank / 2 + 6);
+	} else {
+		if (ctrl->rank_mirror[channel][rank])
+			reg32 |= 1 << (rank / 2 + 14);
+	}
+	MCHBAR32(TC_MR2_SHADOW_ch(channel)) = reg32;
 }
 
 static void dram_mr3(ramctr_timing *ctrl, u8 rank, int channel)