blob: ec1b9d306ba615d132c49f419b12b74b0787e651 [file] [log] [blame]
Thomas Gleixnera61127c2019-05-29 16:57:49 -07001// SPDX-License-Identifier: GPL-2.0-only
Len Brown26717172010-03-08 14:07:30 -05002/*
3 * intel_idle.c - native hardware idle loop for modern Intel processors
4 *
Rafael J. Wysocki317e5ec2020-02-06 18:45:49 +01005 * Copyright (c) 2013 - 2020, Intel Corporation.
Len Brown26717172010-03-08 14:07:30 -05006 * Len Brown <len.brown@intel.com>
Rafael J. Wysocki317e5ec2020-02-06 18:45:49 +01007 * Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Len Brown26717172010-03-08 14:07:30 -05008 */
9
10/*
Alexander Monakov8bb2e2a2020-10-12 15:50:33 +030011 * intel_idle is a cpuidle driver that loads on all Intel CPUs with MWAIT
Len Brown26717172010-03-08 14:07:30 -050012 * in lieu of the legacy ACPI processor_idle driver. The intent is to
13 * make Linux more efficient on these processors, as intel_idle knows
14 * more than ACPI, as well as make Linux more immune to ACPI BIOS bugs.
15 */
16
17/*
18 * Design Assumptions
19 *
20 * All CPUs have same idle states as boot CPU
21 *
22 * Chipset BM_STS (bus master status) bit is a NOP
Alexander Monakov8bb2e2a2020-10-12 15:50:33 +030023 * for preventing entry into deep C-states
24 *
25 * CPU will flush caches as needed when entering a C-state via MWAIT
26 * (in contrast to entering ACPI C3, in which case the WBINVD
27 * instruction needs to be executed to flush the caches)
Len Brown26717172010-03-08 14:07:30 -050028 */
29
30/*
31 * Known limitations
32 *
Len Brown26717172010-03-08 14:07:30 -050033 * ACPI has a .suspend hack to turn off deep c-statees during suspend
34 * to avoid complications with the lapic timer workaround.
35 * Have not seen issues with suspend, but may need same workaround here.
36 *
Len Brown26717172010-03-08 14:07:30 -050037 */
38
39/* un-comment DEBUG to enable pr_debug() statements */
Tom Rix651bc582021-01-15 15:56:46 -080040/* #define DEBUG */
Len Brown26717172010-03-08 14:07:30 -050041
Joe Perches654d08a2017-06-09 12:29:20 -070042#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
43
Rafael J. Wysocki18734952019-12-13 09:56:01 +010044#include <linux/acpi.h>
Len Brown26717172010-03-08 14:07:30 -050045#include <linux/kernel.h>
46#include <linux/cpuidle.h>
Thomas Gleixner76962ca2015-04-03 02:02:34 +020047#include <linux/tick.h>
Len Brown26717172010-03-08 14:07:30 -050048#include <trace/events/power.h>
49#include <linux/sched.h>
Shaohua Li2a2d31c2011-01-10 09:38:12 +080050#include <linux/notifier.h>
51#include <linux/cpu.h>
Paul Gortmaker02c4fae2016-06-17 01:28:33 -040052#include <linux/moduleparam.h>
Andi Kleenb66b8b92012-01-26 00:09:07 +010053#include <asm/cpu_device_id.h>
Dave Hansendb73c5a2016-06-02 17:19:32 -070054#include <asm/intel-family.h>
H. Peter Anvinbc83ccc2010-09-17 15:36:40 -070055#include <asm/mwait.h>
Len Brown14796fc2011-01-18 20:48:27 -050056#include <asm/msr.h>
Len Brown26717172010-03-08 14:07:30 -050057
Rafael J. Wysocki317e5ec2020-02-06 18:45:49 +010058#define INTEL_IDLE_VERSION "0.5.1"
Len Brown26717172010-03-08 14:07:30 -050059
Len Brown26717172010-03-08 14:07:30 -050060static struct cpuidle_driver intel_idle_driver = {
61 .name = "intel_idle",
62 .owner = THIS_MODULE,
63};
64/* intel_idle.max_cstate=0 disables driver */
Len Brown137ecc72013-02-01 21:35:35 -050065static int max_cstate = CPUIDLE_STATE_MAX - 1;
Rafael J. Wysocki4dcb78e2020-02-03 11:57:18 +010066static unsigned int disabled_states_mask;
Len Brown26717172010-03-08 14:07:30 -050067
Rafael J. Wysocki6eb04432020-02-06 18:45:18 +010068static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
Rafael J. Wysocki7f843dd2020-02-06 18:41:24 +010069
70static unsigned long auto_demotion_disable_flags;
71static bool disable_promotion_to_c1e;
72
Andi Kleenb66b8b92012-01-26 00:09:07 +010073struct idle_cpu {
74 struct cpuidle_state *state_table;
75
76 /*
77 * Hardware C-state auto-demotion may not always be optimal.
78 * Indicate which enable bits to clear here.
79 */
80 unsigned long auto_demotion_disable_flags;
Len Brown8c058d532014-07-31 15:21:24 -040081 bool byt_auto_demotion_disable_flag;
Len Brown32e95182013-02-02 01:31:56 -050082 bool disable_promotion_to_c1e;
Rafael J. Wysockibff8e602019-12-13 09:56:21 +010083 bool use_acpi;
Andi Kleenb66b8b92012-01-26 00:09:07 +010084};
85
Rafael J. Wysocki7f843dd2020-02-06 18:41:24 +010086static const struct idle_cpu *icpu __initdata;
Rafael J. Wysocki7f843dd2020-02-06 18:41:24 +010087static struct cpuidle_state *cpuidle_state_table __initdata;
Len Brown26717172010-03-08 14:07:30 -050088
Rafael J. Wysocki6eb04432020-02-06 18:45:18 +010089static unsigned int mwait_substates __initdata;
90
Len Brown26717172010-03-08 14:07:30 -050091/*
Rafael J. Wysockibff8e602019-12-13 09:56:21 +010092 * Enable this state by default even if the ACPI _CST does not list it.
93 */
94#define CPUIDLE_FLAG_ALWAYS_ENABLE BIT(15)
95
96/*
Len Brownb1beab42013-01-31 19:55:37 -050097 * MWAIT takes an 8-bit "hint" in EAX "suggesting"
98 * the C-state (top nibble) and sub-state (bottom nibble)
99 * 0x00 means "MWAIT(C1)", 0x10 means "MWAIT(C2)" etc.
100 *
101 * We store the hint at the top of our "flags" for each state.
102 */
103#define flg2MWAIT(flags) (((flags) >> 24) & 0xFF)
104#define MWAIT2flg(eax) ((eax & 0xFF) << 24)
105
Rafael J. Wysocki30a996f2020-02-06 18:41:15 +0100106/**
107 * intel_idle - Ask the processor to enter the given idle state.
108 * @dev: cpuidle device of the target CPU.
109 * @drv: cpuidle driver (assumed to point to intel_idle_driver).
110 * @index: Target idle state index.
111 *
112 * Use the MWAIT instruction to notify the processor that the CPU represented by
113 * @dev is idle and it can try to enter the idle state corresponding to @index.
114 *
115 * If the local APIC timer is not known to be reliable in the target idle state,
116 * enable one-shot tick broadcasting for the target CPU before executing MWAIT.
117 *
118 * Optionally call leave_mm() for the target CPU upfront to avoid wakeups due to
119 * flushing user TLBs.
120 *
121 * Must be called under local_irq_disable().
122 */
123static __cpuidle int intel_idle(struct cpuidle_device *dev,
124 struct cpuidle_driver *drv, int index)
125{
126 struct cpuidle_state *state = &drv->states[index];
127 unsigned long eax = flg2MWAIT(state->flags);
128 unsigned long ecx = 1; /* break on interrupt flag */
Rafael J. Wysocki30a996f2020-02-06 18:41:15 +0100129
130 mwait_idle_with_hints(eax, ecx);
131
Rafael J. Wysocki30a996f2020-02-06 18:41:15 +0100132 return index;
133}
134
135/**
136 * intel_idle_s2idle - Ask the processor to enter the given idle state.
137 * @dev: cpuidle device of the target CPU.
138 * @drv: cpuidle driver (assumed to point to intel_idle_driver).
139 * @index: Target idle state index.
140 *
141 * Use the MWAIT instruction to notify the processor that the CPU represented by
142 * @dev is idle and it can try to enter the idle state corresponding to @index.
143 *
144 * Invoked as a suspend-to-idle callback routine with frozen user space, frozen
145 * scheduler tick and suspended scheduler clock on the target CPU.
146 */
Neal Liuefe97112020-07-27 11:25:46 +0800147static __cpuidle int intel_idle_s2idle(struct cpuidle_device *dev,
148 struct cpuidle_driver *drv, int index)
Rafael J. Wysocki30a996f2020-02-06 18:41:15 +0100149{
150 unsigned long eax = flg2MWAIT(drv->states[index].flags);
151 unsigned long ecx = 1; /* break on interrupt flag */
152
153 mwait_idle_with_hints(eax, ecx);
Neal Liuefe97112020-07-27 11:25:46 +0800154
155 return 0;
Rafael J. Wysocki30a996f2020-02-06 18:41:15 +0100156}
157
Len Brownb1beab42013-01-31 19:55:37 -0500158/*
Len Brown26717172010-03-08 14:07:30 -0500159 * States are indexed by the cstate number,
160 * which is also the index into the MWAIT hint array.
161 * Thus C0 is a dummy.
162 */
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100163static struct cpuidle_state nehalem_cstates[] __initdata = {
Len Browne022e7e2013-02-01 23:37:30 -0500164 {
Len Brownde09cdd2017-02-28 16:32:44 -0500165 .name = "C1",
Len Brown26717172010-03-08 14:07:30 -0500166 .desc = "MWAIT 0x00",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100167 .flags = MWAIT2flg(0x00),
Len Brown26717172010-03-08 14:07:30 -0500168 .exit_latency = 3,
Len Brown26717172010-03-08 14:07:30 -0500169 .target_residency = 6,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100170 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200171 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500172 {
Len Brownde09cdd2017-02-28 16:32:44 -0500173 .name = "C1E",
Len Brown32e95182013-02-02 01:31:56 -0500174 .desc = "MWAIT 0x01",
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +0100175 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
Len Brown32e95182013-02-02 01:31:56 -0500176 .exit_latency = 10,
177 .target_residency = 20,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100178 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200179 .enter_s2idle = intel_idle_s2idle, },
Len Brown32e95182013-02-02 01:31:56 -0500180 {
Len Brownde09cdd2017-02-28 16:32:44 -0500181 .name = "C3",
Len Brown26717172010-03-08 14:07:30 -0500182 .desc = "MWAIT 0x10",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100183 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown26717172010-03-08 14:07:30 -0500184 .exit_latency = 20,
Len Brown26717172010-03-08 14:07:30 -0500185 .target_residency = 80,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100186 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200187 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500188 {
Len Brownde09cdd2017-02-28 16:32:44 -0500189 .name = "C6",
Len Brown26717172010-03-08 14:07:30 -0500190 .desc = "MWAIT 0x20",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100191 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown26717172010-03-08 14:07:30 -0500192 .exit_latency = 200,
Len Brown26717172010-03-08 14:07:30 -0500193 .target_residency = 800,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100194 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200195 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500196 {
197 .enter = NULL }
Len Brown26717172010-03-08 14:07:30 -0500198};
199
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100200static struct cpuidle_state snb_cstates[] __initdata = {
Len Browne022e7e2013-02-01 23:37:30 -0500201 {
Len Brownde09cdd2017-02-28 16:32:44 -0500202 .name = "C1",
Len Brownd13780d2010-07-07 00:12:03 -0400203 .desc = "MWAIT 0x00",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100204 .flags = MWAIT2flg(0x00),
Len Brown32e95182013-02-02 01:31:56 -0500205 .exit_latency = 2,
206 .target_residency = 2,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100207 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200208 .enter_s2idle = intel_idle_s2idle, },
Len Brown32e95182013-02-02 01:31:56 -0500209 {
Len Brownde09cdd2017-02-28 16:32:44 -0500210 .name = "C1E",
Len Brown32e95182013-02-02 01:31:56 -0500211 .desc = "MWAIT 0x01",
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +0100212 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
Len Brown32e95182013-02-02 01:31:56 -0500213 .exit_latency = 10,
214 .target_residency = 20,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100215 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200216 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500217 {
Len Brownde09cdd2017-02-28 16:32:44 -0500218 .name = "C3",
Len Brownd13780d2010-07-07 00:12:03 -0400219 .desc = "MWAIT 0x10",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100220 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brownd13780d2010-07-07 00:12:03 -0400221 .exit_latency = 80,
Len Brownddbd5502010-12-13 18:28:22 -0500222 .target_residency = 211,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100223 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200224 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500225 {
Len Brownde09cdd2017-02-28 16:32:44 -0500226 .name = "C6",
Len Brownd13780d2010-07-07 00:12:03 -0400227 .desc = "MWAIT 0x20",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100228 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brownd13780d2010-07-07 00:12:03 -0400229 .exit_latency = 104,
Len Brownddbd5502010-12-13 18:28:22 -0500230 .target_residency = 345,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100231 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200232 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500233 {
Len Brownde09cdd2017-02-28 16:32:44 -0500234 .name = "C7",
Len Brownd13780d2010-07-07 00:12:03 -0400235 .desc = "MWAIT 0x30",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100236 .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brownd13780d2010-07-07 00:12:03 -0400237 .exit_latency = 109,
Len Brownddbd5502010-12-13 18:28:22 -0500238 .target_residency = 345,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100239 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200240 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500241 {
242 .enter = NULL }
Len Brownd13780d2010-07-07 00:12:03 -0400243};
244
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100245static struct cpuidle_state byt_cstates[] __initdata = {
Len Brown718987d2014-02-14 02:30:00 -0500246 {
Len Brownde09cdd2017-02-28 16:32:44 -0500247 .name = "C1",
Len Brown718987d2014-02-14 02:30:00 -0500248 .desc = "MWAIT 0x00",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100249 .flags = MWAIT2flg(0x00),
Len Brown718987d2014-02-14 02:30:00 -0500250 .exit_latency = 1,
251 .target_residency = 1,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100252 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200253 .enter_s2idle = intel_idle_s2idle, },
Len Brown718987d2014-02-14 02:30:00 -0500254 {
Len Brownde09cdd2017-02-28 16:32:44 -0500255 .name = "C6N",
Len Brown718987d2014-02-14 02:30:00 -0500256 .desc = "MWAIT 0x58",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100257 .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brownd7ef7672015-03-24 23:23:20 -0400258 .exit_latency = 300,
Len Brown718987d2014-02-14 02:30:00 -0500259 .target_residency = 275,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100260 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200261 .enter_s2idle = intel_idle_s2idle, },
Len Brown718987d2014-02-14 02:30:00 -0500262 {
Len Brownde09cdd2017-02-28 16:32:44 -0500263 .name = "C6S",
Len Brown718987d2014-02-14 02:30:00 -0500264 .desc = "MWAIT 0x52",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100265 .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brownd7ef7672015-03-24 23:23:20 -0400266 .exit_latency = 500,
Len Brown718987d2014-02-14 02:30:00 -0500267 .target_residency = 560,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100268 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200269 .enter_s2idle = intel_idle_s2idle, },
Len Brown718987d2014-02-14 02:30:00 -0500270 {
Len Brownde09cdd2017-02-28 16:32:44 -0500271 .name = "C7",
Len Brown718987d2014-02-14 02:30:00 -0500272 .desc = "MWAIT 0x60",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100273 .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown718987d2014-02-14 02:30:00 -0500274 .exit_latency = 1200,
Len Brownd7ef7672015-03-24 23:23:20 -0400275 .target_residency = 4000,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100276 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200277 .enter_s2idle = intel_idle_s2idle, },
Len Brown718987d2014-02-14 02:30:00 -0500278 {
Len Brownde09cdd2017-02-28 16:32:44 -0500279 .name = "C7S",
Len Brown718987d2014-02-14 02:30:00 -0500280 .desc = "MWAIT 0x64",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100281 .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown718987d2014-02-14 02:30:00 -0500282 .exit_latency = 10000,
283 .target_residency = 20000,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100284 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200285 .enter_s2idle = intel_idle_s2idle, },
Len Brown718987d2014-02-14 02:30:00 -0500286 {
287 .enter = NULL }
288};
289
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100290static struct cpuidle_state cht_cstates[] __initdata = {
Len Browncab07a52015-03-27 20:54:01 -0400291 {
Len Brownde09cdd2017-02-28 16:32:44 -0500292 .name = "C1",
Len Browncab07a52015-03-27 20:54:01 -0400293 .desc = "MWAIT 0x00",
294 .flags = MWAIT2flg(0x00),
295 .exit_latency = 1,
296 .target_residency = 1,
297 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200298 .enter_s2idle = intel_idle_s2idle, },
Len Browncab07a52015-03-27 20:54:01 -0400299 {
Len Brownde09cdd2017-02-28 16:32:44 -0500300 .name = "C6N",
Len Browncab07a52015-03-27 20:54:01 -0400301 .desc = "MWAIT 0x58",
302 .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED,
303 .exit_latency = 80,
304 .target_residency = 275,
305 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200306 .enter_s2idle = intel_idle_s2idle, },
Len Browncab07a52015-03-27 20:54:01 -0400307 {
Len Brownde09cdd2017-02-28 16:32:44 -0500308 .name = "C6S",
Len Browncab07a52015-03-27 20:54:01 -0400309 .desc = "MWAIT 0x52",
310 .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED,
311 .exit_latency = 200,
312 .target_residency = 560,
313 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200314 .enter_s2idle = intel_idle_s2idle, },
Len Browncab07a52015-03-27 20:54:01 -0400315 {
Len Brownde09cdd2017-02-28 16:32:44 -0500316 .name = "C7",
Len Browncab07a52015-03-27 20:54:01 -0400317 .desc = "MWAIT 0x60",
318 .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
319 .exit_latency = 1200,
320 .target_residency = 4000,
321 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200322 .enter_s2idle = intel_idle_s2idle, },
Len Browncab07a52015-03-27 20:54:01 -0400323 {
Len Brownde09cdd2017-02-28 16:32:44 -0500324 .name = "C7S",
Len Browncab07a52015-03-27 20:54:01 -0400325 .desc = "MWAIT 0x64",
326 .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED,
327 .exit_latency = 10000,
328 .target_residency = 20000,
329 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200330 .enter_s2idle = intel_idle_s2idle, },
Len Browncab07a52015-03-27 20:54:01 -0400331 {
332 .enter = NULL }
333};
334
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100335static struct cpuidle_state ivb_cstates[] __initdata = {
Len Browne022e7e2013-02-01 23:37:30 -0500336 {
Len Brownde09cdd2017-02-28 16:32:44 -0500337 .name = "C1",
Len Brown6edab082012-06-01 19:45:32 -0400338 .desc = "MWAIT 0x00",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100339 .flags = MWAIT2flg(0x00),
Len Brown6edab082012-06-01 19:45:32 -0400340 .exit_latency = 1,
341 .target_residency = 1,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100342 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200343 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500344 {
Len Brownde09cdd2017-02-28 16:32:44 -0500345 .name = "C1E",
Len Brown32e95182013-02-02 01:31:56 -0500346 .desc = "MWAIT 0x01",
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +0100347 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
Len Brown32e95182013-02-02 01:31:56 -0500348 .exit_latency = 10,
349 .target_residency = 20,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100350 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200351 .enter_s2idle = intel_idle_s2idle, },
Len Brown32e95182013-02-02 01:31:56 -0500352 {
Len Brownde09cdd2017-02-28 16:32:44 -0500353 .name = "C3",
Len Brown6edab082012-06-01 19:45:32 -0400354 .desc = "MWAIT 0x10",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100355 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown6edab082012-06-01 19:45:32 -0400356 .exit_latency = 59,
357 .target_residency = 156,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100358 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200359 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500360 {
Len Brownde09cdd2017-02-28 16:32:44 -0500361 .name = "C6",
Len Brown6edab082012-06-01 19:45:32 -0400362 .desc = "MWAIT 0x20",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100363 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown6edab082012-06-01 19:45:32 -0400364 .exit_latency = 80,
365 .target_residency = 300,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100366 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200367 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500368 {
Len Brownde09cdd2017-02-28 16:32:44 -0500369 .name = "C7",
Len Brown6edab082012-06-01 19:45:32 -0400370 .desc = "MWAIT 0x30",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100371 .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown6edab082012-06-01 19:45:32 -0400372 .exit_latency = 87,
373 .target_residency = 300,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100374 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200375 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500376 {
377 .enter = NULL }
Len Brown6edab082012-06-01 19:45:32 -0400378};
379
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100380static struct cpuidle_state ivt_cstates[] __initdata = {
Len Brown0138d8f2014-04-04 01:21:07 -0400381 {
Len Brownde09cdd2017-02-28 16:32:44 -0500382 .name = "C1",
Len Brown0138d8f2014-04-04 01:21:07 -0400383 .desc = "MWAIT 0x00",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100384 .flags = MWAIT2flg(0x00),
Len Brown0138d8f2014-04-04 01:21:07 -0400385 .exit_latency = 1,
386 .target_residency = 1,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100387 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200388 .enter_s2idle = intel_idle_s2idle, },
Len Brown0138d8f2014-04-04 01:21:07 -0400389 {
Len Brownde09cdd2017-02-28 16:32:44 -0500390 .name = "C1E",
Len Brown0138d8f2014-04-04 01:21:07 -0400391 .desc = "MWAIT 0x01",
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +0100392 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
Len Brown0138d8f2014-04-04 01:21:07 -0400393 .exit_latency = 10,
394 .target_residency = 80,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100395 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200396 .enter_s2idle = intel_idle_s2idle, },
Len Brown0138d8f2014-04-04 01:21:07 -0400397 {
Len Brownde09cdd2017-02-28 16:32:44 -0500398 .name = "C3",
Len Brown0138d8f2014-04-04 01:21:07 -0400399 .desc = "MWAIT 0x10",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100400 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown0138d8f2014-04-04 01:21:07 -0400401 .exit_latency = 59,
402 .target_residency = 156,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100403 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200404 .enter_s2idle = intel_idle_s2idle, },
Len Brown0138d8f2014-04-04 01:21:07 -0400405 {
Len Brownde09cdd2017-02-28 16:32:44 -0500406 .name = "C6",
Len Brown0138d8f2014-04-04 01:21:07 -0400407 .desc = "MWAIT 0x20",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100408 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown0138d8f2014-04-04 01:21:07 -0400409 .exit_latency = 82,
410 .target_residency = 300,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100411 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200412 .enter_s2idle = intel_idle_s2idle, },
Len Brown0138d8f2014-04-04 01:21:07 -0400413 {
414 .enter = NULL }
415};
416
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100417static struct cpuidle_state ivt_cstates_4s[] __initdata = {
Len Brown0138d8f2014-04-04 01:21:07 -0400418 {
Len Brownde09cdd2017-02-28 16:32:44 -0500419 .name = "C1",
Len Brown0138d8f2014-04-04 01:21:07 -0400420 .desc = "MWAIT 0x00",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100421 .flags = MWAIT2flg(0x00),
Len Brown0138d8f2014-04-04 01:21:07 -0400422 .exit_latency = 1,
423 .target_residency = 1,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100424 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200425 .enter_s2idle = intel_idle_s2idle, },
Len Brown0138d8f2014-04-04 01:21:07 -0400426 {
Len Brownde09cdd2017-02-28 16:32:44 -0500427 .name = "C1E",
Len Brown0138d8f2014-04-04 01:21:07 -0400428 .desc = "MWAIT 0x01",
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +0100429 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
Len Brown0138d8f2014-04-04 01:21:07 -0400430 .exit_latency = 10,
431 .target_residency = 250,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100432 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200433 .enter_s2idle = intel_idle_s2idle, },
Len Brown0138d8f2014-04-04 01:21:07 -0400434 {
Len Brownde09cdd2017-02-28 16:32:44 -0500435 .name = "C3",
Len Brown0138d8f2014-04-04 01:21:07 -0400436 .desc = "MWAIT 0x10",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100437 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown0138d8f2014-04-04 01:21:07 -0400438 .exit_latency = 59,
439 .target_residency = 300,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100440 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200441 .enter_s2idle = intel_idle_s2idle, },
Len Brown0138d8f2014-04-04 01:21:07 -0400442 {
Len Brownde09cdd2017-02-28 16:32:44 -0500443 .name = "C6",
Len Brown0138d8f2014-04-04 01:21:07 -0400444 .desc = "MWAIT 0x20",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100445 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown0138d8f2014-04-04 01:21:07 -0400446 .exit_latency = 84,
447 .target_residency = 400,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100448 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200449 .enter_s2idle = intel_idle_s2idle, },
Len Brown0138d8f2014-04-04 01:21:07 -0400450 {
451 .enter = NULL }
452};
453
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100454static struct cpuidle_state ivt_cstates_8s[] __initdata = {
Len Brown0138d8f2014-04-04 01:21:07 -0400455 {
Len Brownde09cdd2017-02-28 16:32:44 -0500456 .name = "C1",
Len Brown0138d8f2014-04-04 01:21:07 -0400457 .desc = "MWAIT 0x00",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100458 .flags = MWAIT2flg(0x00),
Len Brown0138d8f2014-04-04 01:21:07 -0400459 .exit_latency = 1,
460 .target_residency = 1,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100461 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200462 .enter_s2idle = intel_idle_s2idle, },
Len Brown0138d8f2014-04-04 01:21:07 -0400463 {
Len Brownde09cdd2017-02-28 16:32:44 -0500464 .name = "C1E",
Len Brown0138d8f2014-04-04 01:21:07 -0400465 .desc = "MWAIT 0x01",
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +0100466 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
Len Brown0138d8f2014-04-04 01:21:07 -0400467 .exit_latency = 10,
468 .target_residency = 500,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100469 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200470 .enter_s2idle = intel_idle_s2idle, },
Len Brown0138d8f2014-04-04 01:21:07 -0400471 {
Len Brownde09cdd2017-02-28 16:32:44 -0500472 .name = "C3",
Len Brown0138d8f2014-04-04 01:21:07 -0400473 .desc = "MWAIT 0x10",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100474 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown0138d8f2014-04-04 01:21:07 -0400475 .exit_latency = 59,
476 .target_residency = 600,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100477 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200478 .enter_s2idle = intel_idle_s2idle, },
Len Brown0138d8f2014-04-04 01:21:07 -0400479 {
Len Brownde09cdd2017-02-28 16:32:44 -0500480 .name = "C6",
Len Brown0138d8f2014-04-04 01:21:07 -0400481 .desc = "MWAIT 0x20",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100482 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown0138d8f2014-04-04 01:21:07 -0400483 .exit_latency = 88,
484 .target_residency = 700,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100485 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200486 .enter_s2idle = intel_idle_s2idle, },
Len Brown0138d8f2014-04-04 01:21:07 -0400487 {
488 .enter = NULL }
489};
490
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100491static struct cpuidle_state hsw_cstates[] __initdata = {
Len Browne022e7e2013-02-01 23:37:30 -0500492 {
Len Brownde09cdd2017-02-28 16:32:44 -0500493 .name = "C1",
Len Brown85a4d2d2013-01-31 14:40:49 -0500494 .desc = "MWAIT 0x00",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100495 .flags = MWAIT2flg(0x00),
Len Brown85a4d2d2013-01-31 14:40:49 -0500496 .exit_latency = 2,
497 .target_residency = 2,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100498 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200499 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500500 {
Len Brownde09cdd2017-02-28 16:32:44 -0500501 .name = "C1E",
Len Brown32e95182013-02-02 01:31:56 -0500502 .desc = "MWAIT 0x01",
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +0100503 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
Len Brown32e95182013-02-02 01:31:56 -0500504 .exit_latency = 10,
505 .target_residency = 20,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100506 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200507 .enter_s2idle = intel_idle_s2idle, },
Len Brown32e95182013-02-02 01:31:56 -0500508 {
Len Brownde09cdd2017-02-28 16:32:44 -0500509 .name = "C3",
Len Brown85a4d2d2013-01-31 14:40:49 -0500510 .desc = "MWAIT 0x10",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100511 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown85a4d2d2013-01-31 14:40:49 -0500512 .exit_latency = 33,
513 .target_residency = 100,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100514 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200515 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500516 {
Len Brownde09cdd2017-02-28 16:32:44 -0500517 .name = "C6",
Len Brown85a4d2d2013-01-31 14:40:49 -0500518 .desc = "MWAIT 0x20",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100519 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown85a4d2d2013-01-31 14:40:49 -0500520 .exit_latency = 133,
521 .target_residency = 400,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100522 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200523 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500524 {
Len Brownde09cdd2017-02-28 16:32:44 -0500525 .name = "C7s",
Len Brown85a4d2d2013-01-31 14:40:49 -0500526 .desc = "MWAIT 0x32",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100527 .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown85a4d2d2013-01-31 14:40:49 -0500528 .exit_latency = 166,
529 .target_residency = 500,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100530 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200531 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500532 {
Len Brownde09cdd2017-02-28 16:32:44 -0500533 .name = "C8",
Len Brown86239ce2013-02-27 13:18:50 -0500534 .desc = "MWAIT 0x40",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100535 .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown86239ce2013-02-27 13:18:50 -0500536 .exit_latency = 300,
537 .target_residency = 900,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100538 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200539 .enter_s2idle = intel_idle_s2idle, },
Len Brown86239ce2013-02-27 13:18:50 -0500540 {
Len Brownde09cdd2017-02-28 16:32:44 -0500541 .name = "C9",
Len Brown86239ce2013-02-27 13:18:50 -0500542 .desc = "MWAIT 0x50",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100543 .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown86239ce2013-02-27 13:18:50 -0500544 .exit_latency = 600,
545 .target_residency = 1800,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100546 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200547 .enter_s2idle = intel_idle_s2idle, },
Len Brown86239ce2013-02-27 13:18:50 -0500548 {
Len Brownde09cdd2017-02-28 16:32:44 -0500549 .name = "C10",
Len Brown86239ce2013-02-27 13:18:50 -0500550 .desc = "MWAIT 0x60",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100551 .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown86239ce2013-02-27 13:18:50 -0500552 .exit_latency = 2600,
553 .target_residency = 7700,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100554 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200555 .enter_s2idle = intel_idle_s2idle, },
Len Brown86239ce2013-02-27 13:18:50 -0500556 {
Len Browne022e7e2013-02-01 23:37:30 -0500557 .enter = NULL }
Len Brown85a4d2d2013-01-31 14:40:49 -0500558};
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100559static struct cpuidle_state bdw_cstates[] __initdata = {
Len Browna138b562014-02-04 23:56:40 -0500560 {
Len Brownde09cdd2017-02-28 16:32:44 -0500561 .name = "C1",
Len Browna138b562014-02-04 23:56:40 -0500562 .desc = "MWAIT 0x00",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100563 .flags = MWAIT2flg(0x00),
Len Browna138b562014-02-04 23:56:40 -0500564 .exit_latency = 2,
565 .target_residency = 2,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100566 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200567 .enter_s2idle = intel_idle_s2idle, },
Len Browna138b562014-02-04 23:56:40 -0500568 {
Len Brownde09cdd2017-02-28 16:32:44 -0500569 .name = "C1E",
Len Browna138b562014-02-04 23:56:40 -0500570 .desc = "MWAIT 0x01",
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +0100571 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
Len Browna138b562014-02-04 23:56:40 -0500572 .exit_latency = 10,
573 .target_residency = 20,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100574 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200575 .enter_s2idle = intel_idle_s2idle, },
Len Browna138b562014-02-04 23:56:40 -0500576 {
Len Brownde09cdd2017-02-28 16:32:44 -0500577 .name = "C3",
Len Browna138b562014-02-04 23:56:40 -0500578 .desc = "MWAIT 0x10",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100579 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Browna138b562014-02-04 23:56:40 -0500580 .exit_latency = 40,
581 .target_residency = 100,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100582 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200583 .enter_s2idle = intel_idle_s2idle, },
Len Browna138b562014-02-04 23:56:40 -0500584 {
Len Brownde09cdd2017-02-28 16:32:44 -0500585 .name = "C6",
Len Browna138b562014-02-04 23:56:40 -0500586 .desc = "MWAIT 0x20",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100587 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Browna138b562014-02-04 23:56:40 -0500588 .exit_latency = 133,
589 .target_residency = 400,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100590 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200591 .enter_s2idle = intel_idle_s2idle, },
Len Browna138b562014-02-04 23:56:40 -0500592 {
Len Brownde09cdd2017-02-28 16:32:44 -0500593 .name = "C7s",
Len Browna138b562014-02-04 23:56:40 -0500594 .desc = "MWAIT 0x32",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100595 .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Browna138b562014-02-04 23:56:40 -0500596 .exit_latency = 166,
597 .target_residency = 500,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100598 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200599 .enter_s2idle = intel_idle_s2idle, },
Len Browna138b562014-02-04 23:56:40 -0500600 {
Len Brownde09cdd2017-02-28 16:32:44 -0500601 .name = "C8",
Len Browna138b562014-02-04 23:56:40 -0500602 .desc = "MWAIT 0x40",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100603 .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Browna138b562014-02-04 23:56:40 -0500604 .exit_latency = 300,
605 .target_residency = 900,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100606 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200607 .enter_s2idle = intel_idle_s2idle, },
Len Browna138b562014-02-04 23:56:40 -0500608 {
Len Brownde09cdd2017-02-28 16:32:44 -0500609 .name = "C9",
Len Browna138b562014-02-04 23:56:40 -0500610 .desc = "MWAIT 0x50",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100611 .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Browna138b562014-02-04 23:56:40 -0500612 .exit_latency = 600,
613 .target_residency = 1800,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100614 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200615 .enter_s2idle = intel_idle_s2idle, },
Len Browna138b562014-02-04 23:56:40 -0500616 {
Len Brownde09cdd2017-02-28 16:32:44 -0500617 .name = "C10",
Len Browna138b562014-02-04 23:56:40 -0500618 .desc = "MWAIT 0x60",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100619 .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Browna138b562014-02-04 23:56:40 -0500620 .exit_latency = 2600,
621 .target_residency = 7700,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100622 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200623 .enter_s2idle = intel_idle_s2idle, },
Len Browna138b562014-02-04 23:56:40 -0500624 {
625 .enter = NULL }
626};
Len Brown85a4d2d2013-01-31 14:40:49 -0500627
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100628static struct cpuidle_state skl_cstates[] __initdata = {
Len Brown493f1332015-03-25 23:20:37 -0400629 {
Len Brownde09cdd2017-02-28 16:32:44 -0500630 .name = "C1",
Len Brown493f1332015-03-25 23:20:37 -0400631 .desc = "MWAIT 0x00",
632 .flags = MWAIT2flg(0x00),
633 .exit_latency = 2,
634 .target_residency = 2,
635 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200636 .enter_s2idle = intel_idle_s2idle, },
Len Brown493f1332015-03-25 23:20:37 -0400637 {
Len Brownde09cdd2017-02-28 16:32:44 -0500638 .name = "C1E",
Len Brown493f1332015-03-25 23:20:37 -0400639 .desc = "MWAIT 0x01",
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +0100640 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
Len Brown493f1332015-03-25 23:20:37 -0400641 .exit_latency = 10,
642 .target_residency = 20,
643 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200644 .enter_s2idle = intel_idle_s2idle, },
Len Brown493f1332015-03-25 23:20:37 -0400645 {
Len Brownde09cdd2017-02-28 16:32:44 -0500646 .name = "C3",
Len Brown493f1332015-03-25 23:20:37 -0400647 .desc = "MWAIT 0x10",
648 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
649 .exit_latency = 70,
650 .target_residency = 100,
651 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200652 .enter_s2idle = intel_idle_s2idle, },
Len Brown493f1332015-03-25 23:20:37 -0400653 {
Len Brownde09cdd2017-02-28 16:32:44 -0500654 .name = "C6",
Len Brown493f1332015-03-25 23:20:37 -0400655 .desc = "MWAIT 0x20",
656 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown135919a2015-09-09 13:35:05 -0400657 .exit_latency = 85,
Len Brown493f1332015-03-25 23:20:37 -0400658 .target_residency = 200,
659 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200660 .enter_s2idle = intel_idle_s2idle, },
Len Brown493f1332015-03-25 23:20:37 -0400661 {
Len Brownde09cdd2017-02-28 16:32:44 -0500662 .name = "C7s",
Len Brown493f1332015-03-25 23:20:37 -0400663 .desc = "MWAIT 0x33",
664 .flags = MWAIT2flg(0x33) | CPUIDLE_FLAG_TLB_FLUSHED,
665 .exit_latency = 124,
666 .target_residency = 800,
667 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200668 .enter_s2idle = intel_idle_s2idle, },
Len Brown493f1332015-03-25 23:20:37 -0400669 {
Len Brownde09cdd2017-02-28 16:32:44 -0500670 .name = "C8",
Len Brown493f1332015-03-25 23:20:37 -0400671 .desc = "MWAIT 0x40",
672 .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown135919a2015-09-09 13:35:05 -0400673 .exit_latency = 200,
Len Brown493f1332015-03-25 23:20:37 -0400674 .target_residency = 800,
675 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200676 .enter_s2idle = intel_idle_s2idle, },
Len Brown493f1332015-03-25 23:20:37 -0400677 {
Len Brownde09cdd2017-02-28 16:32:44 -0500678 .name = "C9",
Len Brown135919a2015-09-09 13:35:05 -0400679 .desc = "MWAIT 0x50",
680 .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED,
681 .exit_latency = 480,
682 .target_residency = 5000,
683 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200684 .enter_s2idle = intel_idle_s2idle, },
Len Brown135919a2015-09-09 13:35:05 -0400685 {
Len Brownde09cdd2017-02-28 16:32:44 -0500686 .name = "C10",
Len Brown493f1332015-03-25 23:20:37 -0400687 .desc = "MWAIT 0x60",
688 .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
689 .exit_latency = 890,
690 .target_residency = 5000,
691 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200692 .enter_s2idle = intel_idle_s2idle, },
Len Brown493f1332015-03-25 23:20:37 -0400693 {
694 .enter = NULL }
695};
696
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100697static struct cpuidle_state skx_cstates[] __initdata = {
Len Brownf9e71652016-04-06 17:00:58 -0400698 {
Len Brownde09cdd2017-02-28 16:32:44 -0500699 .name = "C1",
Len Brownf9e71652016-04-06 17:00:58 -0400700 .desc = "MWAIT 0x00",
701 .flags = MWAIT2flg(0x00),
702 .exit_latency = 2,
703 .target_residency = 2,
704 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200705 .enter_s2idle = intel_idle_s2idle, },
Len Brownf9e71652016-04-06 17:00:58 -0400706 {
Len Brownde09cdd2017-02-28 16:32:44 -0500707 .name = "C1E",
Len Brownf9e71652016-04-06 17:00:58 -0400708 .desc = "MWAIT 0x01",
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +0100709 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
Len Brownf9e71652016-04-06 17:00:58 -0400710 .exit_latency = 10,
711 .target_residency = 20,
712 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200713 .enter_s2idle = intel_idle_s2idle, },
Len Brownf9e71652016-04-06 17:00:58 -0400714 {
Len Brownde09cdd2017-02-28 16:32:44 -0500715 .name = "C6",
Len Brownf9e71652016-04-06 17:00:58 -0400716 .desc = "MWAIT 0x20",
717 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
718 .exit_latency = 133,
719 .target_residency = 600,
720 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200721 .enter_s2idle = intel_idle_s2idle, },
Len Brownf9e71652016-04-06 17:00:58 -0400722 {
723 .enter = NULL }
724};
725
Chen Yua472ad22020-07-10 12:12:01 +0800726static struct cpuidle_state icx_cstates[] __initdata = {
727 {
728 .name = "C1",
729 .desc = "MWAIT 0x00",
730 .flags = MWAIT2flg(0x00),
731 .exit_latency = 1,
732 .target_residency = 1,
733 .enter = &intel_idle,
734 .enter_s2idle = intel_idle_s2idle, },
735 {
736 .name = "C1E",
737 .desc = "MWAIT 0x01",
738 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
739 .exit_latency = 4,
740 .target_residency = 4,
741 .enter = &intel_idle,
742 .enter_s2idle = intel_idle_s2idle, },
743 {
744 .name = "C6",
745 .desc = "MWAIT 0x20",
746 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
Artem Bityutskiyd484b8b2021-03-08 16:31:46 +0200747 .exit_latency = 170,
748 .target_residency = 600,
Chen Yua472ad22020-07-10 12:12:01 +0800749 .enter = &intel_idle,
750 .enter_s2idle = intel_idle_s2idle, },
751 {
752 .enter = NULL }
753};
754
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100755static struct cpuidle_state atom_cstates[] __initdata = {
Len Browne022e7e2013-02-01 23:37:30 -0500756 {
Len Brownde09cdd2017-02-28 16:32:44 -0500757 .name = "C1E",
Len Brown26717172010-03-08 14:07:30 -0500758 .desc = "MWAIT 0x00",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100759 .flags = MWAIT2flg(0x00),
Len Brown32e95182013-02-02 01:31:56 -0500760 .exit_latency = 10,
761 .target_residency = 20,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100762 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200763 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500764 {
Len Brownde09cdd2017-02-28 16:32:44 -0500765 .name = "C2",
Len Brown26717172010-03-08 14:07:30 -0500766 .desc = "MWAIT 0x10",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100767 .flags = MWAIT2flg(0x10),
Len Brown26717172010-03-08 14:07:30 -0500768 .exit_latency = 20,
Len Brown26717172010-03-08 14:07:30 -0500769 .target_residency = 80,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100770 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200771 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500772 {
Len Brownde09cdd2017-02-28 16:32:44 -0500773 .name = "C4",
Len Brown26717172010-03-08 14:07:30 -0500774 .desc = "MWAIT 0x30",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100775 .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown26717172010-03-08 14:07:30 -0500776 .exit_latency = 100,
Len Brown26717172010-03-08 14:07:30 -0500777 .target_residency = 400,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100778 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200779 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500780 {
Len Brownde09cdd2017-02-28 16:32:44 -0500781 .name = "C6",
Len Brown7fcca7d2010-10-05 13:43:14 -0400782 .desc = "MWAIT 0x52",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100783 .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brown7fcca7d2010-10-05 13:43:14 -0400784 .exit_latency = 140,
Len Brown7fcca7d2010-10-05 13:43:14 -0400785 .target_residency = 560,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100786 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200787 .enter_s2idle = intel_idle_s2idle, },
Len Browne022e7e2013-02-01 23:37:30 -0500788 {
789 .enter = NULL }
Len Brown26717172010-03-08 14:07:30 -0500790};
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100791static struct cpuidle_state tangier_cstates[] __initdata = {
Andy Shevchenko5e7ec262016-10-25 17:11:39 +0300792 {
Len Brownde09cdd2017-02-28 16:32:44 -0500793 .name = "C1",
Andy Shevchenko5e7ec262016-10-25 17:11:39 +0300794 .desc = "MWAIT 0x00",
795 .flags = MWAIT2flg(0x00),
796 .exit_latency = 1,
797 .target_residency = 4,
798 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200799 .enter_s2idle = intel_idle_s2idle, },
Andy Shevchenko5e7ec262016-10-25 17:11:39 +0300800 {
Len Brownde09cdd2017-02-28 16:32:44 -0500801 .name = "C4",
Andy Shevchenko5e7ec262016-10-25 17:11:39 +0300802 .desc = "MWAIT 0x30",
803 .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED,
804 .exit_latency = 100,
805 .target_residency = 400,
806 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200807 .enter_s2idle = intel_idle_s2idle, },
Andy Shevchenko5e7ec262016-10-25 17:11:39 +0300808 {
Len Brownde09cdd2017-02-28 16:32:44 -0500809 .name = "C6",
Andy Shevchenko5e7ec262016-10-25 17:11:39 +0300810 .desc = "MWAIT 0x52",
811 .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED,
812 .exit_latency = 140,
813 .target_residency = 560,
814 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200815 .enter_s2idle = intel_idle_s2idle, },
Andy Shevchenko5e7ec262016-10-25 17:11:39 +0300816 {
Len Brownde09cdd2017-02-28 16:32:44 -0500817 .name = "C7",
Andy Shevchenko5e7ec262016-10-25 17:11:39 +0300818 .desc = "MWAIT 0x60",
819 .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
820 .exit_latency = 1200,
821 .target_residency = 4000,
822 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200823 .enter_s2idle = intel_idle_s2idle, },
Andy Shevchenko5e7ec262016-10-25 17:11:39 +0300824 {
Len Brownde09cdd2017-02-28 16:32:44 -0500825 .name = "C9",
Andy Shevchenko5e7ec262016-10-25 17:11:39 +0300826 .desc = "MWAIT 0x64",
827 .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED,
828 .exit_latency = 10000,
829 .target_residency = 20000,
830 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200831 .enter_s2idle = intel_idle_s2idle, },
Andy Shevchenko5e7ec262016-10-25 17:11:39 +0300832 {
833 .enter = NULL }
834};
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100835static struct cpuidle_state avn_cstates[] __initdata = {
Len Brownfab04b22013-11-09 00:30:17 -0500836 {
Len Brownde09cdd2017-02-28 16:32:44 -0500837 .name = "C1",
Len Brownfab04b22013-11-09 00:30:17 -0500838 .desc = "MWAIT 0x00",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100839 .flags = MWAIT2flg(0x00),
Len Brownfab04b22013-11-09 00:30:17 -0500840 .exit_latency = 2,
841 .target_residency = 2,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100842 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200843 .enter_s2idle = intel_idle_s2idle, },
Len Brownfab04b22013-11-09 00:30:17 -0500844 {
Len Brownde09cdd2017-02-28 16:32:44 -0500845 .name = "C6",
Len Brownfab04b22013-11-09 00:30:17 -0500846 .desc = "MWAIT 0x51",
Daniel Lezcanob82b6cc2014-11-12 16:03:50 +0100847 .flags = MWAIT2flg(0x51) | CPUIDLE_FLAG_TLB_FLUSHED,
Len Brownfab04b22013-11-09 00:30:17 -0500848 .exit_latency = 15,
849 .target_residency = 45,
Rafael J. Wysocki5fe2e522015-02-11 05:04:17 +0100850 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200851 .enter_s2idle = intel_idle_s2idle, },
Jiang Liu88390992014-01-09 15:30:27 +0800852 {
853 .enter = NULL }
Len Brownfab04b22013-11-09 00:30:17 -0500854};
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100855static struct cpuidle_state knl_cstates[] __initdata = {
Dasaratharaman Chandramouli281baf72014-09-04 17:22:54 -0700856 {
Len Brownde09cdd2017-02-28 16:32:44 -0500857 .name = "C1",
Dasaratharaman Chandramouli281baf72014-09-04 17:22:54 -0700858 .desc = "MWAIT 0x00",
859 .flags = MWAIT2flg(0x00),
860 .exit_latency = 1,
861 .target_residency = 2,
862 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200863 .enter_s2idle = intel_idle_s2idle },
Dasaratharaman Chandramouli281baf72014-09-04 17:22:54 -0700864 {
Len Brownde09cdd2017-02-28 16:32:44 -0500865 .name = "C6",
Dasaratharaman Chandramouli281baf72014-09-04 17:22:54 -0700866 .desc = "MWAIT 0x10",
867 .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
868 .exit_latency = 120,
869 .target_residency = 500,
870 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200871 .enter_s2idle = intel_idle_s2idle },
Dasaratharaman Chandramouli281baf72014-09-04 17:22:54 -0700872 {
873 .enter = NULL }
874};
Len Brown26717172010-03-08 14:07:30 -0500875
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100876static struct cpuidle_state bxt_cstates[] __initdata = {
Len Brown5dcef692016-04-06 17:00:47 -0400877 {
Len Brownde09cdd2017-02-28 16:32:44 -0500878 .name = "C1",
Len Brown5dcef692016-04-06 17:00:47 -0400879 .desc = "MWAIT 0x00",
880 .flags = MWAIT2flg(0x00),
881 .exit_latency = 2,
882 .target_residency = 2,
883 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200884 .enter_s2idle = intel_idle_s2idle, },
Len Brown5dcef692016-04-06 17:00:47 -0400885 {
Len Brownde09cdd2017-02-28 16:32:44 -0500886 .name = "C1E",
Len Brown5dcef692016-04-06 17:00:47 -0400887 .desc = "MWAIT 0x01",
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +0100888 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
Len Brown5dcef692016-04-06 17:00:47 -0400889 .exit_latency = 10,
890 .target_residency = 20,
891 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200892 .enter_s2idle = intel_idle_s2idle, },
Len Brown5dcef692016-04-06 17:00:47 -0400893 {
Len Brownde09cdd2017-02-28 16:32:44 -0500894 .name = "C6",
Len Brown5dcef692016-04-06 17:00:47 -0400895 .desc = "MWAIT 0x20",
896 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
897 .exit_latency = 133,
898 .target_residency = 133,
899 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200900 .enter_s2idle = intel_idle_s2idle, },
Len Brown5dcef692016-04-06 17:00:47 -0400901 {
Len Brownde09cdd2017-02-28 16:32:44 -0500902 .name = "C7s",
Len Brown5dcef692016-04-06 17:00:47 -0400903 .desc = "MWAIT 0x31",
904 .flags = MWAIT2flg(0x31) | CPUIDLE_FLAG_TLB_FLUSHED,
905 .exit_latency = 155,
906 .target_residency = 155,
907 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200908 .enter_s2idle = intel_idle_s2idle, },
Len Brown5dcef692016-04-06 17:00:47 -0400909 {
Len Brownde09cdd2017-02-28 16:32:44 -0500910 .name = "C8",
Len Brown5dcef692016-04-06 17:00:47 -0400911 .desc = "MWAIT 0x40",
912 .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED,
913 .exit_latency = 1000,
914 .target_residency = 1000,
915 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200916 .enter_s2idle = intel_idle_s2idle, },
Len Brown5dcef692016-04-06 17:00:47 -0400917 {
Len Brownde09cdd2017-02-28 16:32:44 -0500918 .name = "C9",
Len Brown5dcef692016-04-06 17:00:47 -0400919 .desc = "MWAIT 0x50",
920 .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED,
921 .exit_latency = 2000,
922 .target_residency = 2000,
923 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200924 .enter_s2idle = intel_idle_s2idle, },
Len Brown5dcef692016-04-06 17:00:47 -0400925 {
Len Brownde09cdd2017-02-28 16:32:44 -0500926 .name = "C10",
Len Brown5dcef692016-04-06 17:00:47 -0400927 .desc = "MWAIT 0x60",
928 .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED,
929 .exit_latency = 10000,
930 .target_residency = 10000,
931 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200932 .enter_s2idle = intel_idle_s2idle, },
Len Brown5dcef692016-04-06 17:00:47 -0400933 {
934 .enter = NULL }
935};
936
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100937static struct cpuidle_state dnv_cstates[] __initdata = {
Jacob Pan0080d652016-06-17 01:28:34 -0400938 {
Len Brownde09cdd2017-02-28 16:32:44 -0500939 .name = "C1",
Jacob Pan0080d652016-06-17 01:28:34 -0400940 .desc = "MWAIT 0x00",
941 .flags = MWAIT2flg(0x00),
942 .exit_latency = 2,
943 .target_residency = 2,
944 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200945 .enter_s2idle = intel_idle_s2idle, },
Jacob Pan0080d652016-06-17 01:28:34 -0400946 {
Len Brownde09cdd2017-02-28 16:32:44 -0500947 .name = "C1E",
Jacob Pan0080d652016-06-17 01:28:34 -0400948 .desc = "MWAIT 0x01",
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +0100949 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
Jacob Pan0080d652016-06-17 01:28:34 -0400950 .exit_latency = 10,
951 .target_residency = 20,
952 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200953 .enter_s2idle = intel_idle_s2idle, },
Jacob Pan0080d652016-06-17 01:28:34 -0400954 {
Len Brownde09cdd2017-02-28 16:32:44 -0500955 .name = "C6",
Jacob Pan0080d652016-06-17 01:28:34 -0400956 .desc = "MWAIT 0x20",
957 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
958 .exit_latency = 50,
959 .target_residency = 500,
960 .enter = &intel_idle,
Rafael J. Wysocki28ba0862017-08-10 00:14:45 +0200961 .enter_s2idle = intel_idle_s2idle, },
Jacob Pan0080d652016-06-17 01:28:34 -0400962 {
963 .enter = NULL }
964};
965
Artem Bityutskiy9cf93f052020-12-27 12:11:16 +0200966/*
967 * Note, depending on HW and FW revision, SnowRidge SoC may or may not support
968 * C6, and this is indicated in the CPUID mwait leaf.
969 */
970static struct cpuidle_state snr_cstates[] __initdata = {
971 {
972 .name = "C1",
973 .desc = "MWAIT 0x00",
974 .flags = MWAIT2flg(0x00),
975 .exit_latency = 2,
976 .target_residency = 2,
977 .enter = &intel_idle,
978 .enter_s2idle = intel_idle_s2idle, },
979 {
980 .name = "C1E",
981 .desc = "MWAIT 0x01",
982 .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
983 .exit_latency = 15,
984 .target_residency = 25,
985 .enter = &intel_idle,
986 .enter_s2idle = intel_idle_s2idle, },
987 {
988 .name = "C6",
989 .desc = "MWAIT 0x20",
990 .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
991 .exit_latency = 130,
992 .target_residency = 500,
993 .enter = &intel_idle,
994 .enter_s2idle = intel_idle_s2idle, },
995 {
996 .enter = NULL }
997};
998
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +0100999static const struct idle_cpu idle_cpu_nehalem __initconst = {
Andi Kleenb66b8b92012-01-26 00:09:07 +01001000 .state_table = nehalem_cstates,
Andi Kleenb66b8b92012-01-26 00:09:07 +01001001 .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE,
Len Brown32e95182013-02-02 01:31:56 -05001002 .disable_promotion_to_c1e = true,
Andi Kleenb66b8b92012-01-26 00:09:07 +01001003};
1004
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001005static const struct idle_cpu idle_cpu_nhx __initconst = {
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +01001006 .state_table = nehalem_cstates,
1007 .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE,
1008 .disable_promotion_to_c1e = true,
1009 .use_acpi = true,
1010};
1011
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001012static const struct idle_cpu idle_cpu_atom __initconst = {
Andi Kleenb66b8b92012-01-26 00:09:07 +01001013 .state_table = atom_cstates,
1014};
1015
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001016static const struct idle_cpu idle_cpu_tangier __initconst = {
Andy Shevchenko5e7ec262016-10-25 17:11:39 +03001017 .state_table = tangier_cstates,
1018};
1019
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001020static const struct idle_cpu idle_cpu_lincroft __initconst = {
Andi Kleenb66b8b92012-01-26 00:09:07 +01001021 .state_table = atom_cstates,
1022 .auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE,
1023};
1024
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001025static const struct idle_cpu idle_cpu_snb __initconst = {
Andi Kleenb66b8b92012-01-26 00:09:07 +01001026 .state_table = snb_cstates,
Len Brown32e95182013-02-02 01:31:56 -05001027 .disable_promotion_to_c1e = true,
Andi Kleenb66b8b92012-01-26 00:09:07 +01001028};
1029
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001030static const struct idle_cpu idle_cpu_snx __initconst = {
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +01001031 .state_table = snb_cstates,
1032 .disable_promotion_to_c1e = true,
1033 .use_acpi = true,
1034};
1035
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001036static const struct idle_cpu idle_cpu_byt __initconst = {
Len Brown718987d2014-02-14 02:30:00 -05001037 .state_table = byt_cstates,
1038 .disable_promotion_to_c1e = true,
Len Brown8c058d532014-07-31 15:21:24 -04001039 .byt_auto_demotion_disable_flag = true,
Len Brown718987d2014-02-14 02:30:00 -05001040};
1041
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001042static const struct idle_cpu idle_cpu_cht __initconst = {
Len Browncab07a52015-03-27 20:54:01 -04001043 .state_table = cht_cstates,
1044 .disable_promotion_to_c1e = true,
1045 .byt_auto_demotion_disable_flag = true,
1046};
1047
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001048static const struct idle_cpu idle_cpu_ivb __initconst = {
Len Brown6edab082012-06-01 19:45:32 -04001049 .state_table = ivb_cstates,
Len Brown32e95182013-02-02 01:31:56 -05001050 .disable_promotion_to_c1e = true,
Len Brown6edab082012-06-01 19:45:32 -04001051};
1052
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001053static const struct idle_cpu idle_cpu_ivt __initconst = {
Len Brown0138d8f2014-04-04 01:21:07 -04001054 .state_table = ivt_cstates,
1055 .disable_promotion_to_c1e = true,
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +01001056 .use_acpi = true,
Len Brown0138d8f2014-04-04 01:21:07 -04001057};
1058
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001059static const struct idle_cpu idle_cpu_hsw __initconst = {
Len Brown85a4d2d2013-01-31 14:40:49 -05001060 .state_table = hsw_cstates,
Len Brown32e95182013-02-02 01:31:56 -05001061 .disable_promotion_to_c1e = true,
Len Brown85a4d2d2013-01-31 14:40:49 -05001062};
1063
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001064static const struct idle_cpu idle_cpu_hsx __initconst = {
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +01001065 .state_table = hsw_cstates,
1066 .disable_promotion_to_c1e = true,
1067 .use_acpi = true,
1068};
1069
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001070static const struct idle_cpu idle_cpu_bdw __initconst = {
Len Browna138b562014-02-04 23:56:40 -05001071 .state_table = bdw_cstates,
1072 .disable_promotion_to_c1e = true,
1073};
1074
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001075static const struct idle_cpu idle_cpu_bdx __initconst = {
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +01001076 .state_table = bdw_cstates,
1077 .disable_promotion_to_c1e = true,
1078 .use_acpi = true,
1079};
1080
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001081static const struct idle_cpu idle_cpu_skl __initconst = {
Len Brown493f1332015-03-25 23:20:37 -04001082 .state_table = skl_cstates,
1083 .disable_promotion_to_c1e = true,
1084};
1085
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001086static const struct idle_cpu idle_cpu_skx __initconst = {
Len Brownf9e71652016-04-06 17:00:58 -04001087 .state_table = skx_cstates,
1088 .disable_promotion_to_c1e = true,
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +01001089 .use_acpi = true,
Len Brownf9e71652016-04-06 17:00:58 -04001090};
Len Brown493f1332015-03-25 23:20:37 -04001091
Chen Yua472ad22020-07-10 12:12:01 +08001092static const struct idle_cpu idle_cpu_icx __initconst = {
1093 .state_table = icx_cstates,
1094 .disable_promotion_to_c1e = true,
1095 .use_acpi = true,
1096};
1097
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001098static const struct idle_cpu idle_cpu_avn __initconst = {
Len Brownfab04b22013-11-09 00:30:17 -05001099 .state_table = avn_cstates,
1100 .disable_promotion_to_c1e = true,
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +01001101 .use_acpi = true,
Len Brownfab04b22013-11-09 00:30:17 -05001102};
1103
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001104static const struct idle_cpu idle_cpu_knl __initconst = {
Dasaratharaman Chandramouli281baf72014-09-04 17:22:54 -07001105 .state_table = knl_cstates,
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +01001106 .use_acpi = true,
Dasaratharaman Chandramouli281baf72014-09-04 17:22:54 -07001107};
1108
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001109static const struct idle_cpu idle_cpu_bxt __initconst = {
Len Brown5dcef692016-04-06 17:00:47 -04001110 .state_table = bxt_cstates,
1111 .disable_promotion_to_c1e = true,
1112};
1113
Rafael J. Wysockiab1a85222020-02-06 18:45:06 +01001114static const struct idle_cpu idle_cpu_dnv __initconst = {
Jacob Pan0080d652016-06-17 01:28:34 -04001115 .state_table = dnv_cstates,
1116 .disable_promotion_to_c1e = true,
Rafael J. Wysockie6d4f082019-12-13 09:56:38 +01001117 .use_acpi = true,
Jacob Pan0080d652016-06-17 01:28:34 -04001118};
1119
Artem Bityutskiy9cf93f052020-12-27 12:11:16 +02001120static const struct idle_cpu idle_cpu_snr __initconst = {
1121 .state_table = snr_cstates,
1122 .disable_promotion_to_c1e = true,
1123 .use_acpi = true,
1124};
1125
Mathias Kraused5cdc3c2015-03-25 22:15:14 +01001126static const struct x86_cpu_id intel_idle_ids[] __initconst = {
Thomas Gleixner4a9f45a2020-03-20 14:14:00 +01001127 X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EP, &idle_cpu_nhx),
1128 X86_MATCH_INTEL_FAM6_MODEL(NEHALEM, &idle_cpu_nehalem),
1129 X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_G, &idle_cpu_nehalem),
1130 X86_MATCH_INTEL_FAM6_MODEL(WESTMERE, &idle_cpu_nehalem),
1131 X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EP, &idle_cpu_nhx),
1132 X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EX, &idle_cpu_nhx),
1133 X86_MATCH_INTEL_FAM6_MODEL(ATOM_BONNELL, &idle_cpu_atom),
1134 X86_MATCH_INTEL_FAM6_MODEL(ATOM_BONNELL_MID, &idle_cpu_lincroft),
1135 X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EX, &idle_cpu_nhx),
1136 X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE, &idle_cpu_snb),
1137 X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE_X, &idle_cpu_snx),
1138 X86_MATCH_INTEL_FAM6_MODEL(ATOM_SALTWELL, &idle_cpu_atom),
1139 X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT, &idle_cpu_byt),
1140 X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_MID, &idle_cpu_tangier),
1141 X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT, &idle_cpu_cht),
1142 X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE, &idle_cpu_ivb),
1143 X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE_X, &idle_cpu_ivt),
1144 X86_MATCH_INTEL_FAM6_MODEL(HASWELL, &idle_cpu_hsw),
1145 X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, &idle_cpu_hsx),
1146 X86_MATCH_INTEL_FAM6_MODEL(HASWELL_L, &idle_cpu_hsw),
1147 X86_MATCH_INTEL_FAM6_MODEL(HASWELL_G, &idle_cpu_hsw),
1148 X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_D, &idle_cpu_avn),
1149 X86_MATCH_INTEL_FAM6_MODEL(BROADWELL, &idle_cpu_bdw),
1150 X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_G, &idle_cpu_bdw),
1151 X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, &idle_cpu_bdx),
1152 X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D, &idle_cpu_bdx),
1153 X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, &idle_cpu_skl),
1154 X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, &idle_cpu_skl),
1155 X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, &idle_cpu_skl),
1156 X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, &idle_cpu_skl),
1157 X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &idle_cpu_skx),
Chen Yua472ad22020-07-10 12:12:01 +08001158 X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &idle_cpu_icx),
Artem Bityutskiy22141d52021-04-07 09:10:28 +03001159 X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &idle_cpu_icx),
Thomas Gleixner4a9f45a2020-03-20 14:14:00 +01001160 X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &idle_cpu_knl),
1161 X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &idle_cpu_knl),
1162 X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &idle_cpu_bxt),
1163 X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS, &idle_cpu_bxt),
1164 X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D, &idle_cpu_dnv),
Artem Bityutskiy9cf93f052020-12-27 12:11:16 +02001165 X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &idle_cpu_snr),
Andi Kleenb66b8b92012-01-26 00:09:07 +01001166 {}
1167};
Andi Kleenb66b8b92012-01-26 00:09:07 +01001168
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001169static const struct x86_cpu_id intel_mwait_ids[] __initconst = {
Thomas Gleixner4a9f45a2020-03-20 14:14:00 +01001170 X86_MATCH_VENDOR_FAM_FEATURE(INTEL, 6, X86_FEATURE_MWAIT, NULL),
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001171 {}
1172};
1173
Rafael J. Wysocki095928a2020-01-10 11:51:22 +01001174static bool __init intel_idle_max_cstate_reached(int cstate)
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001175{
1176 if (cstate + 1 > max_cstate) {
1177 pr_info("max_cstate %d reached\n", max_cstate);
1178 return true;
1179 }
1180 return false;
1181}
1182
Peter Zijlstra4d916142020-11-30 12:54:34 +01001183static bool __init intel_idle_state_needs_timer_stop(struct cpuidle_state *state)
1184{
1185 unsigned long eax = flg2MWAIT(state->flags);
1186
1187 if (boot_cpu_has(X86_FEATURE_ARAT))
1188 return false;
1189
1190 /*
1191 * Switch over to one-shot tick broadcast if the target C-state
1192 * is deeper than C1.
1193 */
1194 return !!((eax >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK);
1195}
1196
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001197#ifdef CONFIG_ACPI_PROCESSOR_CSTATE
1198#include <acpi/processor.h>
1199
Rafael J. Wysocki4ec32d92019-12-13 09:56:29 +01001200static bool no_acpi __read_mostly;
1201module_param(no_acpi, bool, 0444);
1202MODULE_PARM_DESC(no_acpi, "Do not use ACPI _CST for building the idle states list");
1203
Rafael J. Wysocki3a5be9b2020-02-03 11:57:08 +01001204static bool force_use_acpi __read_mostly; /* No effect if no_acpi is set. */
1205module_param_named(use_acpi, force_use_acpi, bool, 0444);
1206MODULE_PARM_DESC(use_acpi, "Use ACPI _CST for building the idle states list");
1207
Rafael J. Wysocki095928a2020-01-10 11:51:22 +01001208static struct acpi_processor_power acpi_state_table __initdata;
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001209
1210/**
1211 * intel_idle_cst_usable - Check if the _CST information can be used.
1212 *
1213 * Check if all of the C-states listed by _CST in the max_cstate range are
1214 * ACPI_CSTATE_FFH, which means that they should be entered via MWAIT.
1215 */
Rafael J. Wysocki095928a2020-01-10 11:51:22 +01001216static bool __init intel_idle_cst_usable(void)
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001217{
1218 int cstate, limit;
1219
1220 limit = min_t(int, min_t(int, CPUIDLE_STATE_MAX, max_cstate + 1),
1221 acpi_state_table.count);
1222
1223 for (cstate = 1; cstate < limit; cstate++) {
1224 struct acpi_processor_cx *cx = &acpi_state_table.states[cstate];
1225
1226 if (cx->entry_method != ACPI_CSTATE_FFH)
1227 return false;
1228 }
1229
1230 return true;
1231}
1232
Rafael J. Wysocki095928a2020-01-10 11:51:22 +01001233static bool __init intel_idle_acpi_cst_extract(void)
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001234{
1235 unsigned int cpu;
1236
Rafael J. Wysocki4ec32d92019-12-13 09:56:29 +01001237 if (no_acpi) {
1238 pr_debug("Not allowed to use ACPI _CST\n");
1239 return false;
1240 }
1241
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001242 for_each_possible_cpu(cpu) {
1243 struct acpi_processor *pr = per_cpu(processors, cpu);
1244
1245 if (!pr)
1246 continue;
1247
1248 if (acpi_processor_evaluate_cst(pr->handle, cpu, &acpi_state_table))
1249 continue;
1250
1251 acpi_state_table.count++;
1252
1253 if (!intel_idle_cst_usable())
1254 continue;
1255
Mel Gorman75af76d2020-10-16 17:28:32 +02001256 if (!acpi_processor_claim_cst_control())
1257 break;
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001258
1259 return true;
1260 }
1261
Mel Gorman75af76d2020-10-16 17:28:32 +02001262 acpi_state_table.count = 0;
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001263 pr_debug("ACPI _CST not found or not usable\n");
1264 return false;
1265}
1266
Rafael J. Wysocki095928a2020-01-10 11:51:22 +01001267static void __init intel_idle_init_cstates_acpi(struct cpuidle_driver *drv)
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001268{
1269 int cstate, limit = min_t(int, CPUIDLE_STATE_MAX, acpi_state_table.count);
1270
1271 /*
1272 * If limit > 0, intel_idle_cst_usable() has returned 'true', so all of
1273 * the interesting states are ACPI_CSTATE_FFH.
1274 */
1275 for (cstate = 1; cstate < limit; cstate++) {
1276 struct acpi_processor_cx *cx;
1277 struct cpuidle_state *state;
1278
Chen Yu4e0ba552020-10-25 00:29:53 +08001279 if (intel_idle_max_cstate_reached(cstate - 1))
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001280 break;
1281
1282 cx = &acpi_state_table.states[cstate];
1283
1284 state = &drv->states[drv->state_count++];
1285
1286 snprintf(state->name, CPUIDLE_NAME_LEN, "C%d_ACPI", cstate);
1287 strlcpy(state->desc, cx->desc, CPUIDLE_DESC_LEN);
1288 state->exit_latency = cx->latency;
1289 /*
1290 * For C1-type C-states use the same number for both the exit
1291 * latency and target residency, because that is the case for
1292 * C1 in the majority of the static C-states tables above.
1293 * For the other types of C-states, however, set the target
1294 * residency to 3 times the exit latency which should lead to
1295 * a reasonable balance between energy-efficiency and
1296 * performance in the majority of interesting cases.
1297 */
1298 state->target_residency = cx->latency;
1299 if (cx->type > ACPI_STATE_C1)
1300 state->target_residency *= 3;
1301
1302 state->flags = MWAIT2flg(cx->address);
1303 if (cx->type > ACPI_STATE_C2)
1304 state->flags |= CPUIDLE_FLAG_TLB_FLUSHED;
1305
Rafael J. Wysocki4dcb78e2020-02-03 11:57:18 +01001306 if (disabled_states_mask & BIT(cstate))
1307 state->flags |= CPUIDLE_FLAG_OFF;
1308
Peter Zijlstra6e1d2bc2020-11-20 11:28:35 +01001309 if (intel_idle_state_needs_timer_stop(state))
1310 state->flags |= CPUIDLE_FLAG_TIMER_STOP;
1311
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001312 state->enter = intel_idle;
1313 state->enter_s2idle = intel_idle_s2idle;
1314 }
1315}
Rafael J. Wysockibff8e602019-12-13 09:56:21 +01001316
Rafael J. Wysocki095928a2020-01-10 11:51:22 +01001317static bool __init intel_idle_off_by_default(u32 mwait_hint)
Rafael J. Wysockibff8e602019-12-13 09:56:21 +01001318{
1319 int cstate, limit;
1320
1321 /*
1322 * If there are no _CST C-states, do not disable any C-states by
1323 * default.
1324 */
1325 if (!acpi_state_table.count)
1326 return false;
1327
1328 limit = min_t(int, CPUIDLE_STATE_MAX, acpi_state_table.count);
1329 /*
1330 * If limit > 0, intel_idle_cst_usable() has returned 'true', so all of
1331 * the interesting states are ACPI_CSTATE_FFH.
1332 */
1333 for (cstate = 1; cstate < limit; cstate++) {
1334 if (acpi_state_table.states[cstate].address == mwait_hint)
1335 return false;
1336 }
1337 return true;
1338}
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001339#else /* !CONFIG_ACPI_PROCESSOR_CSTATE */
Rafael J. Wysocki3a5be9b2020-02-03 11:57:08 +01001340#define force_use_acpi (false)
1341
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001342static inline bool intel_idle_acpi_cst_extract(void) { return false; }
1343static inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { }
Rafael J. Wysockibff8e602019-12-13 09:56:21 +01001344static inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; }
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001345#endif /* !CONFIG_ACPI_PROCESSOR_CSTATE */
1346
Rafael J. Wysocki6eacb152020-02-06 18:45:29 +01001347/**
1348 * ivt_idle_state_table_update - Tune the idle states table for Ivy Town.
Len Brownd70e28f2016-03-13 00:33:48 -05001349 *
Rafael J. Wysocki6eacb152020-02-06 18:45:29 +01001350 * Tune IVT multi-socket targets.
1351 * Assumption: num_sockets == (max_package_num + 1).
Len Brownd70e28f2016-03-13 00:33:48 -05001352 */
Rafael J. Wysocki095928a2020-01-10 11:51:22 +01001353static void __init ivt_idle_state_table_update(void)
Len Brownd70e28f2016-03-13 00:33:48 -05001354{
1355 /* IVT uses a different table for 1-2, 3-4, and > 4 sockets */
1356 int cpu, package_num, num_sockets = 1;
1357
1358 for_each_online_cpu(cpu) {
1359 package_num = topology_physical_package_id(cpu);
1360 if (package_num + 1 > num_sockets) {
1361 num_sockets = package_num + 1;
1362
1363 if (num_sockets > 4) {
1364 cpuidle_state_table = ivt_cstates_8s;
1365 return;
1366 }
1367 }
1368 }
1369
1370 if (num_sockets > 2)
1371 cpuidle_state_table = ivt_cstates_4s;
1372
1373 /* else, 1 and 2 socket systems use default ivt_cstates */
1374}
Len Brown5dcef692016-04-06 17:00:47 -04001375
Rafael J. Wysocki86e94662020-01-17 11:46:24 +01001376/**
1377 * irtl_2_usec - IRTL to microseconds conversion.
1378 * @irtl: IRTL MSR value.
1379 *
1380 * Translate the IRTL (Interrupt Response Time Limit) MSR value to microseconds.
Len Brown5dcef692016-04-06 17:00:47 -04001381 */
Rafael J. Wysocki095928a2020-01-10 11:51:22 +01001382static unsigned long long __init irtl_2_usec(unsigned long long irtl)
Len Brown5dcef692016-04-06 17:00:47 -04001383{
Rafael J. Wysocki86e94662020-01-17 11:46:24 +01001384 static const unsigned int irtl_ns_units[] __initconst = {
1385 1, 32, 1024, 32768, 1048576, 33554432, 0, 0
1386 };
Len Brown5dcef692016-04-06 17:00:47 -04001387 unsigned long long ns;
1388
Jan Beulich3451ab32016-06-27 00:35:12 -06001389 if (!irtl)
1390 return 0;
1391
Jan Beulichbef45092016-06-27 00:35:48 -06001392 ns = irtl_ns_units[(irtl >> 10) & 0x7];
Len Brown5dcef692016-04-06 17:00:47 -04001393
Rafael J. Wysocki86e94662020-01-17 11:46:24 +01001394 return div_u64((irtl & 0x3FF) * ns, NSEC_PER_USEC);
Len Brown5dcef692016-04-06 17:00:47 -04001395}
Rafael J. Wysocki86e94662020-01-17 11:46:24 +01001396
Rafael J. Wysocki6eacb152020-02-06 18:45:29 +01001397/**
1398 * bxt_idle_state_table_update - Fix up the Broxton idle states table.
Len Brown5dcef692016-04-06 17:00:47 -04001399 *
Rafael J. Wysocki6eacb152020-02-06 18:45:29 +01001400 * On BXT, trust the IRTL (Interrupt Response Time Limit) MSR to show the
1401 * definitive maximum latency and use the same value for target_residency.
Len Brown5dcef692016-04-06 17:00:47 -04001402 */
Rafael J. Wysocki095928a2020-01-10 11:51:22 +01001403static void __init bxt_idle_state_table_update(void)
Len Brown5dcef692016-04-06 17:00:47 -04001404{
1405 unsigned long long msr;
Jan Beulich3451ab32016-06-27 00:35:12 -06001406 unsigned int usec;
Len Brown5dcef692016-04-06 17:00:47 -04001407
1408 rdmsrl(MSR_PKGC6_IRTL, msr);
Jan Beulich3451ab32016-06-27 00:35:12 -06001409 usec = irtl_2_usec(msr);
1410 if (usec) {
Len Brown5dcef692016-04-06 17:00:47 -04001411 bxt_cstates[2].exit_latency = usec;
1412 bxt_cstates[2].target_residency = usec;
1413 }
1414
1415 rdmsrl(MSR_PKGC7_IRTL, msr);
Jan Beulich3451ab32016-06-27 00:35:12 -06001416 usec = irtl_2_usec(msr);
1417 if (usec) {
Len Brown5dcef692016-04-06 17:00:47 -04001418 bxt_cstates[3].exit_latency = usec;
1419 bxt_cstates[3].target_residency = usec;
1420 }
1421
1422 rdmsrl(MSR_PKGC8_IRTL, msr);
Jan Beulich3451ab32016-06-27 00:35:12 -06001423 usec = irtl_2_usec(msr);
1424 if (usec) {
Len Brown5dcef692016-04-06 17:00:47 -04001425 bxt_cstates[4].exit_latency = usec;
1426 bxt_cstates[4].target_residency = usec;
1427 }
1428
1429 rdmsrl(MSR_PKGC9_IRTL, msr);
Jan Beulich3451ab32016-06-27 00:35:12 -06001430 usec = irtl_2_usec(msr);
1431 if (usec) {
Len Brown5dcef692016-04-06 17:00:47 -04001432 bxt_cstates[5].exit_latency = usec;
1433 bxt_cstates[5].target_residency = usec;
1434 }
1435
1436 rdmsrl(MSR_PKGC10_IRTL, msr);
Jan Beulich3451ab32016-06-27 00:35:12 -06001437 usec = irtl_2_usec(msr);
1438 if (usec) {
Len Brown5dcef692016-04-06 17:00:47 -04001439 bxt_cstates[6].exit_latency = usec;
1440 bxt_cstates[6].target_residency = usec;
1441 }
1442
1443}
Rafael J. Wysocki6eacb152020-02-06 18:45:29 +01001444
1445/**
1446 * sklh_idle_state_table_update - Fix up the Sky Lake idle states table.
Len Brownd70e28f2016-03-13 00:33:48 -05001447 *
Rafael J. Wysocki6eacb152020-02-06 18:45:29 +01001448 * On SKL-H (model 0x5e) skip C8 and C9 if C10 is enabled and SGX disabled.
Len Brownd70e28f2016-03-13 00:33:48 -05001449 */
Rafael J. Wysocki095928a2020-01-10 11:51:22 +01001450static void __init sklh_idle_state_table_update(void)
Len Brownd70e28f2016-03-13 00:33:48 -05001451{
1452 unsigned long long msr;
1453 unsigned int eax, ebx, ecx, edx;
1454
1455
1456 /* if PC10 disabled via cmdline intel_idle.max_cstate=7 or shallower */
1457 if (max_cstate <= 7)
1458 return;
1459
1460 /* if PC10 not present in CPUID.MWAIT.EDX */
1461 if ((mwait_substates & (0xF << 28)) == 0)
1462 return;
1463
Len Brown6cfb2372017-01-07 23:23:25 -05001464 rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr);
Len Brownd70e28f2016-03-13 00:33:48 -05001465
1466 /* PC10 is not enabled in PKG C-state limit */
1467 if ((msr & 0xF) != 8)
1468 return;
1469
1470 ecx = 0;
1471 cpuid(7, &eax, &ebx, &ecx, &edx);
1472
1473 /* if SGX is present */
1474 if (ebx & (1 << 2)) {
1475
Sean Christopherson32ad73d2019-12-20 20:44:55 -08001476 rdmsrl(MSR_IA32_FEAT_CTL, msr);
Len Brownd70e28f2016-03-13 00:33:48 -05001477
1478 /* if SGX is enabled */
1479 if (msr & (1 << 18))
1480 return;
1481 }
1482
Rafael J. Wysockiba1e78a2019-11-21 19:41:51 +01001483 skl_cstates[5].flags |= CPUIDLE_FLAG_UNUSABLE; /* C8-SKL */
1484 skl_cstates[6].flags |= CPUIDLE_FLAG_UNUSABLE; /* C9-SKL */
Len Brownd70e28f2016-03-13 00:33:48 -05001485}
Len Brownd70e28f2016-03-13 00:33:48 -05001486
Rafael J. Wysocki1aefbd72020-01-10 11:52:32 +01001487static bool __init intel_idle_verify_cstate(unsigned int mwait_hint)
1488{
1489 unsigned int mwait_cstate = MWAIT_HINT2CSTATE(mwait_hint) + 1;
1490 unsigned int num_substates = (mwait_substates >> mwait_cstate * 4) &
1491 MWAIT_SUBSTATE_MASK;
1492
1493 /* Ignore the C-state if there are NO sub-states in CPUID for it. */
1494 if (num_substates == 0)
1495 return false;
1496
1497 if (mwait_cstate > 2 && !boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
1498 mark_tsc_unstable("TSC halts in idle states deeper than C2");
1499
1500 return true;
1501}
1502
Rafael J. Wysocki095928a2020-01-10 11:51:22 +01001503static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
Len Brown0138d8f2014-04-04 01:21:07 -04001504{
Rafael J. Wysocki3d3a1ae2020-01-10 11:48:25 +01001505 int cstate;
Len Brown0138d8f2014-04-04 01:21:07 -04001506
Rafael J. Wysocki3d3a1ae2020-01-10 11:48:25 +01001507 switch (boot_cpu_data.x86_model) {
Dave Hansendb73c5a2016-06-02 17:19:32 -07001508 case INTEL_FAM6_IVYBRIDGE_X:
Len Brownd70e28f2016-03-13 00:33:48 -05001509 ivt_idle_state_table_update();
1510 break;
Dave Hansendb73c5a2016-06-02 17:19:32 -07001511 case INTEL_FAM6_ATOM_GOLDMONT:
Peter Zijlstraf2c4db12018-08-07 10:17:27 -07001512 case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
Len Brown5dcef692016-04-06 17:00:47 -04001513 bxt_idle_state_table_update();
1514 break;
Peter Zijlstrac66f78a2019-08-27 21:48:21 +02001515 case INTEL_FAM6_SKYLAKE:
Len Brownd70e28f2016-03-13 00:33:48 -05001516 sklh_idle_state_table_update();
1517 break;
Len Brown0138d8f2014-04-04 01:21:07 -04001518 }
Deepthi Dharwar46bcfad2011-10-28 16:20:42 +05301519
Len Browne022e7e2013-02-01 23:37:30 -05001520 for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) {
Rafael J. Wysocki9f3d6da2019-12-13 09:55:52 +01001521 unsigned int mwait_hint;
Deepthi Dharwar46bcfad2011-10-28 16:20:42 +05301522
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001523 if (intel_idle_max_cstate_reached(cstate))
1524 break;
1525
Rafael J. Wysocki9f3d6da2019-12-13 09:55:52 +01001526 if (!cpuidle_state_table[cstate].enter &&
1527 !cpuidle_state_table[cstate].enter_s2idle)
Len Browne022e7e2013-02-01 23:37:30 -05001528 break;
1529
Rafael J. Wysocki9f3d6da2019-12-13 09:55:52 +01001530 /* If marked as unusable, skip this state. */
Rafael J. Wysockiba1e78a2019-11-21 19:41:51 +01001531 if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_UNUSABLE) {
Joe Perches654d08a2017-06-09 12:29:20 -07001532 pr_debug("state %s is disabled\n",
1533 cpuidle_state_table[cstate].name);
Len Brownd70e28f2016-03-13 00:33:48 -05001534 continue;
1535 }
1536
Rafael J. Wysocki9f3d6da2019-12-13 09:55:52 +01001537 mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags);
1538 if (!intel_idle_verify_cstate(mwait_hint))
1539 continue;
Len Brownd70e28f2016-03-13 00:33:48 -05001540
Rafael J. Wysocki9f3d6da2019-12-13 09:55:52 +01001541 /* Structure copy. */
Rafael J. Wysockibff8e602019-12-13 09:56:21 +01001542 drv->states[drv->state_count] = cpuidle_state_table[cstate];
1543
Rafael J. Wysocki4dcb78e2020-02-03 11:57:18 +01001544 if ((disabled_states_mask & BIT(drv->state_count)) ||
1545 ((icpu->use_acpi || force_use_acpi) &&
1546 intel_idle_off_by_default(mwait_hint) &&
1547 !(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_ALWAYS_ENABLE)))
Rafael J. Wysockibff8e602019-12-13 09:56:21 +01001548 drv->states[drv->state_count].flags |= CPUIDLE_FLAG_OFF;
1549
Peter Zijlstra6e1d2bc2020-11-20 11:28:35 +01001550 if (intel_idle_state_needs_timer_stop(&drv->states[drv->state_count]))
1551 drv->states[drv->state_count].flags |= CPUIDLE_FLAG_TIMER_STOP;
1552
Rafael J. Wysockibff8e602019-12-13 09:56:21 +01001553 drv->state_count++;
Deepthi Dharwar46bcfad2011-10-28 16:20:42 +05301554 }
1555
Len Brown8c058d532014-07-31 15:21:24 -04001556 if (icpu->byt_auto_demotion_disable_flag) {
1557 wrmsrl(MSR_CC6_DEMOTION_POLICY_CONFIG, 0);
1558 wrmsrl(MSR_MC6_DEMOTION_POLICY_CONFIG, 0);
1559 }
Deepthi Dharwar46bcfad2011-10-28 16:20:42 +05301560}
1561
Rafael J. Wysocki6eacb152020-02-06 18:45:29 +01001562/**
1563 * intel_idle_cpuidle_driver_init - Create the list of available idle states.
1564 * @drv: cpuidle driver structure to initialize.
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001565 */
Rafael J. Wysocki3d3a1ae2020-01-10 11:48:25 +01001566static void __init intel_idle_cpuidle_driver_init(struct cpuidle_driver *drv)
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001567{
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001568 cpuidle_poll_state_init(drv);
Rafael J. Wysocki4dcb78e2020-02-03 11:57:18 +01001569
1570 if (disabled_states_mask & BIT(0))
1571 drv->states[0].flags |= CPUIDLE_FLAG_OFF;
1572
Rafael J. Wysocki18734952019-12-13 09:56:01 +01001573 drv->state_count = 1;
1574
1575 if (icpu)
1576 intel_idle_init_cstates_icpu(drv);
1577 else
1578 intel_idle_init_cstates_acpi(drv);
1579}
Deepthi Dharwar46bcfad2011-10-28 16:20:42 +05301580
Rafael J. Wysocki1aefbd72020-01-10 11:52:32 +01001581static void auto_demotion_disable(void)
1582{
1583 unsigned long long msr_bits;
1584
1585 rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr_bits);
Rafael J. Wysocki7f843dd2020-02-06 18:41:24 +01001586 msr_bits &= ~auto_demotion_disable_flags;
Rafael J. Wysocki1aefbd72020-01-10 11:52:32 +01001587 wrmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr_bits);
1588}
1589
1590static void c1e_promotion_disable(void)
1591{
1592 unsigned long long msr_bits;
1593
1594 rdmsrl(MSR_IA32_POWER_CTL, msr_bits);
1595 msr_bits &= ~0x2;
1596 wrmsrl(MSR_IA32_POWER_CTL, msr_bits);
1597}
1598
Rafael J. Wysocki6eacb152020-02-06 18:45:29 +01001599/**
1600 * intel_idle_cpu_init - Register the target CPU with the cpuidle core.
1601 * @cpu: CPU to initialize.
1602 *
1603 * Register a cpuidle device object for @cpu and update its MSRs in accordance
1604 * with the processor model flags.
Len Brown26717172010-03-08 14:07:30 -05001605 */
Sebastian Andrzej Siewiorfb1013a2016-11-29 10:51:43 +01001606static int intel_idle_cpu_init(unsigned int cpu)
Len Brown26717172010-03-08 14:07:30 -05001607{
Len Brown26717172010-03-08 14:07:30 -05001608 struct cpuidle_device *dev;
1609
Thomas Renninger65b7f832012-01-17 22:40:08 +01001610 dev = per_cpu_ptr(intel_idle_cpuidle_devices, cpu);
Thomas Renninger65b7f832012-01-17 22:40:08 +01001611 dev->cpu = cpu;
Len Brown26717172010-03-08 14:07:30 -05001612
Thomas Renninger65b7f832012-01-17 22:40:08 +01001613 if (cpuidle_register_device(dev)) {
Joe Perches654d08a2017-06-09 12:29:20 -07001614 pr_debug("cpuidle_register_device %d failed!\n", cpu);
Thomas Renninger65b7f832012-01-17 22:40:08 +01001615 return -EIO;
Len Brown26717172010-03-08 14:07:30 -05001616 }
1617
Rafael J. Wysocki7f843dd2020-02-06 18:41:24 +01001618 if (auto_demotion_disable_flags)
Sebastian Andrzej Siewiorfb1013a2016-11-29 10:51:43 +01001619 auto_demotion_disable();
Thomas Renninger65b7f832012-01-17 22:40:08 +01001620
Rafael J. Wysocki7f843dd2020-02-06 18:41:24 +01001621 if (disable_promotion_to_c1e)
Sebastian Andrzej Siewiorfb1013a2016-11-29 10:51:43 +01001622 c1e_promotion_disable();
1623
1624 return 0;
1625}
1626
1627static int intel_idle_cpu_online(unsigned int cpu)
1628{
1629 struct cpuidle_device *dev;
1630
Rafael J. Wysockidab20172020-06-29 13:58:28 +02001631 if (!boot_cpu_has(X86_FEATURE_ARAT))
Rafael J. Wysockicbd2c4c2020-01-10 11:43:23 +01001632 tick_broadcast_enable();
Sebastian Andrzej Siewiorfb1013a2016-11-29 10:51:43 +01001633
1634 /*
1635 * Some systems can hotplug a cpu at runtime after
1636 * the kernel has booted, we have to initialize the
1637 * driver in this case
1638 */
1639 dev = per_cpu_ptr(intel_idle_cpuidle_devices, cpu);
1640 if (!dev->registered)
1641 return intel_idle_cpu_init(cpu);
Bartlomiej Zolnierkiewiczdbf87ab2013-12-20 19:47:28 +01001642
Len Brown26717172010-03-08 14:07:30 -05001643 return 0;
1644}
Len Brown26717172010-03-08 14:07:30 -05001645
Rafael J. Wysocki0755a9b2020-01-10 11:49:58 +01001646/**
1647 * intel_idle_cpuidle_devices_uninit - Unregister all cpuidle devices.
1648 */
1649static void __init intel_idle_cpuidle_devices_uninit(void)
1650{
1651 int i;
1652
1653 for_each_online_cpu(i)
1654 cpuidle_unregister_device(per_cpu_ptr(intel_idle_cpuidle_devices, i));
1655}
1656
Len Brown26717172010-03-08 14:07:30 -05001657static int __init intel_idle_init(void)
1658{
Rafael J. Wysockia6c86e32020-01-10 11:44:58 +01001659 const struct x86_cpu_id *id;
1660 unsigned int eax, ebx, ecx;
Sebastian Andrzej Siewiorfb1013a2016-11-29 10:51:43 +01001661 int retval;
Len Brown26717172010-03-08 14:07:30 -05001662
Thomas Renningerd1896042010-11-03 17:06:14 +01001663 /* Do not load intel_idle at all for now if idle= is passed */
1664 if (boot_option_idle_override != IDLE_NO_OVERRIDE)
1665 return -ENODEV;
1666
Rafael J. Wysockia6c86e32020-01-10 11:44:58 +01001667 if (max_cstate == 0) {
1668 pr_debug("disabled\n");
1669 return -EPERM;
1670 }
1671
1672 id = x86_match_cpu(intel_idle_ids);
1673 if (id) {
1674 if (!boot_cpu_has(X86_FEATURE_MWAIT)) {
1675 pr_debug("Please enable MWAIT in BIOS SETUP\n");
1676 return -ENODEV;
1677 }
1678 } else {
1679 id = x86_match_cpu(intel_mwait_ids);
1680 if (!id)
1681 return -ENODEV;
1682 }
1683
1684 if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
1685 return -ENODEV;
1686
1687 cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates);
1688
1689 if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
1690 !(ecx & CPUID5_ECX_INTERRUPT_BREAK) ||
1691 !mwait_substates)
1692 return -ENODEV;
1693
1694 pr_debug("MWAIT substates: 0x%x\n", mwait_substates);
1695
1696 icpu = (const struct idle_cpu *)id->driver_data;
1697 if (icpu) {
1698 cpuidle_state_table = icpu->state_table;
Rafael J. Wysocki7f843dd2020-02-06 18:41:24 +01001699 auto_demotion_disable_flags = icpu->auto_demotion_disable_flags;
1700 disable_promotion_to_c1e = icpu->disable_promotion_to_c1e;
Rafael J. Wysocki3a5be9b2020-02-03 11:57:08 +01001701 if (icpu->use_acpi || force_use_acpi)
Rafael J. Wysockia6c86e32020-01-10 11:44:58 +01001702 intel_idle_acpi_cst_extract();
1703 } else if (!intel_idle_acpi_cst_extract()) {
1704 return -ENODEV;
1705 }
1706
1707 pr_debug("v" INTEL_IDLE_VERSION " model 0x%X\n",
1708 boot_cpu_data.x86_model);
Len Brown26717172010-03-08 14:07:30 -05001709
Richard Cochrane9df69c2016-04-06 17:00:52 -04001710 intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device);
Rafael J. Wysocki533da742020-01-10 11:45:49 +01001711 if (!intel_idle_cpuidle_devices)
Richard Cochrane9df69c2016-04-06 17:00:52 -04001712 return -ENOMEM;
1713
Rafael J. Wysocki3d3a1ae2020-01-10 11:48:25 +01001714 intel_idle_cpuidle_driver_init(&intel_idle_driver);
1715
Len Brown26717172010-03-08 14:07:30 -05001716 retval = cpuidle_register_driver(&intel_idle_driver);
1717 if (retval) {
Konrad Rzeszutek Wilk3735d522012-08-16 22:06:55 +02001718 struct cpuidle_driver *drv = cpuidle_get_driver();
Joe Perches654d08a2017-06-09 12:29:20 -07001719 printk(KERN_DEBUG pr_fmt("intel_idle yielding to %s\n"),
1720 drv ? drv->name : "none");
Sebastian Andrzej Siewiorfb1013a2016-11-29 10:51:43 +01001721 goto init_driver_fail;
Len Brown26717172010-03-08 14:07:30 -05001722 }
1723
Sebastian Andrzej Siewiorfb1013a2016-11-29 10:51:43 +01001724 retval = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "idle/intel:online",
1725 intel_idle_cpu_online, NULL);
1726 if (retval < 0)
1727 goto hp_setup_fail;
Len Brown26717172010-03-08 14:07:30 -05001728
Rafael J. Wysocki40ab82e2020-02-06 18:40:54 +01001729 pr_debug("Local APIC timer is reliable in %s\n",
Rafael J. Wysockidab20172020-06-29 13:58:28 +02001730 boot_cpu_has(X86_FEATURE_ARAT) ? "all C-states" : "C1");
Richard Cochran2259a812016-04-06 17:00:54 -04001731
Len Brown26717172010-03-08 14:07:30 -05001732 return 0;
Sebastian Andrzej Siewiorfb1013a2016-11-29 10:51:43 +01001733
1734hp_setup_fail:
1735 intel_idle_cpuidle_devices_uninit();
1736 cpuidle_unregister_driver(&intel_idle_driver);
1737init_driver_fail:
1738 free_percpu(intel_idle_cpuidle_devices);
1739 return retval;
1740
Len Brown26717172010-03-08 14:07:30 -05001741}
Paul Gortmaker02c4fae2016-06-17 01:28:33 -04001742device_initcall(intel_idle_init);
Len Brown26717172010-03-08 14:07:30 -05001743
Paul Gortmaker02c4fae2016-06-17 01:28:33 -04001744/*
1745 * We are not really modular, but we used to support that. Meaning we also
1746 * support "intel_idle.max_cstate=..." at boot and also a read-only export of
1747 * it at /sys/module/intel_idle/parameters/max_cstate -- so using module_param
1748 * is the easiest way (currently) to continue doing that.
1749 */
Len Brown26717172010-03-08 14:07:30 -05001750module_param(max_cstate, int, 0444);
Rafael J. Wysocki4dcb78e2020-02-03 11:57:18 +01001751/*
1752 * The positions of the bits that are set in this number are the indices of the
1753 * idle states to be disabled by default (as reflected by the names of the
1754 * corresponding idle state directories in sysfs, "state0", "state1" ...
1755 * "state<i>" ..., where <i> is the index of the given state).
1756 */
1757module_param_named(states_off, disabled_states_mask, uint, 0444);
1758MODULE_PARM_DESC(states_off, "Mask of disabled idle states");