blob: f8d85d5a339b2db5f1b032335736e060b9ed39bb [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Simon Glasse8045012014-11-14 18:18:43 -07002/*
3 * From Coreboot file of the same name
4 *
5 * Copyright (C) 2011 The Chromium Authors.
Simon Glasse8045012014-11-14 18:18:43 -07006 */
7
8#include <common.h>
Simon Glass0f2af882020-05-10 11:40:05 -06009#include <log.h>
Simon Glasse8045012014-11-14 18:18:43 -070010#include <asm/cpu.h>
11#include <asm/msr.h>
12#include <asm/processor.h>
13#include <asm/turbo.h>
14
Simon Glass37e706d2017-01-16 07:04:17 -070015DECLARE_GLOBAL_DATA_PTR;
16
Bin Meng842c31e2017-08-17 01:10:42 -070017#ifdef CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED
Simon Glasse8045012014-11-14 18:18:43 -070018static inline int get_global_turbo_state(void)
19{
20 return TURBO_UNKNOWN;
21}
22
23static inline void set_global_turbo_state(int state)
24{
25}
26#else
Simon Glasse8045012014-11-14 18:18:43 -070027static inline int get_global_turbo_state(void)
28{
Simon Glass37e706d2017-01-16 07:04:17 -070029 return gd->arch.turbo_state;
Simon Glasse8045012014-11-14 18:18:43 -070030}
31
32static inline void set_global_turbo_state(int state)
33{
Simon Glass37e706d2017-01-16 07:04:17 -070034 gd->arch.turbo_state = state;
Simon Glasse8045012014-11-14 18:18:43 -070035}
36#endif
37
38static 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 */
50int 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
Simon Glass05e85b92019-09-25 08:56:39 -060064 msr = msr_read(MSR_IA32_MISC_ENABLE);
65 turbo_en = !(msr.hi & MISC_DISABLE_TURBO);
Simon Glasse8045012014-11-14 18:18:43 -070066
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
83void 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 */
Simon Glass05e85b92019-09-25 08:56:39 -060090 msr = msr_read(MSR_IA32_MISC_ENABLE);
91 msr.hi &= ~MISC_DISABLE_TURBO;
92 msr_write(MSR_IA32_MISC_ENABLE, msr);
Simon Glasse8045012014-11-14 18:18:43 -070093
94 /* Update cached turbo state */
95 set_global_turbo_state(TURBO_ENABLED);
96 debug("Turbo has been enabled\n");
97 }
98}