From 35282a0f1b059a42a5a2abef03b559a719cd230f Mon Sep 17 00:00:00 2001 From: Richard Spiegel Date: Thu, 14 Jun 2018 14:57:54 -0700 Subject: [PATCH] soc/amd/stoneyridge/southbridge.c: Store PM related registers in cbmem PM registers used for generating SWS values are being stored in a static variable within southbridge.c. In order to have it available for any source involved in building the platform, move the storage to cbmem, using id CBMEM_ID_POWER_STATE. Also add a variable that informs from which state the system is waking from, extracted from register ACPI_PM1_CNT_BLK. This variable will later be useful in detecting failed S3 resume. BUG=b:80119811 TEST=Add code to print SWS parameters and state it's waking from. Build and boot grunt, suspend and resume, check output for valid values. Remove the print code. Change-Id: Ib27a743b7e7f8c94918caf7ba5efd473f4054986 Signed-off-by: Richard Spiegel Reviewed-on: https://review.coreboot.org/27109 Reviewed-by: Martin Roth Tested-by: build bot (Jenkins) --- .../amd/stoneyridge/include/soc/southbridge.h | 8 +++++ src/soc/amd/stoneyridge/southbridge.c | 33 ++++++++++--------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index 1750547dea..77e4979698 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -361,6 +361,14 @@ struct stoneyridge_aoac { int status; }; +struct soc_power_reg { + uint16_t pm1_sts; + uint16_t pm1_en; + uint32_t gpe0_sts; + uint32_t gpe0_en; + uint16_t wake_from; +}; + void enable_aoac_devices(void); void sb_enable_rom(void); void configure_stoneyridge_i2c(void); diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index 02daa26046..91435ad42b 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -662,25 +662,24 @@ static void sb_log_pm1_status(uint16_t pm1_sts) elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0); } -struct soc_amd_sws { - 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(uint16_t pm1_status) { + struct soc_power_reg *sws; uint32_t reg32; + uint16_t reg16; - sws.pm1_sts = pm1_status; - sws.pm1_en = inw(ACPI_PM1_EN); + sws = cbmem_add(CBMEM_ID_POWER_STATE, sizeof(struct soc_power_reg)); + if (sws == NULL) + return; + 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); + sws->gpe0_sts = reg32; + sws->gpe0_en = inl(ACPI_GPE0_EN); + reg16 = inw(ACPI_PM1_CNT_BLK); + reg16 &= SLP_TYP; + sws->wake_from = reg16 >> SLP_TYP_SHIFT; } static void sb_clear_pm1_status(void) @@ -715,20 +714,24 @@ static int get_index_bit(uint32_t value, uint16_t limit) static void set_nvs_sws(void *unused) { + struct soc_power_reg *sws; struct global_nvs_t *gnvs; int index; + sws = cbmem_find(CBMEM_ID_POWER_STATE); + if (sws == NULL) + return; gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); if (gnvs == NULL) return; - index = get_index_bit(sws.pm1_sts & sws.pm1_en, PM1_LIMIT); + index = get_index_bit(sws->pm1_sts & sws->pm1_en, PM1_LIMIT); if (index < 0) gnvs->pm1i = ~0ULL; else gnvs->pm1i = index; - index = get_index_bit(sws.gpe0_sts & sws.gpe0_en, GPE0_LIMIT); + index = get_index_bit(sws->gpe0_sts & sws->gpe0_en, GPE0_LIMIT); if (index < 0) gnvs->gpei = ~0ULL; else