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