From a6b85ad950fb3a51d12cb91c869420b72b433619 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Tue, 21 Jan 2014 15:24:40 -0800 Subject: [PATCH] baytrail: Add basic support for ACPI System Wake Source This adds the very basic top-level support for determining the system wake source from ACPI. It only implements the _SWS method in the _SB scope which just returns a bit index into the PM1 status register for the first fixed functional block. This can be used to determine wake source of RTC or Power Button but does not help determine wake source for USB or GPIO. The ACPI spec says to return -1 if no source can be determined from PM1 status register. BUG=chrome-os-partner:8127 BRANCH=baytrail TEST=build and boot on rambi 1) Test resume from S3 by RTC: ACPI System Wake Source is PM1 Index 10 (bit 10 is RTC_STS in ACPI spec, ACPI_EVENT_RTC in kernel) 2) Test resume from S3 by power button: ACPI System Wake Source is PM1 Index 8 (bit 8 is PWRBTN_STS in ACPI spec, ACPI_EVENT_POWER_BUTTON in kernel) 3) Test resume from S3 by USB: ACPI System Wake Source is PM1 Index -1 Change-Id: Ifc5c0867f82cf291af157537b8c13fe44923d8f5 Signed-off-by: Duncan Laurie Reviewed-on: https://chromium-review.googlesource.com/183333 Reviewed-by: Aaron Durbin --- src/soc/intel/baytrail/acpi.c | 3 +++ src/soc/intel/baytrail/acpi/globalnvs.asl | 1 + src/soc/intel/baytrail/acpi/platform.asl | 5 ++++ src/soc/intel/baytrail/baytrail/nvs.h | 3 ++- src/soc/intel/baytrail/ramstage.c | 29 +++++++++++++++++++++++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/soc/intel/baytrail/acpi.c b/src/soc/intel/baytrail/acpi.c index 57233a9833..1ab1eb3748 100644 --- a/src/soc/intel/baytrail/acpi.c +++ b/src/soc/intel/baytrail/acpi.c @@ -80,6 +80,9 @@ static acpi_cstate_t cstate_map[] = { void acpi_init_gnvs(global_nvs_t *gnvs) { + /* Set unknown wake source */ + gnvs->pm1i = -1; + /* CPU core count */ gnvs->pcnt = dev_count_cpu(); diff --git a/src/soc/intel/baytrail/acpi/globalnvs.asl b/src/soc/intel/baytrail/acpi/globalnvs.asl index b384cea1ec..a201c03d50 100644 --- a/src/soc/intel/baytrail/acpi/globalnvs.asl +++ b/src/soc/intel/baytrail/acpi/globalnvs.asl @@ -52,6 +52,7 @@ Field (GNVS, ByteAcc, NoLock, Preserve) TPMP, 8, // 0x12 - TPM Present and Enabled TLVL, 8, // 0x13 - Throttle Level PPCM, 8, // 0x14 - Maximum P-state usable by OS + PM1I, 32, // 0x15 - System Wake Source - PM1 Index /* Device Config */ Offset (0x20), diff --git a/src/soc/intel/baytrail/acpi/platform.asl b/src/soc/intel/baytrail/acpi/platform.asl index e0693928fa..e32880ef9b 100644 --- a/src/soc/intel/baytrail/acpi/platform.asl +++ b/src/soc/intel/baytrail/acpi/platform.asl @@ -71,3 +71,8 @@ Method(_WAK,1) Return(Package(){0,0}) } +Method (_SWS) +{ + /* Index into PM1 for device that caused wake */ + Return (\PM1I) +} diff --git a/src/soc/intel/baytrail/baytrail/nvs.h b/src/soc/intel/baytrail/baytrail/nvs.h index 5bc1b0eb5a..b1561f74f9 100644 --- a/src/soc/intel/baytrail/baytrail/nvs.h +++ b/src/soc/intel/baytrail/baytrail/nvs.h @@ -43,7 +43,8 @@ typedef struct { u8 tpmp; /* 0x12 - TPM Present and Enabled */ u8 tlvl; /* 0x13 - Throttle Level */ u8 ppcm; /* 0x14 - Maximum P-state usable by OS */ - u8 rsvd1[11]; + u32 pm1i; /* 0x15 - System Wake Source - PM1 Index */ + u8 rsvd1[7]; /* Device Config */ u8 s5u0; /* 0x20 - Enable USB0 in S5 */ diff --git a/src/soc/intel/baytrail/ramstage.c b/src/soc/intel/baytrail/ramstage.c index 9fe6c27dfe..0cc932700f 100644 --- a/src/soc/intel/baytrail/ramstage.c +++ b/src/soc/intel/baytrail/ramstage.c @@ -36,6 +36,7 @@ #include #include #include +#include #include /* Global PATTRS */ @@ -131,6 +132,32 @@ static inline void set_acpi_sleep_type(int val) #endif } +/* Save bit index for first enabled event in PM1_STS for \_SB._SWS */ +static void s3_save_acpi_wake_source(global_nvs_t *gnvs) +{ + struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE); + uint16_t pm1; + + if (!ps) + return; + + pm1 = ps->pm1_sts & ps->pm1_en; + + /* Scan for first set bit in PM1 */ + for (gnvs->pm1i = 0; gnvs->pm1i < 16; gnvs->pm1i++) { + if (pm1 & 1) + break; + pm1 >>= 1; + } + + /* If unable to determine then return -1 */ + if (gnvs->pm1i >= 16) + gnvs->pm1i = -1; + + printk(BIOS_DEBUG, "ACPI System Wake Source is PM1 Index %d\n", + gnvs->pm1i); +} + static void s3_resume_prepare(void) { global_nvs_t *gnvs; @@ -148,6 +175,8 @@ static void s3_resume_prepare(void) } set_acpi_sleep_type(3); + + s3_save_acpi_wake_source(gnvs); } void baytrail_init_pre_device(void)