intel sandy/ivy: Improve DIMM replacement detection

When MRC cache is available, first read only the SPD unique
identifier bytes required to detect possible DIMM replacement.
As this is 11 vs 256 bytes with slow SMBus operations, we save
about 70ms for every installed DIMM on normal boot path.

In the DIMM replacement case this adds some 10ms per installed DIMM
as some SPD gets read twice, but we are on slow RAM training boot path
anyways.

Change-Id: I294a56e7b7562c3dea322c644b21a15abb033870
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/17491
Tested-by: build bot (Jenkins)
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c
index 63e951f..f3a1ba5 100644
--- a/src/northbridge/intel/sandybridge/raminit.c
+++ b/src/northbridge/intel/sandybridge/raminit.c
@@ -361,11 +361,16 @@
 	return match;
 }
 
-void read_spd(spd_raw_data * spd, u8 addr)
+void read_spd(spd_raw_data * spd, u8 addr, bool id_only)
 {
 	int j;
-	for (j = 0; j < 256; j++)
-		(*spd)[j] = do_smbus_read_byte(SMBUS_IO_BASE, addr, j);
+	if (id_only) {
+		for (j = 117; j < 128; j++)
+			(*spd)[j] = do_smbus_read_byte(SMBUS_IO_BASE, addr, j);
+	} else {
+		for (j = 0; j < 256; j++)
+			(*spd)[j] = do_smbus_read_byte(SMBUS_IO_BASE, addr, j);
+	}
 }
 
 static void dram_find_spds_ddr3(spd_raw_data *spd, ramctr_timing *ctrl)
@@ -4235,14 +4240,12 @@
 		ctrl_cached = (ramctr_timing *)mrc_cache->mrc_data;
 	}
 
-
-	if (!s3resume) {
-		memset(spds, 0, sizeof(spds));
-		mainboard_get_spd(spds);
-	}
-
 	/* verify MRC cache for fast boot */
 	if (!s3resume && ctrl_cached) {
+		/* Load SPD unique information data. */
+		memset(spds, 0, sizeof(spds));
+		mainboard_get_spd(spds, 1);
+
 		/* check SPD CRC16 to make sure the DIMMs haven't been replaced */
 		fast_boot = verify_crc16_spds_ddr3(spds, ctrl_cached);
 		if (!fast_boot)
@@ -4273,6 +4276,8 @@
 		ctrl.tCK = min_tck;
 
 		/* Get DDR3 SPD data */
+		memset(spds, 0, sizeof(spds));
+		mainboard_get_spd(spds, 0);
 		dram_find_spds_ddr3(spds, &ctrl);
 
 		err = try_init_dram_ddr3(&ctrl, fast_boot, s3resume, me_uma_size);