xref: /rk3399_rockchip-uboot/arch/x86/cpu/turbo.c (revision 0031af9ce7b1c2d98ce77cc20bd7546d64e334fe)
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 Glass static 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 Glass static inline void set_global_turbo_state(int state)
2418739e2cSSimon Glass {
2518739e2cSSimon Glass }
2618739e2cSSimon Glass #else
get_global_turbo_state(void)2718739e2cSSimon Glass static 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 Glass static 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 Glass int 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 Glass void 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