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