broadwell: Add support for ACPI \_GPE._SWS
In order to report the GPE that woke the system to the kernel
coreboot needs to keep track of the first GPE wake source and
save it in NVS so it can be returned in \_GPE._SWS method.
This is similar to the saving of PM1 status but needs to go
through all the GPE0_STS registers and check for enabled and
triggered events.
A bit of cleanup is done for areas that were touched:
- ramstage.c:s3_resume_prepare() was not indented with tabs
- platform.asl was not formatted correctly
BUG=chrome-os-partner:8127
BRANCH=samus,auron
TEST=manual:
- suspend/resume and wake from EC event like keyboard:
ACPI _SWS is PM1 Index -1 GPE Index 112 ("special" GPIO27)
- suspend/resume and wake from RTC event:
ACPI _SWS is PM1 Index 10 GPE Index -1 (RTC)
- suspend/resume and wake from power button:
ACPI _SWS is PM1 Index 8 GPE Index -1
- suspend/resume and wake from touchpad:
ACPI _SWS is PM1 Index -1 GPE Index 13
- suspend/resume and wake from WLAN:
ACPI _SWS is PM1 Index -1 GPE Index 10
Change-Id: I9bfbbe4385f2acc2a50f41ae321b4bae262b7078
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/220324
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
0f1cccfd00
commit
d4e06c7dfc
5 changed files with 70 additions and 32 deletions
|
|
@ -61,6 +61,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),
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,8 @@ typedef struct {
|
|||
u32 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;
|
||||
|
|
|
|||
|
|
@ -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] */
|
||||
|
|
|
|||
|
|
@ -28,11 +28,12 @@
|
|||
#include <broadwell/ramstage.h>
|
||||
#include <chip.h>
|
||||
|
||||
/* 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 inline void set_acpi_sleep_type(int val)
|
||||
|
|
@ -63,22 +86,20 @@ static inline void set_acpi_sleep_type(int val)
|
|||
|
||||
static void s3_resume_prepare(void)
|
||||
{
|
||||
global_nvs_t *gnvs;
|
||||
struct romstage_handoff *romstage_handoff;
|
||||
global_nvs_t *gnvs;
|
||||
struct romstage_handoff *romstage_handoff;
|
||||
|
||||
gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof(global_nvs_t));
|
||||
gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof(global_nvs_t));
|
||||
|
||||
romstage_handoff = cbmem_find(CBMEM_ID_ROMSTAGE_INFO);
|
||||
if (romstage_handoff == NULL || romstage_handoff->s3_resume == 0) {
|
||||
if (gnvs != NULL) {
|
||||
memset(gnvs, 0, sizeof(global_nvs_t));
|
||||
}
|
||||
set_acpi_sleep_type(0);
|
||||
return;
|
||||
}
|
||||
romstage_handoff = cbmem_find(CBMEM_ID_ROMSTAGE_INFO);
|
||||
if (romstage_handoff == NULL || romstage_handoff->s3_resume == 0) {
|
||||
if (gnvs != NULL)
|
||||
memset(gnvs, 0, sizeof(global_nvs_t));
|
||||
return;
|
||||
}
|
||||
|
||||
set_acpi_sleep_type(3);
|
||||
s3_save_acpi_wake_source(gnvs);
|
||||
set_acpi_sleep_type(3);
|
||||
save_acpi_wake_source(gnvs);
|
||||
}
|
||||
|
||||
void broadwell_init_pre_device(void *chip_info)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue