xref: /aosp_15_r20/external/coreboot/src/soc/intel/common/block/cpu/pm_timer_emulation.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <commonlib/helpers.h>
4 #include <cpu/x86/msr.h>
5 #include <intelblocks/cpulib.h>
6 #include <intelblocks/msr.h>
7 #include <soc/iomap.h>
8 #include <soc/pm.h>
9 
enable_pm_timer_emulation(void)10 void enable_pm_timer_emulation(void)
11 {
12 	msr_t msr;
13 
14 	if (CONFIG(USE_PM_ACPI_TIMER) || !CONFIG_CPU_XTAL_HZ)
15 		return;
16 
17 	/*
18 	 * The derived frequency is calculated as follows:
19 	 * (clock * msr[63:32]) >> 32 = target frequency.
20 	 * Back solve the multiplier so the 3.579545MHz ACPI timer frequency is used.
21 	 */
22 	msr.hi = DIV_ROUND_CLOSEST((3579545ULL << 32), CONFIG_CPU_XTAL_HZ);
23 	/* Set PM1 timer IO port and enable */
24 	msr.lo = (EMULATE_DELAY_VALUE << EMULATE_DELAY_OFFSET_VALUE) |
25 		  EMULATE_PM_TMR_EN | (ACPI_BASE_ADDRESS + PM1_TMR);
26 	wrmsr(MSR_EMULATE_PM_TIMER, msr);
27 }
28