diff options
author | Subrata Banik <subratabanik@google.com> | 2022-02-18 00:44:15 +0530 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2022-03-29 13:56:04 +0000 |
commit | af27ac26b34216f4a188ee1738825177d469cf48 (patch) | |
tree | cf6f519b0f7379aaa6b6b058d400d951496b9c1e /src/soc/intel/common | |
parent | d58580e0032f855b290815ed412a9d77c66f759e (diff) |
soc/intel: Move `pmc_clear_pmcon_sts()` into IA common code
This patch moves `pmc_clear_pmcon_sts` function into common code and
remove SoC specific instances.
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.
SoC users to select `SOC_INTEL_MEM_MAPPED_PM_CONFIGURATION` Kconfig to
perform GEN_PMCON_A register programming using PMC MMIO.
BUG=b:211954778
TEST=Able to build brya.
Signed-off-by: Subrata Banik <subratabanik@google.com>
Change-Id: I8d15f421c128630f928a1b6a7e2840056d68d7b1
Reviewed-on: https://review.coreboot.org/c/coreboot/+/62064
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Jeff Daly <jeffd@silicom-usa.com>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
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", |