From 310c7637daba6ba4e9249928e5cd0e45ef4661e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Niew=C3=B6hner?= Date: Thu, 1 Oct 2020 22:28:03 +0200 Subject: soc/intel: deduplicate ACPI timer emulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code for enabling ACPI timer emulation is the same for the SoCs SKL, CNL, ICL, TGL, JSL and EHL. Deduplicate it by moving it to common code. APL differs in not having the delay settings. However, the bits are marked as "spare" and BWG mentions there are no "reserved bit checks done". Thus, we can write them unconditionally without any effect. Note: The ACPI timer emulation can only be used by SoCs with microcode supporting CTC (Common Timer Copy) / ACPI timer emulation. Change-Id: Ied4b312b6d53e80e71c55f4d1ca78a8cb2799793 Signed-off-by: Michael Niewöhner Reviewed-on: https://review.coreboot.org/c/coreboot/+/45951 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/soc/intel/alderlake/cpu.c | 21 ----------------- src/soc/intel/apollolake/Makefile.inc | 1 + src/soc/intel/apollolake/include/soc/pm.h | 2 -- src/soc/intel/apollolake/pmutil.c | 18 --------------- src/soc/intel/cannonlake/cpu.c | 25 --------------------- src/soc/intel/common/block/cpu/Makefile.inc | 1 + .../intel/common/block/cpu/pm_timer_emulation.c | 26 ++++++++++++++++++++++ .../common/block/include/intelblocks/cpulib.h | 6 +++++ src/soc/intel/elkhartlake/cpu.c | 21 ----------------- src/soc/intel/icelake/cpu.c | 21 ----------------- src/soc/intel/jasperlake/cpu.c | 21 ----------------- src/soc/intel/skylake/cpu.c | 24 -------------------- src/soc/intel/tigerlake/cpu.c | 21 ----------------- 13 files changed, 34 insertions(+), 174 deletions(-) create mode 100644 src/soc/intel/common/block/cpu/pm_timer_emulation.c (limited to 'src/soc/intel') diff --git a/src/soc/intel/alderlake/cpu.c b/src/soc/intel/alderlake/cpu.c index 39a42651bd..9fab277781 100644 --- a/src/soc/intel/alderlake/cpu.c +++ b/src/soc/intel/alderlake/cpu.c @@ -23,7 +23,6 @@ #include #include #include -#include #include static void soc_fsp_load(void) @@ -62,25 +61,6 @@ static void configure_misc(void) wrmsr(MSR_POWER_CTL, msr); } -static 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); -} - /* All CPUs including BSP will run the following function. */ void soc_core_init(struct device *cpu) { @@ -97,7 +77,6 @@ void soc_core_init(struct device *cpu) /* Configure Enhanced SpeedStep and Thermal Sensors */ configure_misc(); - /* Enable PM timer emulation */ enable_pm_timer_emulation(); /* Enable Direct Cache Access */ diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc index 79fab1a9d1..64889e56f9 100644 --- a/src/soc/intel/apollolake/Makefile.inc +++ b/src/soc/intel/apollolake/Makefile.inc @@ -10,6 +10,7 @@ subdirs-y += ../../../cpu/x86/tsc subdirs-y += ../../../cpu/x86/cache bootblock-y += bootblock/bootblock.c +bootblock-y += ../common/block/cpu/pm_timer_emulation.c bootblock-$(CONFIG_FSP_CAR) += fspcar.c bootblock-y += car.c bootblock-y += heci.c diff --git a/src/soc/intel/apollolake/include/soc/pm.h b/src/soc/intel/apollolake/include/soc/pm.h index aaf62583e6..748f76adba 100644 --- a/src/soc/intel/apollolake/include/soc/pm.h +++ b/src/soc/intel/apollolake/include/soc/pm.h @@ -234,8 +234,6 @@ struct chipset_power_state { void pch_log_state(void); -void enable_pm_timer_emulation(void); - /* STM Support */ uint16_t get_pmbase(void); diff --git a/src/soc/intel/apollolake/pmutil.c b/src/soc/intel/apollolake/pmutil.c index e0de93eae4..6e96b57a07 100644 --- a/src/soc/intel/apollolake/pmutil.c +++ b/src/soc/intel/apollolake/pmutil.c @@ -178,24 +178,6 @@ int soc_prev_sleep_state(const struct chipset_power_state *ps, return prev_sleep_state; } -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_PM_TMR_EN | (ACPI_BASE_ADDRESS + R_ACPI_PM1_TMR); - wrmsr(MSR_EMULATE_PM_TIMER, msr); -} - static int rtc_failed(uint32_t gen_pmcon1) { return !!(gen_pmcon1 & RPS); diff --git a/src/soc/intel/cannonlake/cpu.c b/src/soc/intel/cannonlake/cpu.c index 20da942f84..61b19894eb 100644 --- a/src/soc/intel/cannonlake/cpu.c +++ b/src/soc/intel/cannonlake/cpu.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -58,29 +57,6 @@ static void configure_misc(void) wrmsr(MSR_POWER_CTL, msr); } -/* - * The emulated ACPI timer allows replacing of the ACPI timer - * (PM1_TMR) to have no impart on the system. - */ -static 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); -} - static void configure_c_states(void) { msr_t msr; @@ -135,7 +111,6 @@ void soc_core_init(struct device *cpu) set_aesni_lock(); - /* Enable ACPI Timer Emulation via MSR 0x121 */ enable_pm_timer_emulation(); /* Enable Direct Cache Access */ 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 +#include +#include +#include +#include + +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 */ diff --git a/src/soc/intel/elkhartlake/cpu.c b/src/soc/intel/elkhartlake/cpu.c index 720a295e15..d0fa019ef8 100644 --- a/src/soc/intel/elkhartlake/cpu.c +++ b/src/soc/intel/elkhartlake/cpu.c @@ -17,7 +17,6 @@ #include #include #include -#include #include static void soc_fsp_load(void) @@ -56,25 +55,6 @@ static void configure_misc(void) wrmsr(MSR_POWER_CTL, msr); } -static 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); -} - /* All CPUs including BSP will run the following function. */ void soc_core_init(struct device *cpu) { @@ -91,7 +71,6 @@ void soc_core_init(struct device *cpu) /* Configure Enhanced SpeedStep and Thermal Sensors */ configure_misc(); - /* Enable PM timer emulation */ enable_pm_timer_emulation(); /* Enable Direct Cache Access */ diff --git a/src/soc/intel/icelake/cpu.c b/src/soc/intel/icelake/cpu.c index ea2b3574b2..1734ba6c30 100644 --- a/src/soc/intel/icelake/cpu.c +++ b/src/soc/intel/icelake/cpu.c @@ -17,7 +17,6 @@ #include #include #include -#include #include static void soc_fsp_load(void) @@ -56,25 +55,6 @@ static void configure_misc(void) wrmsr(MSR_POWER_CTL, msr); } -static 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); -} - static void configure_c_states(void) { msr_t msr; @@ -127,7 +107,6 @@ void soc_core_init(struct device *cpu) /* Configure Enhanced SpeedStep and Thermal Sensors */ configure_misc(); - /* Enable PM timer emulation */ enable_pm_timer_emulation(); /* Enable Direct Cache Access */ diff --git a/src/soc/intel/jasperlake/cpu.c b/src/soc/intel/jasperlake/cpu.c index 312fc7d7af..6518945d8d 100644 --- a/src/soc/intel/jasperlake/cpu.c +++ b/src/soc/intel/jasperlake/cpu.c @@ -17,7 +17,6 @@ #include #include #include -#include #include static void soc_fsp_load(void) @@ -56,25 +55,6 @@ static void configure_misc(void) wrmsr(MSR_POWER_CTL, msr); } -static 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); -} - /* All CPUs including BSP will run the following function. */ void soc_core_init(struct device *cpu) { @@ -91,7 +71,6 @@ void soc_core_init(struct device *cpu) /* Configure Enhanced SpeedStep and Thermal Sensors */ configure_misc(); - /* Enable PM timer emulation */ enable_pm_timer_emulation(); /* Enable Direct Cache Access */ diff --git a/src/soc/intel/skylake/cpu.c b/src/soc/intel/skylake/cpu.c index 1682503d4b..6872c12101 100644 --- a/src/soc/intel/skylake/cpu.c +++ b/src/soc/intel/skylake/cpu.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -96,29 +95,6 @@ static void configure_c_states(void) wrmsr(MSR_C_STATE_LATENCY_CONTROL_5, msr); } -/* - * The emulated ACPI timer allows disabling of the ACPI timer - * (PM1_TMR) to have no impart on the system. - */ -static 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); -} - /* All CPUs including BSP will run the following function. */ void soc_core_init(struct device *cpu) { diff --git a/src/soc/intel/tigerlake/cpu.c b/src/soc/intel/tigerlake/cpu.c index d7234e7191..36dfa1b738 100644 --- a/src/soc/intel/tigerlake/cpu.c +++ b/src/soc/intel/tigerlake/cpu.c @@ -23,7 +23,6 @@ #include #include #include -#include #include static void soc_fsp_load(void) @@ -62,25 +61,6 @@ static void configure_misc(void) wrmsr(MSR_POWER_CTL, msr); } -static 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); -} - /* All CPUs including BSP will run the following function. */ void soc_core_init(struct device *cpu) { @@ -97,7 +77,6 @@ void soc_core_init(struct device *cpu) /* Configure Enhanced SpeedStep and Thermal Sensors */ configure_misc(); - /* Enable PM timer emulation */ enable_pm_timer_emulation(); /* Enable Direct Cache Access */ -- cgit v1.2.3