soc/intel/cmn/pmc: Create API to clear PMC power failure status bits

This patch implements an API named `pmc_clear_pmcon_pwr_failure_sts()`
to clear power failure status bits of PMC General PM Configuration A/B
based on the underlying SoC.

Based on the available PMC register definitions between Sky Lake till
latest Meteor Lake platform, the SoC platform that selects
SOC_INTEL_MEM_MAPPED_PM_CONFIGURATION config has power failure bits
mapped into the MMIO mapped GEN_PMCON_A register where else for the
other SoCs, those power failure bits are belongs to the PCI config
space mapped GEN_PMCON_B register.

BUG=b:265939425
TEST=Able to build the google/marasov.

Signed-off-by: Subrata Banik <subratabanik@google.com>
Change-Id: Icbbe47ccfd489edf9c38f52bdf7cf2de7aa9eedf
Reviewed-on: https://review.coreboot.org/c/coreboot/+/72053
Reviewed-by: Kapil Porwal <kapilporwal@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
Reviewed-by: Sridhar Siricilla <sridhar.siricilla@intel.com>
This commit is contained in:
Subrata Banik 2023-01-19 23:11:43 +05:30
parent 08b5200db7
commit 7d68353d15
2 changed files with 45 additions and 0 deletions

View File

@ -183,6 +183,9 @@ int pmc_fill_power_state(struct chipset_power_state *ps);
*/ */
void pmc_gpe_init(void); void pmc_gpe_init(void);
/* Clear PMC GEN_PMCON_X register power failure status bits */
void pmc_clear_pmcon_pwr_failure_sts(void);
/* Clear PMC GEN_PMCON_A register status bits */ /* Clear PMC GEN_PMCON_A register status bits */
void pmc_clear_pmcon_sts(void); void pmc_clear_pmcon_sts(void);

View File

@ -605,6 +605,48 @@ void pmc_gpe_init(void)
gpio_route_gpe(dw0, dw1, dw2); gpio_route_gpe(dw0, dw1, dw2);
} }
static void pmc_clear_pmcon_pwr_failure_sts_mmio(void)
{
uint8_t *addr = pmc_mmio_regs();
/*
* Clear PMC GEN_PMCON_A register power failure status bits:
* SUS_PWR_FLR, PWR_FLR bits
* while retaining MS4V write-1-to-clear bit
*
* Note: clearing `GBL_RST_STS` bit earlier than FSP-M/MRC having an adverse effect
* on the PMC sleep type register which results in calculating wrong
* `prev_sleep_state` post a global reset, hence, just clearing the power failure
* status bits rather than clearing the complete PMC PMCON_A register.
*/
clrbits32((addr + GEN_PMCON_A), (MS4V | GBL_RST_STS));
}
static void pmc_clear_pmcon_pwr_failure_sts_pci(void)
{
#if defined(__SIMPLE_DEVICE__)
pci_devfn_t dev = PCI_DEV(0, PCI_SLOT(PCH_DEVFN_PMC), PCI_FUNC(PCH_DEVFN_PMC));
#else
struct device *dev = pcidev_path_on_root(PCH_DEVFN_PMC);
if (!dev)
return;
#endif
pci_or_config32(dev, GEN_PMCON_B, (SUS_PWR_FLR | PWR_FLR));
}
/*
* Clear PMC GEN_PMCON_X register power failure status bits:
* SUS_PWR_FLR, PWR_FLR bits (keep the other bits intact)
*/
void pmc_clear_pmcon_pwr_failure_sts(void)
{
if (CONFIG(SOC_INTEL_MEM_MAPPED_PM_CONFIGURATION))
pmc_clear_pmcon_pwr_failure_sts_mmio();
else
pmc_clear_pmcon_pwr_failure_sts_pci();
}
#if ENV_RAMSTAGE #if ENV_RAMSTAGE
static void pmc_clear_pmcon_sts_mmio(void) static void pmc_clear_pmcon_sts_mmio(void)
{ {