xref: /aosp_15_r20/external/coreboot/src/drivers/intel/fsp2_0/save_mrc_data.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <acpi/acpi.h>
4 #include <cbmem.h>
5 #include <console/console.h>
6 #include <fsp/util.h>
7 #include <mrc_cache.h>
8 
save_memory_training_data(void)9 void save_memory_training_data(void)
10 {
11 	size_t mrc_data_size;
12 	const void *mrc_data;
13 	uint32_t cbmem_id = CONFIG(MRC_CACHE_USING_MRC_VERSION) ? CBMEM_ID_MRC_VERSION :
14 					 CBMEM_ID_FSPM_VERSION;
15 	uint32_t *version;
16 
17 	if (acpi_is_wakeup_s3())
18 		return;
19 
20 	version = cbmem_find(cbmem_id);
21 	if (!version) {
22 		printk(BIOS_ERR, "Failed to read %s version from cbmem.\n",
23 				CONFIG(MRC_CACHE_USING_MRC_VERSION) ? "MRC" : "FSP-M");
24 		return;
25 	}
26 
27 	mrc_data = fsp_find_nv_storage_data(&mrc_data_size);
28 	if (!mrc_data) {
29 		printk(BIOS_ERR, "FSP_NON_VOLATILE_STORAGE_HOB missing!\n");
30 		return;
31 	}
32 
33 	/*
34 	 * Save MRC data to SPI flash. By always saving the data this forces
35 	 * a retrain after a trip through ChromeOS recovery path. The
36 	 * code which saves the data to flash doesn't write if the latest
37 	 * training data matches this one.
38 	 */
39 	if (mrc_cache_stash_data(MRC_TRAINING_DATA, *version, mrc_data,
40 				 mrc_data_size) < 0)
41 		printk(BIOS_ERR, "Failed to stash MRC data\n");
42 }
43