soc/intel: deduplicate ACPI timer emulation

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 <foss@mniewoehner.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/45951
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
Michael Niewöhner 2020-10-01 22:28:03 +02:00
parent 72e49cef80
commit 310c7637da
13 changed files with 34 additions and 174 deletions

View File

@ -23,7 +23,6 @@
#include <soc/cpu.h> #include <soc/cpu.h>
#include <soc/msr.h> #include <soc/msr.h>
#include <soc/pci_devs.h> #include <soc/pci_devs.h>
#include <soc/pm.h>
#include <soc/soc_chip.h> #include <soc/soc_chip.h>
static void soc_fsp_load(void) static void soc_fsp_load(void)
@ -62,25 +61,6 @@ static void configure_misc(void)
wrmsr(MSR_POWER_CTL, msr); 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. */ /* All CPUs including BSP will run the following function. */
void soc_core_init(struct device *cpu) 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 Enhanced SpeedStep and Thermal Sensors */
configure_misc(); configure_misc();
/* Enable PM timer emulation */
enable_pm_timer_emulation(); enable_pm_timer_emulation();
/* Enable Direct Cache Access */ /* Enable Direct Cache Access */

View File

@ -10,6 +10,7 @@ subdirs-y += ../../../cpu/x86/tsc
subdirs-y += ../../../cpu/x86/cache subdirs-y += ../../../cpu/x86/cache
bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/bootblock.c
bootblock-y += ../common/block/cpu/pm_timer_emulation.c
bootblock-$(CONFIG_FSP_CAR) += fspcar.c bootblock-$(CONFIG_FSP_CAR) += fspcar.c
bootblock-y += car.c bootblock-y += car.c
bootblock-y += heci.c bootblock-y += heci.c

View File

@ -234,8 +234,6 @@ struct chipset_power_state {
void pch_log_state(void); void pch_log_state(void);
void enable_pm_timer_emulation(void);
/* STM Support */ /* STM Support */
uint16_t get_pmbase(void); uint16_t get_pmbase(void);

View File

@ -178,24 +178,6 @@ int soc_prev_sleep_state(const struct chipset_power_state *ps,
return prev_sleep_state; 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) static int rtc_failed(uint32_t gen_pmcon1)
{ {
return !!(gen_pmcon1 & RPS); return !!(gen_pmcon1 & RPS);

View File

@ -14,7 +14,6 @@
#include <soc/cpu.h> #include <soc/cpu.h>
#include <soc/msr.h> #include <soc/msr.h>
#include <soc/pci_devs.h> #include <soc/pci_devs.h>
#include <soc/pm.h>
#include <soc/systemagent.h> #include <soc/systemagent.h>
#include <cpu/x86/mtrr.h> #include <cpu/x86/mtrr.h>
#include <cpu/intel/microcode.h> #include <cpu/intel/microcode.h>
@ -58,29 +57,6 @@ static void configure_misc(void)
wrmsr(MSR_POWER_CTL, msr); 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) static void configure_c_states(void)
{ {
msr_t msr; msr_t msr;
@ -135,7 +111,6 @@ void soc_core_init(struct device *cpu)
set_aesni_lock(); set_aesni_lock();
/* Enable ACPI Timer Emulation via MSR 0x121 */
enable_pm_timer_emulation(); enable_pm_timer_emulation();
/* Enable Direct Cache Access */ /* Enable Direct Cache Access */

View File

@ -11,3 +11,4 @@ bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU) += cpulib.c
romstage-$(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) += cpulib.c
ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT) += mp_init.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT) += mp_init.c
ramstage-$(CONFIG_CPU_SUPPORTS_PM_TIMER_EMULATION) += pm_timer_emulation.c

View File

@ -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);
}

View File

@ -156,4 +156,10 @@ void cpu_lt_lock_memory(void *unused);
/* Get a supported PRMRR size in bytes with respect to users choice */ /* Get a supported PRMRR size in bytes with respect to users choice */
int get_valid_prmrr_size(void); 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 */ #endif /* SOC_INTEL_COMMON_BLOCK_CPULIB_H */

View File

