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