1 /* SPDX-License-Identifier: GPL-2.0-only */
4 * Helper functions for dealing with power management registers
5 * and the differences between PCH variants.
8 #define __SIMPLE_DEVICE__
10 #include <console/console.h>
11 #include <device/pci.h>
12 #include <intelblocks/pmclib.h>
13 #include <intelblocks/rtc.h>
14 #include <soc/pci_devs.h>
18 uint8_t *pmc_mmio_regs(void)
20 return (void *)(uintptr_t)pci_read_config32(PCH_DEV_PMC
, PWRMBASE
);
23 uintptr_t soc_read_pmc_base(void)
25 return (uintptr_t)(pmc_mmio_regs());
28 uint32_t *soc_pmc_etr_addr(void)
31 * The pointer returned must not be cached, because the address depends on the
32 * MMCONF base address and the assigned PCI bus number, which both may change
33 * during the boot process!
35 return pci_mmio_config32_addr(PCH_DEVFN_PMC
<< 12, ETR
);
38 int soc_get_rtc_failed(void)
40 uint32_t pmcon_b
= pci_s_read_config32(PCH_DEV_PMC
, GEN_PMCON_B
);
41 int rtc_fail
= !!(pmcon_b
& RTC_BATTERY_DEAD
);
44 printk(BIOS_ERR
, "%s: RTC battery dead or removed\n", __func__
);
49 void soc_fill_power_state(struct chipset_power_state
*ps
)
53 ps
->gen_pmcon_a
= pci_read_config32(PCH_DEV_PMC
, GEN_PMCON_A
);
54 ps
->gen_pmcon_b
= pci_read_config32(PCH_DEV_PMC
, GEN_PMCON_B
);
56 pmc
= pmc_mmio_regs();
57 ps
->gblrst_cause
[0] = read32(pmc
+ GBLRST_CAUSE0
);
58 ps
->gblrst_cause
[1] = read32(pmc
+ GBLRST_CAUSE1
);
60 printk(BIOS_DEBUG
, "GEN_PMCON: %08x %08x\n", ps
->gen_pmcon_a
, ps
->gen_pmcon_b
);
62 printk(BIOS_DEBUG
, "GBLRST_CAUSE: %08x %08x\n",
63 ps
->gblrst_cause
[0], ps
->gblrst_cause
[1]);
67 * Set which power state system will be after reapplying
68 * the power (from G3 State)
70 void pmc_soc_set_afterg3_en(const bool on
)
74 reg8
= pci_read_config8(PCH_DEV_PMC
, GEN_PMCON_B
);
76 reg8
&= ~SLEEP_AFTER_POWER_FAIL
;
78 reg8
|= SLEEP_AFTER_POWER_FAIL
;
79 pci_write_config8(PCH_DEV_PMC
, GEN_PMCON_B
, reg8
);
82 void pmc_lock_smi(void)
84 printk(BIOS_DEBUG
, "Locking SMM enable.\n");
85 pci_or_config32(PCH_DEV_PMC
, GEN_PMCON_A
, SMI_LOCK
);
88 void pmc_lockdown_config(void)
91 pmc_or_mmio32(PMSYNC_TPR_CFG
, PMSYNC_LOCK
);
93 /* Make sure payload/OS can't trigger global reset */
94 pmc_global_reset_disable_and_lock();
96 /* Lock PMC stretch policy */
97 pci_or_config32(PCH_DEV_PMC
, GEN_PMCON_B
, SLP_STR_POL_LOCK
);