118739e2cSSimon Glass /* 218739e2cSSimon Glass * From Coreboot file of the same name 318739e2cSSimon Glass * 418739e2cSSimon Glass * Copyright (C) 2011 The Chromium Authors. 518739e2cSSimon Glass * 618739e2cSSimon Glass * SPDX-License-Identifier: GPL-2.0 718739e2cSSimon Glass */ 818739e2cSSimon Glass 918739e2cSSimon Glass #include <common.h> 1018739e2cSSimon Glass #include <asm/cpu.h> 1118739e2cSSimon Glass #include <asm/msr.h> 1218739e2cSSimon Glass #include <asm/processor.h> 1318739e2cSSimon Glass #include <asm/turbo.h> 1418739e2cSSimon Glass 15a0c75f90SSimon Glass DECLARE_GLOBAL_DATA_PTR; 16a0c75f90SSimon Glass 17*2ddb1a17SBin Meng #ifdef CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED get_global_turbo_state(void)1818739e2cSSimon Glassstatic inline int get_global_turbo_state(void) 1918739e2cSSimon Glass { 2018739e2cSSimon Glass return TURBO_UNKNOWN; 2118739e2cSSimon Glass } 2218739e2cSSimon Glass set_global_turbo_state(int state)2318739e2cSSimon Glassstatic inline void set_global_turbo_state(int state) 2418739e2cSSimon Glass { 2518739e2cSSimon Glass } 2618739e2cSSimon Glass #else get_global_turbo_state(void)2718739e2cSSimon Glassstatic inline int get_global_turbo_state(void) 2818739e2cSSimon Glass { 29a0c75f90SSimon Glass return gd->arch.turbo_state; 3018739e2cSSimon Glass } 3118739e2cSSimon Glass set_global_turbo_state(int state)3218739e2cSSimon Glassstatic inline void set_global_turbo_state(int state) 3318739e2cSSimon Glass { 34a0c75f90SSimon Glass gd->arch.turbo_state = state; 3518739e2cSSimon Glass } 3618739e2cSSimon Glass #endif 3718739e2cSSimon Glass 3818739e2cSSimon Glass static const char *const turbo_state_desc[] = { 3918739e2cSSimon Glass [TURBO_UNKNOWN] = "unknown", 4018739e2cSSimon Glass [TURBO_UNAVAILABLE] = "unavailable", 4118739e2cSSimon Glass [TURBO_DISABLED] = "available but hidden", 4218739e2cSSimon Glass [TURBO_ENABLED] = "available and visible" 4318739e2cSSimon Glass }; 4418739e2cSSimon Glass 4518739e2cSSimon Glass /* 4618739e2cSSimon Glass * Determine the current state of Turbo and cache it for later. 4718739e2cSSimon Glass * Turbo is a package level config so it does not need to be 4818739e2cSSimon Glass * enabled on every core. 4918739e2cSSimon Glass */ turbo_get_state(void)5018739e2cSSimon Glassint turbo_get_state(void) 5118739e2cSSimon Glass { 5218739e2cSSimon Glass struct cpuid_result cpuid_regs; 5318739e2cSSimon Glass int turbo_en, turbo_cap; 5418739e2cSSimon Glass msr_t msr; 5518739e2cSSimon Glass int turbo_state = get_global_turbo_state(); 5618739e2cSSimon Glass 5718739e2cSSimon Glass /* Return cached state if available */ 5818739e2cSSimon Glass if (turbo_state != TURBO_UNKNOWN) 5918739e2cSSimon Glass return turbo_state; 6018739e2cSSimon Glass 6118739e2cSSimon Glass cpuid_regs = cpuid(CPUID_LEAF_PM); 6218739e2cSSimon Glass turbo_cap = !!(cpuid_regs.eax & PM_CAP_TURBO_MODE); 6318739e2cSSimon Glass 6418739e2cSSimon Glass msr = msr_read(MSR_IA32_MISC_ENABLES); 6518739e2cSSimon Glass turbo_en = !(msr.hi & H_MISC_DISABLE_TURBO); 6618739e2cSSimon Glass 6718739e2cSSimon Glass if (!turbo_cap && turbo_en) { 6818739e2cSSimon Glass /* Unavailable */ 6918739e2cSSimon Glass turbo_state = TURBO_UNAVAILABLE; 7018739e2cSSimon Glass } else if (!turbo_cap && !turbo_en) { 7118739e2cSSimon Glass /* Available but disabled */ 7218739e2cSSimon Glass turbo_state = TURBO_DISABLED; 7318739e2cSSimon Glass } else if (turbo_cap && turbo_en) { 7418739e2cSSimon Glass /* Available */ 7518739e2cSSimon Glass turbo_state = TURBO_ENABLED; 7618739e2cSSimon Glass } 7718739e2cSSimon Glass 7818739e2cSSimon Glass set_global_turbo_state(turbo_state); 7918739e2cSSimon Glass debug("Turbo is %s\n", turbo_state_desc[turbo_state]); 8018739e2cSSimon Glass return turbo_state; 8118739e2cSSimon Glass } 8218739e2cSSimon Glass turbo_enable(void)8318739e2cSSimon Glassvoid turbo_enable(void) 8418739e2cSSimon Glass { 8518739e2cSSimon Glass msr_t msr; 8618739e2cSSimon Glass 8718739e2cSSimon Glass /* Only possible if turbo is available but hidden */ 8818739e2cSSimon Glass if (turbo_get_state() == TURBO_DISABLED) { 8918739e2cSSimon Glass /* Clear Turbo Disable bit in Misc Enables */ 9018739e2cSSimon Glass msr = msr_read(MSR_IA32_MISC_ENABLES); 9118739e2cSSimon Glass msr.hi &= ~H_MISC_DISABLE_TURBO; 9218739e2cSSimon Glass msr_write(MSR_IA32_MISC_ENABLES, msr); 9318739e2cSSimon Glass 9418739e2cSSimon Glass /* Update cached turbo state */ 9518739e2cSSimon Glass set_global_turbo_state(TURBO_ENABLED); 9618739e2cSSimon Glass debug("Turbo has been enabled\n"); 9718739e2cSSimon Glass } 9818739e2cSSimon Glass } 99