1a61127c2SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 226717172SLen Brown /* 326717172SLen Brown * intel_idle.c - native hardware idle loop for modern Intel processors 426717172SLen Brown * 5317e5ec3SRafael J. Wysocki * Copyright (c) 2013 - 2020, Intel Corporation. 626717172SLen Brown * Len Brown <len.brown@intel.com> 7317e5ec3SRafael J. Wysocki * Rafael J. Wysocki <rafael.j.wysocki@intel.com> 826717172SLen Brown */ 926717172SLen Brown 1026717172SLen Brown /* 118bb2e2a8SAlexander Monakov * intel_idle is a cpuidle driver that loads on all Intel CPUs with MWAIT 1226717172SLen Brown * in lieu of the legacy ACPI processor_idle driver. The intent is to 1326717172SLen Brown * make Linux more efficient on these processors, as intel_idle knows 1426717172SLen Brown * more than ACPI, as well as make Linux more immune to ACPI BIOS bugs. 1526717172SLen Brown */ 1626717172SLen Brown 1726717172SLen Brown /* 1826717172SLen Brown * Design Assumptions 1926717172SLen Brown * 2026717172SLen Brown * All CPUs have same idle states as boot CPU 2126717172SLen Brown * 2226717172SLen Brown * Chipset BM_STS (bus master status) bit is a NOP 238bb2e2a8SAlexander Monakov * for preventing entry into deep C-states 248bb2e2a8SAlexander Monakov * 258bb2e2a8SAlexander Monakov * CPU will flush caches as needed when entering a C-state via MWAIT 268bb2e2a8SAlexander Monakov * (in contrast to entering ACPI C3, in which case the WBINVD 278bb2e2a8SAlexander Monakov * instruction needs to be executed to flush the caches) 2826717172SLen Brown */ 2926717172SLen Brown 3026717172SLen Brown /* 3126717172SLen Brown * Known limitations 3226717172SLen Brown * 3326717172SLen Brown * ACPI has a .suspend hack to turn off deep c-statees during suspend 3426717172SLen Brown * to avoid complications with the lapic timer workaround. 3526717172SLen Brown * Have not seen issues with suspend, but may need same workaround here. 3626717172SLen Brown * 3726717172SLen Brown */ 3826717172SLen Brown 3926717172SLen Brown /* un-comment DEBUG to enable pr_debug() statements */ 40651bc581STom Rix /* #define DEBUG */ 4126717172SLen Brown 42654d08a4SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 43654d08a4SJoe Perches 4418734958SRafael J. Wysocki #include <linux/acpi.h> 4526717172SLen Brown #include <linux/kernel.h> 4626717172SLen Brown #include <linux/cpuidle.h> 4776962caaSThomas Gleixner #include <linux/tick.h> 4826717172SLen Brown #include <trace/events/power.h> 4926717172SLen Brown #include <linux/sched.h> 50*bf5835bcSPeter Zijlstra #include <linux/sched/smt.h> 512a2d31c8SShaohua Li #include <linux/notifier.h> 522a2d31c8SShaohua Li #include <linux/cpu.h> 5302c4fae9SPaul Gortmaker #include <linux/moduleparam.h> 54b66b8b9aSAndi Kleen #include <asm/cpu_device_id.h> 55db73c5a8SDave Hansen #include <asm/intel-family.h> 56*bf5835bcSPeter Zijlstra #include <asm/nospec-branch.h> 57bc83ccccSH. Peter Anvin #include <asm/mwait.h> 5814796fcaSLen Brown #include <asm/msr.h> 5926717172SLen Brown 60317e5ec3SRafael J. Wysocki #define INTEL_IDLE_VERSION "0.5.1" 6126717172SLen Brown 6226717172SLen Brown static struct cpuidle_driver intel_idle_driver = { 6326717172SLen Brown .name = "intel_idle", 6426717172SLen Brown .owner = THIS_MODULE, 6526717172SLen Brown }; 6626717172SLen Brown /* intel_idle.max_cstate=0 disables driver */ 67137ecc77SLen Brown static int max_cstate = CPUIDLE_STATE_MAX - 1; 684dcb78eeSRafael J. Wysocki static unsigned int disabled_states_mask; 69da0e58c0SArtem Bityutskiy static unsigned int preferred_states_mask; 7026717172SLen Brown 716eb0443aSRafael J. Wysocki static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; 727f843dd7SRafael J. Wysocki 737f843dd7SRafael J. Wysocki static unsigned long auto_demotion_disable_flags; 7439c184a6SArtem Bityutskiy 7539c184a6SArtem Bityutskiy static enum { 7639c184a6SArtem Bityutskiy C1E_PROMOTION_PRESERVE, 7739c184a6SArtem Bityutskiy C1E_PROMOTION_ENABLE, 7839c184a6SArtem Bityutskiy C1E_PROMOTION_DISABLE 7939c184a6SArtem Bityutskiy } c1e_promotion = C1E_PROMOTION_PRESERVE; 807f843dd7SRafael J. Wysocki 81b66b8b9aSAndi Kleen struct idle_cpu { 82b66b8b9aSAndi Kleen struct cpuidle_state *state_table; 8326717172SLen Brown 8426717172SLen Brown /* 8514796fcaSLen Brown * Hardware C-state auto-demotion may not always be optimal. 8614796fcaSLen Brown * Indicate which enable bits to clear here. 8714796fcaSLen Brown */ 88b66b8b9aSAndi Kleen unsigned long auto_demotion_disable_flags; 898c058d53SLen Brown bool byt_auto_demotion_disable_flag; 9032e95180SLen Brown bool disable_promotion_to_c1e; 91bff8e60aSRafael J. Wysocki bool use_acpi; 92b66b8b9aSAndi Kleen }; 93b66b8b9aSAndi Kleen 947f843dd7SRafael J. Wysocki static const struct idle_cpu *icpu __initdata; 957f843dd7SRafael J. Wysocki static struct cpuidle_state *cpuidle_state_table __initdata; 9614796fcaSLen Brown 976eb0443aSRafael J. Wysocki static unsigned int mwait_substates __initdata; 986eb0443aSRafael J. Wysocki 9914796fcaSLen Brown /* 100c227233aSArtem Bityutskiy * Enable interrupts before entering the C-state. On some platforms and for 101c227233aSArtem Bityutskiy * some C-states, this may measurably decrease interrupt latency. 102c227233aSArtem Bityutskiy */ 103c227233aSArtem Bityutskiy #define CPUIDLE_FLAG_IRQ_ENABLE BIT(14) 104c227233aSArtem Bityutskiy 105c227233aSArtem Bityutskiy /* 106bff8e60aSRafael J. Wysocki * Enable this state by default even if the ACPI _CST does not list it. 107bff8e60aSRafael J. Wysocki */ 108bff8e60aSRafael J. Wysocki #define CPUIDLE_FLAG_ALWAYS_ENABLE BIT(15) 109bff8e60aSRafael J. Wysocki 110bff8e60aSRafael J. Wysocki /* 111*bf5835bcSPeter Zijlstra * Disable IBRS across idle (when KERNEL_IBRS), is exclusive vs IRQ_ENABLE 112*bf5835bcSPeter Zijlstra * above. 113*bf5835bcSPeter Zijlstra */ 114*bf5835bcSPeter Zijlstra #define CPUIDLE_FLAG_IBRS BIT(16) 115*bf5835bcSPeter Zijlstra 116*bf5835bcSPeter Zijlstra /* 117b1beab48SLen Brown * MWAIT takes an 8-bit "hint" in EAX "suggesting" 118b1beab48SLen Brown * the C-state (top nibble) and sub-state (bottom nibble) 119b1beab48SLen Brown * 0x00 means "MWAIT(C1)", 0x10 means "MWAIT(C2)" etc. 120b1beab48SLen Brown * 121b1beab48SLen Brown * We store the hint at the top of our "flags" for each state. 122b1beab48SLen Brown */ 123b1beab48SLen Brown #define flg2MWAIT(flags) (((flags) >> 24) & 0xFF) 124b1beab48SLen Brown #define MWAIT2flg(eax) ((eax & 0xFF) << 24) 125b1beab48SLen Brown 12632d4fd57SPeter Zijlstra static __always_inline int __intel_idle(struct cpuidle_device *dev, 12732d4fd57SPeter Zijlstra struct cpuidle_driver *drv, int index) 12832d4fd57SPeter Zijlstra { 12932d4fd57SPeter Zijlstra struct cpuidle_state *state = &drv->states[index]; 13032d4fd57SPeter Zijlstra unsigned long eax = flg2MWAIT(state->flags); 13132d4fd57SPeter Zijlstra unsigned long ecx = 1; /* break on interrupt flag */ 13232d4fd57SPeter Zijlstra 13332d4fd57SPeter Zijlstra mwait_idle_with_hints(eax, ecx); 13432d4fd57SPeter Zijlstra 13532d4fd57SPeter Zijlstra return index; 13632d4fd57SPeter Zijlstra } 13732d4fd57SPeter Zijlstra 13830a996fbSRafael J. Wysocki /** 13930a996fbSRafael J. Wysocki * intel_idle - Ask the processor to enter the given idle state. 14030a996fbSRafael J. Wysocki * @dev: cpuidle device of the target CPU. 14130a996fbSRafael J. Wysocki * @drv: cpuidle driver (assumed to point to intel_idle_driver). 14230a996fbSRafael J. Wysocki * @index: Target idle state index. 14330a996fbSRafael J. Wysocki * 14430a996fbSRafael J. Wysocki * Use the MWAIT instruction to notify the processor that the CPU represented by 14530a996fbSRafael J. Wysocki * @dev is idle and it can try to enter the idle state corresponding to @index. 14630a996fbSRafael J. Wysocki * 14730a996fbSRafael J. Wysocki * If the local APIC timer is not known to be reliable in the target idle state, 14830a996fbSRafael J. Wysocki * enable one-shot tick broadcasting for the target CPU before executing MWAIT. 14930a996fbSRafael J. Wysocki * 15030a996fbSRafael J. Wysocki * Must be called under local_irq_disable(). 15130a996fbSRafael J. Wysocki */ 15230a996fbSRafael J. Wysocki static __cpuidle int intel_idle(struct cpuidle_device *dev, 15330a996fbSRafael J. Wysocki struct cpuidle_driver *drv, int index) 15430a996fbSRafael J. Wysocki { 15532d4fd57SPeter Zijlstra return __intel_idle(dev, drv, index); 15632d4fd57SPeter Zijlstra } 15730a996fbSRafael J. Wysocki 15832d4fd57SPeter Zijlstra static __cpuidle int intel_idle_irq(struct cpuidle_device *dev, 15932d4fd57SPeter Zijlstra struct cpuidle_driver *drv, int index) 16032d4fd57SPeter Zijlstra { 16132d4fd57SPeter Zijlstra int ret; 162c227233aSArtem Bityutskiy 16332d4fd57SPeter Zijlstra raw_local_irq_enable(); 16432d4fd57SPeter Zijlstra ret = __intel_idle(dev, drv, index); 16532d4fd57SPeter Zijlstra raw_local_irq_disable(); 16630a996fbSRafael J. Wysocki 16732d4fd57SPeter Zijlstra return ret; 16830a996fbSRafael J. Wysocki } 16930a996fbSRafael J. Wysocki 170*bf5835bcSPeter Zijlstra static __cpuidle int intel_idle_ibrs(struct cpuidle_device *dev, 171*bf5835bcSPeter Zijlstra struct cpuidle_driver *drv, int index) 172*bf5835bcSPeter Zijlstra { 173*bf5835bcSPeter Zijlstra bool smt_active = sched_smt_active(); 174*bf5835bcSPeter Zijlstra u64 spec_ctrl = spec_ctrl_current(); 175*bf5835bcSPeter Zijlstra int ret; 176*bf5835bcSPeter Zijlstra 177*bf5835bcSPeter Zijlstra if (smt_active) 178*bf5835bcSPeter Zijlstra wrmsrl(MSR_IA32_SPEC_CTRL, 0); 179*bf5835bcSPeter Zijlstra 180*bf5835bcSPeter Zijlstra ret = __intel_idle(dev, drv, index); 181*bf5835bcSPeter Zijlstra 182*bf5835bcSPeter Zijlstra if (smt_active) 183*bf5835bcSPeter Zijlstra wrmsrl(MSR_IA32_SPEC_CTRL, spec_ctrl); 184*bf5835bcSPeter Zijlstra 185*bf5835bcSPeter Zijlstra return ret; 186*bf5835bcSPeter Zijlstra } 187*bf5835bcSPeter Zijlstra 18830a996fbSRafael J. Wysocki /** 18930a996fbSRafael J. Wysocki * intel_idle_s2idle - Ask the processor to enter the given idle state. 19030a996fbSRafael J. Wysocki * @dev: cpuidle device of the target CPU. 19130a996fbSRafael J. Wysocki * @drv: cpuidle driver (assumed to point to intel_idle_driver). 19230a996fbSRafael J. Wysocki * @index: Target idle state index. 19330a996fbSRafael J. Wysocki * 19430a996fbSRafael J. Wysocki * Use the MWAIT instruction to notify the processor that the CPU represented by 19530a996fbSRafael J. Wysocki * @dev is idle and it can try to enter the idle state corresponding to @index. 19630a996fbSRafael J. Wysocki * 19730a996fbSRafael J. Wysocki * Invoked as a suspend-to-idle callback routine with frozen user space, frozen 19830a996fbSRafael J. Wysocki * scheduler tick and suspended scheduler clock on the target CPU. 19930a996fbSRafael J. Wysocki */ 200efe97112SNeal Liu static __cpuidle int intel_idle_s2idle(struct cpuidle_device *dev, 20130a996fbSRafael J. Wysocki struct cpuidle_driver *drv, int index) 20230a996fbSRafael J. Wysocki { 20330a996fbSRafael J. Wysocki unsigned long eax = flg2MWAIT(drv->states[index].flags); 20430a996fbSRafael J. Wysocki unsigned long ecx = 1; /* break on interrupt flag */ 20530a996fbSRafael J. Wysocki 20630a996fbSRafael J. Wysocki mwait_idle_with_hints(eax, ecx); 207efe97112SNeal Liu 208efe97112SNeal Liu return 0; 20930a996fbSRafael J. Wysocki } 21030a996fbSRafael J. Wysocki 211b1beab48SLen Brown /* 21226717172SLen Brown * States are indexed by the cstate number, 21326717172SLen Brown * which is also the index into the MWAIT hint array. 21426717172SLen Brown * Thus C0 is a dummy. 21526717172SLen Brown */ 216ab1a8522SRafael J. Wysocki static struct cpuidle_state nehalem_cstates[] __initdata = { 217e022e7ebSLen Brown { 218de09cdd0SLen Brown .name = "C1", 21926717172SLen Brown .desc = "MWAIT 0x00", 220b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x00), 22126717172SLen Brown .exit_latency = 3, 22226717172SLen Brown .target_residency = 6, 2235fe2e527SRafael J. Wysocki .enter = &intel_idle, 22428ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 225e022e7ebSLen Brown { 226de09cdd0SLen Brown .name = "C1E", 22732e95180SLen Brown .desc = "MWAIT 0x01", 228e6d4f08aSRafael J. Wysocki .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 22932e95180SLen Brown .exit_latency = 10, 23032e95180SLen Brown .target_residency = 20, 2315fe2e527SRafael J. Wysocki .enter = &intel_idle, 23228ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 23332e95180SLen Brown { 234de09cdd0SLen Brown .name = "C3", 23526717172SLen Brown .desc = "MWAIT 0x10", 236b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 23726717172SLen Brown .exit_latency = 20, 23826717172SLen Brown .target_residency = 80, 2395fe2e527SRafael J. Wysocki .enter = &intel_idle, 24028ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 241e022e7ebSLen Brown { 242de09cdd0SLen Brown .name = "C6", 24326717172SLen Brown .desc = "MWAIT 0x20", 244b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 24526717172SLen Brown .exit_latency = 200, 24626717172SLen Brown .target_residency = 800, 2475fe2e527SRafael J. Wysocki .enter = &intel_idle, 24828ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 249e022e7ebSLen Brown { 250e022e7ebSLen Brown .enter = NULL } 25126717172SLen Brown }; 25226717172SLen Brown 253ab1a8522SRafael J. Wysocki static struct cpuidle_state snb_cstates[] __initdata = { 254e022e7ebSLen Brown { 255de09cdd0SLen Brown .name = "C1", 256d13780d4SLen Brown .desc = "MWAIT 0x00", 257b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x00), 25832e95180SLen Brown .exit_latency = 2, 25932e95180SLen Brown .target_residency = 2, 2605fe2e527SRafael J. Wysocki .enter = &intel_idle, 26128ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 26232e95180SLen Brown { 263de09cdd0SLen Brown .name = "C1E", 26432e95180SLen Brown .desc = "MWAIT 0x01", 265e6d4f08aSRafael J. Wysocki .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 26632e95180SLen Brown .exit_latency = 10, 26732e95180SLen Brown .target_residency = 20, 2685fe2e527SRafael J. Wysocki .enter = &intel_idle, 26928ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 270e022e7ebSLen Brown { 271de09cdd0SLen Brown .name = "C3", 272d13780d4SLen Brown .desc = "MWAIT 0x10", 273b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 274d13780d4SLen Brown .exit_latency = 80, 275ddbd550dSLen Brown .target_residency = 211, 2765fe2e527SRafael J. Wysocki .enter = &intel_idle, 27728ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 278e022e7ebSLen Brown { 279de09cdd0SLen Brown .name = "C6", 280d13780d4SLen Brown .desc = "MWAIT 0x20", 281b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 282d13780d4SLen Brown .exit_latency = 104, 283ddbd550dSLen Brown .target_residency = 345, 2845fe2e527SRafael J. Wysocki .enter = &intel_idle, 28528ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 286e022e7ebSLen Brown { 287de09cdd0SLen Brown .name = "C7", 288d13780d4SLen Brown .desc = "MWAIT 0x30", 289b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, 290d13780d4SLen Brown .exit_latency = 109, 291ddbd550dSLen Brown .target_residency = 345, 2925fe2e527SRafael J. Wysocki .enter = &intel_idle, 29328ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 294e022e7ebSLen Brown { 295e022e7ebSLen Brown .enter = NULL } 296d13780d4SLen Brown }; 297d13780d4SLen Brown 298ab1a8522SRafael J. Wysocki static struct cpuidle_state byt_cstates[] __initdata = { 299718987d6SLen Brown { 300de09cdd0SLen Brown .name = "C1", 301718987d6SLen Brown .desc = "MWAIT 0x00", 302b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x00), 303718987d6SLen Brown .exit_latency = 1, 304718987d6SLen Brown .target_residency = 1, 3055fe2e527SRafael J. Wysocki .enter = &intel_idle, 30628ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 307718987d6SLen Brown { 308de09cdd0SLen Brown .name = "C6N", 309718987d6SLen Brown .desc = "MWAIT 0x58", 310b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED, 311d7ef7671SLen Brown .exit_latency = 300, 312718987d6SLen Brown .target_residency = 275, 3135fe2e527SRafael J. Wysocki .enter = &intel_idle, 31428ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 315718987d6SLen Brown { 316de09cdd0SLen Brown .name = "C6S", 317718987d6SLen Brown .desc = "MWAIT 0x52", 318b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, 319d7ef7671SLen Brown .exit_latency = 500, 320718987d6SLen Brown .target_residency = 560, 3215fe2e527SRafael J. Wysocki .enter = &intel_idle, 32228ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 323718987d6SLen Brown { 324de09cdd0SLen Brown .name = "C7", 325718987d6SLen Brown .desc = "MWAIT 0x60", 326b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 327718987d6SLen Brown .exit_latency = 1200, 328d7ef7671SLen Brown .target_residency = 4000, 3295fe2e527SRafael J. Wysocki .enter = &intel_idle, 33028ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 331718987d6SLen Brown { 332de09cdd0SLen Brown .name = "C7S", 333718987d6SLen Brown .desc = "MWAIT 0x64", 334b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED, 335718987d6SLen Brown .exit_latency = 10000, 336718987d6SLen Brown .target_residency = 20000, 3375fe2e527SRafael J. Wysocki .enter = &intel_idle, 33828ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 339718987d6SLen Brown { 340718987d6SLen Brown .enter = NULL } 341718987d6SLen Brown }; 342718987d6SLen Brown 343ab1a8522SRafael J. Wysocki static struct cpuidle_state cht_cstates[] __initdata = { 344cab07a56SLen Brown { 345de09cdd0SLen Brown .name = "C1", 346cab07a56SLen Brown .desc = "MWAIT 0x00", 347cab07a56SLen Brown .flags = MWAIT2flg(0x00), 348cab07a56SLen Brown .exit_latency = 1, 349cab07a56SLen Brown .target_residency = 1, 350cab07a56SLen Brown .enter = &intel_idle, 35128ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 352cab07a56SLen Brown { 353de09cdd0SLen Brown .name = "C6N", 354cab07a56SLen Brown .desc = "MWAIT 0x58", 355cab07a56SLen Brown .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED, 356cab07a56SLen Brown .exit_latency = 80, 357cab07a56SLen Brown .target_residency = 275, 358cab07a56SLen Brown .enter = &intel_idle, 35928ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 360cab07a56SLen Brown { 361de09cdd0SLen Brown .name = "C6S", 362cab07a56SLen Brown .desc = "MWAIT 0x52", 363cab07a56SLen Brown .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, 364cab07a56SLen Brown .exit_latency = 200, 365cab07a56SLen Brown .target_residency = 560, 366cab07a56SLen Brown .enter = &intel_idle, 36728ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 368cab07a56SLen Brown { 369de09cdd0SLen Brown .name = "C7", 370cab07a56SLen Brown .desc = "MWAIT 0x60", 371cab07a56SLen Brown .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 372cab07a56SLen Brown .exit_latency = 1200, 373cab07a56SLen Brown .target_residency = 4000, 374cab07a56SLen Brown .enter = &intel_idle, 37528ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 376cab07a56SLen Brown { 377de09cdd0SLen Brown .name = "C7S", 378cab07a56SLen Brown .desc = "MWAIT 0x64", 379cab07a56SLen Brown .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED, 380cab07a56SLen Brown .exit_latency = 10000, 381cab07a56SLen Brown .target_residency = 20000, 382cab07a56SLen Brown .enter = &intel_idle, 38328ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 384cab07a56SLen Brown { 385cab07a56SLen Brown .enter = NULL } 386cab07a56SLen Brown }; 387cab07a56SLen Brown 388ab1a8522SRafael J. Wysocki static struct cpuidle_state ivb_cstates[] __initdata = { 389e022e7ebSLen Brown { 390de09cdd0SLen Brown .name = "C1", 3916edab08cSLen Brown .desc = "MWAIT 0x00", 392b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x00), 3936edab08cSLen Brown .exit_latency = 1, 3946edab08cSLen Brown .target_residency = 1, 3955fe2e527SRafael J. Wysocki .enter = &intel_idle, 39628ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 397e022e7ebSLen Brown { 398de09cdd0SLen Brown .name = "C1E", 39932e95180SLen Brown .desc = "MWAIT 0x01", 400e6d4f08aSRafael J. Wysocki .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 40132e95180SLen Brown .exit_latency = 10, 40232e95180SLen Brown .target_residency = 20, 4035fe2e527SRafael J. Wysocki .enter = &intel_idle, 40428ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 40532e95180SLen Brown { 406de09cdd0SLen Brown .name = "C3", 4076edab08cSLen Brown .desc = "MWAIT 0x10", 408b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 4096edab08cSLen Brown .exit_latency = 59, 4106edab08cSLen Brown .target_residency = 156, 4115fe2e527SRafael J. Wysocki .enter = &intel_idle, 41228ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 413e022e7ebSLen Brown { 414de09cdd0SLen Brown .name = "C6", 4156edab08cSLen Brown .desc = "MWAIT 0x20", 416b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 4176edab08cSLen Brown .exit_latency = 80, 4186edab08cSLen Brown .target_residency = 300, 4195fe2e527SRafael J. Wysocki .enter = &intel_idle, 42028ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 421e022e7ebSLen Brown { 422de09cdd0SLen Brown .name = "C7", 4236edab08cSLen Brown .desc = "MWAIT 0x30", 424b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, 4256edab08cSLen Brown .exit_latency = 87, 4266edab08cSLen Brown .target_residency = 300, 4275fe2e527SRafael J. Wysocki .enter = &intel_idle, 42828ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 429e022e7ebSLen Brown { 430e022e7ebSLen Brown .enter = NULL } 4316edab08cSLen Brown }; 4326edab08cSLen Brown 433ab1a8522SRafael J. Wysocki static struct cpuidle_state ivt_cstates[] __initdata = { 4340138d8f0SLen Brown { 435de09cdd0SLen Brown .name = "C1", 4360138d8f0SLen Brown .desc = "MWAIT 0x00", 437b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x00), 4380138d8f0SLen Brown .exit_latency = 1, 4390138d8f0SLen Brown .target_residency = 1, 4405fe2e527SRafael J. Wysocki .enter = &intel_idle, 44128ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 4420138d8f0SLen Brown { 443de09cdd0SLen Brown .name = "C1E", 4440138d8f0SLen Brown .desc = "MWAIT 0x01", 445e6d4f08aSRafael J. Wysocki .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 4460138d8f0SLen Brown .exit_latency = 10, 4470138d8f0SLen Brown .target_residency = 80, 4485fe2e527SRafael J. Wysocki .enter = &intel_idle, 44928ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 4500138d8f0SLen Brown { 451de09cdd0SLen Brown .name = "C3", 4520138d8f0SLen Brown .desc = "MWAIT 0x10", 453b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 4540138d8f0SLen Brown .exit_latency = 59, 4550138d8f0SLen Brown .target_residency = 156, 4565fe2e527SRafael J. Wysocki .enter = &intel_idle, 45728ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 4580138d8f0SLen Brown { 459de09cdd0SLen Brown .name = "C6", 4600138d8f0SLen Brown .desc = "MWAIT 0x20", 461b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 4620138d8f0SLen Brown .exit_latency = 82, 4630138d8f0SLen Brown .target_residency = 300, 4645fe2e527SRafael J. Wysocki .enter = &intel_idle, 46528ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 4660138d8f0SLen Brown { 4670138d8f0SLen Brown .enter = NULL } 4680138d8f0SLen Brown }; 4690138d8f0SLen Brown 470ab1a8522SRafael J. Wysocki static struct cpuidle_state ivt_cstates_4s[] __initdata = { 4710138d8f0SLen Brown { 472de09cdd0SLen Brown .name = "C1", 4730138d8f0SLen Brown .desc = "MWAIT 0x00", 474b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x00), 4750138d8f0SLen Brown .exit_latency = 1, 4760138d8f0SLen Brown .target_residency = 1, 4775fe2e527SRafael J. Wysocki .enter = &intel_idle, 47828ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 4790138d8f0SLen Brown { 480de09cdd0SLen Brown .name = "C1E", 4810138d8f0SLen Brown .desc = "MWAIT 0x01", 482e6d4f08aSRafael J. Wysocki .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 4830138d8f0SLen Brown .exit_latency = 10, 4840138d8f0SLen Brown .target_residency = 250, 4855fe2e527SRafael J. Wysocki .enter = &intel_idle, 48628ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 4870138d8f0SLen Brown { 488de09cdd0SLen Brown .name = "C3", 4890138d8f0SLen Brown .desc = "MWAIT 0x10", 490b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 4910138d8f0SLen Brown .exit_latency = 59, 4920138d8f0SLen Brown .target_residency = 300, 4935fe2e527SRafael J. Wysocki .enter = &intel_idle, 49428ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 4950138d8f0SLen Brown { 496de09cdd0SLen Brown .name = "C6", 4970138d8f0SLen Brown .desc = "MWAIT 0x20", 498b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 4990138d8f0SLen Brown .exit_latency = 84, 5000138d8f0SLen Brown .target_residency = 400, 5015fe2e527SRafael J. Wysocki .enter = &intel_idle, 50228ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 5030138d8f0SLen Brown { 5040138d8f0SLen Brown .enter = NULL } 5050138d8f0SLen Brown }; 5060138d8f0SLen Brown 507ab1a8522SRafael J. Wysocki static struct cpuidle_state ivt_cstates_8s[] __initdata = { 5080138d8f0SLen Brown { 509de09cdd0SLen Brown .name = "C1", 5100138d8f0SLen Brown .desc = "MWAIT 0x00", 511b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x00), 5120138d8f0SLen Brown .exit_latency = 1, 5130138d8f0SLen Brown .target_residency = 1, 5145fe2e527SRafael J. Wysocki .enter = &intel_idle, 51528ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 5160138d8f0SLen Brown { 517de09cdd0SLen Brown .name = "C1E", 5180138d8f0SLen Brown .desc = "MWAIT 0x01", 519e6d4f08aSRafael J. Wysocki .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 5200138d8f0SLen Brown .exit_latency = 10, 5210138d8f0SLen Brown .target_residency = 500, 5225fe2e527SRafael J. Wysocki .enter = &intel_idle, 52328ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 5240138d8f0SLen Brown { 525de09cdd0SLen Brown .name = "C3", 5260138d8f0SLen Brown .desc = "MWAIT 0x10", 527b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 5280138d8f0SLen Brown .exit_latency = 59, 5290138d8f0SLen Brown .target_residency = 600, 5305fe2e527SRafael J. Wysocki .enter = &intel_idle, 53128ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 5320138d8f0SLen Brown { 533de09cdd0SLen Brown .name = "C6", 5340138d8f0SLen Brown .desc = "MWAIT 0x20", 535b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 5360138d8f0SLen Brown .exit_latency = 88, 5370138d8f0SLen Brown .target_residency = 700, 5385fe2e527SRafael J. Wysocki .enter = &intel_idle, 53928ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 5400138d8f0SLen Brown { 5410138d8f0SLen Brown .enter = NULL } 5420138d8f0SLen Brown }; 5430138d8f0SLen Brown 544ab1a8522SRafael J. Wysocki static struct cpuidle_state hsw_cstates[] __initdata = { 545e022e7ebSLen Brown { 546de09cdd0SLen Brown .name = "C1", 54785a4d2d4SLen Brown .desc = "MWAIT 0x00", 548b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x00), 54985a4d2d4SLen Brown .exit_latency = 2, 55085a4d2d4SLen Brown .target_residency = 2, 5515fe2e527SRafael J. Wysocki .enter = &intel_idle, 55228ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 553e022e7ebSLen Brown { 554de09cdd0SLen Brown .name = "C1E", 55532e95180SLen Brown .desc = "MWAIT 0x01", 556e6d4f08aSRafael J. Wysocki .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 55732e95180SLen Brown .exit_latency = 10, 55832e95180SLen Brown .target_residency = 20, 5595fe2e527SRafael J. Wysocki .enter = &intel_idle, 56028ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 56132e95180SLen Brown { 562de09cdd0SLen Brown .name = "C3", 56385a4d2d4SLen Brown .desc = "MWAIT 0x10", 564b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 56585a4d2d4SLen Brown .exit_latency = 33, 56685a4d2d4SLen Brown .target_residency = 100, 5675fe2e527SRafael J. Wysocki .enter = &intel_idle, 56828ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 569e022e7ebSLen Brown { 570de09cdd0SLen Brown .name = "C6", 57185a4d2d4SLen Brown .desc = "MWAIT 0x20", 572b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 57385a4d2d4SLen Brown .exit_latency = 133, 57485a4d2d4SLen Brown .target_residency = 400, 5755fe2e527SRafael J. Wysocki .enter = &intel_idle, 57628ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 577e022e7ebSLen Brown { 578de09cdd0SLen Brown .name = "C7s", 57985a4d2d4SLen Brown .desc = "MWAIT 0x32", 580b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TLB_FLUSHED, 58185a4d2d4SLen Brown .exit_latency = 166, 58285a4d2d4SLen Brown .target_residency = 500, 5835fe2e527SRafael J. Wysocki .enter = &intel_idle, 58428ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 585e022e7ebSLen Brown { 586de09cdd0SLen Brown .name = "C8", 58786239cebSLen Brown .desc = "MWAIT 0x40", 588b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, 58986239cebSLen Brown .exit_latency = 300, 59086239cebSLen Brown .target_residency = 900, 5915fe2e527SRafael J. Wysocki .enter = &intel_idle, 59228ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 59386239cebSLen Brown { 594de09cdd0SLen Brown .name = "C9", 59586239cebSLen Brown .desc = "MWAIT 0x50", 596b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, 59786239cebSLen Brown .exit_latency = 600, 59886239cebSLen Brown .target_residency = 1800, 5995fe2e527SRafael J. Wysocki .enter = &intel_idle, 60028ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 60186239cebSLen Brown { 602de09cdd0SLen Brown .name = "C10", 60386239cebSLen Brown .desc = "MWAIT 0x60", 604b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 60586239cebSLen Brown .exit_latency = 2600, 60686239cebSLen Brown .target_residency = 7700, 6075fe2e527SRafael J. Wysocki .enter = &intel_idle, 60828ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 60986239cebSLen Brown { 610e022e7ebSLen Brown .enter = NULL } 61185a4d2d4SLen Brown }; 612ab1a8522SRafael J. Wysocki static struct cpuidle_state bdw_cstates[] __initdata = { 613a138b568SLen Brown { 614de09cdd0SLen Brown .name = "C1", 615a138b568SLen Brown .desc = "MWAIT 0x00", 616b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x00), 617a138b568SLen Brown .exit_latency = 2, 618a138b568SLen Brown .target_residency = 2, 6195fe2e527SRafael J. Wysocki .enter = &intel_idle, 62028ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 621a138b568SLen Brown { 622de09cdd0SLen Brown .name = "C1E", 623a138b568SLen Brown .desc = "MWAIT 0x01", 624e6d4f08aSRafael J. Wysocki .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 625a138b568SLen Brown .exit_latency = 10, 626a138b568SLen Brown .target_residency = 20, 6275fe2e527SRafael J. Wysocki .enter = &intel_idle, 62828ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 629a138b568SLen Brown { 630de09cdd0SLen Brown .name = "C3", 631a138b568SLen Brown .desc = "MWAIT 0x10", 632b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 633a138b568SLen Brown .exit_latency = 40, 634a138b568SLen Brown .target_residency = 100, 6355fe2e527SRafael J. Wysocki .enter = &intel_idle, 63628ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 637a138b568SLen Brown { 638de09cdd0SLen Brown .name = "C6", 639a138b568SLen Brown .desc = "MWAIT 0x20", 640b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 641a138b568SLen Brown .exit_latency = 133, 642a138b568SLen Brown .target_residency = 400, 6435fe2e527SRafael J. Wysocki .enter = &intel_idle, 64428ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 645a138b568SLen Brown { 646de09cdd0SLen Brown .name = "C7s", 647a138b568SLen Brown .desc = "MWAIT 0x32", 648b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TLB_FLUSHED, 649a138b568SLen Brown .exit_latency = 166, 650a138b568SLen Brown .target_residency = 500, 6515fe2e527SRafael J. Wysocki .enter = &intel_idle, 65228ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 653a138b568SLen Brown { 654de09cdd0SLen Brown .name = "C8", 655a138b568SLen Brown .desc = "MWAIT 0x40", 656b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, 657a138b568SLen Brown .exit_latency = 300, 658a138b568SLen Brown .target_residency = 900, 6595fe2e527SRafael J. Wysocki .enter = &intel_idle, 66028ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 661a138b568SLen Brown { 662de09cdd0SLen Brown .name = "C9", 663a138b568SLen Brown .desc = "MWAIT 0x50", 664b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, 665a138b568SLen Brown .exit_latency = 600, 666a138b568SLen Brown .target_residency = 1800, 6675fe2e527SRafael J. Wysocki .enter = &intel_idle, 66828ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 669a138b568SLen Brown { 670de09cdd0SLen Brown .name = "C10", 671a138b568SLen Brown .desc = "MWAIT 0x60", 672b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 673a138b568SLen Brown .exit_latency = 2600, 674a138b568SLen Brown .target_residency = 7700, 6755fe2e527SRafael J. Wysocki .enter = &intel_idle, 67628ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 677a138b568SLen Brown { 678a138b568SLen Brown .enter = NULL } 679a138b568SLen Brown }; 68085a4d2d4SLen Brown 681ab1a8522SRafael J. Wysocki static struct cpuidle_state skl_cstates[] __initdata = { 682493f133fSLen Brown { 683de09cdd0SLen Brown .name = "C1", 684493f133fSLen Brown .desc = "MWAIT 0x00", 685493f133fSLen Brown .flags = MWAIT2flg(0x00), 686493f133fSLen Brown .exit_latency = 2, 687493f133fSLen Brown .target_residency = 2, 688493f133fSLen Brown .enter = &intel_idle, 68928ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 690493f133fSLen Brown { 691de09cdd0SLen Brown .name = "C1E", 692493f133fSLen Brown .desc = "MWAIT 0x01", 693e6d4f08aSRafael J. Wysocki .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 694493f133fSLen Brown .exit_latency = 10, 695493f133fSLen Brown .target_residency = 20, 696493f133fSLen Brown .enter = &intel_idle, 69728ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 698493f133fSLen Brown { 699de09cdd0SLen Brown .name = "C3", 700493f133fSLen Brown .desc = "MWAIT 0x10", 701493f133fSLen Brown .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 702493f133fSLen Brown .exit_latency = 70, 703493f133fSLen Brown .target_residency = 100, 704493f133fSLen Brown .enter = &intel_idle, 70528ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 706493f133fSLen Brown { 707de09cdd0SLen Brown .name = "C6", 708493f133fSLen Brown .desc = "MWAIT 0x20", 709*bf5835bcSPeter Zijlstra .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 710135919a3SLen Brown .exit_latency = 85, 711493f133fSLen Brown .target_residency = 200, 712493f133fSLen Brown .enter = &intel_idle, 71328ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 714493f133fSLen Brown { 715de09cdd0SLen Brown .name = "C7s", 716493f133fSLen Brown .desc = "MWAIT 0x33", 717*bf5835bcSPeter Zijlstra .flags = MWAIT2flg(0x33) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 718493f133fSLen Brown .exit_latency = 124, 719493f133fSLen Brown .target_residency = 800, 720493f133fSLen Brown .enter = &intel_idle, 72128ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 722493f133fSLen Brown { 723de09cdd0SLen Brown .name = "C8", 724493f133fSLen Brown .desc = "MWAIT 0x40", 725*bf5835bcSPeter Zijlstra .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 726135919a3SLen Brown .exit_latency = 200, 727493f133fSLen Brown .target_residency = 800, 728493f133fSLen Brown .enter = &intel_idle, 72928ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 730493f133fSLen Brown { 731de09cdd0SLen Brown .name = "C9", 732135919a3SLen Brown .desc = "MWAIT 0x50", 733*bf5835bcSPeter Zijlstra .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 734135919a3SLen Brown .exit_latency = 480, 735135919a3SLen Brown .target_residency = 5000, 736135919a3SLen Brown .enter = &intel_idle, 73728ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 738135919a3SLen Brown { 739de09cdd0SLen Brown .name = "C10", 740493f133fSLen Brown .desc = "MWAIT 0x60", 741*bf5835bcSPeter Zijlstra .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 742493f133fSLen Brown .exit_latency = 890, 743493f133fSLen Brown .target_residency = 5000, 744493f133fSLen Brown .enter = &intel_idle, 74528ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 746493f133fSLen Brown { 747493f133fSLen Brown .enter = NULL } 748493f133fSLen Brown }; 749493f133fSLen Brown 750ab1a8522SRafael J. Wysocki static struct cpuidle_state skx_cstates[] __initdata = { 751f9e71657SLen Brown { 752de09cdd0SLen Brown .name = "C1", 753f9e71657SLen Brown .desc = "MWAIT 0x00", 754c227233aSArtem Bityutskiy .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_IRQ_ENABLE, 755f9e71657SLen Brown .exit_latency = 2, 756f9e71657SLen Brown .target_residency = 2, 757f9e71657SLen Brown .enter = &intel_idle, 75828ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 759f9e71657SLen Brown { 760de09cdd0SLen Brown .name = "C1E", 761f9e71657SLen Brown .desc = "MWAIT 0x01", 762e6d4f08aSRafael J. Wysocki .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 763f9e71657SLen Brown .exit_latency = 10, 764f9e71657SLen Brown .target_residency = 20, 765f9e71657SLen Brown .enter = &intel_idle, 76628ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 767f9e71657SLen Brown { 768de09cdd0SLen Brown .name = "C6", 769f9e71657SLen Brown .desc = "MWAIT 0x20", 770*bf5835bcSPeter Zijlstra .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 771f9e71657SLen Brown .exit_latency = 133, 772f9e71657SLen Brown .target_residency = 600, 773f9e71657SLen Brown .enter = &intel_idle, 77428ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 775f9e71657SLen Brown { 776f9e71657SLen Brown .enter = NULL } 777f9e71657SLen Brown }; 778f9e71657SLen Brown 779a472ad2bSChen Yu static struct cpuidle_state icx_cstates[] __initdata = { 780a472ad2bSChen Yu { 781a472ad2bSChen Yu .name = "C1", 782a472ad2bSChen Yu .desc = "MWAIT 0x00", 783c227233aSArtem Bityutskiy .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_IRQ_ENABLE, 784a472ad2bSChen Yu .exit_latency = 1, 785a472ad2bSChen Yu .target_residency = 1, 786a472ad2bSChen Yu .enter = &intel_idle, 787a472ad2bSChen Yu .enter_s2idle = intel_idle_s2idle, }, 788a472ad2bSChen Yu { 789a472ad2bSChen Yu .name = "C1E", 790a472ad2bSChen Yu .desc = "MWAIT 0x01", 791a472ad2bSChen Yu .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 792a472ad2bSChen Yu .exit_latency = 4, 793a472ad2bSChen Yu .target_residency = 4, 794a472ad2bSChen Yu .enter = &intel_idle, 795a472ad2bSChen Yu .enter_s2idle = intel_idle_s2idle, }, 796a472ad2bSChen Yu { 797a472ad2bSChen Yu .name = "C6", 798a472ad2bSChen Yu .desc = "MWAIT 0x20", 799a472ad2bSChen Yu .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 800d484b8bfSArtem Bityutskiy .exit_latency = 170, 801d484b8bfSArtem Bityutskiy .target_residency = 600, 802a472ad2bSChen Yu .enter = &intel_idle, 803a472ad2bSChen Yu .enter_s2idle = intel_idle_s2idle, }, 804a472ad2bSChen Yu { 805a472ad2bSChen Yu .enter = NULL } 806a472ad2bSChen Yu }; 807a472ad2bSChen Yu 8089edf3c0fSArtem Bityutskiy /* 809d1cf8bbfSZhang Rui * On AlderLake C1 has to be disabled if C1E is enabled, and vice versa. 810d1cf8bbfSZhang Rui * C1E is enabled only if "C1E promotion" bit is set in MSR_IA32_POWER_CTL. 811d1cf8bbfSZhang Rui * But in this case there is effectively no C1, because C1 requests are 812d1cf8bbfSZhang Rui * promoted to C1E. If the "C1E promotion" bit is cleared, then both C1 813d1cf8bbfSZhang Rui * and C1E requests end up with C1, so there is effectively no C1E. 814d1cf8bbfSZhang Rui * 815d1cf8bbfSZhang Rui * By default we enable C1E and disable C1 by marking it with 816d1cf8bbfSZhang Rui * 'CPUIDLE_FLAG_UNUSABLE'. 817d1cf8bbfSZhang Rui */ 818d1cf8bbfSZhang Rui static struct cpuidle_state adl_cstates[] __initdata = { 819d1cf8bbfSZhang Rui { 820d1cf8bbfSZhang Rui .name = "C1", 821d1cf8bbfSZhang Rui .desc = "MWAIT 0x00", 822d1cf8bbfSZhang Rui .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_UNUSABLE, 823d1cf8bbfSZhang Rui .exit_latency = 1, 824d1cf8bbfSZhang Rui .target_residency = 1, 825d1cf8bbfSZhang Rui .enter = &intel_idle, 826d1cf8bbfSZhang Rui .enter_s2idle = intel_idle_s2idle, }, 827d1cf8bbfSZhang Rui { 828d1cf8bbfSZhang Rui .name = "C1E", 829d1cf8bbfSZhang Rui .desc = "MWAIT 0x01", 830d1cf8bbfSZhang Rui .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 831d1cf8bbfSZhang Rui .exit_latency = 2, 832d1cf8bbfSZhang Rui .target_residency = 4, 833d1cf8bbfSZhang Rui .enter = &intel_idle, 834d1cf8bbfSZhang Rui .enter_s2idle = intel_idle_s2idle, }, 835d1cf8bbfSZhang Rui { 836d1cf8bbfSZhang Rui .name = "C6", 837d1cf8bbfSZhang Rui .desc = "MWAIT 0x20", 838d1cf8bbfSZhang Rui .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 839d1cf8bbfSZhang Rui .exit_latency = 220, 840d1cf8bbfSZhang Rui .target_residency = 600, 841d1cf8bbfSZhang Rui .enter = &intel_idle, 842d1cf8bbfSZhang Rui .enter_s2idle = intel_idle_s2idle, }, 843d1cf8bbfSZhang Rui { 844d1cf8bbfSZhang Rui .name = "C8", 845d1cf8bbfSZhang Rui .desc = "MWAIT 0x40", 846d1cf8bbfSZhang Rui .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, 847d1cf8bbfSZhang Rui .exit_latency = 280, 848d1cf8bbfSZhang Rui .target_residency = 800, 849d1cf8bbfSZhang Rui .enter = &intel_idle, 850d1cf8bbfSZhang Rui .enter_s2idle = intel_idle_s2idle, }, 851d1cf8bbfSZhang Rui { 852d1cf8bbfSZhang Rui .name = "C10", 853d1cf8bbfSZhang Rui .desc = "MWAIT 0x60", 854d1cf8bbfSZhang Rui .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 855d1cf8bbfSZhang Rui .exit_latency = 680, 856d1cf8bbfSZhang Rui .target_residency = 2000, 857d1cf8bbfSZhang Rui .enter = &intel_idle, 858d1cf8bbfSZhang Rui .enter_s2idle = intel_idle_s2idle, }, 859d1cf8bbfSZhang Rui { 860d1cf8bbfSZhang Rui .enter = NULL } 861d1cf8bbfSZhang Rui }; 862d1cf8bbfSZhang Rui 863d1cf8bbfSZhang Rui static struct cpuidle_state adl_l_cstates[] __initdata = { 864d1cf8bbfSZhang Rui { 865d1cf8bbfSZhang Rui .name = "C1", 866d1cf8bbfSZhang Rui .desc = "MWAIT 0x00", 867d1cf8bbfSZhang Rui .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_UNUSABLE, 868d1cf8bbfSZhang Rui .exit_latency = 1, 869d1cf8bbfSZhang Rui .target_residency = 1, 870d1cf8bbfSZhang Rui .enter = &intel_idle, 871d1cf8bbfSZhang Rui .enter_s2idle = intel_idle_s2idle, }, 872d1cf8bbfSZhang Rui { 873d1cf8bbfSZhang Rui .name = "C1E", 874d1cf8bbfSZhang Rui .desc = "MWAIT 0x01", 875d1cf8bbfSZhang Rui .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 876d1cf8bbfSZhang Rui .exit_latency = 2, 877d1cf8bbfSZhang Rui .target_residency = 4, 878d1cf8bbfSZhang Rui .enter = &intel_idle, 879d1cf8bbfSZhang Rui .enter_s2idle = intel_idle_s2idle, }, 880d1cf8bbfSZhang Rui { 881d1cf8bbfSZhang Rui .name = "C6", 882d1cf8bbfSZhang Rui .desc = "MWAIT 0x20", 883d1cf8bbfSZhang Rui .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 884d1cf8bbfSZhang Rui .exit_latency = 170, 885d1cf8bbfSZhang Rui .target_residency = 500, 886d1cf8bbfSZhang Rui .enter = &intel_idle, 887d1cf8bbfSZhang Rui .enter_s2idle = intel_idle_s2idle, }, 888d1cf8bbfSZhang Rui { 889d1cf8bbfSZhang Rui .name = "C8", 890d1cf8bbfSZhang Rui .desc = "MWAIT 0x40", 891d1cf8bbfSZhang Rui .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, 892d1cf8bbfSZhang Rui .exit_latency = 200, 893d1cf8bbfSZhang Rui .target_residency = 600, 894d1cf8bbfSZhang Rui .enter = &intel_idle, 895d1cf8bbfSZhang Rui .enter_s2idle = intel_idle_s2idle, }, 896d1cf8bbfSZhang Rui { 897d1cf8bbfSZhang Rui .name = "C10", 898d1cf8bbfSZhang Rui .desc = "MWAIT 0x60", 899d1cf8bbfSZhang Rui .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 900d1cf8bbfSZhang Rui .exit_latency = 230, 901d1cf8bbfSZhang Rui .target_residency = 700, 902d1cf8bbfSZhang Rui .enter = &intel_idle, 903d1cf8bbfSZhang Rui .enter_s2idle = intel_idle_s2idle, }, 904d1cf8bbfSZhang Rui { 905d1cf8bbfSZhang Rui .enter = NULL } 906d1cf8bbfSZhang Rui }; 907d1cf8bbfSZhang Rui 908d1cf8bbfSZhang Rui /* 9099edf3c0fSArtem Bityutskiy * On Sapphire Rapids Xeon C1 has to be disabled if C1E is enabled, and vice 9109edf3c0fSArtem Bityutskiy * versa. On SPR C1E is enabled only if "C1E promotion" bit is set in 9119edf3c0fSArtem Bityutskiy * MSR_IA32_POWER_CTL. But in this case there effectively no C1, because C1 9129edf3c0fSArtem Bityutskiy * requests are promoted to C1E. If the "C1E promotion" bit is cleared, then 9139edf3c0fSArtem Bityutskiy * both C1 and C1E requests end up with C1, so there is effectively no C1E. 9149edf3c0fSArtem Bityutskiy * 9159edf3c0fSArtem Bityutskiy * By default we enable C1 and disable C1E by marking it with 9169edf3c0fSArtem Bityutskiy * 'CPUIDLE_FLAG_UNUSABLE'. 9179edf3c0fSArtem Bityutskiy */ 9189edf3c0fSArtem Bityutskiy static struct cpuidle_state spr_cstates[] __initdata = { 9199edf3c0fSArtem Bityutskiy { 9209edf3c0fSArtem Bityutskiy .name = "C1", 9219edf3c0fSArtem Bityutskiy .desc = "MWAIT 0x00", 9229edf3c0fSArtem Bityutskiy .flags = MWAIT2flg(0x00), 9239edf3c0fSArtem Bityutskiy .exit_latency = 1, 9249edf3c0fSArtem Bityutskiy .target_residency = 1, 9259edf3c0fSArtem Bityutskiy .enter = &intel_idle, 9269edf3c0fSArtem Bityutskiy .enter_s2idle = intel_idle_s2idle, }, 9279edf3c0fSArtem Bityutskiy { 9289edf3c0fSArtem Bityutskiy .name = "C1E", 9299edf3c0fSArtem Bityutskiy .desc = "MWAIT 0x01", 93003eb6522SRafael J. Wysocki .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE | 9319edf3c0fSArtem Bityutskiy CPUIDLE_FLAG_UNUSABLE, 9329edf3c0fSArtem Bityutskiy .exit_latency = 2, 9339edf3c0fSArtem Bityutskiy .target_residency = 4, 9349edf3c0fSArtem Bityutskiy .enter = &intel_idle, 9359edf3c0fSArtem Bityutskiy .enter_s2idle = intel_idle_s2idle, }, 9369edf3c0fSArtem Bityutskiy { 9379edf3c0fSArtem Bityutskiy .name = "C6", 9389edf3c0fSArtem Bityutskiy .desc = "MWAIT 0x20", 9399edf3c0fSArtem Bityutskiy .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 9409edf3c0fSArtem Bityutskiy .exit_latency = 290, 9419edf3c0fSArtem Bityutskiy .target_residency = 800, 9429edf3c0fSArtem Bityutskiy .enter = &intel_idle, 9439edf3c0fSArtem Bityutskiy .enter_s2idle = intel_idle_s2idle, }, 9449edf3c0fSArtem Bityutskiy { 9459edf3c0fSArtem Bityutskiy .enter = NULL } 9469edf3c0fSArtem Bityutskiy }; 9479edf3c0fSArtem Bityutskiy 948ab1a8522SRafael J. Wysocki static struct cpuidle_state atom_cstates[] __initdata = { 949e022e7ebSLen Brown { 950de09cdd0SLen Brown .name = "C1E", 95126717172SLen Brown .desc = "MWAIT 0x00", 952b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x00), 95332e95180SLen Brown .exit_latency = 10, 95432e95180SLen Brown .target_residency = 20, 9555fe2e527SRafael J. Wysocki .enter = &intel_idle, 95628ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 957e022e7ebSLen Brown { 958de09cdd0SLen Brown .name = "C2", 95926717172SLen Brown .desc = "MWAIT 0x10", 960b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x10), 96126717172SLen Brown .exit_latency = 20, 96226717172SLen Brown .target_residency = 80, 9635fe2e527SRafael J. Wysocki .enter = &intel_idle, 96428ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 965e022e7ebSLen Brown { 966de09cdd0SLen Brown .name = "C4", 96726717172SLen Brown .desc = "MWAIT 0x30", 968b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, 96926717172SLen Brown .exit_latency = 100, 97026717172SLen Brown .target_residency = 400, 9715fe2e527SRafael J. Wysocki .enter = &intel_idle, 97228ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 973e022e7ebSLen Brown { 974de09cdd0SLen Brown .name = "C6", 9757fcca7d9SLen Brown .desc = "MWAIT 0x52", 976b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, 9777fcca7d9SLen Brown .exit_latency = 140, 9787fcca7d9SLen Brown .target_residency = 560, 9795fe2e527SRafael J. Wysocki .enter = &intel_idle, 98028ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 981e022e7ebSLen Brown { 982e022e7ebSLen Brown .enter = NULL } 98326717172SLen Brown }; 984ab1a8522SRafael J. Wysocki static struct cpuidle_state tangier_cstates[] __initdata = { 9855e7ec268SAndy Shevchenko { 986de09cdd0SLen Brown .name = "C1", 9875e7ec268SAndy Shevchenko .desc = "MWAIT 0x00", 9885e7ec268SAndy Shevchenko .flags = MWAIT2flg(0x00), 9895e7ec268SAndy Shevchenko .exit_latency = 1, 9905e7ec268SAndy Shevchenko .target_residency = 4, 9915e7ec268SAndy Shevchenko .enter = &intel_idle, 99228ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 9935e7ec268SAndy Shevchenko { 994de09cdd0SLen Brown .name = "C4", 9955e7ec268SAndy Shevchenko .desc = "MWAIT 0x30", 9965e7ec268SAndy Shevchenko .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, 9975e7ec268SAndy Shevchenko .exit_latency = 100, 9985e7ec268SAndy Shevchenko .target_residency = 400, 9995e7ec268SAndy Shevchenko .enter = &intel_idle, 100028ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 10015e7ec268SAndy Shevchenko { 1002de09cdd0SLen Brown .name = "C6", 10035e7ec268SAndy Shevchenko .desc = "MWAIT 0x52", 10045e7ec268SAndy Shevchenko .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, 10055e7ec268SAndy Shevchenko .exit_latency = 140, 10065e7ec268SAndy Shevchenko .target_residency = 560, 10075e7ec268SAndy Shevchenko .enter = &intel_idle, 100828ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 10095e7ec268SAndy Shevchenko { 1010de09cdd0SLen Brown .name = "C7", 10115e7ec268SAndy Shevchenko .desc = "MWAIT 0x60", 10125e7ec268SAndy Shevchenko .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 10135e7ec268SAndy Shevchenko .exit_latency = 1200, 10145e7ec268SAndy Shevchenko .target_residency = 4000, 10155e7ec268SAndy Shevchenko .enter = &intel_idle, 101628ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 10175e7ec268SAndy Shevchenko { 1018de09cdd0SLen Brown .name = "C9", 10195e7ec268SAndy Shevchenko .desc = "MWAIT 0x64", 10205e7ec268SAndy Shevchenko .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED, 10215e7ec268SAndy Shevchenko .exit_latency = 10000, 10225e7ec268SAndy Shevchenko .target_residency = 20000, 10235e7ec268SAndy Shevchenko .enter = &intel_idle, 102428ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 10255e7ec268SAndy Shevchenko { 10265e7ec268SAndy Shevchenko .enter = NULL } 10275e7ec268SAndy Shevchenko }; 1028ab1a8522SRafael J. Wysocki static struct cpuidle_state avn_cstates[] __initdata = { 1029fab04b22SLen Brown { 1030de09cdd0SLen Brown .name = "C1", 1031fab04b22SLen Brown .desc = "MWAIT 0x00", 1032b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x00), 1033fab04b22SLen Brown .exit_latency = 2, 1034fab04b22SLen Brown .target_residency = 2, 10355fe2e527SRafael J. Wysocki .enter = &intel_idle, 103628ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 1037fab04b22SLen Brown { 1038de09cdd0SLen Brown .name = "C6", 1039fab04b22SLen Brown .desc = "MWAIT 0x51", 1040b82b6ccaSDaniel Lezcano .flags = MWAIT2flg(0x51) | CPUIDLE_FLAG_TLB_FLUSHED, 1041fab04b22SLen Brown .exit_latency = 15, 1042fab04b22SLen Brown .target_residency = 45, 10435fe2e527SRafael J. Wysocki .enter = &intel_idle, 104428ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 104588390996SJiang Liu { 104688390996SJiang Liu .enter = NULL } 1047fab04b22SLen Brown }; 1048ab1a8522SRafael J. Wysocki static struct cpuidle_state knl_cstates[] __initdata = { 1049281baf7aSDasaratharaman Chandramouli { 1050de09cdd0SLen Brown .name = "C1", 1051281baf7aSDasaratharaman Chandramouli .desc = "MWAIT 0x00", 1052281baf7aSDasaratharaman Chandramouli .flags = MWAIT2flg(0x00), 1053281baf7aSDasaratharaman Chandramouli .exit_latency = 1, 1054281baf7aSDasaratharaman Chandramouli .target_residency = 2, 1055281baf7aSDasaratharaman Chandramouli .enter = &intel_idle, 105628ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle }, 1057281baf7aSDasaratharaman Chandramouli { 1058de09cdd0SLen Brown .name = "C6", 1059281baf7aSDasaratharaman Chandramouli .desc = "MWAIT 0x10", 1060281baf7aSDasaratharaman Chandramouli .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 1061281baf7aSDasaratharaman Chandramouli .exit_latency = 120, 1062281baf7aSDasaratharaman Chandramouli .target_residency = 500, 1063281baf7aSDasaratharaman Chandramouli .enter = &intel_idle, 106428ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle }, 1065281baf7aSDasaratharaman Chandramouli { 1066281baf7aSDasaratharaman Chandramouli .enter = NULL } 1067281baf7aSDasaratharaman Chandramouli }; 106826717172SLen Brown 1069ab1a8522SRafael J. Wysocki static struct cpuidle_state bxt_cstates[] __initdata = { 10705dcef694SLen Brown { 1071de09cdd0SLen Brown .name = "C1", 10725dcef694SLen Brown .desc = "MWAIT 0x00", 10735dcef694SLen Brown .flags = MWAIT2flg(0x00), 10745dcef694SLen Brown .exit_latency = 2, 10755dcef694SLen Brown .target_residency = 2, 10765dcef694SLen Brown .enter = &intel_idle, 107728ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 10785dcef694SLen Brown { 1079de09cdd0SLen Brown .name = "C1E", 10805dcef694SLen Brown .desc = "MWAIT 0x01", 1081e6d4f08aSRafael J. Wysocki .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 10825dcef694SLen Brown .exit_latency = 10, 10835dcef694SLen Brown .target_residency = 20, 10845dcef694SLen Brown .enter = &intel_idle, 108528ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 10865dcef694SLen Brown { 1087de09cdd0SLen Brown .name = "C6", 10885dcef694SLen Brown .desc = "MWAIT 0x20", 10895dcef694SLen Brown .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 10905dcef694SLen Brown .exit_latency = 133, 10915dcef694SLen Brown .target_residency = 133, 10925dcef694SLen Brown .enter = &intel_idle, 109328ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 10945dcef694SLen Brown { 1095de09cdd0SLen Brown .name = "C7s", 10965dcef694SLen Brown .desc = "MWAIT 0x31", 10975dcef694SLen Brown .flags = MWAIT2flg(0x31) | CPUIDLE_FLAG_TLB_FLUSHED, 10985dcef694SLen Brown .exit_latency = 155, 10995dcef694SLen Brown .target_residency = 155, 11005dcef694SLen Brown .enter = &intel_idle, 110128ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 11025dcef694SLen Brown { 1103de09cdd0SLen Brown .name = "C8", 11045dcef694SLen Brown .desc = "MWAIT 0x40", 11055dcef694SLen Brown .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, 11065dcef694SLen Brown .exit_latency = 1000, 11075dcef694SLen Brown .target_residency = 1000, 11085dcef694SLen Brown .enter = &intel_idle, 110928ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 11105dcef694SLen Brown { 1111de09cdd0SLen Brown .name = "C9", 11125dcef694SLen Brown .desc = "MWAIT 0x50", 11135dcef694SLen Brown .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, 11145dcef694SLen Brown .exit_latency = 2000, 11155dcef694SLen Brown .target_residency = 2000, 11165dcef694SLen Brown .enter = &intel_idle, 111728ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 11185dcef694SLen Brown { 1119de09cdd0SLen Brown .name = "C10", 11205dcef694SLen Brown .desc = "MWAIT 0x60", 11215dcef694SLen Brown .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 11225dcef694SLen Brown .exit_latency = 10000, 11235dcef694SLen Brown .target_residency = 10000, 11245dcef694SLen Brown .enter = &intel_idle, 112528ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 11265dcef694SLen Brown { 11275dcef694SLen Brown .enter = NULL } 11285dcef694SLen Brown }; 11295dcef694SLen Brown 1130ab1a8522SRafael J. Wysocki static struct cpuidle_state dnv_cstates[] __initdata = { 11310080d65bSJacob Pan { 1132de09cdd0SLen Brown .name = "C1", 11330080d65bSJacob Pan .desc = "MWAIT 0x00", 11340080d65bSJacob Pan .flags = MWAIT2flg(0x00), 11350080d65bSJacob Pan .exit_latency = 2, 11360080d65bSJacob Pan .target_residency = 2, 11370080d65bSJacob Pan .enter = &intel_idle, 113828ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 11390080d65bSJacob Pan { 1140de09cdd0SLen Brown .name = "C1E", 11410080d65bSJacob Pan .desc = "MWAIT 0x01", 1142e6d4f08aSRafael J. Wysocki .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 11430080d65bSJacob Pan .exit_latency = 10, 11440080d65bSJacob Pan .target_residency = 20, 11450080d65bSJacob Pan .enter = &intel_idle, 114628ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 11470080d65bSJacob Pan { 1148de09cdd0SLen Brown .name = "C6", 11490080d65bSJacob Pan .desc = "MWAIT 0x20", 11500080d65bSJacob Pan .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 11510080d65bSJacob Pan .exit_latency = 50, 11520080d65bSJacob Pan .target_residency = 500, 11530080d65bSJacob Pan .enter = &intel_idle, 115428ba086eSRafael J. Wysocki .enter_s2idle = intel_idle_s2idle, }, 11550080d65bSJacob Pan { 11560080d65bSJacob Pan .enter = NULL } 11570080d65bSJacob Pan }; 11580080d65bSJacob Pan 11599cf93f05SArtem Bityutskiy /* 11609cf93f05SArtem Bityutskiy * Note, depending on HW and FW revision, SnowRidge SoC may or may not support 11619cf93f05SArtem Bityutskiy * C6, and this is indicated in the CPUID mwait leaf. 11629cf93f05SArtem Bityutskiy */ 11639cf93f05SArtem Bityutskiy static struct cpuidle_state snr_cstates[] __initdata = { 11649cf93f05SArtem Bityutskiy { 11659cf93f05SArtem Bityutskiy .name = "C1", 11669cf93f05SArtem Bityutskiy .desc = "MWAIT 0x00", 11679cf93f05SArtem Bityutskiy .flags = MWAIT2flg(0x00), 11689cf93f05SArtem Bityutskiy .exit_latency = 2, 11699cf93f05SArtem Bityutskiy .target_residency = 2, 11709cf93f05SArtem Bityutskiy .enter = &intel_idle, 11719cf93f05SArtem Bityutskiy .enter_s2idle = intel_idle_s2idle, }, 11729cf93f05SArtem Bityutskiy { 11739cf93f05SArtem Bityutskiy .name = "C1E", 11749cf93f05SArtem Bityutskiy .desc = "MWAIT 0x01", 11759cf93f05SArtem Bityutskiy .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 11769cf93f05SArtem Bityutskiy .exit_latency = 15, 11779cf93f05SArtem Bityutskiy .target_residency = 25, 11789cf93f05SArtem Bityutskiy .enter = &intel_idle, 11799cf93f05SArtem Bityutskiy .enter_s2idle = intel_idle_s2idle, }, 11809cf93f05SArtem Bityutskiy { 11819cf93f05SArtem Bityutskiy .name = "C6", 11829cf93f05SArtem Bityutskiy .desc = "MWAIT 0x20", 11839cf93f05SArtem Bityutskiy .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 11849cf93f05SArtem Bityutskiy .exit_latency = 130, 11859cf93f05SArtem Bityutskiy .target_residency = 500, 11869cf93f05SArtem Bityutskiy .enter = &intel_idle, 11879cf93f05SArtem Bityutskiy .enter_s2idle = intel_idle_s2idle, }, 11889cf93f05SArtem Bityutskiy { 11899cf93f05SArtem Bityutskiy .enter = NULL } 11909cf93f05SArtem Bityutskiy }; 11919cf93f05SArtem Bityutskiy 1192ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_nehalem __initconst = { 1193b66b8b9aSAndi Kleen .state_table = nehalem_cstates, 1194b66b8b9aSAndi Kleen .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, 119532e95180SLen Brown .disable_promotion_to_c1e = true, 1196b66b8b9aSAndi Kleen }; 1197b66b8b9aSAndi Kleen 1198ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_nhx __initconst = { 1199e6d4f08aSRafael J. Wysocki .state_table = nehalem_cstates, 1200e6d4f08aSRafael J. Wysocki .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, 1201e6d4f08aSRafael J. Wysocki .disable_promotion_to_c1e = true, 1202e6d4f08aSRafael J. Wysocki .use_acpi = true, 1203e6d4f08aSRafael J. Wysocki }; 1204e6d4f08aSRafael J. Wysocki 1205ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_atom __initconst = { 1206b66b8b9aSAndi Kleen .state_table = atom_cstates, 1207b66b8b9aSAndi Kleen }; 1208b66b8b9aSAndi Kleen 1209ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_tangier __initconst = { 12105e7ec268SAndy Shevchenko .state_table = tangier_cstates, 12115e7ec268SAndy Shevchenko }; 12125e7ec268SAndy Shevchenko 1213ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_lincroft __initconst = { 1214b66b8b9aSAndi Kleen .state_table = atom_cstates, 1215b66b8b9aSAndi Kleen .auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE, 1216b66b8b9aSAndi Kleen }; 1217b66b8b9aSAndi Kleen 1218ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_snb __initconst = { 1219b66b8b9aSAndi Kleen .state_table = snb_cstates, 122032e95180SLen Brown .disable_promotion_to_c1e = true, 1221b66b8b9aSAndi Kleen }; 1222b66b8b9aSAndi Kleen 1223ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_snx __initconst = { 1224e6d4f08aSRafael J. Wysocki .state_table = snb_cstates, 1225e6d4f08aSRafael J. Wysocki .disable_promotion_to_c1e = true, 1226e6d4f08aSRafael J. Wysocki .use_acpi = true, 1227e6d4f08aSRafael J. Wysocki }; 1228e6d4f08aSRafael J. Wysocki 1229ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_byt __initconst = { 1230718987d6SLen Brown .state_table = byt_cstates, 1231718987d6SLen Brown .disable_promotion_to_c1e = true, 12328c058d53SLen Brown .byt_auto_demotion_disable_flag = true, 1233718987d6SLen Brown }; 1234718987d6SLen Brown 1235ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_cht __initconst = { 1236cab07a56SLen Brown .state_table = cht_cstates, 1237cab07a56SLen Brown .disable_promotion_to_c1e = true, 1238cab07a56SLen Brown .byt_auto_demotion_disable_flag = true, 1239cab07a56SLen Brown }; 1240cab07a56SLen Brown 1241ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_ivb __initconst = { 12426edab08cSLen Brown .state_table = ivb_cstates, 124332e95180SLen Brown .disable_promotion_to_c1e = true, 12446edab08cSLen Brown }; 12456edab08cSLen Brown 1246ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_ivt __initconst = { 12470138d8f0SLen Brown .state_table = ivt_cstates, 12480138d8f0SLen Brown .disable_promotion_to_c1e = true, 1249e6d4f08aSRafael J. Wysocki .use_acpi = true, 12500138d8f0SLen Brown }; 12510138d8f0SLen Brown 1252ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_hsw __initconst = { 125385a4d2d4SLen Brown .state_table = hsw_cstates, 125432e95180SLen Brown .disable_promotion_to_c1e = true, 125585a4d2d4SLen Brown }; 125685a4d2d4SLen Brown 1257ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_hsx __initconst = { 1258e6d4f08aSRafael J. Wysocki .state_table = hsw_cstates, 1259e6d4f08aSRafael J. Wysocki .disable_promotion_to_c1e = true, 1260e6d4f08aSRafael J. Wysocki .use_acpi = true, 1261e6d4f08aSRafael J. Wysocki }; 1262e6d4f08aSRafael J. Wysocki 1263ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_bdw __initconst = { 1264a138b568SLen Brown .state_table = bdw_cstates, 1265a138b568SLen Brown .disable_promotion_to_c1e = true, 1266a138b568SLen Brown }; 1267a138b568SLen Brown 1268ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_bdx __initconst = { 1269e6d4f08aSRafael J. Wysocki .state_table = bdw_cstates, 1270e6d4f08aSRafael J. Wysocki .disable_promotion_to_c1e = true, 1271e6d4f08aSRafael J. Wysocki .use_acpi = true, 1272e6d4f08aSRafael J. Wysocki }; 1273e6d4f08aSRafael J. Wysocki 1274ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_skl __initconst = { 1275493f133fSLen Brown .state_table = skl_cstates, 1276493f133fSLen Brown .disable_promotion_to_c1e = true, 1277493f133fSLen Brown }; 1278493f133fSLen Brown 1279ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_skx __initconst = { 1280f9e71657SLen Brown .state_table = skx_cstates, 1281f9e71657SLen Brown .disable_promotion_to_c1e = true, 1282e6d4f08aSRafael J. Wysocki .use_acpi = true, 1283f9e71657SLen Brown }; 1284493f133fSLen Brown 1285a472ad2bSChen Yu static const struct idle_cpu idle_cpu_icx __initconst = { 1286a472ad2bSChen Yu .state_table = icx_cstates, 1287a472ad2bSChen Yu .disable_promotion_to_c1e = true, 1288a472ad2bSChen Yu .use_acpi = true, 1289a472ad2bSChen Yu }; 1290a472ad2bSChen Yu 1291d1cf8bbfSZhang Rui static const struct idle_cpu idle_cpu_adl __initconst = { 1292d1cf8bbfSZhang Rui .state_table = adl_cstates, 1293d1cf8bbfSZhang Rui }; 1294d1cf8bbfSZhang Rui 1295d1cf8bbfSZhang Rui static const struct idle_cpu idle_cpu_adl_l __initconst = { 1296d1cf8bbfSZhang Rui .state_table = adl_l_cstates, 1297d1cf8bbfSZhang Rui }; 1298d1cf8bbfSZhang Rui 12999edf3c0fSArtem Bityutskiy static const struct idle_cpu idle_cpu_spr __initconst = { 13009edf3c0fSArtem Bityutskiy .state_table = spr_cstates, 13019edf3c0fSArtem Bityutskiy .disable_promotion_to_c1e = true, 13029edf3c0fSArtem Bityutskiy .use_acpi = true, 13039edf3c0fSArtem Bityutskiy }; 13049edf3c0fSArtem Bityutskiy 1305ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_avn __initconst = { 1306fab04b22SLen Brown .state_table = avn_cstates, 1307fab04b22SLen Brown .disable_promotion_to_c1e = true, 1308e6d4f08aSRafael J. Wysocki .use_acpi = true, 1309fab04b22SLen Brown }; 1310fab04b22SLen Brown 1311ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_knl __initconst = { 1312281baf7aSDasaratharaman Chandramouli .state_table = knl_cstates, 1313e6d4f08aSRafael J. Wysocki .use_acpi = true, 1314281baf7aSDasaratharaman Chandramouli }; 1315281baf7aSDasaratharaman Chandramouli 1316ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_bxt __initconst = { 13175dcef694SLen Brown .state_table = bxt_cstates, 13185dcef694SLen Brown .disable_promotion_to_c1e = true, 13195dcef694SLen Brown }; 13205dcef694SLen Brown 1321ab1a8522SRafael J. Wysocki static const struct idle_cpu idle_cpu_dnv __initconst = { 13220080d65bSJacob Pan .state_table = dnv_cstates, 13230080d65bSJacob Pan .disable_promotion_to_c1e = true, 1324e6d4f08aSRafael J. Wysocki .use_acpi = true, 13250080d65bSJacob Pan }; 13260080d65bSJacob Pan 13279cf93f05SArtem Bityutskiy static const struct idle_cpu idle_cpu_snr __initconst = { 13289cf93f05SArtem Bityutskiy .state_table = snr_cstates, 13299cf93f05SArtem Bityutskiy .disable_promotion_to_c1e = true, 13309cf93f05SArtem Bityutskiy .use_acpi = true, 13319cf93f05SArtem Bityutskiy }; 13329cf93f05SArtem Bityutskiy 1333d5cdc3c4SMathias Krause static const struct x86_cpu_id intel_idle_ids[] __initconst = { 13344a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EP, &idle_cpu_nhx), 13354a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(NEHALEM, &idle_cpu_nehalem), 13364a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_G, &idle_cpu_nehalem), 13374a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(WESTMERE, &idle_cpu_nehalem), 13384a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EP, &idle_cpu_nhx), 13394a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EX, &idle_cpu_nhx), 13404a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(ATOM_BONNELL, &idle_cpu_atom), 13414a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(ATOM_BONNELL_MID, &idle_cpu_lincroft), 13424a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EX, &idle_cpu_nhx), 13434a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE, &idle_cpu_snb), 13444a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE_X, &idle_cpu_snx), 13454a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(ATOM_SALTWELL, &idle_cpu_atom), 13464a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT, &idle_cpu_byt), 13474a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_MID, &idle_cpu_tangier), 13484a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT, &idle_cpu_cht), 13494a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE, &idle_cpu_ivb), 13504a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE_X, &idle_cpu_ivt), 13514a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(HASWELL, &idle_cpu_hsw), 13524a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, &idle_cpu_hsx), 13534a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(HASWELL_L, &idle_cpu_hsw), 13544a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(HASWELL_G, &idle_cpu_hsw), 13554a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_D, &idle_cpu_avn), 13564a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(BROADWELL, &idle_cpu_bdw), 13574a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_G, &idle_cpu_bdw), 13584a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, &idle_cpu_bdx), 13594a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D, &idle_cpu_bdx), 13604a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, &idle_cpu_skl), 13614a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, &idle_cpu_skl), 13624a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, &idle_cpu_skl), 13634a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, &idle_cpu_skl), 13644a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &idle_cpu_skx), 1365a472ad2bSChen Yu X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &idle_cpu_icx), 136622141d5fSArtem Bityutskiy X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &idle_cpu_icx), 1367d1cf8bbfSZhang Rui X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &idle_cpu_adl), 1368d1cf8bbfSZhang Rui X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &idle_cpu_adl_l), 13699edf3c0fSArtem Bityutskiy X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &idle_cpu_spr), 13704a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &idle_cpu_knl), 13714a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &idle_cpu_knl), 13724a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &idle_cpu_bxt), 13734a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS, &idle_cpu_bxt), 13744a9f45a0SThomas Gleixner X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D, &idle_cpu_dnv), 13759cf93f05SArtem Bityutskiy X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &idle_cpu_snr), 1376b66b8b9aSAndi Kleen {} 1377b66b8b9aSAndi Kleen }; 1378b66b8b9aSAndi Kleen 137918734958SRafael J. Wysocki static const struct x86_cpu_id intel_mwait_ids[] __initconst = { 13804a9f45a0SThomas Gleixner X86_MATCH_VENDOR_FAM_FEATURE(INTEL, 6, X86_FEATURE_MWAIT, NULL), 138118734958SRafael J. Wysocki {} 138218734958SRafael J. Wysocki }; 138318734958SRafael J. Wysocki 1384095928aeSRafael J. Wysocki static bool __init intel_idle_max_cstate_reached(int cstate) 138518734958SRafael J. Wysocki { 138618734958SRafael J. Wysocki if (cstate + 1 > max_cstate) { 138718734958SRafael J. Wysocki pr_info("max_cstate %d reached\n", max_cstate); 138818734958SRafael J. Wysocki return true; 138918734958SRafael J. Wysocki } 139018734958SRafael J. Wysocki return false; 139118734958SRafael J. Wysocki } 139218734958SRafael J. Wysocki 13934d916140SPeter Zijlstra static bool __init intel_idle_state_needs_timer_stop(struct cpuidle_state *state) 13944d916140SPeter Zijlstra { 13954d916140SPeter Zijlstra unsigned long eax = flg2MWAIT(state->flags); 13964d916140SPeter Zijlstra 13974d916140SPeter Zijlstra if (boot_cpu_has(X86_FEATURE_ARAT)) 13984d916140SPeter Zijlstra return false; 13994d916140SPeter Zijlstra 14004d916140SPeter Zijlstra /* 14014d916140SPeter Zijlstra * Switch over to one-shot tick broadcast if the target C-state 14024d916140SPeter Zijlstra * is deeper than C1. 14034d916140SPeter Zijlstra */ 14044d916140SPeter Zijlstra return !!((eax >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK); 14054d916140SPeter Zijlstra } 14064d916140SPeter Zijlstra 140718734958SRafael J. Wysocki #ifdef CONFIG_ACPI_PROCESSOR_CSTATE 140818734958SRafael J. Wysocki #include <acpi/processor.h> 140918734958SRafael J. Wysocki 14104ec32d9eSRafael J. Wysocki static bool no_acpi __read_mostly; 14114ec32d9eSRafael J. Wysocki module_param(no_acpi, bool, 0444); 14124ec32d9eSRafael J. Wysocki MODULE_PARM_DESC(no_acpi, "Do not use ACPI _CST for building the idle states list"); 14134ec32d9eSRafael J. Wysocki 14143a5be9b8SRafael J. Wysocki static bool force_use_acpi __read_mostly; /* No effect if no_acpi is set. */ 14153a5be9b8SRafael J. Wysocki module_param_named(use_acpi, force_use_acpi, bool, 0444); 14163a5be9b8SRafael J. Wysocki MODULE_PARM_DESC(use_acpi, "Use ACPI _CST for building the idle states list"); 14173a5be9b8SRafael J. Wysocki 1418095928aeSRafael J. Wysocki static struct acpi_processor_power acpi_state_table __initdata; 141918734958SRafael J. Wysocki 142018734958SRafael J. Wysocki /** 142118734958SRafael J. Wysocki * intel_idle_cst_usable - Check if the _CST information can be used. 142218734958SRafael J. Wysocki * 142318734958SRafael J. Wysocki * Check if all of the C-states listed by _CST in the max_cstate range are 142418734958SRafael J. Wysocki * ACPI_CSTATE_FFH, which means that they should be entered via MWAIT. 142518734958SRafael J. Wysocki */ 1426095928aeSRafael J. Wysocki static bool __init intel_idle_cst_usable(void) 142718734958SRafael J. Wysocki { 142818734958SRafael J. Wysocki int cstate, limit; 142918734958SRafael J. Wysocki 143018734958SRafael J. Wysocki limit = min_t(int, min_t(int, CPUIDLE_STATE_MAX, max_cstate + 1), 143118734958SRafael J. Wysocki acpi_state_table.count); 143218734958SRafael J. Wysocki 143318734958SRafael J. Wysocki for (cstate = 1; cstate < limit; cstate++) { 143418734958SRafael J. Wysocki struct acpi_processor_cx *cx = &acpi_state_table.states[cstate]; 143518734958SRafael J. Wysocki 143618734958SRafael J. Wysocki if (cx->entry_method != ACPI_CSTATE_FFH) 143718734958SRafael J. Wysocki return false; 143818734958SRafael J. Wysocki } 143918734958SRafael J. Wysocki 144018734958SRafael J. Wysocki return true; 144118734958SRafael J. Wysocki } 144218734958SRafael J. Wysocki 1443095928aeSRafael J. Wysocki static bool __init intel_idle_acpi_cst_extract(void) 144418734958SRafael J. Wysocki { 144518734958SRafael J. Wysocki unsigned int cpu; 144618734958SRafael J. Wysocki 14474ec32d9eSRafael J. Wysocki if (no_acpi) { 14484ec32d9eSRafael J. Wysocki pr_debug("Not allowed to use ACPI _CST\n"); 14494ec32d9eSRafael J. Wysocki return false; 14504ec32d9eSRafael J. Wysocki } 14514ec32d9eSRafael J. Wysocki 145218734958SRafael J. Wysocki for_each_possible_cpu(cpu) { 145318734958SRafael J. Wysocki struct acpi_processor *pr = per_cpu(processors, cpu); 145418734958SRafael J. Wysocki 145518734958SRafael J. Wysocki if (!pr) 145618734958SRafael J. Wysocki continue; 145718734958SRafael J. Wysocki 145818734958SRafael J. Wysocki if (acpi_processor_evaluate_cst(pr->handle, cpu, &acpi_state_table)) 145918734958SRafael J. Wysocki continue; 146018734958SRafael J. Wysocki 146118734958SRafael J. Wysocki acpi_state_table.count++; 146218734958SRafael J. Wysocki 146318734958SRafael J. Wysocki if (!intel_idle_cst_usable()) 146418734958SRafael J. Wysocki continue; 146518734958SRafael J. Wysocki 146675af76d0SMel Gorman if (!acpi_processor_claim_cst_control()) 146775af76d0SMel Gorman break; 146818734958SRafael J. Wysocki 146918734958SRafael J. Wysocki return true; 147018734958SRafael J. Wysocki } 147118734958SRafael J. Wysocki 147275af76d0SMel Gorman acpi_state_table.count = 0; 147318734958SRafael J. Wysocki pr_debug("ACPI _CST not found or not usable\n"); 147418734958SRafael J. Wysocki return false; 147518734958SRafael J. Wysocki } 147618734958SRafael J. Wysocki 1477095928aeSRafael J. Wysocki static void __init intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) 147818734958SRafael J. Wysocki { 147918734958SRafael J. Wysocki int cstate, limit = min_t(int, CPUIDLE_STATE_MAX, acpi_state_table.count); 148018734958SRafael J. Wysocki 148118734958SRafael J. Wysocki /* 148218734958SRafael J. Wysocki * If limit > 0, intel_idle_cst_usable() has returned 'true', so all of 148318734958SRafael J. Wysocki * the interesting states are ACPI_CSTATE_FFH. 148418734958SRafael J. Wysocki */ 148518734958SRafael J. Wysocki for (cstate = 1; cstate < limit; cstate++) { 148618734958SRafael J. Wysocki struct acpi_processor_cx *cx; 148718734958SRafael J. Wysocki struct cpuidle_state *state; 148818734958SRafael J. Wysocki 14894e0ba557SChen Yu if (intel_idle_max_cstate_reached(cstate - 1)) 149018734958SRafael J. Wysocki break; 149118734958SRafael J. Wysocki 149218734958SRafael J. Wysocki cx = &acpi_state_table.states[cstate]; 149318734958SRafael J. Wysocki 149418734958SRafael J. Wysocki state = &drv->states[drv->state_count++]; 149518734958SRafael J. Wysocki 149618734958SRafael J. Wysocki snprintf(state->name, CPUIDLE_NAME_LEN, "C%d_ACPI", cstate); 149718734958SRafael J. Wysocki strlcpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); 149818734958SRafael J. Wysocki state->exit_latency = cx->latency; 149918734958SRafael J. Wysocki /* 150018734958SRafael J. Wysocki * For C1-type C-states use the same number for both the exit 150118734958SRafael J. Wysocki * latency and target residency, because that is the case for 150218734958SRafael J. Wysocki * C1 in the majority of the static C-states tables above. 150318734958SRafael J. Wysocki * For the other types of C-states, however, set the target 150418734958SRafael J. Wysocki * residency to 3 times the exit latency which should lead to 150518734958SRafael J. Wysocki * a reasonable balance between energy-efficiency and 150618734958SRafael J. Wysocki * performance in the majority of interesting cases. 150718734958SRafael J. Wysocki */ 150818734958SRafael J. Wysocki state->target_residency = cx->latency; 150918734958SRafael J. Wysocki if (cx->type > ACPI_STATE_C1) 151018734958SRafael J. Wysocki state->target_residency *= 3; 151118734958SRafael J. Wysocki 151218734958SRafael J. Wysocki state->flags = MWAIT2flg(cx->address); 151318734958SRafael J. Wysocki if (cx->type > ACPI_STATE_C2) 151418734958SRafael J. Wysocki state->flags |= CPUIDLE_FLAG_TLB_FLUSHED; 151518734958SRafael J. Wysocki 15164dcb78eeSRafael J. Wysocki if (disabled_states_mask & BIT(cstate)) 15174dcb78eeSRafael J. Wysocki state->flags |= CPUIDLE_FLAG_OFF; 15184dcb78eeSRafael J. Wysocki 15196e1d2bc6SPeter Zijlstra if (intel_idle_state_needs_timer_stop(state)) 15206e1d2bc6SPeter Zijlstra state->flags |= CPUIDLE_FLAG_TIMER_STOP; 15216e1d2bc6SPeter Zijlstra 152218734958SRafael J. Wysocki state->enter = intel_idle; 152318734958SRafael J. Wysocki state->enter_s2idle = intel_idle_s2idle; 152418734958SRafael J. Wysocki } 152518734958SRafael J. Wysocki } 1526bff8e60aSRafael J. Wysocki 1527095928aeSRafael J. Wysocki static bool __init intel_idle_off_by_default(u32 mwait_hint) 1528bff8e60aSRafael J. Wysocki { 1529bff8e60aSRafael J. Wysocki int cstate, limit; 1530bff8e60aSRafael J. Wysocki 1531bff8e60aSRafael J. Wysocki /* 1532bff8e60aSRafael J. Wysocki * If there are no _CST C-states, do not disable any C-states by 1533bff8e60aSRafael J. Wysocki * default. 1534bff8e60aSRafael J. Wysocki */ 1535bff8e60aSRafael J. Wysocki if (!acpi_state_table.count) 1536bff8e60aSRafael J. Wysocki return false; 1537bff8e60aSRafael J. Wysocki 1538bff8e60aSRafael J. Wysocki limit = min_t(int, CPUIDLE_STATE_MAX, acpi_state_table.count); 1539bff8e60aSRafael J. Wysocki /* 1540bff8e60aSRafael J. Wysocki * If limit > 0, intel_idle_cst_usable() has returned 'true', so all of 1541bff8e60aSRafael J. Wysocki * the interesting states are ACPI_CSTATE_FFH. 1542bff8e60aSRafael J. Wysocki */ 1543bff8e60aSRafael J. Wysocki for (cstate = 1; cstate < limit; cstate++) { 1544bff8e60aSRafael J. Wysocki if (acpi_state_table.states[cstate].address == mwait_hint) 1545bff8e60aSRafael J. Wysocki return false; 1546bff8e60aSRafael J. Wysocki } 1547bff8e60aSRafael J. Wysocki return true; 1548bff8e60aSRafael J. Wysocki } 154918734958SRafael J. Wysocki #else /* !CONFIG_ACPI_PROCESSOR_CSTATE */ 15503a5be9b8SRafael J. Wysocki #define force_use_acpi (false) 15513a5be9b8SRafael J. Wysocki 155218734958SRafael J. Wysocki static inline bool intel_idle_acpi_cst_extract(void) { return false; } 155318734958SRafael J. Wysocki static inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { } 1554bff8e60aSRafael J. Wysocki static inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; } 155518734958SRafael J. Wysocki #endif /* !CONFIG_ACPI_PROCESSOR_CSTATE */ 155618734958SRafael J. Wysocki 15576eacb15fSRafael J. Wysocki /** 15586eacb15fSRafael J. Wysocki * ivt_idle_state_table_update - Tune the idle states table for Ivy Town. 15590138d8f0SLen Brown * 15606eacb15fSRafael J. Wysocki * Tune IVT multi-socket targets. 15616eacb15fSRafael J. Wysocki * Assumption: num_sockets == (max_package_num + 1). 15620138d8f0SLen Brown */ 1563095928aeSRafael J. Wysocki static void __init ivt_idle_state_table_update(void) 15640138d8f0SLen Brown { 15650138d8f0SLen Brown /* IVT uses a different table for 1-2, 3-4, and > 4 sockets */ 15660138d8f0SLen Brown int cpu, package_num, num_sockets = 1; 15670138d8f0SLen Brown 15680138d8f0SLen Brown for_each_online_cpu(cpu) { 15690138d8f0SLen Brown package_num = topology_physical_package_id(cpu); 15700138d8f0SLen Brown if (package_num + 1 > num_sockets) { 15710138d8f0SLen Brown num_sockets = package_num + 1; 15720138d8f0SLen Brown 1573d27dca42SChristoph Jaeger if (num_sockets > 4) { 15740138d8f0SLen Brown cpuidle_state_table = ivt_cstates_8s; 15750138d8f0SLen Brown return; 15760138d8f0SLen Brown } 15770138d8f0SLen Brown } 1578d27dca42SChristoph Jaeger } 15790138d8f0SLen Brown 15800138d8f0SLen Brown if (num_sockets > 2) 15810138d8f0SLen Brown cpuidle_state_table = ivt_cstates_4s; 1582d70e28f5SLen Brown 15830138d8f0SLen Brown /* else, 1 and 2 socket systems use default ivt_cstates */ 15840138d8f0SLen Brown } 15855dcef694SLen Brown 158686e9466aSRafael J. Wysocki /** 158786e9466aSRafael J. Wysocki * irtl_2_usec - IRTL to microseconds conversion. 158886e9466aSRafael J. Wysocki * @irtl: IRTL MSR value. 158986e9466aSRafael J. Wysocki * 159086e9466aSRafael J. Wysocki * Translate the IRTL (Interrupt Response Time Limit) MSR value to microseconds. 15915dcef694SLen Brown */ 159286e9466aSRafael J. Wysocki static unsigned long long __init irtl_2_usec(unsigned long long irtl) 159386e9466aSRafael J. Wysocki { 1594095928aeSRafael J. Wysocki static const unsigned int irtl_ns_units[] __initconst = { 1595095928aeSRafael J. Wysocki 1, 32, 1024, 32768, 1048576, 33554432, 0, 0 1596095928aeSRafael J. Wysocki }; 15975dcef694SLen Brown unsigned long long ns; 15985dcef694SLen Brown 15993451ab3eSJan Beulich if (!irtl) 16003451ab3eSJan Beulich return 0; 16013451ab3eSJan Beulich 1602bef45096SJan Beulich ns = irtl_ns_units[(irtl >> 10) & 0x7]; 16035dcef694SLen Brown 160486e9466aSRafael J. Wysocki return div_u64((irtl & 0x3FF) * ns, NSEC_PER_USEC); 16055dcef694SLen Brown } 160686e9466aSRafael J. Wysocki 16076eacb15fSRafael J. Wysocki /** 16086eacb15fSRafael J. Wysocki * bxt_idle_state_table_update - Fix up the Broxton idle states table. 16095dcef694SLen Brown * 16106eacb15fSRafael J. Wysocki * On BXT, trust the IRTL (Interrupt Response Time Limit) MSR to show the 16116eacb15fSRafael J. Wysocki * definitive maximum latency and use the same value for target_residency. 16125dcef694SLen Brown */ 1613095928aeSRafael J. Wysocki static void __init bxt_idle_state_table_update(void) 16145dcef694SLen Brown { 16155dcef694SLen Brown unsigned long long msr; 16163451ab3eSJan Beulich unsigned int usec; 16175dcef694SLen Brown 16185dcef694SLen Brown rdmsrl(MSR_PKGC6_IRTL, msr); 16193451ab3eSJan Beulich usec = irtl_2_usec(msr); 16203451ab3eSJan Beulich if (usec) { 16215dcef694SLen Brown bxt_cstates[2].exit_latency = usec; 16225dcef694SLen Brown bxt_cstates[2].target_residency = usec; 16235dcef694SLen Brown } 16245dcef694SLen Brown 16255dcef694SLen Brown rdmsrl(MSR_PKGC7_IRTL, msr); 16263451ab3eSJan Beulich usec = irtl_2_usec(msr); 16273451ab3eSJan Beulich if (usec) { 16285dcef694SLen Brown bxt_cstates[3].exit_latency = usec; 16295dcef694SLen Brown bxt_cstates[3].target_residency = usec; 16305dcef694SLen Brown } 16315dcef694SLen Brown 16325dcef694SLen Brown rdmsrl(MSR_PKGC8_IRTL, msr); 16333451ab3eSJan Beulich usec = irtl_2_usec(msr); 16343451ab3eSJan Beulich if (usec) { 16355dcef694SLen Brown bxt_cstates[4].exit_latency = usec; 16365dcef694SLen Brown bxt_cstates[4].target_residency = usec; 16375dcef694SLen Brown } 16385dcef694SLen Brown 16395dcef694SLen Brown rdmsrl(MSR_PKGC9_IRTL, msr); 16403451ab3eSJan Beulich usec = irtl_2_usec(msr); 16413451ab3eSJan Beulich if (usec) { 16425dcef694SLen Brown bxt_cstates[5].exit_latency = usec; 16435dcef694SLen Brown bxt_cstates[5].target_residency = usec; 16445dcef694SLen Brown } 16455dcef694SLen Brown 16465dcef694SLen Brown rdmsrl(MSR_PKGC10_IRTL, msr); 16473451ab3eSJan Beulich usec = irtl_2_usec(msr); 16483451ab3eSJan Beulich if (usec) { 16495dcef694SLen Brown bxt_cstates[6].exit_latency = usec; 16505dcef694SLen Brown bxt_cstates[6].target_residency = usec; 16515dcef694SLen Brown } 16525dcef694SLen Brown 16535dcef694SLen Brown } 16546eacb15fSRafael J. Wysocki 16556eacb15fSRafael J. Wysocki /** 16566eacb15fSRafael J. Wysocki * sklh_idle_state_table_update - Fix up the Sky Lake idle states table. 1657d70e28f5SLen Brown * 16586eacb15fSRafael J. Wysocki * On SKL-H (model 0x5e) skip C8 and C9 if C10 is enabled and SGX disabled. 1659d70e28f5SLen Brown */ 1660095928aeSRafael J. Wysocki static void __init sklh_idle_state_table_update(void) 1661d70e28f5SLen Brown { 1662d70e28f5SLen Brown unsigned long long msr; 1663d70e28f5SLen Brown unsigned int eax, ebx, ecx, edx; 1664d70e28f5SLen Brown 1665d70e28f5SLen Brown 1666d70e28f5SLen Brown /* if PC10 disabled via cmdline intel_idle.max_cstate=7 or shallower */ 1667d70e28f5SLen Brown if (max_cstate <= 7) 16680138d8f0SLen Brown return; 1669d70e28f5SLen Brown 1670d70e28f5SLen Brown /* if PC10 not present in CPUID.MWAIT.EDX */ 1671d70e28f5SLen Brown if ((mwait_substates & (0xF << 28)) == 0) 1672d70e28f5SLen Brown return; 1673d70e28f5SLen Brown 16746cfb2374SLen Brown rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr); 1675d70e28f5SLen Brown 1676d70e28f5SLen Brown /* PC10 is not enabled in PKG C-state limit */ 1677d70e28f5SLen Brown if ((msr & 0xF) != 8) 1678d70e28f5SLen Brown return; 1679d70e28f5SLen Brown 1680d70e28f5SLen Brown ecx = 0; 1681d70e28f5SLen Brown cpuid(7, &eax, &ebx, &ecx, &edx); 1682d70e28f5SLen Brown 1683d70e28f5SLen Brown /* if SGX is present */ 1684d70e28f5SLen Brown if (ebx & (1 << 2)) { 1685d70e28f5SLen Brown 168632ad73dbSSean Christopherson rdmsrl(MSR_IA32_FEAT_CTL, msr); 1687d70e28f5SLen Brown 1688d70e28f5SLen Brown /* if SGX is enabled */ 1689d70e28f5SLen Brown if (msr & (1 << 18)) 1690d70e28f5SLen Brown return; 1691d70e28f5SLen Brown } 1692d70e28f5SLen Brown 1693ba1e78a1SRafael J. Wysocki skl_cstates[5].flags |= CPUIDLE_FLAG_UNUSABLE; /* C8-SKL */ 1694ba1e78a1SRafael J. Wysocki skl_cstates[6].flags |= CPUIDLE_FLAG_UNUSABLE; /* C9-SKL */ 1695d70e28f5SLen Brown } 1696d70e28f5SLen Brown 169764233338SChen Yu /** 169864233338SChen Yu * skx_idle_state_table_update - Adjust the Sky Lake/Cascade Lake 169964233338SChen Yu * idle states table. 170064233338SChen Yu */ 170164233338SChen Yu static void __init skx_idle_state_table_update(void) 170264233338SChen Yu { 170364233338SChen Yu unsigned long long msr; 170464233338SChen Yu 170564233338SChen Yu rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr); 170664233338SChen Yu 170764233338SChen Yu /* 170864233338SChen Yu * 000b: C0/C1 (no package C-state support) 170964233338SChen Yu * 001b: C2 171064233338SChen Yu * 010b: C6 (non-retention) 171164233338SChen Yu * 011b: C6 (retention) 171264233338SChen Yu * 111b: No Package C state limits. 171364233338SChen Yu */ 171464233338SChen Yu if ((msr & 0x7) < 2) { 171564233338SChen Yu /* 171664233338SChen Yu * Uses the CC6 + PC0 latency and 3 times of 171764233338SChen Yu * latency for target_residency if the PC6 171864233338SChen Yu * is disabled in BIOS. This is consistent 171964233338SChen Yu * with how intel_idle driver uses _CST 172064233338SChen Yu * to set the target_residency. 172164233338SChen Yu */ 172264233338SChen Yu skx_cstates[2].exit_latency = 92; 172364233338SChen Yu skx_cstates[2].target_residency = 276; 172464233338SChen Yu } 172564233338SChen Yu } 172664233338SChen Yu 1727da0e58c0SArtem Bityutskiy /** 1728d1cf8bbfSZhang Rui * adl_idle_state_table_update - Adjust AlderLake idle states table. 1729d1cf8bbfSZhang Rui */ 1730d1cf8bbfSZhang Rui static void __init adl_idle_state_table_update(void) 1731d1cf8bbfSZhang Rui { 1732d1cf8bbfSZhang Rui /* Check if user prefers C1 over C1E. */ 1733d1cf8bbfSZhang Rui if (preferred_states_mask & BIT(1) && !(preferred_states_mask & BIT(2))) { 1734d1cf8bbfSZhang Rui cpuidle_state_table[0].flags &= ~CPUIDLE_FLAG_UNUSABLE; 1735d1cf8bbfSZhang Rui cpuidle_state_table[1].flags |= CPUIDLE_FLAG_UNUSABLE; 1736d1cf8bbfSZhang Rui 1737d1cf8bbfSZhang Rui /* Disable C1E by clearing the "C1E promotion" bit. */ 1738d1cf8bbfSZhang Rui c1e_promotion = C1E_PROMOTION_DISABLE; 1739d1cf8bbfSZhang Rui return; 1740d1cf8bbfSZhang Rui } 1741d1cf8bbfSZhang Rui 1742d1cf8bbfSZhang Rui /* Make sure C1E is enabled by default */ 1743d1cf8bbfSZhang Rui c1e_promotion = C1E_PROMOTION_ENABLE; 1744d1cf8bbfSZhang Rui } 1745d1cf8bbfSZhang Rui 1746d1cf8bbfSZhang Rui /** 1747da0e58c0SArtem Bityutskiy * spr_idle_state_table_update - Adjust Sapphire Rapids idle states table. 1748da0e58c0SArtem Bityutskiy */ 1749da0e58c0SArtem Bityutskiy static void __init spr_idle_state_table_update(void) 1750da0e58c0SArtem Bityutskiy { 17513a9cf77bSArtem Bityutskiy unsigned long long msr; 17523a9cf77bSArtem Bityutskiy 1753da0e58c0SArtem Bityutskiy /* Check if user prefers C1E over C1. */ 17547eac3bd3SArtem Bityutskiy if ((preferred_states_mask & BIT(2)) && 17557eac3bd3SArtem Bityutskiy !(preferred_states_mask & BIT(1))) { 17567eac3bd3SArtem Bityutskiy /* Disable C1 and enable C1E. */ 1757da0e58c0SArtem Bityutskiy spr_cstates[0].flags |= CPUIDLE_FLAG_UNUSABLE; 1758da0e58c0SArtem Bityutskiy spr_cstates[1].flags &= ~CPUIDLE_FLAG_UNUSABLE; 1759da0e58c0SArtem Bityutskiy 1760da0e58c0SArtem Bityutskiy /* Enable C1E using the "C1E promotion" bit. */ 176139c184a6SArtem Bityutskiy c1e_promotion = C1E_PROMOTION_ENABLE; 1762da0e58c0SArtem Bityutskiy } 17633a9cf77bSArtem Bityutskiy 17643a9cf77bSArtem Bityutskiy /* 17653a9cf77bSArtem Bityutskiy * By default, the C6 state assumes the worst-case scenario of package 17663a9cf77bSArtem Bityutskiy * C6. However, if PC6 is disabled, we update the numbers to match 17673a9cf77bSArtem Bityutskiy * core C6. 17683a9cf77bSArtem Bityutskiy */ 17693a9cf77bSArtem Bityutskiy rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr); 17703a9cf77bSArtem Bityutskiy 17713a9cf77bSArtem Bityutskiy /* Limit value 2 and above allow for PC6. */ 17723a9cf77bSArtem Bityutskiy if ((msr & 0x7) < 2) { 17733a9cf77bSArtem Bityutskiy spr_cstates[2].exit_latency = 190; 17743a9cf77bSArtem Bityutskiy spr_cstates[2].target_residency = 600; 17753a9cf77bSArtem Bityutskiy } 1776da0e58c0SArtem Bityutskiy } 1777da0e58c0SArtem Bityutskiy 17781aefbd7aSRafael J. Wysocki static bool __init intel_idle_verify_cstate(unsigned int mwait_hint) 17791aefbd7aSRafael J. Wysocki { 17801aefbd7aSRafael J. Wysocki unsigned int mwait_cstate = MWAIT_HINT2CSTATE(mwait_hint) + 1; 17811aefbd7aSRafael J. Wysocki unsigned int num_substates = (mwait_substates >> mwait_cstate * 4) & 17821aefbd7aSRafael J. Wysocki MWAIT_SUBSTATE_MASK; 17831aefbd7aSRafael J. Wysocki 17841aefbd7aSRafael J. Wysocki /* Ignore the C-state if there are NO sub-states in CPUID for it. */ 17851aefbd7aSRafael J. Wysocki if (num_substates == 0) 17861aefbd7aSRafael J. Wysocki return false; 17871aefbd7aSRafael J. Wysocki 17881aefbd7aSRafael J. Wysocki if (mwait_cstate > 2 && !boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) 17891aefbd7aSRafael J. Wysocki mark_tsc_unstable("TSC halts in idle states deeper than C2"); 17901aefbd7aSRafael J. Wysocki 17911aefbd7aSRafael J. Wysocki return true; 17921aefbd7aSRafael J. Wysocki } 17931aefbd7aSRafael J. Wysocki 1794095928aeSRafael J. Wysocki static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv) 1795d70e28f5SLen Brown { 17963d3a1ae9SRafael J. Wysocki int cstate; 1797d70e28f5SLen Brown 17983d3a1ae9SRafael J. Wysocki switch (boot_cpu_data.x86_model) { 1799db73c5a8SDave Hansen case INTEL_FAM6_IVYBRIDGE_X: 1800d70e28f5SLen Brown ivt_idle_state_table_update(); 1801d70e28f5SLen Brown break; 1802db73c5a8SDave Hansen case INTEL_FAM6_ATOM_GOLDMONT: 1803f2c4db1bSPeter Zijlstra case INTEL_FAM6_ATOM_GOLDMONT_PLUS: 18045dcef694SLen Brown bxt_idle_state_table_update(); 18055dcef694SLen Brown break; 1806c66f78a6SPeter Zijlstra case INTEL_FAM6_SKYLAKE: 1807d70e28f5SLen Brown sklh_idle_state_table_update(); 1808d70e28f5SLen Brown break; 180964233338SChen Yu case INTEL_FAM6_SKYLAKE_X: 181064233338SChen Yu skx_idle_state_table_update(); 181164233338SChen Yu break; 1812da0e58c0SArtem Bityutskiy case INTEL_FAM6_SAPPHIRERAPIDS_X: 1813da0e58c0SArtem Bityutskiy spr_idle_state_table_update(); 1814da0e58c0SArtem Bityutskiy break; 1815d1cf8bbfSZhang Rui case INTEL_FAM6_ALDERLAKE: 1816d1cf8bbfSZhang Rui case INTEL_FAM6_ALDERLAKE_L: 1817d1cf8bbfSZhang Rui adl_idle_state_table_update(); 1818d1cf8bbfSZhang Rui break; 1819d70e28f5SLen Brown } 182046bcfad7SDeepthi Dharwar 1821e022e7ebSLen Brown for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) { 18229f3d6dafSRafael J. Wysocki unsigned int mwait_hint; 182346bcfad7SDeepthi Dharwar 182418734958SRafael J. Wysocki if (intel_idle_max_cstate_reached(cstate)) 182518734958SRafael J. Wysocki break; 182618734958SRafael J. Wysocki 18279f3d6dafSRafael J. Wysocki if (!cpuidle_state_table[cstate].enter && 18289f3d6dafSRafael J. Wysocki !cpuidle_state_table[cstate].enter_s2idle) 1829e022e7ebSLen Brown break; 1830e022e7ebSLen Brown 18319f3d6dafSRafael J. Wysocki /* If marked as unusable, skip this state. */ 1832ba1e78a1SRafael J. Wysocki if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_UNUSABLE) { 1833654d08a4SJoe Perches pr_debug("state %s is disabled\n", 1834d70e28f5SLen Brown cpuidle_state_table[cstate].name); 1835d70e28f5SLen Brown continue; 1836d70e28f5SLen Brown } 1837d70e28f5SLen Brown 18389f3d6dafSRafael J. Wysocki mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags); 18399f3d6dafSRafael J. Wysocki if (!intel_idle_verify_cstate(mwait_hint)) 18409f3d6dafSRafael J. Wysocki continue; 1841d70e28f5SLen Brown 18429f3d6dafSRafael J. Wysocki /* Structure copy. */ 1843bff8e60aSRafael J. Wysocki drv->states[drv->state_count] = cpuidle_state_table[cstate]; 1844bff8e60aSRafael J. Wysocki 184532d4fd57SPeter Zijlstra if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_IRQ_ENABLE) 184632d4fd57SPeter Zijlstra drv->states[drv->state_count].enter = intel_idle_irq; 184732d4fd57SPeter Zijlstra 1848*bf5835bcSPeter Zijlstra if (cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS) && 1849*bf5835bcSPeter Zijlstra cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_IBRS) { 1850*bf5835bcSPeter Zijlstra WARN_ON_ONCE(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_IRQ_ENABLE); 1851*bf5835bcSPeter Zijlstra drv->states[drv->state_count].enter = intel_idle_ibrs; 1852*bf5835bcSPeter Zijlstra } 1853*bf5835bcSPeter Zijlstra 18544dcb78eeSRafael J. Wysocki if ((disabled_states_mask & BIT(drv->state_count)) || 18554dcb78eeSRafael J. Wysocki ((icpu->use_acpi || force_use_acpi) && 18563a5be9b8SRafael J. Wysocki intel_idle_off_by_default(mwait_hint) && 18574dcb78eeSRafael J. Wysocki !(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_ALWAYS_ENABLE))) 1858bff8e60aSRafael J. Wysocki drv->states[drv->state_count].flags |= CPUIDLE_FLAG_OFF; 1859bff8e60aSRafael J. Wysocki 18606e1d2bc6SPeter Zijlstra if (intel_idle_state_needs_timer_stop(&drv->states[drv->state_count])) 18616e1d2bc6SPeter Zijlstra drv->states[drv->state_count].flags |= CPUIDLE_FLAG_TIMER_STOP; 18626e1d2bc6SPeter Zijlstra 1863bff8e60aSRafael J. Wysocki drv->state_count++; 186446bcfad7SDeepthi Dharwar } 186546bcfad7SDeepthi Dharwar 18668c058d53SLen Brown if (icpu->byt_auto_demotion_disable_flag) { 18678c058d53SLen Brown wrmsrl(MSR_CC6_DEMOTION_POLICY_CONFIG, 0); 18688c058d53SLen Brown wrmsrl(MSR_MC6_DEMOTION_POLICY_CONFIG, 0); 18698c058d53SLen Brown } 187046bcfad7SDeepthi Dharwar } 187146bcfad7SDeepthi Dharwar 18726eacb15fSRafael J. Wysocki /** 18736eacb15fSRafael J. Wysocki * intel_idle_cpuidle_driver_init - Create the list of available idle states. 18746eacb15fSRafael J. Wysocki * @drv: cpuidle driver structure to initialize. 187518734958SRafael J. Wysocki */ 18763d3a1ae9SRafael J. Wysocki static void __init intel_idle_cpuidle_driver_init(struct cpuidle_driver *drv) 187718734958SRafael J. Wysocki { 187818734958SRafael J. Wysocki cpuidle_poll_state_init(drv); 18794dcb78eeSRafael J. Wysocki 18804dcb78eeSRafael J. Wysocki if (disabled_states_mask & BIT(0)) 18814dcb78eeSRafael J. Wysocki drv->states[0].flags |= CPUIDLE_FLAG_OFF; 18824dcb78eeSRafael J. Wysocki 188318734958SRafael J. Wysocki drv->state_count = 1; 188418734958SRafael J. Wysocki 188518734958SRafael J. Wysocki if (icpu) 188618734958SRafael J. Wysocki intel_idle_init_cstates_icpu(drv); 188718734958SRafael J. Wysocki else 188818734958SRafael J. Wysocki intel_idle_init_cstates_acpi(drv); 188918734958SRafael J. Wysocki } 189046bcfad7SDeepthi Dharwar 18911aefbd7aSRafael J. Wysocki static void auto_demotion_disable(void) 18921aefbd7aSRafael J. Wysocki { 18931aefbd7aSRafael J. Wysocki unsigned long long msr_bits; 18941aefbd7aSRafael J. Wysocki 18951aefbd7aSRafael J. Wysocki rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr_bits); 18967f843dd7SRafael J. Wysocki msr_bits &= ~auto_demotion_disable_flags; 18971aefbd7aSRafael J. Wysocki wrmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr_bits); 18981aefbd7aSRafael J. Wysocki } 18991aefbd7aSRafael J. Wysocki 1900da0e58c0SArtem Bityutskiy static void c1e_promotion_enable(void) 1901da0e58c0SArtem Bityutskiy { 1902da0e58c0SArtem Bityutskiy unsigned long long msr_bits; 1903da0e58c0SArtem Bityutskiy 1904da0e58c0SArtem Bityutskiy rdmsrl(MSR_IA32_POWER_CTL, msr_bits); 1905da0e58c0SArtem Bityutskiy msr_bits |= 0x2; 1906da0e58c0SArtem Bityutskiy wrmsrl(MSR_IA32_POWER_CTL, msr_bits); 1907da0e58c0SArtem Bityutskiy } 1908da0e58c0SArtem Bityutskiy 19091aefbd7aSRafael J. Wysocki static void c1e_promotion_disable(void) 19101aefbd7aSRafael J. Wysocki { 19111aefbd7aSRafael J. Wysocki unsigned long long msr_bits; 19121aefbd7aSRafael J. Wysocki 19131aefbd7aSRafael J. Wysocki rdmsrl(MSR_IA32_POWER_CTL, msr_bits); 19141aefbd7aSRafael J. Wysocki msr_bits &= ~0x2; 19151aefbd7aSRafael J. Wysocki wrmsrl(MSR_IA32_POWER_CTL, msr_bits); 19161aefbd7aSRafael J. Wysocki } 19171aefbd7aSRafael J. Wysocki 19186eacb15fSRafael J. Wysocki /** 19196eacb15fSRafael J. Wysocki * intel_idle_cpu_init - Register the target CPU with the cpuidle core. 19206eacb15fSRafael J. Wysocki * @cpu: CPU to initialize. 19216eacb15fSRafael J. Wysocki * 19226eacb15fSRafael J. Wysocki * Register a cpuidle device object for @cpu and update its MSRs in accordance 19236eacb15fSRafael J. Wysocki * with the processor model flags. 192426717172SLen Brown */ 1925fb1013a0SSebastian Andrzej Siewior static int intel_idle_cpu_init(unsigned int cpu) 192626717172SLen Brown { 192726717172SLen Brown struct cpuidle_device *dev; 192826717172SLen Brown 192965b7f839SThomas Renninger dev = per_cpu_ptr(intel_idle_cpuidle_devices, cpu); 193065b7f839SThomas Renninger dev->cpu = cpu; 193126717172SLen Brown 193226717172SLen Brown if (cpuidle_register_device(dev)) { 1933654d08a4SJoe Perches pr_debug("cpuidle_register_device %d failed!\n", cpu); 193426717172SLen Brown return -EIO; 193526717172SLen Brown } 193665b7f839SThomas Renninger 19377f843dd7SRafael J. Wysocki if (auto_demotion_disable_flags) 1938fb1013a0SSebastian Andrzej Siewior auto_demotion_disable(); 193926717172SLen Brown 194039c184a6SArtem Bityutskiy if (c1e_promotion == C1E_PROMOTION_ENABLE) 194139c184a6SArtem Bityutskiy c1e_promotion_enable(); 194239c184a6SArtem Bityutskiy else if (c1e_promotion == C1E_PROMOTION_DISABLE) 1943fb1013a0SSebastian Andrzej Siewior c1e_promotion_disable(); 1944fb1013a0SSebastian Andrzej Siewior 1945fb1013a0SSebastian Andrzej Siewior return 0; 1946fb1013a0SSebastian Andrzej Siewior } 1947fb1013a0SSebastian Andrzej Siewior 1948fb1013a0SSebastian Andrzej Siewior static int intel_idle_cpu_online(unsigned int cpu) 1949fb1013a0SSebastian Andrzej Siewior { 1950fb1013a0SSebastian Andrzej Siewior struct cpuidle_device *dev; 1951fb1013a0SSebastian Andrzej Siewior 1952dab20177SRafael J. Wysocki if (!boot_cpu_has(X86_FEATURE_ARAT)) 1953cbd2c4c2SRafael J. Wysocki tick_broadcast_enable(); 1954fb1013a0SSebastian Andrzej Siewior 1955fb1013a0SSebastian Andrzej Siewior /* 1956fb1013a0SSebastian Andrzej Siewior * Some systems can hotplug a cpu at runtime after 1957fb1013a0SSebastian Andrzej Siewior * the kernel has booted, we have to initialize the 1958fb1013a0SSebastian Andrzej Siewior * driver in this case 1959fb1013a0SSebastian Andrzej Siewior */ 1960fb1013a0SSebastian Andrzej Siewior dev = per_cpu_ptr(intel_idle_cpuidle_devices, cpu); 1961fb1013a0SSebastian Andrzej Siewior if (!dev->registered) 1962fb1013a0SSebastian Andrzej Siewior return intel_idle_cpu_init(cpu); 1963dbf87ab8SBartlomiej Zolnierkiewicz 196426717172SLen Brown return 0; 196526717172SLen Brown } 196626717172SLen Brown 19670755a9bdSRafael J. Wysocki /** 19680755a9bdSRafael J. Wysocki * intel_idle_cpuidle_devices_uninit - Unregister all cpuidle devices. 19690755a9bdSRafael J. Wysocki */ 19700755a9bdSRafael J. Wysocki static void __init intel_idle_cpuidle_devices_uninit(void) 19710755a9bdSRafael J. Wysocki { 19720755a9bdSRafael J. Wysocki int i; 19730755a9bdSRafael J. Wysocki 19740755a9bdSRafael J. Wysocki for_each_online_cpu(i) 19750755a9bdSRafael J. Wysocki cpuidle_unregister_device(per_cpu_ptr(intel_idle_cpuidle_devices, i)); 19760755a9bdSRafael J. Wysocki } 19770755a9bdSRafael J. Wysocki 197826717172SLen Brown static int __init intel_idle_init(void) 197926717172SLen Brown { 1980a6c86e33SRafael J. Wysocki const struct x86_cpu_id *id; 1981a6c86e33SRafael J. Wysocki unsigned int eax, ebx, ecx; 1982fb1013a0SSebastian Andrzej Siewior int retval; 198326717172SLen Brown 1984d1896049SThomas Renninger /* Do not load intel_idle at all for now if idle= is passed */ 1985d1896049SThomas Renninger if (boot_option_idle_override != IDLE_NO_OVERRIDE) 1986d1896049SThomas Renninger return -ENODEV; 1987d1896049SThomas Renninger 1988a6c86e33SRafael J. Wysocki if (max_cstate == 0) { 1989a6c86e33SRafael J. Wysocki pr_debug("disabled\n"); 1990a6c86e33SRafael J. Wysocki return -EPERM; 1991a6c86e33SRafael J. Wysocki } 1992a6c86e33SRafael J. Wysocki 1993a6c86e33SRafael J. Wysocki id = x86_match_cpu(intel_idle_ids); 1994a6c86e33SRafael J. Wysocki if (id) { 1995a6c86e33SRafael J. Wysocki if (!boot_cpu_has(X86_FEATURE_MWAIT)) { 1996a6c86e33SRafael J. Wysocki pr_debug("Please enable MWAIT in BIOS SETUP\n"); 1997a6c86e33SRafael J. Wysocki return -ENODEV; 1998a6c86e33SRafael J. Wysocki } 1999a6c86e33SRafael J. Wysocki } else { 2000a6c86e33SRafael J. Wysocki id = x86_match_cpu(intel_mwait_ids); 2001a6c86e33SRafael J. Wysocki if (!id) 2002a6c86e33SRafael J. Wysocki return -ENODEV; 2003a6c86e33SRafael J. Wysocki } 2004a6c86e33SRafael J. Wysocki 2005a6c86e33SRafael J. Wysocki if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) 2006a6c86e33SRafael J. Wysocki return -ENODEV; 2007a6c86e33SRafael J. Wysocki 2008a6c86e33SRafael J. Wysocki cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates); 2009a6c86e33SRafael J. Wysocki 2010a6c86e33SRafael J. Wysocki if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || 2011a6c86e33SRafael J. Wysocki !(ecx & CPUID5_ECX_INTERRUPT_BREAK) || 2012a6c86e33SRafael J. Wysocki !mwait_substates) 2013a6c86e33SRafael J. Wysocki return -ENODEV; 2014a6c86e33SRafael J. Wysocki 2015a6c86e33SRafael J. Wysocki pr_debug("MWAIT substates: 0x%x\n", mwait_substates); 2016a6c86e33SRafael J. Wysocki 2017a6c86e33SRafael J. Wysocki icpu = (const struct idle_cpu *)id->driver_data; 2018a6c86e33SRafael J. Wysocki if (icpu) { 2019a6c86e33SRafael J. Wysocki cpuidle_state_table = icpu->state_table; 20207f843dd7SRafael J. Wysocki auto_demotion_disable_flags = icpu->auto_demotion_disable_flags; 202139c184a6SArtem Bityutskiy if (icpu->disable_promotion_to_c1e) 202239c184a6SArtem Bityutskiy c1e_promotion = C1E_PROMOTION_DISABLE; 20233a5be9b8SRafael J. Wysocki if (icpu->use_acpi || force_use_acpi) 2024a6c86e33SRafael J. Wysocki intel_idle_acpi_cst_extract(); 2025a6c86e33SRafael J. Wysocki } else if (!intel_idle_acpi_cst_extract()) { 2026a6c86e33SRafael J. Wysocki return -ENODEV; 2027a6c86e33SRafael J. Wysocki } 2028a6c86e33SRafael J. Wysocki 2029a6c86e33SRafael J. Wysocki pr_debug("v" INTEL_IDLE_VERSION " model 0x%X\n", 2030a6c86e33SRafael J. Wysocki boot_cpu_data.x86_model); 203126717172SLen Brown 2032e9df69ccSRichard Cochran intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device); 2033533da74aSRafael J. Wysocki if (!intel_idle_cpuidle_devices) 2034e9df69ccSRichard Cochran return -ENOMEM; 2035e9df69ccSRichard Cochran 20363d3a1ae9SRafael J. Wysocki intel_idle_cpuidle_driver_init(&intel_idle_driver); 20373d3a1ae9SRafael J. Wysocki 203826717172SLen Brown retval = cpuidle_register_driver(&intel_idle_driver); 203926717172SLen Brown if (retval) { 20403735d524SKonrad Rzeszutek Wilk struct cpuidle_driver *drv = cpuidle_get_driver(); 2041654d08a4SJoe Perches printk(KERN_DEBUG pr_fmt("intel_idle yielding to %s\n"), 20423735d524SKonrad Rzeszutek Wilk drv ? drv->name : "none"); 2043fb1013a0SSebastian Andrzej Siewior goto init_driver_fail; 204426717172SLen Brown } 204526717172SLen Brown 2046fb1013a0SSebastian Andrzej Siewior retval = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "idle/intel:online", 2047fb1013a0SSebastian Andrzej Siewior intel_idle_cpu_online, NULL); 2048fb1013a0SSebastian Andrzej Siewior if (retval < 0) 2049fb1013a0SSebastian Andrzej Siewior goto hp_setup_fail; 205026717172SLen Brown 205140ab82e0SRafael J. Wysocki pr_debug("Local APIC timer is reliable in %s\n", 2052dab20177SRafael J. Wysocki boot_cpu_has(X86_FEATURE_ARAT) ? "all C-states" : "C1"); 20532259a819SRichard Cochran 205426717172SLen Brown return 0; 2055fb1013a0SSebastian Andrzej Siewior 2056fb1013a0SSebastian Andrzej Siewior hp_setup_fail: 2057fb1013a0SSebastian Andrzej Siewior intel_idle_cpuidle_devices_uninit(); 2058fb1013a0SSebastian Andrzej Siewior cpuidle_unregister_driver(&intel_idle_driver); 2059fb1013a0SSebastian Andrzej Siewior init_driver_fail: 2060fb1013a0SSebastian Andrzej Siewior free_percpu(intel_idle_cpuidle_devices); 2061fb1013a0SSebastian Andrzej Siewior return retval; 2062fb1013a0SSebastian Andrzej Siewior 206326717172SLen Brown } 206402c4fae9SPaul Gortmaker device_initcall(intel_idle_init); 206526717172SLen Brown 206602c4fae9SPaul Gortmaker /* 206702c4fae9SPaul Gortmaker * We are not really modular, but we used to support that. Meaning we also 206802c4fae9SPaul Gortmaker * support "intel_idle.max_cstate=..." at boot and also a read-only export of 206902c4fae9SPaul Gortmaker * it at /sys/module/intel_idle/parameters/max_cstate -- so using module_param 207002c4fae9SPaul Gortmaker * is the easiest way (currently) to continue doing that. 207102c4fae9SPaul Gortmaker */ 207226717172SLen Brown module_param(max_cstate, int, 0444); 20734dcb78eeSRafael J. Wysocki /* 20744dcb78eeSRafael J. Wysocki * The positions of the bits that are set in this number are the indices of the 20754dcb78eeSRafael J. Wysocki * idle states to be disabled by default (as reflected by the names of the 20764dcb78eeSRafael J. Wysocki * corresponding idle state directories in sysfs, "state0", "state1" ... 20774dcb78eeSRafael J. Wysocki * "state<i>" ..., where <i> is the index of the given state). 20784dcb78eeSRafael J. Wysocki */ 20794dcb78eeSRafael J. Wysocki module_param_named(states_off, disabled_states_mask, uint, 0444); 20804dcb78eeSRafael J. Wysocki MODULE_PARM_DESC(states_off, "Mask of disabled idle states"); 2081da0e58c0SArtem Bityutskiy /* 2082da0e58c0SArtem Bityutskiy * Some platforms come with mutually exclusive C-states, so that if one is 2083da0e58c0SArtem Bityutskiy * enabled, the other C-states must not be used. Example: C1 and C1E on 2084da0e58c0SArtem Bityutskiy * Sapphire Rapids platform. This parameter allows for selecting the 2085da0e58c0SArtem Bityutskiy * preferred C-states among the groups of mutually exclusive C-states - the 2086da0e58c0SArtem Bityutskiy * selected C-states will be registered, the other C-states from the mutually 2087da0e58c0SArtem Bityutskiy * exclusive group won't be registered. If the platform has no mutually 2088da0e58c0SArtem Bityutskiy * exclusive C-states, this parameter has no effect. 2089da0e58c0SArtem Bityutskiy */ 2090da0e58c0SArtem Bityutskiy module_param_named(preferred_cstates, preferred_states_mask, uint, 0444); 2091da0e58c0SArtem Bityutskiy MODULE_PARM_DESC(preferred_cstates, "Mask of preferred idle states"); 2092