summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/drivers/intel/fsp2_0/Kconfig8
-rw-r--r--src/drivers/intel/fsp2_0/include/fsp/api.h9
-rw-r--r--src/drivers/intel/fsp2_0/memory_init.c44
3 files changed, 58 insertions, 3 deletions
diff --git a/src/drivers/intel/fsp2_0/Kconfig b/src/drivers/intel/fsp2_0/Kconfig
index 6cc56b2a647f..864b3a1a2d3f 100644
--- a/src/drivers/intel/fsp2_0/Kconfig
+++ b/src/drivers/intel/fsp2_0/Kconfig
@@ -118,4 +118,12 @@ config FSP2_0_USES_TPM_MRC_HASH
default n
select VBOOT_HAS_REC_HASH_SPACE
+config FSP_PLATFORM_MEMORY_SETTINGS_VERSIONS
+ bool
+ help
+ This is selected by SoC or mainboard to supply their own
+ concept of a version for the memory settings respectively.
+ This allows deployed systems to bump their version number
+ with the same FSP which will trigger a retrain of the memory.
+
endif
diff --git a/src/drivers/intel/fsp2_0/include/fsp/api.h b/src/drivers/intel/fsp2_0/include/fsp/api.h
index 3532ad2ef882..123db303ca86 100644
--- a/src/drivers/intel/fsp2_0/include/fsp/api.h
+++ b/src/drivers/intel/fsp2_0/include/fsp/api.h
@@ -53,6 +53,15 @@ void fsps_load(bool s3wake);
void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version);
void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd);
+/*
+ * The following functions are used when FSP_PLATFORM_MEMORY_SETTINGS_VERSION
+ * is employed allowing the mainboard and SoC to supply their own version
+ * for memory settings respectively. The valid values are 0-15 for each
+ * function.
+ */
+uint8_t fsp_memory_mainboard_version(void);
+uint8_t fsp_memory_soc_version(void);
+
/* Callback after processing FSP notify */
void platform_fsp_notify_status(enum fsp_notify_phase phase);
diff --git a/src/drivers/intel/fsp2_0/memory_init.c b/src/drivers/intel/fsp2_0/memory_init.c
index 559d83e9df21..424a325958d0 100644
--- a/src/drivers/intel/fsp2_0/memory_init.c
+++ b/src/drivers/intel/fsp2_0/memory_init.c
@@ -281,6 +281,41 @@ static enum cb_err fsp_fill_common_arch_params(FSPM_ARCH_UPD *arch_upd,
return CB_SUCCESS;
}
+__attribute__ ((weak))
+uint8_t fsp_memory_mainboard_version(void)
+{
+ return 0;
+}
+
+__attribute__ ((weak))
+uint8_t fsp_memory_soc_version(void)
+{
+ return 0;
+}
+
+/*
+ * Allow SoC and/or mainboard to bump the revision of the FSP setting
+ * number. The FSP spec uses the low 8 bits as the build number. Take over
+ * bits 3:0 for the SoC setting and bits 7:4 for the mainboard. That way
+ * a tweak in the settings will bump the version used to track the cached
+ * setting which triggers retraining when the FSP version hasn't changed, but
+ * the SoC or mainboard settings have.
+ */
+static uint32_t fsp_memory_settings_version(const struct fsp_header *hdr)
+{
+ /* Use the full FSP version by default. */
+ uint32_t ver = hdr->fsp_revision;
+
+ if (!IS_ENABLED(CONFIG_FSP_PLATFORM_MEMORY_SETTINGS_VERSIONS))
+ return ver;
+
+ ver &= ~0xff;
+ ver |= (0xf & fsp_memory_mainboard_version()) << 4;
+ ver |= (0xf & fsp_memory_soc_version()) << 0;
+
+ return ver;
+}
+
static void do_fsp_memory_init(struct fsp_header *hdr, bool s3wake,
const struct memranges *memmap)
{
@@ -288,9 +323,12 @@ static void do_fsp_memory_init(struct fsp_header *hdr, bool s3wake,
fsp_memory_init_fn fsp_raminit;
FSPM_UPD fspm_upd, *upd;
FSPM_ARCH_UPD *arch_upd;
+ uint32_t fsp_version;
post_code(0x34);
+ fsp_version = fsp_memory_settings_version(hdr);
+
upd = (FSPM_UPD *)(hdr->cfg_region_offset + hdr->image_base);
if (upd->FspUpdHeader.Signature != FSPM_UPD_SIGNATURE)
@@ -305,12 +343,12 @@ static void do_fsp_memory_init(struct fsp_header *hdr, bool s3wake,
arch_upd->BootLoaderTolumSize = cbmem_overhead_size();
/* Fill common settings on behalf of chipset. */
- if (fsp_fill_common_arch_params(arch_upd, s3wake, hdr->fsp_revision,
+ if (fsp_fill_common_arch_params(arch_upd, s3wake, fsp_version,
memmap) != CB_SUCCESS)
die("FSPM_ARCH_UPD not found!\n");
/* Give SoC and mainboard a chance to update the UPD */
- platform_fsp_memory_init_params_cb(&fspm_upd, hdr->fsp_revision);
+ platform_fsp_memory_init_params_cb(&fspm_upd, fsp_version);
if (IS_ENABLED(CONFIG_MMA))
setup_mma(&fspm_upd.FspmConfig);
@@ -334,7 +372,7 @@ static void do_fsp_memory_init(struct fsp_header *hdr, bool s3wake,
die("FspMemoryInit returned an error!\n");
}
- do_fsp_post_memory_init(s3wake, hdr->fsp_revision);
+ do_fsp_post_memory_init(s3wake, fsp_version);
}
/* Load the binary into the memory specified by the info header. */