summaryrefslogtreecommitdiff
path: root/src/soc/amd/stoneyridge/southbridge.c
diff options
context:
space:
mode:
authorRichard Spiegel <richard.spiegel@amd.corp-partner.google.com>2018-05-25 15:49:33 -0700
committerMartin Roth <martinroth@google.com>2018-06-13 14:24:31 +0000
commit572f4988ddb3b85bdce019de7d6a594bea070bfb (patch)
treecdd97252e963587a34a7fa4833102daa0354119e /src/soc/amd/stoneyridge/southbridge.c
parent9b05af367fde33fc620c4cd759c2b09cdc036cc9 (diff)
soc/amd/stoneyridge/southbridge.c: Fix saving _SWS parameters
PM1 and GPE0 are being stored directly to NVS, when actually what should be saved is the index of the bit responsible for waking. Fix the procedures and add definitions to the actual IO addresses to be read when recording status and enable registers. BUG=b:75996437 TEST=Build and boot grunt. Once in OS, execute a sleep and a wake. See the message indicating which indexes are being save in NVS for _SWS. Try sleep stress test, verify that the index is different from that of power button. Change-Id: I8bafc7bb7dd66e7f0eb8499e748535bbdcac5f53 Signed-off-by: Richard Spiegel <richard.spiegel@silverbackltd.com> Reviewed-on: https://review.coreboot.org/26547 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/soc/amd/stoneyridge/southbridge.c')
-rw-r--r--src/soc/amd/stoneyridge/southbridge.c59
1 files changed, 45 insertions, 14 deletions
diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c
index cc21601c3e..02daa26046 100644
--- a/src/soc/amd/stoneyridge/southbridge.c
+++ b/src/soc/amd/stoneyridge/southbridge.c
@@ -616,8 +616,8 @@ static void print_num_status_bits(int num_bits, uint32_t status,
static uint16_t reset_pm1_status(void)
{
- uint16_t pm1_sts = inw(ACPI_PM_EVT_BLK);
- outw(pm1_sts, ACPI_PM_EVT_BLK);
+ uint16_t pm1_sts = inw(ACPI_PM1_STS);
+ outw(pm1_sts, ACPI_PM1_STS);
return pm1_sts;
}
@@ -663,21 +663,24 @@ static void sb_log_pm1_status(uint16_t pm1_sts)
}
struct soc_amd_sws {
- uint32_t pm1i;
- uint32_t gevent;
+ uint16_t pm1_sts;
+ uint16_t pm1_en;
+ uint32_t gpe0_sts;
+ uint32_t gpe0_en;
};
static struct soc_amd_sws sws;
-static void sb_save_sws(uint32_t pm1_status)
+static void sb_save_sws(uint16_t pm1_status)
{
uint32_t reg32;
- sws.pm1i = pm1_status;
- reg32 = inl(ACPI_GPE0_BLK);
- outl(ACPI_GPE0_BLK, reg32);
- reg32 &= inl(ACPI_GPE0_BLK + sizeof(uint32_t));
- sws.gevent = reg32;
+ sws.pm1_sts = pm1_status;
+ sws.pm1_en = inw(ACPI_PM1_EN);
+ reg32 = inl(ACPI_GPE0_STS);
+ outl(ACPI_GPE0_STS, reg32);
+ sws.gpe0_sts = reg32;
+ sws.gpe0_en = inl(ACPI_GPE0_EN);
}
static void sb_clear_pm1_status(void)
@@ -689,19 +692,47 @@ static void sb_clear_pm1_status(void)
print_pm1_status(pm1_sts);
}
+static int get_index_bit(uint32_t value, uint16_t limit)
+{
+ uint16_t i;
+ uint32_t t;
+
+ if (limit >= sizeof(uint32_t))
+ return -1;
+
+ /* get a mask of valid bits. Ex limit = 3, set bits 0-2 */
+ t = (1 << limit) - 1;
+ if ((value & t) == 0)
+ return -1;
+ t = 1;
+ for (i = 0; i < limit; i++) {
+ if (value & t)
+ break;
+ t <<= 1;
+ }
+ return i;
+}
+
static void set_nvs_sws(void *unused)
{
struct global_nvs_t *gnvs;
+ int index;
gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
if (gnvs == NULL)
return;
- gnvs->pm1i = sws.pm1i;
- gnvs->gpei = sws.gevent;
+ index = get_index_bit(sws.pm1_sts & sws.pm1_en, PM1_LIMIT);
+ if (index < 0)
+ gnvs->pm1i = ~0ULL;
+ else
+ gnvs->pm1i = index;
- printk(BIOS_DEBUG, "Loaded _SWS parameters PM1 0x%08x, EVENT 0x%08x into nvs\n",
- sws.pm1i, sws.gevent);
+ index = get_index_bit(sws.gpe0_sts & sws.gpe0_en, GPE0_LIMIT);
+ if (index < 0)
+ gnvs->gpei = ~0ULL;
+ else
+ gnvs->gpei = index;
}
BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, set_nvs_sws, NULL);