summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorBin Meng <bmeng.cn@gmail.com>2017-04-21 07:24:29 -0700
committerBin Meng <bmeng.cn@gmail.com>2017-05-17 17:11:46 +0800
commitfcf2fba472ede05df2e7ed5fb141b8caf4f09681 (patch)
tree686ef2ffdb688051794fa0e35f2ce4990cce5fea /arch
parent4372c111d49f1fa0fec0c8645c23a6266617e69d (diff)
x86: baytrail: acpi: Add APIs for determining/clearing sleep state
This adds APIs for determining previous sleep state from ACPI I/O registers, as well as clearing sleep state on BayTrail SoC. Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org> Tested-by: Stefan Roese <sr@denx.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/cpu/baytrail/acpi.c47
-rw-r--r--arch/x86/include/asm/arch-baytrail/iomap.h24
2 files changed, 71 insertions, 0 deletions
diff --git a/arch/x86/cpu/baytrail/acpi.c b/arch/x86/cpu/baytrail/acpi.c
index fa92d8852e..55ed7de781 100644
--- a/arch/x86/cpu/baytrail/acpi.c
+++ b/arch/x86/cpu/baytrail/acpi.c
@@ -8,7 +8,9 @@
#include <cpu.h>
#include <dm.h>
#include <dm/uclass-internal.h>
+#include <asm/acpi_s3.h>
#include <asm/acpi_table.h>
+#include <asm/io.h>
#include <asm/ioapic.h>
#include <asm/mpspec.h>
#include <asm/tables.h>
@@ -187,3 +189,48 @@ void acpi_create_gnvs(struct acpi_global_nvs *gnvs)
else
gnvs->iuart_en = 0;
}
+
+#ifdef CONFIG_HAVE_ACPI_RESUME
+/*
+ * The following two routines are called at a very early stage, even before
+ * FSP 2nd phase API fsp_init() is called. Registers off ACPI_BASE_ADDRESS
+ * and PMC_BASE_ADDRESS are accessed, so we need make sure the base addresses
+ * of these two blocks are programmed by either U-Boot or FSP.
+ *
+ * It has been verified that 1st phase API (see arch/x86/lib/fsp/fsp_car.S)
+ * on Intel BayTrail SoC already initializes these two base addresses so
+ * we are safe to access these registers here.
+ */
+
+enum acpi_sleep_state chipset_prev_sleep_state(void)
+{
+ u32 pm1_sts;
+ u32 pm1_cnt;
+ u32 gen_pmcon1;
+ enum acpi_sleep_state prev_sleep_state = ACPI_S0;
+
+ /* Read Power State */
+ pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS);
+ pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
+ gen_pmcon1 = readl(PMC_BASE_ADDRESS + GEN_PMCON1);
+
+ debug("PM1_STS = 0x%x PM1_CNT = 0x%x GEN_PMCON1 = 0x%x\n",
+ pm1_sts, pm1_cnt, gen_pmcon1);
+
+ if (pm1_sts & WAK_STS)
+ prev_sleep_state = acpi_sleep_from_pm1(pm1_cnt);
+
+ if (gen_pmcon1 & (PWR_FLR | SUS_PWR_FLR))
+ prev_sleep_state = ACPI_S5;
+
+ return prev_sleep_state;
+}
+
+void chipset_clear_sleep_state(void)
+{
+ u32 pm1_cnt;
+
+ pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
+ outl(pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT);
+}
+#endif
diff --git a/arch/x86/include/asm/arch-baytrail/iomap.h b/arch/x86/include/asm/arch-baytrail/iomap.h
index 62a91051e4..ec4e9d5212 100644
--- a/arch/x86/include/asm/arch-baytrail/iomap.h
+++ b/arch/x86/include/asm/arch-baytrail/iomap.h
@@ -35,6 +35,27 @@
#define PMC_BASE_ADDRESS 0xfed03000
#define PMC_BASE_SIZE 0x400
+#define GEN_PMCON1 0x20
+#define UART_EN (1 << 24)
+#define DISB (1 << 23)
+#define MEM_SR (1 << 21)
+#define SRS (1 << 20)
+#define CTS (1 << 19)
+#define MS4V (1 << 18)
+#define PWR_FLR (1 << 16)
+#define PME_B0_S5_DIS (1 << 15)
+#define SUS_PWR_FLR (1 << 14)
+#define WOL_EN_OVRD (1 << 13)
+#define DIS_SLP_X_STRCH_SUS_UP (1 << 12)
+#define GEN_RST_STS (1 << 9)
+#define RPS (1 << 2)
+#define AFTERG3_EN (1 << 0)
+#define GEN_PMCON2 0x24
+#define SLPSX_STR_POL_LOCK (1 << 18)
+#define BIOS_PCI_EXP_EN (1 << 10)
+#define PWRBTN_LVL (1 << 9)
+#define SMI_LOCK (1 << 4)
+
/* Power Management Unit */
#define PUNIT_BASE_ADDRESS 0xfed05000
#define PUNIT_BASE_SIZE 0x800
@@ -62,6 +83,9 @@
#define ACPI_BASE_ADDRESS 0x0400
#define ACPI_BASE_SIZE 0x80
+#define PM1_STS 0x00
+#define PM1_CNT 0x04
+
#define GPIO_BASE_ADDRESS 0x0500
#define GPIO_BASE_SIZE 0x100