@ -17,7 +17,6 @@
#include <soc/cpu.h> #include <soc/cpu.h>
#include <soc/msr.h> #include <soc/msr.h>
#include <soc/pci_devs.h> #include <soc/pci_devs.h>
#include <soc/pm.h>
#include <soc/soc_chip.h> #include <soc/soc_chip.h>
static void soc_fsp_load(void) static void soc_fsp_load(void)
@ -56,25 +55,6 @@ static void configure_misc(void)
wrmsr(MSR_POWER_CTL, msr); 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. */ /* All CPUs including BSP will run the following function. */
void soc_core_init(struct device *cpu) 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 Enhanced SpeedStep and Thermal Sensors */
configure_misc(); configure_misc();
/* Enable PM timer emulation */
enable_pm_timer_emulation(); enable_pm_timer_emulation();
/* Enable Direct Cache Access */ /* Enable Direct Cache Access */

View File

@ -17,7 +17,6 @@
#include <soc/cpu.h> #include <soc/cpu.h>
#include <soc/msr.h> #include <soc/msr.h>
#include <soc/pci_devs.h> #include <soc/pci_devs.h>
#include <soc/pm.h>
#include <soc/soc_chip.h> #include <soc/soc_chip.h>
static void soc_fsp_load(void) static void soc_fsp_load(void)
@ -56,25 +55,6 @@ static void configure_misc(void)
wrmsr(MSR_POWER_CTL, msr); 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) static void configure_c_states(void)
{ {
msr_t msr; msr_t msr;
@ -127,7 +107,6 @@ void soc_core_init(struct device *cpu)
/* Configure Enhanced SpeedStep and Thermal Sensors */ /* Configure Enhanced SpeedStep and Thermal Sensors */
configure_misc(); configure_misc();
/* Enable PM timer emulation */
enable_pm_timer_emulation(); enable_pm_timer_emulation();
/* Enable Direct Cache Access */ /* Enable Direct Cache Access */

View File

@ -17,7 +17,6 @@
#include <soc/cpu.h> #include <soc/cpu.h>
#include <soc/msr.h> #include <soc/msr.h>
#include <soc/pci_devs.h> #include <soc/pci_devs.h>
#include <soc/pm.h>
#include <soc/soc_chip.h> #include <soc/soc_chip.h>
static void soc_fsp_load(void) static void soc_fsp_load(void)
@ -56,25 +55,6 @@ static void configure_misc(void)
wrmsr(MSR_POWER_CTL, msr); 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. */ /* All CPUs including BSP will run the following function. */
void soc_core_init(struct device *cpu) 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 Enhanced SpeedStep and Thermal Sensors */
configure_misc(); configure_misc();
/* Enable PM timer emulation */
enable_pm_timer_emulation(); enable_pm_timer_emulation();
/* Enable Direct Cache Access */ /* Enable Direct Cache Access */

View File

@ -21,7 +21,6 @@
#include <soc/cpu.h> #include <soc/cpu.h>
#include <soc/msr.h> #include <soc/msr.h>
#include <soc/pci_devs.h> #include <soc/pci_devs.h>
#include <soc/pm.h>
#include <soc/ramstage.h> #include <soc/ramstage.h>
#include <soc/systemagent.h> #include <soc/systemagent.h>
@ -96,29 +95,6 @@ static void configure_c_states(void)
wrmsr(MSR_C_STATE_LATENCY_CONTROL_5, msr); 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. */ /* All CPUs including BSP will run the following function. */
void soc_core_init(struct device *cpu) void soc_core_init(struct device *cpu)
{ {

View File

@ -23,7 +23,6 @@
#include <soc/cpu.h> #include <soc/cpu.h>
#include <soc/msr.h> #include <soc/msr.h>
#include <soc/pci_devs.h> #include <soc/pci_devs.h>
#include <soc/pm.h>
#include <soc/soc_chip.h> #include <soc/soc_chip.h>
static void soc_fsp_load(void) static void soc_fsp_load(void)
@ -62,25 +61,6 @@ static void configure_misc(void)
wrmsr(MSR_POWER_CTL, msr); 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. */ /* All CPUs including BSP will run the following function. */
void soc_core_init(struct device *cpu) 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 Enhanced SpeedStep and Thermal Sensors */
configure_misc(); configure_misc();
/* Enable PM timer emulation */
enable_pm_timer_emulation(); enable_pm_timer_emulation();
/* Enable Direct Cache Access */ /* Enable Direct Cache Access */