diff options
Diffstat (limited to 'src/soc/intel/common')
-rw-r--r-- | src/soc/intel/common/block/cpu/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/intel/common/block/cpu/pm_timer_emulation.c | 26 | ||||
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/cpulib.h | 6 |
3 files changed, 33 insertions, 0 deletions
diff --git a/src/soc/intel/common/block/cpu/Makefile.inc b/src/soc/intel/common/block/cpu/Makefile.inc index deddb67a16..7692076375 100644 --- a/src/soc/intel/common/block/cpu/Makefile.inc +++ b/src/soc/intel/common/block/cpu/Makefile.inc @@ -11,3 +11,4 @@ bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU) += cpulib.c romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU) += cpulib.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU) += cpulib.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT) += mp_init.c +ramstage-$(CONFIG_CPU_SUPPORTS_PM_TIMER_EMULATION) += pm_timer_emulation.c diff --git a/src/soc/intel/common/block/cpu/pm_timer_emulation.c b/src/soc/intel/common/block/cpu/pm_timer_emulation.c new file mode 100644 index 0000000000..8f56da54c5 --- /dev/null +++ b/src/soc/intel/common/block/cpu/pm_timer_emulation.c @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <cpu/x86/msr.h> +#include <intelblocks/cpulib.h> +#include <intelblocks/msr.h> +#include <soc/iomap.h> +#include <soc/pm.h> + +void enable_pm_timer_emulation(void) +{ + msr_t msr; + + if (!CONFIG_CPU_XTAL_HZ) + return; + + /* + * The derived frequency is calculated as follows: + * (clock * msr[63:32]) >> 32 = target frequency. + * Back solve the multiplier so the 3.579545MHz ACPI timer frequency is used. + */ + msr.hi = (3579545ULL << 32) / CONFIG_CPU_XTAL_HZ; + /* Set PM1 timer IO port and enable */ + msr.lo = (EMULATE_DELAY_VALUE << EMULATE_DELAY_OFFSET_VALUE) | + EMULATE_PM_TMR_EN | (ACPI_BASE_ADDRESS + PM1_TMR); + wrmsr(MSR_EMULATE_PM_TIMER, msr); +} diff --git a/src/soc/intel/common/block/include/intelblocks/cpulib.h b/src/soc/intel/common/block/include/intelblocks/cpulib.h index d2b00efb2f..4dfbef48f6 100644 --- a/src/soc/intel/common/block/include/intelblocks/cpulib.h +++ b/src/soc/intel/common/block/include/intelblocks/cpulib.h @@ -156,4 +156,10 @@ void cpu_lt_lock_memory(void *unused); /* Get a supported PRMRR size in bytes with respect to users choice */ int get_valid_prmrr_size(void); +/* + * Enable the emulated ACPI timer in case it's not available or to allow + * disabling the PM ACPI timer (PM1_TMR) for power saving. + */ +void enable_pm_timer_emulation(void); + #endif /* SOC_INTEL_COMMON_BLOCK_CPULIB_H */ |