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