drivers/intel/fsp2_0: honor FSP revision for memory training data

Utilizing the FSP revision while saving the memory training data is
important because it means when the FSP is updated the memory training
is redone. The previous implementation was just using '0' as a revision.
Because of that behavior a retrain would not have been done on an FSP
upgrade.

BUG=chrome-os-partner:52679

Change-Id: I1430bd78c770a840d2deff2476f47150c02cf27d
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://review.coreboot.org/15744
Tested-by: build bot (Jenkins)
Reviewed-by: Furquan Shaikh <furquan@google.com>
Reviewed-by: Andrey Petrov <andrey.petrov@intel.com>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
This commit is contained in:
Aaron Durbin 2016-07-18 11:24:36 -05:00
parent ec065e8096
commit f0ec82450b
1 changed files with 55 additions and 24 deletions

View File

@ -31,11 +31,35 @@
typedef asmlinkage enum fsp_status (*fsp_memory_init_fn) typedef asmlinkage enum fsp_status (*fsp_memory_init_fn)
(void *raminit_upd, void **hob_list); (void *raminit_upd, void **hob_list);
static enum fsp_status do_fsp_post_memory_init(void *hob_list_ptr, bool s3wake) static void save_memory_training_data(bool s3wake, uint32_t fsp_version)
{ {
struct range_entry fsp_mem;
size_t mrc_data_size; size_t mrc_data_size;
const void *mrc_data; const void *mrc_data;
if (!IS_ENABLED(CONFIG_CACHE_MRC_SETTINGS) || s3wake)
return;
mrc_data = fsp_find_nv_storage_data(&mrc_data_size);
if (!mrc_data) {
printk(BIOS_ERR, "Couldn't find memory training data HOB.\n");
return;
}
/*
* Save MRC Data to CBMEM. By always saving the data this forces
* a retrain after a trip through Chrome OS 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_with_version(mrc_data, mrc_data_size,
fsp_version) < 0)
printk(BIOS_ERR, "Failed to stash MRC data\n");
}
static enum fsp_status do_fsp_post_memory_init(void *hob_list_ptr, bool s3wake,
uint32_t fsp_version)
{
struct range_entry fsp_mem;
struct romstage_handoff *handoff; struct romstage_handoff *handoff;
fsp_find_reserved_memory(&fsp_mem, hob_list_ptr); fsp_find_reserved_memory(&fsp_mem, hob_list_ptr);
@ -61,12 +85,7 @@ static enum fsp_status do_fsp_post_memory_init(void *hob_list_ptr, bool s3wake)
/* Now that CBMEM is up, save the list so ramstage can use it */ /* Now that CBMEM is up, save the list so ramstage can use it */
fsp_save_hob_list(hob_list_ptr); fsp_save_hob_list(hob_list_ptr);
/* Save MRC Data to CBMEM */ save_memory_training_data(s3wake, fsp_version);
if (IS_ENABLED(CONFIG_CACHE_MRC_SETTINGS) && !s3wake) {
mrc_data = fsp_find_nv_storage_data(&mrc_data_size);
if (mrc_data && mrc_cache_stash_data(mrc_data, mrc_data_size) < 0)
printk(BIOS_ERR, "Failed to stash MRC data\n");
}
/* Create romstage handof information */ /* Create romstage handof information */
handoff = romstage_handoff_find_or_add(); handoff = romstage_handoff_find_or_add();
@ -78,11 +97,33 @@ static enum fsp_status do_fsp_post_memory_init(void *hob_list_ptr, bool s3wake)
return FSP_SUCCESS; return FSP_SUCCESS;
} }
static void fsp_fill_common_arch_params(struct FSPM_ARCH_UPD *arch_upd, static void fsp_fill_mrc_cache(struct FSPM_ARCH_UPD *arch_upd, bool s3wake,
bool s3wake) uint32_t fsp_version)
{ {
const struct mrc_saved_data *mrc_cache; const struct mrc_saved_data *mrc_cache;
arch_upd->NvsBufferPtr = NULL;
if (!IS_ENABLED(CONFIG_CACHE_MRC_SETTINGS))
return;
if (mrc_cache_get_current_with_version(&mrc_cache, fsp_version)) {
printk(BIOS_DEBUG, "MRC cache was not found\n");
return;
}
/* MRC cache found */
arch_upd->NvsBufferPtr = (void *)mrc_cache->data;
arch_upd->BootMode = s3wake ?
FSP_BOOT_ON_S3_RESUME:
FSP_BOOT_ASSUMING_NO_CONFIGURATION_CHANGES;
printk(BIOS_DEBUG, "MRC cache found, size %x bootmode:%d\n",
mrc_cache->size, arch_upd->BootMode);
}
static void fsp_fill_common_arch_params(struct FSPM_ARCH_UPD *arch_upd,
bool s3wake, uint32_t fsp_version)
{
/* /*
* FSPM_UPD passed here is populated with default values provided by * FSPM_UPD passed here is populated with default values provided by
* the blob itself. We let FSPM use top of CAR region of the size it * the blob itself. We let FSPM use top of CAR region of the size it
@ -93,18 +134,7 @@ static void fsp_fill_common_arch_params(struct FSPM_ARCH_UPD *arch_upd,
arch_upd->BootMode = FSP_BOOT_WITH_FULL_CONFIGURATION; arch_upd->BootMode = FSP_BOOT_WITH_FULL_CONFIGURATION;
if (IS_ENABLED(CONFIG_CACHE_MRC_SETTINGS)) { fsp_fill_mrc_cache(arch_upd, s3wake, fsp_version);
if (!mrc_cache_get_current_with_version(&mrc_cache, 0)) {
/* MRC cache found */
arch_upd->NvsBufferPtr = (void *)mrc_cache->data;
arch_upd->BootMode = s3wake ?
FSP_BOOT_ON_S3_RESUME:
FSP_BOOT_ASSUMING_NO_CONFIGURATION_CHANGES;
printk(BIOS_DEBUG, "MRC cache found, size %x bootmode:%d\n",
mrc_cache->size, arch_upd->BootMode);
} else
printk(BIOS_DEBUG, "MRC cache was not found\n");
}
} }
static enum fsp_status do_fsp_memory_init(struct fsp_header *hdr, bool s3wake) static enum fsp_status do_fsp_memory_init(struct fsp_header *hdr, bool s3wake)
@ -130,7 +160,8 @@ static enum fsp_status do_fsp_memory_init(struct fsp_header *hdr, bool s3wake)
fspm_upd.FspmArchUpd.BootLoaderTolumSize = cbmem_overhead_size(); fspm_upd.FspmArchUpd.BootLoaderTolumSize = cbmem_overhead_size();
/* Fill common settings on behalf of chipset. */ /* Fill common settings on behalf of chipset. */
fsp_fill_common_arch_params(&fspm_upd.FspmArchUpd, s3wake); fsp_fill_common_arch_params(&fspm_upd.FspmArchUpd, s3wake,
hdr->fsp_revision);
/* Give SoC and mainboard a chance to update the UPD */ /* Give SoC and mainboard a chance to update the UPD */
platform_fsp_memory_init_params_cb(&fspm_upd); platform_fsp_memory_init_params_cb(&fspm_upd);
@ -153,7 +184,7 @@ static enum fsp_status do_fsp_memory_init(struct fsp_header *hdr, bool s3wake)
if (status != FSP_SUCCESS) if (status != FSP_SUCCESS)
return status; return status;
return do_fsp_post_memory_init(hob_list_ptr, s3wake); return do_fsp_post_memory_init(hob_list_ptr, s3wake, hdr->fsp_revision);
} }
/* Load the binary into the memory specified by the info header. */ /* Load the binary into the memory specified by the info header. */