summaryrefslogtreecommitdiff
path: root/src/soc/intel/apollolake/acpi.c
diff options
context:
space:
mode:
authorShaunak Saha <shaunak.saha@intel.com>2016-08-02 17:25:13 -0700
committerAaron Durbin <adurbin@chromium.org>2016-08-04 16:14:14 +0200
commit60b4618a841a2aecd5a9a37bd451f1e6af7e6b1a (patch)
tree30d149cbdb81a26d94ec0571acd26da77231c1e6 /src/soc/intel/apollolake/acpi.c
parentb6739d1b5666267a1c536bf8635e174436b836ae (diff)
soc/apollolake: Return correct wake status in _SWS
Wake status is calculated from the four pairs of gpe0 in cbmem CBMEM_ID_POWER_STATE which is filled very early in romstage and depends on the routing information in PMC GPE_CFG register. Coreboot sets the proper value of routing based on devicetree from pmc_init. But when system goes to S3 on waking up PMC is writing default values again in GPE_CFG which results in returning wrong wake status in _SWS. This patch corrects that behaviour by correcting the gpe0 pairs in cbmem after PMC sets the routing table in resume path. BUG=chrome-os-partner:54876 TEST=On resume through powerbtn, lidopen, keyboard press, etc. we are getting proper wake status. Change-Id: I5942d5c20d8c6aef73468dc611190bb7c49c7c7a Signed-off-by: Shaunak Saha <shaunak.saha@intel.com> Reviewed-on: https://review.coreboot.org/16040 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Brandon Breitenstein <brandon.breitenstein@intel.com>
Diffstat (limited to 'src/soc/intel/apollolake/acpi.c')
-rw-r--r--src/soc/intel/apollolake/acpi.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/soc/intel/apollolake/acpi.c b/src/soc/intel/apollolake/acpi.c
index 262e140e6c..4f4276ad72 100644
--- a/src/soc/intel/apollolake/acpi.c
+++ b/src/soc/intel/apollolake/acpi.c
@@ -168,6 +168,41 @@ static void acpi_create_gnvs(struct global_nvs_t *gnvs)
/* Enable DPTF based on mainboard configuration */
gnvs->dpte = cfg->dptf_enable;
+
+ /* Set unknown wake source */
+ gnvs->pm1i = ~0ULL;
+}
+
+/* Save wake source information for calculating ACPI _SWS values */
+int soc_fill_acpi_wake(uint32_t *pm1, uint32_t **gpe0)
+{
+ struct chipset_power_state *ps;
+ static uint32_t gpe0_sts[GPE0_REG_MAX];
+ uint32_t pm1_en;
+ int i;
+
+ ps = cbmem_find(CBMEM_ID_POWER_STATE);
+ if (ps == NULL)
+ return -1;
+
+ /*
+ * PM1_EN to check the basic wake events which can happen through
+ * powerbtn or any other wake source like lidopen, key board press etc.
+ * WAK_STS bit is set when the system is in one of the sleep states
+ * (via the SLP_EN bit) and an enabled wake event occurs. Upon setting
+ * this bit, the PMC will transition the system to the ON state and
+ * can only be set by hardware and can only be cleared by writing a one
+ * to this bit position.
+ */
+ pm1_en = ps->pm1_en | WAK_STS | RTC_EN | PWRBTN_EN;
+ *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++)
+ gpe0_sts[i] = ps->gpe0_sts[i] & ps->gpe0_en[i];
+
+ return GPE0_REG_MAX;
}
void southbridge_inject_dsdt(device_t device)