diff options
-rw-r--r-- | src/soc/amd/common/block/acpi/acpi.c | 38 | ||||
-rw-r--r-- | src/soc/amd/common/block/include/amdblocks/acpi.h | 3 |
2 files changed, 41 insertions, 0 deletions
diff --git a/src/soc/amd/common/block/acpi/acpi.c b/src/soc/amd/common/block/acpi/acpi.c index be331e3fea..0e6dabf150 100644 --- a/src/soc/amd/common/block/acpi/acpi.c +++ b/src/soc/amd/common/block/acpi/acpi.c @@ -113,6 +113,44 @@ void acpi_clear_pm_gpe_status(void) acpi_write32(MMIO_ACPI_GPE0_STS, acpi_read32(MMIO_ACPI_GPE0_STS)); } +static int get_index_bit(uint32_t value, uint16_t limit) +{ + uint16_t i; + uint32_t t; + + if (limit >= TOTAL_BITS(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; +} + +void acpi_fill_gnvs(struct global_nvs *gnvs, const struct acpi_pm_gpe_state *state) +{ + int index; + + index = get_index_bit(state->pm1_sts & state->pm1_en, PM1_LIMIT); + if (index < 0) + gnvs->pm1i = ~0ULL; + else + gnvs->pm1i = index; + + index = get_index_bit(state->gpe0_sts & state->gpe0_en, GPE0_LIMIT); + if (index < 0) + gnvs->gpei = ~0ULL; + else + gnvs->gpei = index; +} + static void save_sws(uint16_t pm1_status) { struct soc_power_reg *sws; diff --git a/src/soc/amd/common/block/include/amdblocks/acpi.h b/src/soc/amd/common/block/include/amdblocks/acpi.h index 8f16054fd7..8d0e5f664e 100644 --- a/src/soc/amd/common/block/include/amdblocks/acpi.h +++ b/src/soc/amd/common/block/include/amdblocks/acpi.h @@ -4,6 +4,7 @@ #define __AMDBLOCKS_ACPI_H__ #include <types.h> +#include <soc/nvs.h> /* ACPI MMIO registers 0xfed80800 */ #define MMIO_ACPI_PM1_STS 0x00 @@ -32,6 +33,8 @@ void acpi_fill_pm_gpe_state(struct acpi_pm_gpe_state *state); void acpi_pm_gpe_add_events_print_events(const struct acpi_pm_gpe_state *state); /* Clear PM and GPE status registers. */ void acpi_clear_pm_gpe_status(void); +/* Fill GNVS object from PM GPE object. */ +void acpi_fill_gnvs(struct global_nvs *gnvs, const struct acpi_pm_gpe_state *state); void acpi_clear_pm1_status(void); |