diff options
Diffstat (limited to 'roms/u-boot/arch/x86/cpu/turbo.c')
-rw-r--r-- | roms/u-boot/arch/x86/cpu/turbo.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/roms/u-boot/arch/x86/cpu/turbo.c b/roms/u-boot/arch/x86/cpu/turbo.c new file mode 100644 index 000000000..e2c84cdde --- /dev/null +++ b/roms/u-boot/arch/x86/cpu/turbo.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * From Coreboot file of the same name + * + * Copyright (C) 2011 The Chromium Authors. + */ + +#include <common.h> +#include <log.h> +#include <asm/cpu.h> +#include <asm/global_data.h> +#include <asm/msr.h> +#include <asm/processor.h> +#include <asm/turbo.h> + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef 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 inline int get_global_turbo_state(void) +{ + return gd->arch.turbo_state; +} + +static inline void set_global_turbo_state(int state) +{ + gd->arch.turbo_state = state; +} +#endif + +/* gcc 7.3 does not wwant to drop strings, so use #ifdef */ +#ifndef CONFIG_TPL_BUILD +static const char *const turbo_state_desc[] = { + [TURBO_UNKNOWN] = "unknown", + [TURBO_UNAVAILABLE] = "unavailable", + [TURBO_DISABLED] = "available but hidden", + [TURBO_ENABLED] = "available and visible" +}; +#endif + +/* + * Determine the current state of Turbo and cache it for later. + * Turbo is a package level config so it does not need to be + * enabled on every core. + */ +int turbo_get_state(void) +{ + struct cpuid_result cpuid_regs; + int turbo_en, turbo_cap; + msr_t msr; + int turbo_state = get_global_turbo_state(); + + /* Return cached state if available */ + if (turbo_state != TURBO_UNKNOWN) + return turbo_state; + + cpuid_regs = cpuid(CPUID_LEAF_PM); + turbo_cap = !!(cpuid_regs.eax & PM_CAP_TURBO_MODE); + + msr = msr_read(MSR_IA32_MISC_ENABLE); + turbo_en = !(msr.hi & 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); +#ifndef CONFIG_TPL_BUILD + debug("Turbo is %s\n", turbo_state_desc[turbo_state]); +#endif + return turbo_state; +} + +void turbo_enable(void) +{ + msr_t msr; + + /* Only possible if turbo is available but hidden */ + if (turbo_get_state() == TURBO_DISABLED) { + /* Clear Turbo Disable bit in Misc Enables */ + msr = msr_read(MSR_IA32_MISC_ENABLE); + msr.hi &= ~MISC_DISABLE_TURBO; + msr_write(MSR_IA32_MISC_ENABLE, msr); + + /* Update cached turbo state */ + set_global_turbo_state(TURBO_ENABLED); + debug("Turbo has been enabled\n"); + } +} |