diff options
Diffstat (limited to 'src/soc/intel/common')
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/pmclib.h | 3 | ||||
-rw-r--r-- | src/soc/intel/common/block/pmc/Kconfig | 6 | ||||
-rw-r--r-- | src/soc/intel/common/block/pmc/pmc.c | 1 | ||||
-rw-r--r-- | src/soc/intel/common/block/pmc/pmclib.c | 40 |
4 files changed, 50 insertions, 0 deletions
diff --git a/src/soc/intel/common/block/include/intelblocks/pmclib.h b/src/soc/intel/common/block/include/intelblocks/pmclib.h index bb38204718..fc65a089d3 100644 --- a/src/soc/intel/common/block/include/intelblocks/pmclib.h +++ b/src/soc/intel/common/block/include/intelblocks/pmclib.h @@ -178,6 +178,9 @@ int pmc_fill_power_state(struct chipset_power_state *ps); */ void pmc_gpe_init(void); +/* Clear PMC GEN_PMCON_A register status bits */ +void pmc_clear_pmcon_sts(void); + /* Power Management Utility Functions. */ /* Returns PMC base address */ diff --git a/src/soc/intel/common/block/pmc/Kconfig b/src/soc/intel/common/block/pmc/Kconfig index fa1a99076b..effdc12585 100644 --- a/src/soc/intel/common/block/pmc/Kconfig +++ b/src/soc/intel/common/block/pmc/Kconfig @@ -10,6 +10,12 @@ config SOC_INTEL_COMMON_BLOCK_PMC if SOC_INTEL_COMMON_BLOCK_PMC +config SOC_INTEL_MEM_MAPPED_PM_CONFIGURATION + bool + help + Select this on platforms where the PMC register for PM configuration (i.e., + GEN_PMCON_A/B etc. are memory mapped). + config POWER_STATE_DEFAULT_ON_AFTER_FAILURE default y diff --git a/src/soc/intel/common/block/pmc/pmc.c b/src/soc/intel/common/block/pmc/pmc.c index b6a2fc982f..51b2aa6980 100644 --- a/src/soc/intel/common/block/pmc/pmc.c +++ b/src/soc/intel/common/block/pmc/pmc.c @@ -7,6 +7,7 @@ #include <device/pci_ids.h> #include <intelblocks/acpi.h> #include <intelblocks/pmc.h> +#include <intelblocks/pmclib.h> #include <soc/pci_devs.h> #include <soc/pm.h> diff --git a/src/soc/intel/common/block/pmc/pmclib.c b/src/soc/intel/common/block/pmc/pmclib.c index da78d5c424..a2e3e9e1cc 100644 --- a/src/soc/intel/common/block/pmc/pmclib.c +++ b/src/soc/intel/common/block/pmc/pmclib.c @@ -5,6 +5,7 @@ #include <assert.h> #include <bootmode.h> #include <device/mmio.h> +#include <device/pci.h> #include <cbmem.h> #include <cpu/x86/smm.h> #include <console/console.h> @@ -14,6 +15,7 @@ #include <intelblocks/tco.h> #include <option.h> #include <security/vboot/vboot_common.h> +#include <soc/pci_devs.h> #include <soc/pm.h> #include <stdint.h> #include <string.h> @@ -580,6 +582,44 @@ void pmc_gpe_init(void) gpio_route_gpe(dw0, dw1, dw2); } +#if ENV_RAMSTAGE +static void pmc_clear_pmcon_sts_mmio(void) +{ + uint8_t *addr = pmc_mmio_regs(); + + clrbits32((addr + GEN_PMCON_A), MS4V); +} + +static void pmc_clear_pmcon_sts_pci(void) +{ + struct device *dev = pcidev_path_on_root(PCH_DEVFN_PMC); + if (!dev) + return; + + pci_and_config32(dev, GEN_PMCON_A, ~MS4V); +} + +/* + * Clear PMC GEN_PMCON_A register status bits: + * SUS_PWR_FLR, GBL_RST_STS, HOST_RST_STS, PWR_FLR bits + * while retaining MS4V write-1-to-clear bit + */ +void pmc_clear_pmcon_sts(void) +{ + /* + * Accessing PMC GEN_PMCON_A register differs between different Intel chipsets. + * Typically, there are two possible ways to perform GEN_PMCON_A register programming + * (like `pmc_clear_pmcon_sts()`) as: + * 1. Using PCI configuration space when GEN_PMCON_A is a PCI configuration register. + * 2. Using MMIO access when GEN_PMCON_A is a memory mapped register. + */ + if (CONFIG(SOC_INTEL_MEM_MAPPED_PM_CONFIGURATION)) + pmc_clear_pmcon_sts_mmio(); + else + pmc_clear_pmcon_sts_pci(); +} +#endif + void pmc_set_power_failure_state(const bool target_on) { const unsigned int state = get_uint_option("power_on_after_fail", |