aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/common/block
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/common/block')
-rw-r--r--src/soc/intel/common/block/cpu/Makefile.inc1
-rw-r--r--src/soc/intel/common/block/cpu/pm_timer_emulation.c26
-rw-r--r--src/soc/intel/common/block/include/intelblocks/cpulib.h6
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 */