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