summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@chromium.org>2016-10-25 20:07:22 -0700
committerDuncan Laurie <dlaurie@chromium.org>2016-10-27 16:30:01 +0200
commit95f9020de162f29b8b30af361339c94c298acf52 (patch)
tree9b03d4c5dd7803271acdd0edc140a0fcf9b7a25f
parent135c2c48173d9ffb2476d204d8acc1b13d28859c (diff)
skylake: Fix wake source reporting with Deep S3
The Deep S3 state will lose a lot of register contents that we used to rely on for determining wake source. In order to make use of this override the enable bit for wake sources that are enabled for Deep S3 in devicetree.cb. BUG=chrome-os-partner:58666 TEST=check for _SWS reporting wake source on S3 resume on skylake Change-Id: If5113d6890f6cbecc32f92af67a29952266fe0ac Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: https://review.coreboot.org/17137 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh <furquan@google.com>
-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;
}