summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/skylake/acpi.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c
index d4f60302a3..fc4f58c34c 100644
--- a/src/soc/intel/skylake/acpi.c
+++ b/src/soc/intel/skylake/acpi.c
@@ -591,23 +591,40 @@ void southcluster_inject_dsdt(device_t device)
/* Save wake source information for calculating ACPI _SWS values */
int soc_fill_acpi_wake(uint32_t *pm1, uint32_t **gpe0)
{
+ const struct device *dev = dev_find_slot(0, PCH_DEVFN_LPC);
+ const struct soc_intel_skylake_config *config = dev->chip_info;
struct chipset_power_state *ps;
static uint32_t gpe0_sts[GPE0_REG_MAX];
uint32_t pm1_en;
+ uint32_t gpe0_std;
int i;
ps = cbmem_find(CBMEM_ID_POWER_STATE);
if (ps == NULL)
return -1;
- /* PM1_EN state is lost in Deep S3 so enable basic wake events */
- pm1_en = ps->pm1_en | PCIEXPWAK_STS | RTC_STS | PWRBTN_STS | BM_STS;
+ pm1_en = ps->pm1_en;
+ gpe0_std = ps->gpe0_en[3];
+
+ /*
+ * Chipset state in the suspend well (but not RTC) is lost in Deep S3
+ * so enable Deep S3 wake events that are configured by the mainboard
+ */
+ if (ps->prev_sleep_state == ACPI_S3 && config->deep_s3_enable) {
+ pm1_en |= PWRBTN_STS; /* Always enabled as wake source */
+ if (config->deep_sx_config & DSX_EN_LAN_WAKE_PIN)
+ gpe0_std |= LAN_WAK_EN;
+ if (config->deep_sx_config & DSX_EN_WAKE_PIN)
+ pm1_en |= PCIEXPWAK_STS;
+ }
+
*pm1 = ps->pm1_sts & pm1_en;
/* Mask off GPE0 status bits that are not enabled */
*gpe0 = &gpe0_sts[0];
- for (i = 0; i < GPE0_REG_MAX; i++)
+ for (i = 0; i < (GPE0_REG_MAX-1); i++)
gpe0_sts[i] = ps->gpe0_sts[i] & ps->gpe0_en[i];
+ gpe0_sts[3] = ps->gpe0_sts[3] & gpe0_std;
return GPE0_REG_MAX;
}