aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/baytrail/romstage/romstage.c
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2013-11-06 12:04:50 -0600
committerKyösti Mälkki <kyosti.malkki@gmail.com>2014-05-06 17:17:05 +0200
commit6e3289372c598e3e0702f44e52c04d689172b156 (patch)
tree194a27091dced9432029fc69f12c62262a776985 /src/soc/intel/baytrail/romstage/romstage.c
parent2237324e77a5e8ed30878609095c1592081f15e4 (diff)
baytrail: add support for S3 resume
Previously the only path through memory init and coreboot was hardcoding S5. Therefore all S3 paths would not be taken. Allow for S3 resume to work by enabling the proper control paths in romstage. BUG=chrome-os-partner:22867 BRANCH=None TEST=While in kernel 'echo mem > /sys/power/state'. Board went into S3. Power button press resumed back into kernel. Change-Id: I3cbae73223f0d71c74eb3d6b7c25d1b32318ab3e Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/175940 Reviewed-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: http://review.coreboot.org/4943 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Diffstat (limited to 'src/soc/intel/baytrail/romstage/romstage.c')
-rw-r--r--src/soc/intel/baytrail/romstage/romstage.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/src/soc/intel/baytrail/romstage/romstage.c b/src/soc/intel/baytrail/romstage/romstage.c
index 5af9bf4566..969e8487f9 100644
--- a/src/soc/intel/baytrail/romstage/romstage.c
+++ b/src/soc/intel/baytrail/romstage/romstage.c
@@ -36,6 +36,7 @@
#include <baytrail/iomap.h>
#include <baytrail/lpc.h>
#include <baytrail/pci_devs.h>
+#include <baytrail/pmc.h>
#include <baytrail/reset.h>
#include <baytrail/romstage.h>
#include <baytrail/smm.h>
@@ -139,10 +140,50 @@ void * asmlinkage romstage_main(unsigned long bist,
return setup_stack_and_mttrs();
}
+/* Return 0, 3, or 5 to indicate the previous sleep state. */
+static int chipset_prev_sleep_state(void)
+{
+ uint16_t pm1_sts;
+ uint32_t pm1_cnt;
+ uint32_t gen_pmcon1;
+ /* Default to S0. */
+ int prev_sleep_state = 0;
+
+ pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS);
+ pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
+
+ if (pm1_sts & WAK_STS) {
+ switch ((pm1_cnt & SLP_TYP) >> SLP_TYP_SHIFT) {
+ #if CONFIG_HAVE_ACPI_RESUME
+ case SLP_TYP_S3:
+ prev_sleep_state = 3;
+ break;
+ #endif
+ case SLP_TYP_S5:
+ prev_sleep_state = 5;
+ }
+ /* Clear SLP_TYP. */
+ outl(pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT);
+ }
+
+ gen_pmcon1 = read32(PMC_BASE_ADDRESS + GEN_PMCON1);
+ if (gen_pmcon1 & (PWR_FLR | SUS_PWR_FLR)) {
+ /* Clear power failure bits. */
+ write32(PMC_BASE_ADDRESS + GEN_PMCON1, gen_pmcon1);
+ prev_sleep_state = 5;
+ }
+
+ printk(BIOS_DEBUG, "pm1_sts = %04x pm1_cnt = %08x gen_pmcon1 = %08x\n",
+ pm1_sts, pm1_cnt, gen_pmcon1);
+
+ return prev_sleep_state;
+}
+
/* Entry from the mainboard. */
void romstage_common(struct romstage_params *params)
{
struct romstage_handoff *handoff;
+ int prev_sleep_state;
mark_ts(params, timestamp_get());
@@ -150,14 +191,18 @@ void romstage_common(struct romstage_params *params)
boot_count_increment();
#endif
+ prev_sleep_state = chipset_prev_sleep_state();
+
+ printk(BIOS_DEBUG, "prev_sleep_state = S%d\n", prev_sleep_state);
+
/* Initialize RAM */
- raminit(params->mrc_params, 5);
+ raminit(params->mrc_params, prev_sleep_state);
mark_ts(params, timestamp_get());
handoff = romstage_handoff_find_or_add();
if (handoff != NULL)
- handoff->s3_resume = 0;
+ handoff->s3_resume = (prev_sleep_state == 3);
else
printk(BIOS_DEBUG, "Romstage handoff structure not added!\n");