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>
This commit is contained in:
Shaunak Saha
2016-08-02 17:25:13 -07:00
committed by Aaron Durbin
parent b6739d1b56
commit 60b4618a84
5 changed files with 67 additions and 0 deletions

View File

@@ -19,6 +19,7 @@
#include <arch/io.h>
#include <console/console.h>
#include <cbmem.h>
#include <rules.h>
#include <device/pci_def.h>
#include <halt.h>
@@ -327,6 +328,30 @@ int chipset_prev_sleep_state(struct chipset_power_state *ps)
return prev_sleep_state;
}
/*
* This function re-writes the gpe0 register values in power state
* cbmem variable. After system wakes from sleep state internal PMC logic
* writes default values in GPE_CFG register which gives a wrong offset to
* calculate the wake reason. So we need to set it again to the routing
* table as per the devicetree.
*/
void fixup_power_state(void)
{
int i;
struct chipset_power_state *ps;
ps = cbmem_find(CBMEM_ID_POWER_STATE);
if (ps == NULL)
return;
for (i = 0; i < GPE0_REG_MAX; i++) {
ps->gpe0_sts[i] = inl(ACPI_PMIO_BASE + GPE0_STS(i));
ps->gpe0_en[i] = inl(ACPI_PMIO_BASE + GPE0_EN(i));
printk(BIOS_DEBUG, "gpe0_sts[%d]: %08x gpe0_en[%d]: %08x\n",
i, ps->gpe0_sts[i], i, ps->gpe0_en[i]);
}
}
/* returns prev_sleep_state */
int fill_power_state(struct chipset_power_state *ps)
{