1// SPDX-License-Identifier: GPL-2.0 2/* 3 * From Coreboot file of the same name 4 * 5 * Copyright (C) 2011 The Chromium Authors. 6 */ 7 8#include <common.h> 9#include <log.h> 10#include <asm/cpu.h> 11#include <asm/global_data.h> 12#include <asm/msr.h> 13#include <asm/processor.h> 14#include <asm/turbo.h> 15 16DECLARE_GLOBAL_DATA_PTR; 17 18#ifdef CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED 19static inline int get_global_turbo_state(void) 20{ 21 return TURBO_UNKNOWN; 22} 23 24static inline void set_global_turbo_state(int state) 25{ 26} 27#else 28static inline int get_global_turbo_state(void) 29{ 30 return gd->arch.turbo_state; 31} 32 33static inline void set_global_turbo_state(int state) 34{ 35 gd->arch.turbo_state = state; 36} 37#endif 38 39/* gcc 7.3 does not wwant to drop strings, so use #ifdef */ 40#ifndef CONFIG_TPL_BUILD 41static const char *const turbo_state_desc[] = { 42 [TURBO_UNKNOWN] = "unknown", 43 [TURBO_UNAVAILABLE] = "unavailable", 44 [TURBO_DISABLED] = "available but hidden", 45 [TURBO_ENABLED] = "available and visible" 46}; 47#endif 48 49/* 50 * Determine the current state of Turbo and cache it for later. 51 * Turbo is a package level config so it does not need to be 52 * enabled on every core. 53 */ 54int turbo_get_state(void) 55{ 56 struct cpuid_result cpuid_regs; 57 int turbo_en, turbo_cap; 58 msr_t msr; 59 int turbo_state = get_global_turbo_state(); 60 61 /* Return cached state if available */ 62 if (turbo_state != TURBO_UNKNOWN) 63 return turbo_state; 64 65 cpuid_regs = cpuid(CPUID_LEAF_PM); 66 turbo_cap = !!(cpuid_regs.eax & PM_CAP_TURBO_MODE); 67 68 msr = msr_read(MSR_IA32_MISC_ENABLE); 69 turbo_en = !(msr.hi & MISC_DISABLE_TURBO); 70 71 if (!turbo_cap && turbo_en) { 72 /* Unavailable */ 73 turbo_state = TURBO_UNAVAILABLE; 74 } else if (!turbo_cap && !turbo_en) { 75 /* Available but disabled */ 76 turbo_state = TURBO_DISABLED; 77 } else if (turbo_cap && turbo_en) { 78 /* Available */ 79 turbo_state = TURBO_ENABLED; 80 } 81 82 set_global_turbo_state(turbo_state); 83#ifndef CONFIG_TPL_BUILD 84 debug("Turbo is %s\n", turbo_state_desc[turbo_state]); 85#endif 86 return turbo_state; 87} 88 89void turbo_enable(void) 90{ 91 msr_t msr; 92 93 /* Only possible if turbo is available but hidden */ 94 if (turbo_get_state() == TURBO_DISABLED) { 95 /* Clear Turbo Disable bit in Misc Enables */ 96 msr = msr_read(MSR_IA32_MISC_ENABLE); 97 msr.hi &= ~MISC_DISABLE_TURBO; 98 msr_write(MSR_IA32_MISC_ENABLE, msr); 99 100 /* Update cached turbo state */ 101 set_global_turbo_state(TURBO_ENABLED); 102 debug("Turbo has been enabled\n"); 103 } 104} 105