xref: /OK3568_Linux_fs/u-boot/arch/x86/cpu/turbo.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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*4882a593Smuzhiyun static 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*4882a593Smuzhiyun static inline void set_global_turbo_state(int state)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun }
26*4882a593Smuzhiyun #else
get_global_turbo_state(void)27*4882a593Smuzhiyun static 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*4882a593Smuzhiyun static 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*4882a593Smuzhiyun int 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*4882a593Smuzhiyun void 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