@@ -16,10 +16,14 @@ int fspm_update_config(struct udevice *dev, struct fspm_upd *upd)
{
struct fsp_m_config *cfg = &upd->config;
struct fspm_arch_upd *arch = &upd->arch;
+ int cache_ret = 0;
ofnode node;
+ int ret;
arch->nvs_buffer_ptr = NULL;
- prepare_mrc_cache(upd);
+ cache_ret = prepare_mrc_cache(upd);
+ if (cache_ret && cache_ret != -ENOENT)
+ return log_msg_ret("mrc", cache_ret);
arch->stack_base = (void *)0xfef96000;
arch->boot_loader_tolum_size = 0;
arch->boot_mode = FSP_BOOT_WITH_FULL_CONFIGURATION;
@@ -28,7 +32,11 @@ int fspm_update_config(struct udevice *dev, struct fspm_upd *upd)
if (!ofnode_valid(node))
return log_msg_ret("fsp-m settings", -ENOENT);
- return fsp_m_update_config_from_dtb(node, cfg);
+ ret = fsp_m_update_config_from_dtb(node, cfg);
+ if (ret)
+ return log_msg_ret("dtb", cache_ret);
+
+ return cache_ret;
}
/*
@@ -117,6 +117,7 @@
reg = <0x00000000 0 0 0 0>;
compatible = "intel,apl-hostbridge";
pciex-region-size = <0x10000000>;
+ fspm,training-delay = <21>;
/*
* Parameters used by the FSP-S binary blob. This is
* really unfortunate since these parameters mostly
@@ -57,7 +57,8 @@ int arch_fsps_preinit(void);
*
* @dev: Hostbridge device containing config
* @upd: Config data to fill in
- * @return 0 if OK, -ve on error
+ * @return 0 if OK, -ENOENT if OK but no MRC-cache data was found, other -ve on
+ * error
*/
int fspm_update_config(struct udevice *dev, struct fspm_upd *upd);
@@ -9,6 +9,7 @@
#include <common.h>
#include <binman.h>
#include <bootstage.h>
+#include <dm.h>
#include <log.h>
#include <asm/mrccache.h>
#include <asm/fsp/fsp_infoheader.h>
@@ -63,8 +64,10 @@ int fsp_memory_init(bool s3wake, bool use_spi_flash)
struct fsp_header *hdr;
struct hob_header *hob;
struct udevice *dev;
+ int delay;
int ret;
+ log_debug("Locating FSP\n");
ret = fsp_locate_fsp(FSP_M, &entry, use_spi_flash, &dev, &hdr, NULL);
if (ret)
return log_msg_ret("locate FSP", ret);
@@ -76,21 +79,32 @@ int fsp_memory_init(bool s3wake, bool use_spi_flash)
return log_msg_ret("Bad UPD signature", -EPERM);
memcpy(&upd, fsp_upd, sizeof(upd));
+ delay = dev_read_u32_default(dev, "fspm,training-delay", 0);
ret = fspm_update_config(dev, &upd);
- if (ret)
- return log_msg_ret("Could not setup config", ret);
-
- debug("SDRAM init...");
+ if (ret) {
+ if (ret != -ENOENT)
+ return log_msg_ret("Could not setup config", ret);
+ } else {
+ delay = 0;
+ }
+
+ if (delay)
+ printf("SDRAM training (%d seconds)...", delay);
+ else
+ log_debug("SDRAM init...");
bootstage_start(BOOTSTAGE_ID_ACCUM_FSP_M, "fsp-m");
func = (fsp_memory_init_func)(hdr->img_base + hdr->fsp_mem_init);
ret = func(&upd, &hob);
bootstage_accum(BOOTSTAGE_ID_ACCUM_FSP_M);
cpu_reinit_fpu();
+ if (delay)
+ printf("done\n");
+ else
+ log_debug("done\n");
if (ret)
return log_msg_ret("SDRAM init fail\n", ret);
gd->arch.hob_list = hob;
- debug("done\n");
ret = fspm_done(dev);
if (ret)
@@ -17,6 +17,9 @@ values of the FSP-M are used.
[2] https://github.com/IntelFsp/FSP/tree/master/ApolloLakeFspBinPkg/Docs
Optional properties:
+- fspm,training-delay: Time taken to train DDR memory if there is no cached MRC
+ data, in seconds. This is used to show a message if possible. For Intel APL
+ this is typicaly 21 seconds.
- fspm,serial-debug-port-address: Debug Serial Port Base address
- fspm,serial-debug-port-type: Debug Serial Port Type
0: NONE
With DDR4, Intel SOCs take quite a long time to init their memory. During this time, if the user is watching, it looks like SPL has hung. Add a message in this case. This works by adding a return code to fspm_update_config() that indicates whether MRC data was found and a new property to the device tree. Also add one more debug message while starting. Signed-off-by: Simon Glass <sjg at chromium.org> --- arch/x86/cpu/apollolake/fsp_m.c | 12 ++++++++-- arch/x86/dts/chromebook_coral.dts | 1 + arch/x86/include/asm/fsp2/fsp_internal.h | 3 ++- arch/x86/lib/fsp2/fsp_meminit.c | 24 +++++++++++++++---- .../fsp/fsp2/apollolake/fsp-m.txt | 3 +++ 5 files changed, 35 insertions(+), 8 deletions(-)