1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #include <console/console.h> 4 #include <cpu/cpu.h> 5 #include <cpu/intel/turbo.h> 6 #include <cpu/x86/msr.h> 7 8 #if CONFIG(CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED) get_global_turbo_state(void)9static inline int get_global_turbo_state(void) 10 { 11 return TURBO_UNKNOWN; 12 } 13 set_global_turbo_state(int state)14static inline void set_global_turbo_state(int state) 15 { 16 } 17 #else 18 static int g_turbo_state = TURBO_UNKNOWN; 19 get_global_turbo_state(void)20static inline int get_global_turbo_state(void) 21 { 22 return g_turbo_state; 23 } 24 set_global_turbo_state(int state)25static inline void set_global_turbo_state(int state) 26 { 27 g_turbo_state = state; 28 } 29 #endif 30 31 static const char *const turbo_state_desc[] = { 32 [TURBO_UNKNOWN] = "unknown", 33 [TURBO_UNAVAILABLE] = "unavailable", 34 [TURBO_DISABLED] = "available but hidden", 35 [TURBO_ENABLED] = "available and visible" 36 }; 37 38 /* 39 * Try to update the global Turbo state. 40 */ update_turbo_state(void)41static int update_turbo_state(void) 42 { 43 struct cpuid_result cpuid_regs; 44 int turbo_en, turbo_cap; 45 msr_t msr; 46 int turbo_state = get_global_turbo_state(); 47 48 cpuid_regs = cpuid(CPUID_LEAF_PM); 49 turbo_cap = !!(cpuid_regs.eax & PM_CAP_TURBO_MODE); 50 51 msr = rdmsr(IA32_MISC_ENABLE); 52 turbo_en = !(msr.hi & H_MISC_DISABLE_TURBO); 53 54 if (!turbo_cap && turbo_en) { 55 /* Unavailable */ 56 turbo_state = TURBO_UNAVAILABLE; 57 } else if (!turbo_cap && !turbo_en) { 58 /* Available but disabled */ 59 turbo_state = TURBO_DISABLED; 60 } else if (turbo_cap && turbo_en) { 61 /* Available */ 62 turbo_state = TURBO_ENABLED; 63 } 64 65 set_global_turbo_state(turbo_state); 66 printk(BIOS_INFO, "Turbo is %s\n", turbo_state_desc[turbo_state]); 67 68 return turbo_state; 69 } 70 71 /* 72 * Determine the current state of Turbo and cache it for later. Turbo is package 73 * level config so it does not need to be enabled on every core. 74 */ get_turbo_state(void)75int get_turbo_state(void) 76 { 77 int turbo_state = get_global_turbo_state(); 78 79 /* Return cached state if available */ 80 if (turbo_state == TURBO_UNKNOWN) 81 turbo_state = update_turbo_state(); 82 83 return turbo_state; 84 } 85 86 /* 87 * Try to enable Turbo mode. 88 */ enable_turbo(void)89void enable_turbo(void) 90 { 91 msr_t msr; 92 93 /* Only possible if turbo is available but hidden */ 94 if (get_turbo_state() == TURBO_DISABLED) { 95 /* Clear Turbo Disable bit in Misc Enables */ 96 msr = rdmsr(IA32_MISC_ENABLE); 97 msr.hi &= ~H_MISC_DISABLE_TURBO; 98 wrmsr(IA32_MISC_ENABLE, msr); 99 100 /* Update cached turbo state */ 101 update_turbo_state(); 102 } 103 } 104 105 /* 106 * Try to disable Turbo mode. 107 */ disable_turbo(void)108void disable_turbo(void) 109 { 110 msr_t msr; 111 112 /* Only possible if turbo is available and visible */ 113 if (get_turbo_state() == TURBO_ENABLED) { 114 /* Set Turbo Disable bit in Misc Enables */ 115 msr = rdmsr(IA32_MISC_ENABLE); 116 msr.hi |= H_MISC_DISABLE_TURBO; 117 wrmsr(IA32_MISC_ENABLE, msr); 118 119 /* Update cached turbo state */ 120 update_turbo_state(); 121 } 122 } 123