Also sort includes. Change-Id: Ia4a3807e45777e2a596878fe09e3c80b1fd2704d Signed-off-by: Elyes Haouas <ehaouas@noos.fr> Reviewed-on: https://review.coreboot.org/c/coreboot/+/69037 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com>
123 lines
2.6 KiB
C
123 lines
2.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
|
|
#include <console/console.h>
|
|
#include <cpu/cpu.h>
|
|
#include <cpu/intel/turbo.h>
|
|
#include <cpu/x86/msr.h>
|
|
|
|
#if CONFIG(CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED)
|
|
static inline int get_global_turbo_state(void)
|
|
{
|
|
return TURBO_UNKNOWN;
|
|
}
|
|
|
|
static inline void set_global_turbo_state(int state)
|
|
{
|
|
}
|
|
#else
|
|
static int g_turbo_state = TURBO_UNKNOWN;
|
|
|
|
static inline int get_global_turbo_state(void)
|
|
{
|
|
return g_turbo_state;
|
|
}
|
|
|
|
static inline void set_global_turbo_state(int state)
|
|
{
|
|
g_turbo_state = state;
|
|
}
|
|
#endif
|
|
|
|
static const char *const turbo_state_desc[] = {
|
|
[TURBO_UNKNOWN] = "unknown",
|
|
[TURBO_UNAVAILABLE] = "unavailable",
|
|
[TURBO_DISABLED] = "available but hidden",
|
|
[TURBO_ENABLED] = "available and visible"
|
|
};
|
|
|
|
/*
|
|
* Try to update the global Turbo state.
|
|
*/
|
|
static int update_turbo_state(void)
|
|
{
|
|
struct cpuid_result cpuid_regs;
|
|
int turbo_en, turbo_cap;
|
|
msr_t msr;
|
|
int turbo_state = get_global_turbo_state();
|
|
|
|
cpuid_regs = cpuid(CPUID_LEAF_PM);
|
|
turbo_cap = !!(cpuid_regs.eax & PM_CAP_TURBO_MODE);
|
|
|
|
msr = rdmsr(IA32_MISC_ENABLE);
|
|
turbo_en = !(msr.hi & H_MISC_DISABLE_TURBO);
|
|
|
|
if (!turbo_cap && turbo_en) {
|
|
/* Unavailable */
|
|
turbo_state = TURBO_UNAVAILABLE;
|
|
} else if (!turbo_cap && !turbo_en) {
|
|
/* Available but disabled */
|
|
turbo_state = TURBO_DISABLED;
|
|
} else if (turbo_cap && turbo_en) {
|
|
/* Available */
|
|
turbo_state = TURBO_ENABLED;
|
|
}
|
|
|
|
set_global_turbo_state(turbo_state);
|
|
printk(BIOS_INFO, "Turbo is %s\n", turbo_state_desc[turbo_state]);
|
|
|
|
return turbo_state;
|
|
}
|
|
|
|
/*
|
|
* Determine the current state of Turbo and cache it for later. Turbo is package
|
|
* level config so it does not need to be enabled on every core.
|
|
*/
|
|
int get_turbo_state(void)
|
|
{
|
|
int turbo_state = get_global_turbo_state();
|
|
|
|
/* Return cached state if available */
|
|
if (turbo_state == TURBO_UNKNOWN)
|
|
turbo_state = update_turbo_state();
|
|
|
|
return turbo_state;
|
|
}
|
|
|
|
/*
|
|
* Try to enable Turbo mode.
|
|
*/
|
|
void enable_turbo(void)
|
|
{
|
|
msr_t msr;
|
|
|
|
/* Only possible if turbo is available but hidden */
|
|
if (get_turbo_state() == TURBO_DISABLED) {
|
|
/* Clear Turbo Disable bit in Misc Enables */
|
|
msr = rdmsr(IA32_MISC_ENABLE);
|
|
msr.hi &= ~H_MISC_DISABLE_TURBO;
|
|
wrmsr(IA32_MISC_ENABLE, msr);
|
|
|
|
/* Update cached turbo state */
|
|
update_turbo_state();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Try to disable Turbo mode.
|
|
*/
|
|
void disable_turbo(void)
|
|
{
|
|
msr_t msr;
|
|
|
|
/* Only possible if turbo is available and visible */
|
|
if (get_turbo_state() == TURBO_ENABLED) {
|
|
/* Set Turbo Disable bit in Misc Enables */
|
|
msr = rdmsr(IA32_MISC_ENABLE);
|
|
msr.hi |= H_MISC_DISABLE_TURBO;
|
|
wrmsr(IA32_MISC_ENABLE, msr);
|
|
|
|
/* Update cached turbo state */
|
|
update_turbo_state();
|
|
}
|
|
}
|