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 16 DECLARE_GLOBAL_DATA_PTR; 17 18 #ifdef CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED get_global_turbo_state(void)19static inline int get_global_turbo_state(void) 20 { 21 return TURBO_UNKNOWN; 22 } 23 set_global_turbo_state(int state)24static inline void set_global_turbo_state(int state) 25 { 26 } 27 #else get_global_turbo_state(void)28static inline int get_global_turbo_state(void) 29 { 30 return gd->arch.turbo_state; 31 } 32 set_global_turbo_state(int state)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 41 static 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 */ turbo_get_state(void)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 turbo_enable(void)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