drivers/intel/fsp2_0: Update MRC cache in ramstage

Currently the MRC cache is updated in romstage, immediately after
returning from FSP-M. Since cbmem is not cached in romstage, the update
is slow (~6 ms on nissa). Specifically, the new MRC data returned by the
FSP is stored in the FSP reserved memory in cbmem, so hashing the new
data is slow.

Move the MRC cache update to ramstage, where cbmem is cached. On nissa,
this saves ~5 ms of boot time.

Before:
552:finished loading ChromeOS VPD (RW)                631,667 (16)
  3:after RAM initialization                          637,703 (6,036)
  4:end of romstage                                   650,307 (12,603)

After:
552:finished loading ChromeOS VPD (RW)                631,832 (15)
  3:after RAM initialization                          633,002 (1,169)
  4:end of romstage                                   645,582 (12,580)

In ramstage, save_mrc_data() takes ~138 us.

BUG=b:242667207
TEST=MRC caching still works as expected on nivviks - after clearing the
MRC cache, memory is retrained on the next boot, but cached data is used
on subsequent boots.

Change-Id: Ie6aa2dee83a3ab8913830746593935d36a034b8d
Signed-off-by: Reka Norman <rekanorman@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/67669
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
diff --git a/src/drivers/intel/fsp2_0/memory_init.c b/src/drivers/intel/fsp2_0/memory_init.c
index 99b0fea..740b9c6 100644
--- a/src/drivers/intel/fsp2_0/memory_init.c
+++ b/src/drivers/intel/fsp2_0/memory_init.c
@@ -26,31 +26,10 @@
 
 static uint8_t temp_ram[CONFIG_FSP_TEMP_RAM_SIZE] __aligned(sizeof(uint64_t));
 
-static void save_memory_training_data(uint32_t fsp_version)
-{
-	size_t  mrc_data_size;
-	const void *mrc_data;
-
-	mrc_data = fsp_find_nv_storage_data(&mrc_data_size);
-	if (!mrc_data) {
-		printk(BIOS_ERR, "FSP_NON_VOLATILE_STORAGE_HOB missing!\n");
-		return;
-	}
-
-	/*
-	 * Save MRC Data to CBMEM. By always saving the data this forces
-	 * a retrain after a trip through ChromeOS recovery path. The
-	 * code which saves the data to flash doesn't write if the latest
-	 * training data matches this one.
-	 */
-	if (mrc_cache_stash_data(MRC_TRAINING_DATA, fsp_version, mrc_data,
-				mrc_data_size) < 0)
-		printk(BIOS_ERR, "Failed to stash MRC data\n");
-}
-
 static void do_fsp_post_memory_init(bool s3wake, uint32_t fsp_version)
 {
 	struct range_entry fsp_mem;
+	uint32_t *fsp_version_cbmem;
 
 	fsp_find_reserved_memory(&fsp_mem);
 
@@ -73,8 +52,14 @@
 		(uintptr_t)cbmem_find(CBMEM_ID_FSP_RESERVED_MEMORY))
 		die("Failed to accommodate FSP reserved memory request!\n");
 
-	if (CONFIG(CACHE_MRC_SETTINGS) && !s3wake)
-		save_memory_training_data(fsp_version);
+	/* ramstage uses the FSP-M version when updating the MRC cache */
+	if (CONFIG(CACHE_MRC_SETTINGS) && !s3wake) {
+		fsp_version_cbmem = cbmem_add(CBMEM_ID_FSPM_VERSION,
+					      sizeof(fsp_version));
+		if (!fsp_version_cbmem)
+			printk(BIOS_ERR, "Failed to add FSP-M version to cbmem.\n");
+		*fsp_version_cbmem = fsp_version;
+	}
 
 	/* Create romstage handof information */
 	romstage_handoff_init(s3wake);