diff --git a/src/soc/intel/broadwell/acpi/globalnvs.asl b/src/soc/intel/broadwell/acpi/globalnvs.asl index d8b75ac8c1..4ba384a4af 100644 --- a/src/soc/intel/broadwell/acpi/globalnvs.asl +++ b/src/soc/intel/broadwell/acpi/globalnvs.asl @@ -62,6 +62,7 @@ Field (GNVS, ByteAcc, NoLock, Preserve) CMEM, 32, // 0x19 - 0x1c - CBMEM TOC CBMC, 32, // 0x1d - 0x20 - Coreboot Memory Console PM1I, 32, // 0x21 - 0x24 - PM1 wake status bit + GPEI, 32, // 0x25 - 0x28 - GPE wake status bit /* ChromeOS specific */ Offset (0x100), diff --git a/src/soc/intel/broadwell/acpi/platform.asl b/src/soc/intel/broadwell/acpi/platform.asl index 2361fe8b3e..f63168a745 100644 --- a/src/soc/intel/broadwell/acpi/platform.asl +++ b/src/soc/intel/broadwell/acpi/platform.asl @@ -36,7 +36,7 @@ Field (POST, ByteAcc, Lock, Preserve) } /* SMI I/O Trap */ -Method(TRAP, 1, Serialized) +Method (TRAP, 1, Serialized) { Store (Arg0, SMIF) // SMI Function Store (0, TRP0) // Generate trap @@ -50,29 +50,42 @@ Method(TRAP, 1, Serialized) * with a parameter of 1 for Local Apic/IOAPIC configuration. */ -Method(_PIC, 1) +Method (_PIC, 1) { - // Remember the OS' IRQ routing choice. - Store(Arg0, PICM) + /* Remember the OS' IRQ routing choice. */ + Store (Arg0, PICM) } -/* The _PTS method (Prepare To Sleep) is called before the OS is +/* + * The _PTS method (Prepare To Sleep) is called before the OS is * entering a sleep state. The sleep state number is passed in Arg0 */ -Method(_PTS,1) +Method (_PTS, 1) { } /* The _WAK method is called on system wakeup */ -Method(_WAK,1) +Method (_WAK, 1) { - Return(Package(){0,0}) + Return (Package (){ 0, 0 }) } -Method (_SWS) +Scope (\_SB) { - /* Index into PM1 for device that caused wake */ - Return (\PM1I) + Method (_SWS) + { + /* Index into PM1 for device that caused wake */ + Return (\PM1I) + } +} + +Scope (\_GPE) +{ + Method (_SWS) + { + /* Index into GPE for device that caused wake */ + Return (\GPEI) + } } diff --git a/src/soc/intel/broadwell/include/soc/nvs.h b/src/soc/intel/broadwell/include/soc/nvs.h index 41b2e4a8ba..195dd43c3e 100644 --- a/src/soc/intel/broadwell/include/soc/nvs.h +++ b/src/soc/intel/broadwell/include/soc/nvs.h @@ -53,7 +53,8 @@ typedef struct { u32 obsolete_cmem; /* 0x19 - 0x1c - CBMEM TOC */ u32 cbmc; /* 0x1d - 0x20 - Coreboot Memory Console */ u32 pm1i; /* 0x21 - 0x24 - PM1 wake status bit */ - u8 rsvd3[219]; + u32 gpei; /* 0x25 - 0x28 - GPE wake status bit */ + u8 rsvd3[215]; /* ChromeOS specific (0x100 - 0xfff) */ chromeos_acpi_t chromeos; diff --git a/src/soc/intel/broadwell/include/soc/pm.h b/src/soc/intel/broadwell/include/soc/pm.h index 6bc98ef339..54fc4a7f1d 100644 --- a/src/soc/intel/broadwell/include/soc/pm.h +++ b/src/soc/intel/broadwell/include/soc/pm.h @@ -83,6 +83,8 @@ #define TCO2_STS 0x66 #define TCO2_STS_SECOND_TO (1 << 1) +#define GPE0_REG_MAX 4 +#define GPE0_REG_SIZE 32 #define GPE0_STS(x) (0x80 + (x * 4)) #define GPE_31_0 0 /* 0x80/0x90 = GPE[31:0] */ #define GPE_63_32 1 /* 0x84/0x94 = GPE[63:32] */ diff --git a/src/soc/intel/broadwell/ramstage.c b/src/soc/intel/broadwell/ramstage.c index beabded070..c9a422f8e4 100644 --- a/src/soc/intel/broadwell/ramstage.c +++ b/src/soc/intel/broadwell/ramstage.c @@ -28,11 +28,12 @@ #include #include -/* Save bit index for first enabled event in PM1_STS for \_SB._SWS */ -static void s3_save_acpi_wake_source(global_nvs_t *gnvs) +/* Save bit index for PM1_STS and GPE_STS for ACPI _SWS */ +static void save_acpi_wake_source(global_nvs_t *gnvs) { struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE); uint16_t pm1; + int gpe_reg; if (!ps) return; @@ -50,8 +51,30 @@ static void s3_save_acpi_wake_source(global_nvs_t *gnvs) if (gnvs->pm1i >= 16) gnvs->pm1i = -1; - printk(BIOS_DEBUG, "ACPI System Wake Source is PM1 Index %d\n", - gnvs->pm1i); + /* Scan for first set bit in GPE registers */ + for (gpe_reg = 0; gpe_reg < GPE0_REG_MAX; gpe_reg++) { + u32 gpe = ps->gpe0_sts[gpe_reg] & ps->gpe0_en[gpe_reg]; + int start = gpe_reg * GPE0_REG_SIZE; + int end = start + GPE0_REG_SIZE; + + if (gpe == 0) { + gnvs->gpei = end; + continue; + } + + for (gnvs->gpei = start; gnvs->gpei < end; gnvs->gpei++) { + if (gpe & 1) + break; + gpe >>= 1; + } + } + + /* If unable to determine then return -1 */ + if (gnvs->gpei >= (GPE0_REG_MAX * GPE0_REG_SIZE)) + gnvs->gpei = -1; + + printk(BIOS_DEBUG, "ACPI _SWS is PM1 Index %d GPE Index %d\n", + gnvs->pm1i, gnvs->gpei); } static void s3_resume_prepare(void) @@ -65,7 +88,7 @@ static void s3_resume_prepare(void) if (!acpi_is_wakeup_s3()) memset(gnvs, 0, sizeof(global_nvs_t)); else - s3_save_acpi_wake_source(gnvs); + save_acpi_wake_source(gnvs); } void broadwell_init_pre_device(void *chip_info)