summaryrefslogtreecommitdiff
path: root/arch/x86/lib/fsp/fsp_common.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2017-05-17 14:13:16 -0400
committerTom Rini <trini@konsulko.com>2017-05-17 14:13:16 -0400
commitae1b939930b0fffc062bb99196ec22e19afcc7e8 (patch)
treecc8d8c87b15932f82d5ed3c4e26bb118de949aff /arch/x86/lib/fsp/fsp_common.c
parenta9f47426ced2e5057930990f3cd602b8ab936f69 (diff)
parentc2f17939f4b429c90a453e26927a7c578e5456b5 (diff)
Merge git://git.denx.de/u-boot-x86
Diffstat (limited to 'arch/x86/lib/fsp/fsp_common.c')
-rw-r--r--arch/x86/lib/fsp/fsp_common.c63
1 files changed, 62 insertions, 1 deletions
diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c
index 66a388d601..3397bb83ea 100644
--- a/arch/x86/lib/fsp/fsp_common.c
+++ b/arch/x86/lib/fsp/fsp_common.c
@@ -5,7 +5,12 @@
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
+#include <rtc.h>
+#include <asm/acpi_s3.h>
+#include <asm/cmos_layout.h>
+#include <asm/early_cmos.h>
#include <asm/io.h>
#include <asm/mrccache.h>
#include <asm/post.h>
@@ -75,9 +80,41 @@ static __maybe_unused void *fsp_prepare_mrc_cache(void)
return cache->data;
}
+#ifdef CONFIG_HAVE_ACPI_RESUME
+int fsp_save_s3_stack(void)
+{
+ struct udevice *dev;
+ int ret;
+
+ if (gd->arch.prev_sleep_state == ACPI_S3)
+ return 0;
+
+ ret = uclass_get_device(UCLASS_RTC, 0, &dev);
+ if (ret) {
+ debug("Cannot find RTC: err=%d\n", ret);
+ return -ENODEV;
+ }
+
+ /* Save the stack address to CMOS */
+ ret = rtc_write32(dev, CMOS_FSP_STACK_ADDR, gd->start_addr_sp);
+ if (ret) {
+ debug("Save stack address to CMOS: err=%d\n", ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+#endif
+
int arch_fsp_init(void)
{
void *nvs;
+ int stack = CONFIG_FSP_TEMP_RAM_ADDR;
+ int boot_mode = BOOT_FULL_CONFIG;
+#ifdef CONFIG_HAVE_ACPI_RESUME
+ int prev_sleep_state = chipset_prev_sleep_state();
+ gd->arch.prev_sleep_state = prev_sleep_state;
+#endif
if (!gd->arch.hob_list) {
#ifdef CONFIG_ENABLE_MRC_CACHE
@@ -85,12 +122,36 @@ int arch_fsp_init(void)
#else
nvs = NULL;
#endif
+
+#ifdef CONFIG_HAVE_ACPI_RESUME
+ if (prev_sleep_state == ACPI_S3) {
+ if (nvs == NULL) {
+ /* If waking from S3 and no cache then */
+ debug("No MRC cache found in S3 resume path\n");
+ post_code(POST_RESUME_FAILURE);
+ /* Clear Sleep Type */
+ chipset_clear_sleep_state();
+ /* Reboot */
+ debug("Rebooting..\n");
+ reset_cpu(0);
+ /* Should not reach here.. */
+ panic("Reboot System");
+ }
+
+ /*
+ * DM is not avaiable yet at this point, hence call
+ * CMOS access library which does not depend on DM.
+ */
+ stack = cmos_read32(CMOS_FSP_STACK_ADDR);
+ boot_mode = BOOT_ON_S3_RESUME;
+ }
+#endif
/*
* The first time we enter here, call fsp_init().
* Note the execution does not return to this function,
* instead it jumps to fsp_continue().
*/
- fsp_init(CONFIG_FSP_TEMP_RAM_ADDR, BOOT_FULL_CONFIG, nvs);
+ fsp_init(stack, boot_mode, nvs);
} else {
/*
* The second time we enter here, adjust the size of malloc()