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