162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * intel_idle.c - native hardware idle loop for modern Intel processors 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2013 - 2020, Intel Corporation. 662306a36Sopenharmony_ci * Len Brown <len.brown@intel.com> 762306a36Sopenharmony_ci * Rafael J. Wysocki <rafael.j.wysocki@intel.com> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci/* 1162306a36Sopenharmony_ci * intel_idle is a cpuidle driver that loads on all Intel CPUs with MWAIT 1262306a36Sopenharmony_ci * in lieu of the legacy ACPI processor_idle driver. The intent is to 1362306a36Sopenharmony_ci * make Linux more efficient on these processors, as intel_idle knows 1462306a36Sopenharmony_ci * more than ACPI, as well as make Linux more immune to ACPI BIOS bugs. 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* 1862306a36Sopenharmony_ci * Design Assumptions 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * All CPUs have same idle states as boot CPU 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci * Chipset BM_STS (bus master status) bit is a NOP 2362306a36Sopenharmony_ci * for preventing entry into deep C-states 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * CPU will flush caches as needed when entering a C-state via MWAIT 2662306a36Sopenharmony_ci * (in contrast to entering ACPI C3, in which case the WBINVD 2762306a36Sopenharmony_ci * instruction needs to be executed to flush the caches) 2862306a36Sopenharmony_ci */ 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* 3162306a36Sopenharmony_ci * Known limitations 3262306a36Sopenharmony_ci * 3362306a36Sopenharmony_ci * ACPI has a .suspend hack to turn off deep c-statees during suspend 3462306a36Sopenharmony_ci * to avoid complications with the lapic timer workaround. 3562306a36Sopenharmony_ci * Have not seen issues with suspend, but may need same workaround here. 3662306a36Sopenharmony_ci * 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/* un-comment DEBUG to enable pr_debug() statements */ 4062306a36Sopenharmony_ci/* #define DEBUG */ 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci#include <linux/acpi.h> 4562306a36Sopenharmony_ci#include <linux/kernel.h> 4662306a36Sopenharmony_ci#include <linux/cpuidle.h> 4762306a36Sopenharmony_ci#include <linux/tick.h> 4862306a36Sopenharmony_ci#include <trace/events/power.h> 4962306a36Sopenharmony_ci#include <linux/sched.h> 5062306a36Sopenharmony_ci#include <linux/sched/smt.h> 5162306a36Sopenharmony_ci#include <linux/notifier.h> 5262306a36Sopenharmony_ci#include <linux/cpu.h> 5362306a36Sopenharmony_ci#include <linux/moduleparam.h> 5462306a36Sopenharmony_ci#include <asm/cpu_device_id.h> 5562306a36Sopenharmony_ci#include <asm/intel-family.h> 5662306a36Sopenharmony_ci#include <asm/nospec-branch.h> 5762306a36Sopenharmony_ci#include <asm/mwait.h> 5862306a36Sopenharmony_ci#include <asm/msr.h> 5962306a36Sopenharmony_ci#include <asm/fpu/api.h> 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci#define INTEL_IDLE_VERSION "0.5.1" 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistatic struct cpuidle_driver intel_idle_driver = { 6462306a36Sopenharmony_ci .name = "intel_idle", 6562306a36Sopenharmony_ci .owner = THIS_MODULE, 6662306a36Sopenharmony_ci}; 6762306a36Sopenharmony_ci/* intel_idle.max_cstate=0 disables driver */ 6862306a36Sopenharmony_cistatic int max_cstate = CPUIDLE_STATE_MAX - 1; 6962306a36Sopenharmony_cistatic unsigned int disabled_states_mask __read_mostly; 7062306a36Sopenharmony_cistatic unsigned int preferred_states_mask __read_mostly; 7162306a36Sopenharmony_cistatic bool force_irq_on __read_mostly; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_cistatic struct cpuidle_device __percpu *intel_idle_cpuidle_devices; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistatic unsigned long auto_demotion_disable_flags; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic enum { 7862306a36Sopenharmony_ci C1E_PROMOTION_PRESERVE, 7962306a36Sopenharmony_ci C1E_PROMOTION_ENABLE, 8062306a36Sopenharmony_ci C1E_PROMOTION_DISABLE 8162306a36Sopenharmony_ci} c1e_promotion = C1E_PROMOTION_PRESERVE; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_cistruct idle_cpu { 8462306a36Sopenharmony_ci struct cpuidle_state *state_table; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci /* 8762306a36Sopenharmony_ci * Hardware C-state auto-demotion may not always be optimal. 8862306a36Sopenharmony_ci * Indicate which enable bits to clear here. 8962306a36Sopenharmony_ci */ 9062306a36Sopenharmony_ci unsigned long auto_demotion_disable_flags; 9162306a36Sopenharmony_ci bool byt_auto_demotion_disable_flag; 9262306a36Sopenharmony_ci bool disable_promotion_to_c1e; 9362306a36Sopenharmony_ci bool use_acpi; 9462306a36Sopenharmony_ci}; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistatic const struct idle_cpu *icpu __initdata; 9762306a36Sopenharmony_cistatic struct cpuidle_state *cpuidle_state_table __initdata; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_cistatic unsigned int mwait_substates __initdata; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci/* 10262306a36Sopenharmony_ci * Enable interrupts before entering the C-state. On some platforms and for 10362306a36Sopenharmony_ci * some C-states, this may measurably decrease interrupt latency. 10462306a36Sopenharmony_ci */ 10562306a36Sopenharmony_ci#define CPUIDLE_FLAG_IRQ_ENABLE BIT(14) 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci/* 10862306a36Sopenharmony_ci * Enable this state by default even if the ACPI _CST does not list it. 10962306a36Sopenharmony_ci */ 11062306a36Sopenharmony_ci#define CPUIDLE_FLAG_ALWAYS_ENABLE BIT(15) 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci/* 11362306a36Sopenharmony_ci * Disable IBRS across idle (when KERNEL_IBRS), is exclusive vs IRQ_ENABLE 11462306a36Sopenharmony_ci * above. 11562306a36Sopenharmony_ci */ 11662306a36Sopenharmony_ci#define CPUIDLE_FLAG_IBRS BIT(16) 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci/* 11962306a36Sopenharmony_ci * Initialize large xstate for the C6-state entrance. 12062306a36Sopenharmony_ci */ 12162306a36Sopenharmony_ci#define CPUIDLE_FLAG_INIT_XSTATE BIT(17) 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci/* 12462306a36Sopenharmony_ci * MWAIT takes an 8-bit "hint" in EAX "suggesting" 12562306a36Sopenharmony_ci * the C-state (top nibble) and sub-state (bottom nibble) 12662306a36Sopenharmony_ci * 0x00 means "MWAIT(C1)", 0x10 means "MWAIT(C2)" etc. 12762306a36Sopenharmony_ci * 12862306a36Sopenharmony_ci * We store the hint at the top of our "flags" for each state. 12962306a36Sopenharmony_ci */ 13062306a36Sopenharmony_ci#define flg2MWAIT(flags) (((flags) >> 24) & 0xFF) 13162306a36Sopenharmony_ci#define MWAIT2flg(eax) ((eax & 0xFF) << 24) 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistatic __always_inline int __intel_idle(struct cpuidle_device *dev, 13462306a36Sopenharmony_ci struct cpuidle_driver *drv, 13562306a36Sopenharmony_ci int index, bool irqoff) 13662306a36Sopenharmony_ci{ 13762306a36Sopenharmony_ci struct cpuidle_state *state = &drv->states[index]; 13862306a36Sopenharmony_ci unsigned long eax = flg2MWAIT(state->flags); 13962306a36Sopenharmony_ci unsigned long ecx = 1*irqoff; /* break on interrupt flag */ 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci mwait_idle_with_hints(eax, ecx); 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci return index; 14462306a36Sopenharmony_ci} 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci/** 14762306a36Sopenharmony_ci * intel_idle - Ask the processor to enter the given idle state. 14862306a36Sopenharmony_ci * @dev: cpuidle device of the target CPU. 14962306a36Sopenharmony_ci * @drv: cpuidle driver (assumed to point to intel_idle_driver). 15062306a36Sopenharmony_ci * @index: Target idle state index. 15162306a36Sopenharmony_ci * 15262306a36Sopenharmony_ci * Use the MWAIT instruction to notify the processor that the CPU represented by 15362306a36Sopenharmony_ci * @dev is idle and it can try to enter the idle state corresponding to @index. 15462306a36Sopenharmony_ci * 15562306a36Sopenharmony_ci * If the local APIC timer is not known to be reliable in the target idle state, 15662306a36Sopenharmony_ci * enable one-shot tick broadcasting for the target CPU before executing MWAIT. 15762306a36Sopenharmony_ci * 15862306a36Sopenharmony_ci * Must be called under local_irq_disable(). 15962306a36Sopenharmony_ci */ 16062306a36Sopenharmony_cistatic __cpuidle int intel_idle(struct cpuidle_device *dev, 16162306a36Sopenharmony_ci struct cpuidle_driver *drv, int index) 16262306a36Sopenharmony_ci{ 16362306a36Sopenharmony_ci return __intel_idle(dev, drv, index, true); 16462306a36Sopenharmony_ci} 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_cistatic __cpuidle int intel_idle_irq(struct cpuidle_device *dev, 16762306a36Sopenharmony_ci struct cpuidle_driver *drv, int index) 16862306a36Sopenharmony_ci{ 16962306a36Sopenharmony_ci return __intel_idle(dev, drv, index, false); 17062306a36Sopenharmony_ci} 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_cistatic __cpuidle int intel_idle_ibrs(struct cpuidle_device *dev, 17362306a36Sopenharmony_ci struct cpuidle_driver *drv, int index) 17462306a36Sopenharmony_ci{ 17562306a36Sopenharmony_ci bool smt_active = sched_smt_active(); 17662306a36Sopenharmony_ci u64 spec_ctrl = spec_ctrl_current(); 17762306a36Sopenharmony_ci int ret; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci if (smt_active) 18062306a36Sopenharmony_ci native_wrmsrl(MSR_IA32_SPEC_CTRL, 0); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci ret = __intel_idle(dev, drv, index, true); 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci if (smt_active) 18562306a36Sopenharmony_ci native_wrmsrl(MSR_IA32_SPEC_CTRL, spec_ctrl); 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci return ret; 18862306a36Sopenharmony_ci} 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_cistatic __cpuidle int intel_idle_xstate(struct cpuidle_device *dev, 19162306a36Sopenharmony_ci struct cpuidle_driver *drv, int index) 19262306a36Sopenharmony_ci{ 19362306a36Sopenharmony_ci fpu_idle_fpregs(); 19462306a36Sopenharmony_ci return __intel_idle(dev, drv, index, true); 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci/** 19862306a36Sopenharmony_ci * intel_idle_s2idle - Ask the processor to enter the given idle state. 19962306a36Sopenharmony_ci * @dev: cpuidle device of the target CPU. 20062306a36Sopenharmony_ci * @drv: cpuidle driver (assumed to point to intel_idle_driver). 20162306a36Sopenharmony_ci * @index: Target idle state index. 20262306a36Sopenharmony_ci * 20362306a36Sopenharmony_ci * Use the MWAIT instruction to notify the processor that the CPU represented by 20462306a36Sopenharmony_ci * @dev is idle and it can try to enter the idle state corresponding to @index. 20562306a36Sopenharmony_ci * 20662306a36Sopenharmony_ci * Invoked as a suspend-to-idle callback routine with frozen user space, frozen 20762306a36Sopenharmony_ci * scheduler tick and suspended scheduler clock on the target CPU. 20862306a36Sopenharmony_ci */ 20962306a36Sopenharmony_cistatic __cpuidle int intel_idle_s2idle(struct cpuidle_device *dev, 21062306a36Sopenharmony_ci struct cpuidle_driver *drv, int index) 21162306a36Sopenharmony_ci{ 21262306a36Sopenharmony_ci unsigned long ecx = 1; /* break on interrupt flag */ 21362306a36Sopenharmony_ci struct cpuidle_state *state = &drv->states[index]; 21462306a36Sopenharmony_ci unsigned long eax = flg2MWAIT(state->flags); 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci if (state->flags & CPUIDLE_FLAG_INIT_XSTATE) 21762306a36Sopenharmony_ci fpu_idle_fpregs(); 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci mwait_idle_with_hints(eax, ecx); 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci return 0; 22262306a36Sopenharmony_ci} 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci/* 22562306a36Sopenharmony_ci * States are indexed by the cstate number, 22662306a36Sopenharmony_ci * which is also the index into the MWAIT hint array. 22762306a36Sopenharmony_ci * Thus C0 is a dummy. 22862306a36Sopenharmony_ci */ 22962306a36Sopenharmony_cistatic struct cpuidle_state nehalem_cstates[] __initdata = { 23062306a36Sopenharmony_ci { 23162306a36Sopenharmony_ci .name = "C1", 23262306a36Sopenharmony_ci .desc = "MWAIT 0x00", 23362306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 23462306a36Sopenharmony_ci .exit_latency = 3, 23562306a36Sopenharmony_ci .target_residency = 6, 23662306a36Sopenharmony_ci .enter = &intel_idle, 23762306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 23862306a36Sopenharmony_ci { 23962306a36Sopenharmony_ci .name = "C1E", 24062306a36Sopenharmony_ci .desc = "MWAIT 0x01", 24162306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 24262306a36Sopenharmony_ci .exit_latency = 10, 24362306a36Sopenharmony_ci .target_residency = 20, 24462306a36Sopenharmony_ci .enter = &intel_idle, 24562306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 24662306a36Sopenharmony_ci { 24762306a36Sopenharmony_ci .name = "C3", 24862306a36Sopenharmony_ci .desc = "MWAIT 0x10", 24962306a36Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 25062306a36Sopenharmony_ci .exit_latency = 20, 25162306a36Sopenharmony_ci .target_residency = 80, 25262306a36Sopenharmony_ci .enter = &intel_idle, 25362306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 25462306a36Sopenharmony_ci { 25562306a36Sopenharmony_ci .name = "C6", 25662306a36Sopenharmony_ci .desc = "MWAIT 0x20", 25762306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 25862306a36Sopenharmony_ci .exit_latency = 200, 25962306a36Sopenharmony_ci .target_residency = 800, 26062306a36Sopenharmony_ci .enter = &intel_idle, 26162306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 26262306a36Sopenharmony_ci { 26362306a36Sopenharmony_ci .enter = NULL } 26462306a36Sopenharmony_ci}; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_cistatic struct cpuidle_state snb_cstates[] __initdata = { 26762306a36Sopenharmony_ci { 26862306a36Sopenharmony_ci .name = "C1", 26962306a36Sopenharmony_ci .desc = "MWAIT 0x00", 27062306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 27162306a36Sopenharmony_ci .exit_latency = 2, 27262306a36Sopenharmony_ci .target_residency = 2, 27362306a36Sopenharmony_ci .enter = &intel_idle, 27462306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 27562306a36Sopenharmony_ci { 27662306a36Sopenharmony_ci .name = "C1E", 27762306a36Sopenharmony_ci .desc = "MWAIT 0x01", 27862306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 27962306a36Sopenharmony_ci .exit_latency = 10, 28062306a36Sopenharmony_ci .target_residency = 20, 28162306a36Sopenharmony_ci .enter = &intel_idle, 28262306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 28362306a36Sopenharmony_ci { 28462306a36Sopenharmony_ci .name = "C3", 28562306a36Sopenharmony_ci .desc = "MWAIT 0x10", 28662306a36Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 28762306a36Sopenharmony_ci .exit_latency = 80, 28862306a36Sopenharmony_ci .target_residency = 211, 28962306a36Sopenharmony_ci .enter = &intel_idle, 29062306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 29162306a36Sopenharmony_ci { 29262306a36Sopenharmony_ci .name = "C6", 29362306a36Sopenharmony_ci .desc = "MWAIT 0x20", 29462306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 29562306a36Sopenharmony_ci .exit_latency = 104, 29662306a36Sopenharmony_ci .target_residency = 345, 29762306a36Sopenharmony_ci .enter = &intel_idle, 29862306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 29962306a36Sopenharmony_ci { 30062306a36Sopenharmony_ci .name = "C7", 30162306a36Sopenharmony_ci .desc = "MWAIT 0x30", 30262306a36Sopenharmony_ci .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, 30362306a36Sopenharmony_ci .exit_latency = 109, 30462306a36Sopenharmony_ci .target_residency = 345, 30562306a36Sopenharmony_ci .enter = &intel_idle, 30662306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 30762306a36Sopenharmony_ci { 30862306a36Sopenharmony_ci .enter = NULL } 30962306a36Sopenharmony_ci}; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_cistatic struct cpuidle_state byt_cstates[] __initdata = { 31262306a36Sopenharmony_ci { 31362306a36Sopenharmony_ci .name = "C1", 31462306a36Sopenharmony_ci .desc = "MWAIT 0x00", 31562306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 31662306a36Sopenharmony_ci .exit_latency = 1, 31762306a36Sopenharmony_ci .target_residency = 1, 31862306a36Sopenharmony_ci .enter = &intel_idle, 31962306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 32062306a36Sopenharmony_ci { 32162306a36Sopenharmony_ci .name = "C6N", 32262306a36Sopenharmony_ci .desc = "MWAIT 0x58", 32362306a36Sopenharmony_ci .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED, 32462306a36Sopenharmony_ci .exit_latency = 300, 32562306a36Sopenharmony_ci .target_residency = 275, 32662306a36Sopenharmony_ci .enter = &intel_idle, 32762306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 32862306a36Sopenharmony_ci { 32962306a36Sopenharmony_ci .name = "C6S", 33062306a36Sopenharmony_ci .desc = "MWAIT 0x52", 33162306a36Sopenharmony_ci .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, 33262306a36Sopenharmony_ci .exit_latency = 500, 33362306a36Sopenharmony_ci .target_residency = 560, 33462306a36Sopenharmony_ci .enter = &intel_idle, 33562306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 33662306a36Sopenharmony_ci { 33762306a36Sopenharmony_ci .name = "C7", 33862306a36Sopenharmony_ci .desc = "MWAIT 0x60", 33962306a36Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 34062306a36Sopenharmony_ci .exit_latency = 1200, 34162306a36Sopenharmony_ci .target_residency = 4000, 34262306a36Sopenharmony_ci .enter = &intel_idle, 34362306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 34462306a36Sopenharmony_ci { 34562306a36Sopenharmony_ci .name = "C7S", 34662306a36Sopenharmony_ci .desc = "MWAIT 0x64", 34762306a36Sopenharmony_ci .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED, 34862306a36Sopenharmony_ci .exit_latency = 10000, 34962306a36Sopenharmony_ci .target_residency = 20000, 35062306a36Sopenharmony_ci .enter = &intel_idle, 35162306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 35262306a36Sopenharmony_ci { 35362306a36Sopenharmony_ci .enter = NULL } 35462306a36Sopenharmony_ci}; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_cistatic struct cpuidle_state cht_cstates[] __initdata = { 35762306a36Sopenharmony_ci { 35862306a36Sopenharmony_ci .name = "C1", 35962306a36Sopenharmony_ci .desc = "MWAIT 0x00", 36062306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 36162306a36Sopenharmony_ci .exit_latency = 1, 36262306a36Sopenharmony_ci .target_residency = 1, 36362306a36Sopenharmony_ci .enter = &intel_idle, 36462306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 36562306a36Sopenharmony_ci { 36662306a36Sopenharmony_ci .name = "C6N", 36762306a36Sopenharmony_ci .desc = "MWAIT 0x58", 36862306a36Sopenharmony_ci .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED, 36962306a36Sopenharmony_ci .exit_latency = 80, 37062306a36Sopenharmony_ci .target_residency = 275, 37162306a36Sopenharmony_ci .enter = &intel_idle, 37262306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 37362306a36Sopenharmony_ci { 37462306a36Sopenharmony_ci .name = "C6S", 37562306a36Sopenharmony_ci .desc = "MWAIT 0x52", 37662306a36Sopenharmony_ci .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, 37762306a36Sopenharmony_ci .exit_latency = 200, 37862306a36Sopenharmony_ci .target_residency = 560, 37962306a36Sopenharmony_ci .enter = &intel_idle, 38062306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 38162306a36Sopenharmony_ci { 38262306a36Sopenharmony_ci .name = "C7", 38362306a36Sopenharmony_ci .desc = "MWAIT 0x60", 38462306a36Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 38562306a36Sopenharmony_ci .exit_latency = 1200, 38662306a36Sopenharmony_ci .target_residency = 4000, 38762306a36Sopenharmony_ci .enter = &intel_idle, 38862306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 38962306a36Sopenharmony_ci { 39062306a36Sopenharmony_ci .name = "C7S", 39162306a36Sopenharmony_ci .desc = "MWAIT 0x64", 39262306a36Sopenharmony_ci .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED, 39362306a36Sopenharmony_ci .exit_latency = 10000, 39462306a36Sopenharmony_ci .target_residency = 20000, 39562306a36Sopenharmony_ci .enter = &intel_idle, 39662306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 39762306a36Sopenharmony_ci { 39862306a36Sopenharmony_ci .enter = NULL } 39962306a36Sopenharmony_ci}; 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_cistatic struct cpuidle_state ivb_cstates[] __initdata = { 40262306a36Sopenharmony_ci { 40362306a36Sopenharmony_ci .name = "C1", 40462306a36Sopenharmony_ci .desc = "MWAIT 0x00", 40562306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 40662306a36Sopenharmony_ci .exit_latency = 1, 40762306a36Sopenharmony_ci .target_residency = 1, 40862306a36Sopenharmony_ci .enter = &intel_idle, 40962306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 41062306a36Sopenharmony_ci { 41162306a36Sopenharmony_ci .name = "C1E", 41262306a36Sopenharmony_ci .desc = "MWAIT 0x01", 41362306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 41462306a36Sopenharmony_ci .exit_latency = 10, 41562306a36Sopenharmony_ci .target_residency = 20, 41662306a36Sopenharmony_ci .enter = &intel_idle, 41762306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 41862306a36Sopenharmony_ci { 41962306a36Sopenharmony_ci .name = "C3", 42062306a36Sopenharmony_ci .desc = "MWAIT 0x10", 42162306a36Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 42262306a36Sopenharmony_ci .exit_latency = 59, 42362306a36Sopenharmony_ci .target_residency = 156, 42462306a36Sopenharmony_ci .enter = &intel_idle, 42562306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 42662306a36Sopenharmony_ci { 42762306a36Sopenharmony_ci .name = "C6", 42862306a36Sopenharmony_ci .desc = "MWAIT 0x20", 42962306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 43062306a36Sopenharmony_ci .exit_latency = 80, 43162306a36Sopenharmony_ci .target_residency = 300, 43262306a36Sopenharmony_ci .enter = &intel_idle, 43362306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 43462306a36Sopenharmony_ci { 43562306a36Sopenharmony_ci .name = "C7", 43662306a36Sopenharmony_ci .desc = "MWAIT 0x30", 43762306a36Sopenharmony_ci .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, 43862306a36Sopenharmony_ci .exit_latency = 87, 43962306a36Sopenharmony_ci .target_residency = 300, 44062306a36Sopenharmony_ci .enter = &intel_idle, 44162306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 44262306a36Sopenharmony_ci { 44362306a36Sopenharmony_ci .enter = NULL } 44462306a36Sopenharmony_ci}; 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_cistatic struct cpuidle_state ivt_cstates[] __initdata = { 44762306a36Sopenharmony_ci { 44862306a36Sopenharmony_ci .name = "C1", 44962306a36Sopenharmony_ci .desc = "MWAIT 0x00", 45062306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 45162306a36Sopenharmony_ci .exit_latency = 1, 45262306a36Sopenharmony_ci .target_residency = 1, 45362306a36Sopenharmony_ci .enter = &intel_idle, 45462306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 45562306a36Sopenharmony_ci { 45662306a36Sopenharmony_ci .name = "C1E", 45762306a36Sopenharmony_ci .desc = "MWAIT 0x01", 45862306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 45962306a36Sopenharmony_ci .exit_latency = 10, 46062306a36Sopenharmony_ci .target_residency = 80, 46162306a36Sopenharmony_ci .enter = &intel_idle, 46262306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 46362306a36Sopenharmony_ci { 46462306a36Sopenharmony_ci .name = "C3", 46562306a36Sopenharmony_ci .desc = "MWAIT 0x10", 46662306a36Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 46762306a36Sopenharmony_ci .exit_latency = 59, 46862306a36Sopenharmony_ci .target_residency = 156, 46962306a36Sopenharmony_ci .enter = &intel_idle, 47062306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 47162306a36Sopenharmony_ci { 47262306a36Sopenharmony_ci .name = "C6", 47362306a36Sopenharmony_ci .desc = "MWAIT 0x20", 47462306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 47562306a36Sopenharmony_ci .exit_latency = 82, 47662306a36Sopenharmony_ci .target_residency = 300, 47762306a36Sopenharmony_ci .enter = &intel_idle, 47862306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 47962306a36Sopenharmony_ci { 48062306a36Sopenharmony_ci .enter = NULL } 48162306a36Sopenharmony_ci}; 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_cistatic struct cpuidle_state ivt_cstates_4s[] __initdata = { 48462306a36Sopenharmony_ci { 48562306a36Sopenharmony_ci .name = "C1", 48662306a36Sopenharmony_ci .desc = "MWAIT 0x00", 48762306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 48862306a36Sopenharmony_ci .exit_latency = 1, 48962306a36Sopenharmony_ci .target_residency = 1, 49062306a36Sopenharmony_ci .enter = &intel_idle, 49162306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 49262306a36Sopenharmony_ci { 49362306a36Sopenharmony_ci .name = "C1E", 49462306a36Sopenharmony_ci .desc = "MWAIT 0x01", 49562306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 49662306a36Sopenharmony_ci .exit_latency = 10, 49762306a36Sopenharmony_ci .target_residency = 250, 49862306a36Sopenharmony_ci .enter = &intel_idle, 49962306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 50062306a36Sopenharmony_ci { 50162306a36Sopenharmony_ci .name = "C3", 50262306a36Sopenharmony_ci .desc = "MWAIT 0x10", 50362306a36Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 50462306a36Sopenharmony_ci .exit_latency = 59, 50562306a36Sopenharmony_ci .target_residency = 300, 50662306a36Sopenharmony_ci .enter = &intel_idle, 50762306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 50862306a36Sopenharmony_ci { 50962306a36Sopenharmony_ci .name = "C6", 51062306a36Sopenharmony_ci .desc = "MWAIT 0x20", 51162306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 51262306a36Sopenharmony_ci .exit_latency = 84, 51362306a36Sopenharmony_ci .target_residency = 400, 51462306a36Sopenharmony_ci .enter = &intel_idle, 51562306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 51662306a36Sopenharmony_ci { 51762306a36Sopenharmony_ci .enter = NULL } 51862306a36Sopenharmony_ci}; 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_cistatic struct cpuidle_state ivt_cstates_8s[] __initdata = { 52162306a36Sopenharmony_ci { 52262306a36Sopenharmony_ci .name = "C1", 52362306a36Sopenharmony_ci .desc = "MWAIT 0x00", 52462306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 52562306a36Sopenharmony_ci .exit_latency = 1, 52662306a36Sopenharmony_ci .target_residency = 1, 52762306a36Sopenharmony_ci .enter = &intel_idle, 52862306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 52962306a36Sopenharmony_ci { 53062306a36Sopenharmony_ci .name = "C1E", 53162306a36Sopenharmony_ci .desc = "MWAIT 0x01", 53262306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 53362306a36Sopenharmony_ci .exit_latency = 10, 53462306a36Sopenharmony_ci .target_residency = 500, 53562306a36Sopenharmony_ci .enter = &intel_idle, 53662306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 53762306a36Sopenharmony_ci { 53862306a36Sopenharmony_ci .name = "C3", 53962306a36Sopenharmony_ci .desc = "MWAIT 0x10", 54062306a36Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 54162306a36Sopenharmony_ci .exit_latency = 59, 54262306a36Sopenharmony_ci .target_residency = 600, 54362306a36Sopenharmony_ci .enter = &intel_idle, 54462306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 54562306a36Sopenharmony_ci { 54662306a36Sopenharmony_ci .name = "C6", 54762306a36Sopenharmony_ci .desc = "MWAIT 0x20", 54862306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 54962306a36Sopenharmony_ci .exit_latency = 88, 55062306a36Sopenharmony_ci .target_residency = 700, 55162306a36Sopenharmony_ci .enter = &intel_idle, 55262306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 55362306a36Sopenharmony_ci { 55462306a36Sopenharmony_ci .enter = NULL } 55562306a36Sopenharmony_ci}; 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_cistatic struct cpuidle_state hsw_cstates[] __initdata = { 55862306a36Sopenharmony_ci { 55962306a36Sopenharmony_ci .name = "C1", 56062306a36Sopenharmony_ci .desc = "MWAIT 0x00", 56162306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 56262306a36Sopenharmony_ci .exit_latency = 2, 56362306a36Sopenharmony_ci .target_residency = 2, 56462306a36Sopenharmony_ci .enter = &intel_idle, 56562306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 56662306a36Sopenharmony_ci { 56762306a36Sopenharmony_ci .name = "C1E", 56862306a36Sopenharmony_ci .desc = "MWAIT 0x01", 56962306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 57062306a36Sopenharmony_ci .exit_latency = 10, 57162306a36Sopenharmony_ci .target_residency = 20, 57262306a36Sopenharmony_ci .enter = &intel_idle, 57362306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 57462306a36Sopenharmony_ci { 57562306a36Sopenharmony_ci .name = "C3", 57662306a36Sopenharmony_ci .desc = "MWAIT 0x10", 57762306a36Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 57862306a36Sopenharmony_ci .exit_latency = 33, 57962306a36Sopenharmony_ci .target_residency = 100, 58062306a36Sopenharmony_ci .enter = &intel_idle, 58162306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 58262306a36Sopenharmony_ci { 58362306a36Sopenharmony_ci .name = "C6", 58462306a36Sopenharmony_ci .desc = "MWAIT 0x20", 58562306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 58662306a36Sopenharmony_ci .exit_latency = 133, 58762306a36Sopenharmony_ci .target_residency = 400, 58862306a36Sopenharmony_ci .enter = &intel_idle, 58962306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 59062306a36Sopenharmony_ci { 59162306a36Sopenharmony_ci .name = "C7s", 59262306a36Sopenharmony_ci .desc = "MWAIT 0x32", 59362306a36Sopenharmony_ci .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TLB_FLUSHED, 59462306a36Sopenharmony_ci .exit_latency = 166, 59562306a36Sopenharmony_ci .target_residency = 500, 59662306a36Sopenharmony_ci .enter = &intel_idle, 59762306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 59862306a36Sopenharmony_ci { 59962306a36Sopenharmony_ci .name = "C8", 60062306a36Sopenharmony_ci .desc = "MWAIT 0x40", 60162306a36Sopenharmony_ci .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, 60262306a36Sopenharmony_ci .exit_latency = 300, 60362306a36Sopenharmony_ci .target_residency = 900, 60462306a36Sopenharmony_ci .enter = &intel_idle, 60562306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 60662306a36Sopenharmony_ci { 60762306a36Sopenharmony_ci .name = "C9", 60862306a36Sopenharmony_ci .desc = "MWAIT 0x50", 60962306a36Sopenharmony_ci .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, 61062306a36Sopenharmony_ci .exit_latency = 600, 61162306a36Sopenharmony_ci .target_residency = 1800, 61262306a36Sopenharmony_ci .enter = &intel_idle, 61362306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 61462306a36Sopenharmony_ci { 61562306a36Sopenharmony_ci .name = "C10", 61662306a36Sopenharmony_ci .desc = "MWAIT 0x60", 61762306a36Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 61862306a36Sopenharmony_ci .exit_latency = 2600, 61962306a36Sopenharmony_ci .target_residency = 7700, 62062306a36Sopenharmony_ci .enter = &intel_idle, 62162306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 62262306a36Sopenharmony_ci { 62362306a36Sopenharmony_ci .enter = NULL } 62462306a36Sopenharmony_ci}; 62562306a36Sopenharmony_cistatic struct cpuidle_state bdw_cstates[] __initdata = { 62662306a36Sopenharmony_ci { 62762306a36Sopenharmony_ci .name = "C1", 62862306a36Sopenharmony_ci .desc = "MWAIT 0x00", 62962306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 63062306a36Sopenharmony_ci .exit_latency = 2, 63162306a36Sopenharmony_ci .target_residency = 2, 63262306a36Sopenharmony_ci .enter = &intel_idle, 63362306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 63462306a36Sopenharmony_ci { 63562306a36Sopenharmony_ci .name = "C1E", 63662306a36Sopenharmony_ci .desc = "MWAIT 0x01", 63762306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 63862306a36Sopenharmony_ci .exit_latency = 10, 63962306a36Sopenharmony_ci .target_residency = 20, 64062306a36Sopenharmony_ci .enter = &intel_idle, 64162306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 64262306a36Sopenharmony_ci { 64362306a36Sopenharmony_ci .name = "C3", 64462306a36Sopenharmony_ci .desc = "MWAIT 0x10", 64562306a36Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 64662306a36Sopenharmony_ci .exit_latency = 40, 64762306a36Sopenharmony_ci .target_residency = 100, 64862306a36Sopenharmony_ci .enter = &intel_idle, 64962306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 65062306a36Sopenharmony_ci { 65162306a36Sopenharmony_ci .name = "C6", 65262306a36Sopenharmony_ci .desc = "MWAIT 0x20", 65362306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 65462306a36Sopenharmony_ci .exit_latency = 133, 65562306a36Sopenharmony_ci .target_residency = 400, 65662306a36Sopenharmony_ci .enter = &intel_idle, 65762306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 65862306a36Sopenharmony_ci { 65962306a36Sopenharmony_ci .name = "C7s", 66062306a36Sopenharmony_ci .desc = "MWAIT 0x32", 66162306a36Sopenharmony_ci .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TLB_FLUSHED, 66262306a36Sopenharmony_ci .exit_latency = 166, 66362306a36Sopenharmony_ci .target_residency = 500, 66462306a36Sopenharmony_ci .enter = &intel_idle, 66562306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 66662306a36Sopenharmony_ci { 66762306a36Sopenharmony_ci .name = "C8", 66862306a36Sopenharmony_ci .desc = "MWAIT 0x40", 66962306a36Sopenharmony_ci .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, 67062306a36Sopenharmony_ci .exit_latency = 300, 67162306a36Sopenharmony_ci .target_residency = 900, 67262306a36Sopenharmony_ci .enter = &intel_idle, 67362306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 67462306a36Sopenharmony_ci { 67562306a36Sopenharmony_ci .name = "C9", 67662306a36Sopenharmony_ci .desc = "MWAIT 0x50", 67762306a36Sopenharmony_ci .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, 67862306a36Sopenharmony_ci .exit_latency = 600, 67962306a36Sopenharmony_ci .target_residency = 1800, 68062306a36Sopenharmony_ci .enter = &intel_idle, 68162306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 68262306a36Sopenharmony_ci { 68362306a36Sopenharmony_ci .name = "C10", 68462306a36Sopenharmony_ci .desc = "MWAIT 0x60", 68562306a36Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 68662306a36Sopenharmony_ci .exit_latency = 2600, 68762306a36Sopenharmony_ci .target_residency = 7700, 68862306a36Sopenharmony_ci .enter = &intel_idle, 68962306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 69062306a36Sopenharmony_ci { 69162306a36Sopenharmony_ci .enter = NULL } 69262306a36Sopenharmony_ci}; 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_cistatic struct cpuidle_state skl_cstates[] __initdata = { 69562306a36Sopenharmony_ci { 69662306a36Sopenharmony_ci .name = "C1", 69762306a36Sopenharmony_ci .desc = "MWAIT 0x00", 69862306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 69962306a36Sopenharmony_ci .exit_latency = 2, 70062306a36Sopenharmony_ci .target_residency = 2, 70162306a36Sopenharmony_ci .enter = &intel_idle, 70262306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 70362306a36Sopenharmony_ci { 70462306a36Sopenharmony_ci .name = "C1E", 70562306a36Sopenharmony_ci .desc = "MWAIT 0x01", 70662306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 70762306a36Sopenharmony_ci .exit_latency = 10, 70862306a36Sopenharmony_ci .target_residency = 20, 70962306a36Sopenharmony_ci .enter = &intel_idle, 71062306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 71162306a36Sopenharmony_ci { 71262306a36Sopenharmony_ci .name = "C3", 71362306a36Sopenharmony_ci .desc = "MWAIT 0x10", 71462306a36Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 71562306a36Sopenharmony_ci .exit_latency = 70, 71662306a36Sopenharmony_ci .target_residency = 100, 71762306a36Sopenharmony_ci .enter = &intel_idle, 71862306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 71962306a36Sopenharmony_ci { 72062306a36Sopenharmony_ci .name = "C6", 72162306a36Sopenharmony_ci .desc = "MWAIT 0x20", 72262306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 72362306a36Sopenharmony_ci .exit_latency = 85, 72462306a36Sopenharmony_ci .target_residency = 200, 72562306a36Sopenharmony_ci .enter = &intel_idle, 72662306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 72762306a36Sopenharmony_ci { 72862306a36Sopenharmony_ci .name = "C7s", 72962306a36Sopenharmony_ci .desc = "MWAIT 0x33", 73062306a36Sopenharmony_ci .flags = MWAIT2flg(0x33) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 73162306a36Sopenharmony_ci .exit_latency = 124, 73262306a36Sopenharmony_ci .target_residency = 800, 73362306a36Sopenharmony_ci .enter = &intel_idle, 73462306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 73562306a36Sopenharmony_ci { 73662306a36Sopenharmony_ci .name = "C8", 73762306a36Sopenharmony_ci .desc = "MWAIT 0x40", 73862306a36Sopenharmony_ci .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 73962306a36Sopenharmony_ci .exit_latency = 200, 74062306a36Sopenharmony_ci .target_residency = 800, 74162306a36Sopenharmony_ci .enter = &intel_idle, 74262306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 74362306a36Sopenharmony_ci { 74462306a36Sopenharmony_ci .name = "C9", 74562306a36Sopenharmony_ci .desc = "MWAIT 0x50", 74662306a36Sopenharmony_ci .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 74762306a36Sopenharmony_ci .exit_latency = 480, 74862306a36Sopenharmony_ci .target_residency = 5000, 74962306a36Sopenharmony_ci .enter = &intel_idle, 75062306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 75162306a36Sopenharmony_ci { 75262306a36Sopenharmony_ci .name = "C10", 75362306a36Sopenharmony_ci .desc = "MWAIT 0x60", 75462306a36Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 75562306a36Sopenharmony_ci .exit_latency = 890, 75662306a36Sopenharmony_ci .target_residency = 5000, 75762306a36Sopenharmony_ci .enter = &intel_idle, 75862306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 75962306a36Sopenharmony_ci { 76062306a36Sopenharmony_ci .enter = NULL } 76162306a36Sopenharmony_ci}; 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_cistatic struct cpuidle_state skx_cstates[] __initdata = { 76462306a36Sopenharmony_ci { 76562306a36Sopenharmony_ci .name = "C1", 76662306a36Sopenharmony_ci .desc = "MWAIT 0x00", 76762306a36Sopenharmony_ci .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_IRQ_ENABLE, 76862306a36Sopenharmony_ci .exit_latency = 2, 76962306a36Sopenharmony_ci .target_residency = 2, 77062306a36Sopenharmony_ci .enter = &intel_idle, 77162306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 77262306a36Sopenharmony_ci { 77362306a36Sopenharmony_ci .name = "C1E", 77462306a36Sopenharmony_ci .desc = "MWAIT 0x01", 77562306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 77662306a36Sopenharmony_ci .exit_latency = 10, 77762306a36Sopenharmony_ci .target_residency = 20, 77862306a36Sopenharmony_ci .enter = &intel_idle, 77962306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 78062306a36Sopenharmony_ci { 78162306a36Sopenharmony_ci .name = "C6", 78262306a36Sopenharmony_ci .desc = "MWAIT 0x20", 78362306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 78462306a36Sopenharmony_ci .exit_latency = 133, 78562306a36Sopenharmony_ci .target_residency = 600, 78662306a36Sopenharmony_ci .enter = &intel_idle, 78762306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 78862306a36Sopenharmony_ci { 78962306a36Sopenharmony_ci .enter = NULL } 79062306a36Sopenharmony_ci}; 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_cistatic struct cpuidle_state icx_cstates[] __initdata = { 79362306a36Sopenharmony_ci { 79462306a36Sopenharmony_ci .name = "C1", 79562306a36Sopenharmony_ci .desc = "MWAIT 0x00", 79662306a36Sopenharmony_ci .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_IRQ_ENABLE, 79762306a36Sopenharmony_ci .exit_latency = 1, 79862306a36Sopenharmony_ci .target_residency = 1, 79962306a36Sopenharmony_ci .enter = &intel_idle, 80062306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 80162306a36Sopenharmony_ci { 80262306a36Sopenharmony_ci .name = "C1E", 80362306a36Sopenharmony_ci .desc = "MWAIT 0x01", 80462306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 80562306a36Sopenharmony_ci .exit_latency = 4, 80662306a36Sopenharmony_ci .target_residency = 4, 80762306a36Sopenharmony_ci .enter = &intel_idle, 80862306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 80962306a36Sopenharmony_ci { 81062306a36Sopenharmony_ci .name = "C6", 81162306a36Sopenharmony_ci .desc = "MWAIT 0x20", 81262306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 81362306a36Sopenharmony_ci .exit_latency = 170, 81462306a36Sopenharmony_ci .target_residency = 600, 81562306a36Sopenharmony_ci .enter = &intel_idle, 81662306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 81762306a36Sopenharmony_ci { 81862306a36Sopenharmony_ci .enter = NULL } 81962306a36Sopenharmony_ci}; 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci/* 82262306a36Sopenharmony_ci * On AlderLake C1 has to be disabled if C1E is enabled, and vice versa. 82362306a36Sopenharmony_ci * C1E is enabled only if "C1E promotion" bit is set in MSR_IA32_POWER_CTL. 82462306a36Sopenharmony_ci * But in this case there is effectively no C1, because C1 requests are 82562306a36Sopenharmony_ci * promoted to C1E. If the "C1E promotion" bit is cleared, then both C1 82662306a36Sopenharmony_ci * and C1E requests end up with C1, so there is effectively no C1E. 82762306a36Sopenharmony_ci * 82862306a36Sopenharmony_ci * By default we enable C1E and disable C1 by marking it with 82962306a36Sopenharmony_ci * 'CPUIDLE_FLAG_UNUSABLE'. 83062306a36Sopenharmony_ci */ 83162306a36Sopenharmony_cistatic struct cpuidle_state adl_cstates[] __initdata = { 83262306a36Sopenharmony_ci { 83362306a36Sopenharmony_ci .name = "C1", 83462306a36Sopenharmony_ci .desc = "MWAIT 0x00", 83562306a36Sopenharmony_ci .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_UNUSABLE, 83662306a36Sopenharmony_ci .exit_latency = 1, 83762306a36Sopenharmony_ci .target_residency = 1, 83862306a36Sopenharmony_ci .enter = &intel_idle, 83962306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 84062306a36Sopenharmony_ci { 84162306a36Sopenharmony_ci .name = "C1E", 84262306a36Sopenharmony_ci .desc = "MWAIT 0x01", 84362306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 84462306a36Sopenharmony_ci .exit_latency = 2, 84562306a36Sopenharmony_ci .target_residency = 4, 84662306a36Sopenharmony_ci .enter = &intel_idle, 84762306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 84862306a36Sopenharmony_ci { 84962306a36Sopenharmony_ci .name = "C6", 85062306a36Sopenharmony_ci .desc = "MWAIT 0x20", 85162306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 85262306a36Sopenharmony_ci .exit_latency = 220, 85362306a36Sopenharmony_ci .target_residency = 600, 85462306a36Sopenharmony_ci .enter = &intel_idle, 85562306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 85662306a36Sopenharmony_ci { 85762306a36Sopenharmony_ci .name = "C8", 85862306a36Sopenharmony_ci .desc = "MWAIT 0x40", 85962306a36Sopenharmony_ci .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, 86062306a36Sopenharmony_ci .exit_latency = 280, 86162306a36Sopenharmony_ci .target_residency = 800, 86262306a36Sopenharmony_ci .enter = &intel_idle, 86362306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 86462306a36Sopenharmony_ci { 86562306a36Sopenharmony_ci .name = "C10", 86662306a36Sopenharmony_ci .desc = "MWAIT 0x60", 86762306a36Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 86862306a36Sopenharmony_ci .exit_latency = 680, 86962306a36Sopenharmony_ci .target_residency = 2000, 87062306a36Sopenharmony_ci .enter = &intel_idle, 87162306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 87262306a36Sopenharmony_ci { 87362306a36Sopenharmony_ci .enter = NULL } 87462306a36Sopenharmony_ci}; 87562306a36Sopenharmony_ci 87662306a36Sopenharmony_cistatic struct cpuidle_state adl_l_cstates[] __initdata = { 87762306a36Sopenharmony_ci { 87862306a36Sopenharmony_ci .name = "C1", 87962306a36Sopenharmony_ci .desc = "MWAIT 0x00", 88062306a36Sopenharmony_ci .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_UNUSABLE, 88162306a36Sopenharmony_ci .exit_latency = 1, 88262306a36Sopenharmony_ci .target_residency = 1, 88362306a36Sopenharmony_ci .enter = &intel_idle, 88462306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 88562306a36Sopenharmony_ci { 88662306a36Sopenharmony_ci .name = "C1E", 88762306a36Sopenharmony_ci .desc = "MWAIT 0x01", 88862306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 88962306a36Sopenharmony_ci .exit_latency = 2, 89062306a36Sopenharmony_ci .target_residency = 4, 89162306a36Sopenharmony_ci .enter = &intel_idle, 89262306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 89362306a36Sopenharmony_ci { 89462306a36Sopenharmony_ci .name = "C6", 89562306a36Sopenharmony_ci .desc = "MWAIT 0x20", 89662306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 89762306a36Sopenharmony_ci .exit_latency = 170, 89862306a36Sopenharmony_ci .target_residency = 500, 89962306a36Sopenharmony_ci .enter = &intel_idle, 90062306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 90162306a36Sopenharmony_ci { 90262306a36Sopenharmony_ci .name = "C8", 90362306a36Sopenharmony_ci .desc = "MWAIT 0x40", 90462306a36Sopenharmony_ci .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, 90562306a36Sopenharmony_ci .exit_latency = 200, 90662306a36Sopenharmony_ci .target_residency = 600, 90762306a36Sopenharmony_ci .enter = &intel_idle, 90862306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 90962306a36Sopenharmony_ci { 91062306a36Sopenharmony_ci .name = "C10", 91162306a36Sopenharmony_ci .desc = "MWAIT 0x60", 91262306a36Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 91362306a36Sopenharmony_ci .exit_latency = 230, 91462306a36Sopenharmony_ci .target_residency = 700, 91562306a36Sopenharmony_ci .enter = &intel_idle, 91662306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 91762306a36Sopenharmony_ci { 91862306a36Sopenharmony_ci .enter = NULL } 91962306a36Sopenharmony_ci}; 92062306a36Sopenharmony_ci 92162306a36Sopenharmony_cistatic struct cpuidle_state gmt_cstates[] __initdata = { 92262306a36Sopenharmony_ci { 92362306a36Sopenharmony_ci .name = "C1", 92462306a36Sopenharmony_ci .desc = "MWAIT 0x00", 92562306a36Sopenharmony_ci .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_UNUSABLE, 92662306a36Sopenharmony_ci .exit_latency = 1, 92762306a36Sopenharmony_ci .target_residency = 1, 92862306a36Sopenharmony_ci .enter = &intel_idle, 92962306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 93062306a36Sopenharmony_ci { 93162306a36Sopenharmony_ci .name = "C1E", 93262306a36Sopenharmony_ci .desc = "MWAIT 0x01", 93362306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 93462306a36Sopenharmony_ci .exit_latency = 2, 93562306a36Sopenharmony_ci .target_residency = 4, 93662306a36Sopenharmony_ci .enter = &intel_idle, 93762306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 93862306a36Sopenharmony_ci { 93962306a36Sopenharmony_ci .name = "C6", 94062306a36Sopenharmony_ci .desc = "MWAIT 0x20", 94162306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 94262306a36Sopenharmony_ci .exit_latency = 195, 94362306a36Sopenharmony_ci .target_residency = 585, 94462306a36Sopenharmony_ci .enter = &intel_idle, 94562306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 94662306a36Sopenharmony_ci { 94762306a36Sopenharmony_ci .name = "C8", 94862306a36Sopenharmony_ci .desc = "MWAIT 0x40", 94962306a36Sopenharmony_ci .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, 95062306a36Sopenharmony_ci .exit_latency = 260, 95162306a36Sopenharmony_ci .target_residency = 1040, 95262306a36Sopenharmony_ci .enter = &intel_idle, 95362306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 95462306a36Sopenharmony_ci { 95562306a36Sopenharmony_ci .name = "C10", 95662306a36Sopenharmony_ci .desc = "MWAIT 0x60", 95762306a36Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 95862306a36Sopenharmony_ci .exit_latency = 660, 95962306a36Sopenharmony_ci .target_residency = 1980, 96062306a36Sopenharmony_ci .enter = &intel_idle, 96162306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 96262306a36Sopenharmony_ci { 96362306a36Sopenharmony_ci .enter = NULL } 96462306a36Sopenharmony_ci}; 96562306a36Sopenharmony_ci 96662306a36Sopenharmony_cistatic struct cpuidle_state spr_cstates[] __initdata = { 96762306a36Sopenharmony_ci { 96862306a36Sopenharmony_ci .name = "C1", 96962306a36Sopenharmony_ci .desc = "MWAIT 0x00", 97062306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 97162306a36Sopenharmony_ci .exit_latency = 1, 97262306a36Sopenharmony_ci .target_residency = 1, 97362306a36Sopenharmony_ci .enter = &intel_idle, 97462306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 97562306a36Sopenharmony_ci { 97662306a36Sopenharmony_ci .name = "C1E", 97762306a36Sopenharmony_ci .desc = "MWAIT 0x01", 97862306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 97962306a36Sopenharmony_ci .exit_latency = 2, 98062306a36Sopenharmony_ci .target_residency = 4, 98162306a36Sopenharmony_ci .enter = &intel_idle, 98262306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 98362306a36Sopenharmony_ci { 98462306a36Sopenharmony_ci .name = "C6", 98562306a36Sopenharmony_ci .desc = "MWAIT 0x20", 98662306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED | 98762306a36Sopenharmony_ci CPUIDLE_FLAG_INIT_XSTATE, 98862306a36Sopenharmony_ci .exit_latency = 290, 98962306a36Sopenharmony_ci .target_residency = 800, 99062306a36Sopenharmony_ci .enter = &intel_idle, 99162306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 99262306a36Sopenharmony_ci { 99362306a36Sopenharmony_ci .enter = NULL } 99462306a36Sopenharmony_ci}; 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_cistatic struct cpuidle_state atom_cstates[] __initdata = { 99762306a36Sopenharmony_ci { 99862306a36Sopenharmony_ci .name = "C1E", 99962306a36Sopenharmony_ci .desc = "MWAIT 0x00", 100062306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 100162306a36Sopenharmony_ci .exit_latency = 10, 100262306a36Sopenharmony_ci .target_residency = 20, 100362306a36Sopenharmony_ci .enter = &intel_idle, 100462306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 100562306a36Sopenharmony_ci { 100662306a36Sopenharmony_ci .name = "C2", 100762306a36Sopenharmony_ci .desc = "MWAIT 0x10", 100862306a36Sopenharmony_ci .flags = MWAIT2flg(0x10), 100962306a36Sopenharmony_ci .exit_latency = 20, 101062306a36Sopenharmony_ci .target_residency = 80, 101162306a36Sopenharmony_ci .enter = &intel_idle, 101262306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 101362306a36Sopenharmony_ci { 101462306a36Sopenharmony_ci .name = "C4", 101562306a36Sopenharmony_ci .desc = "MWAIT 0x30", 101662306a36Sopenharmony_ci .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, 101762306a36Sopenharmony_ci .exit_latency = 100, 101862306a36Sopenharmony_ci .target_residency = 400, 101962306a36Sopenharmony_ci .enter = &intel_idle, 102062306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 102162306a36Sopenharmony_ci { 102262306a36Sopenharmony_ci .name = "C6", 102362306a36Sopenharmony_ci .desc = "MWAIT 0x52", 102462306a36Sopenharmony_ci .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, 102562306a36Sopenharmony_ci .exit_latency = 140, 102662306a36Sopenharmony_ci .target_residency = 560, 102762306a36Sopenharmony_ci .enter = &intel_idle, 102862306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 102962306a36Sopenharmony_ci { 103062306a36Sopenharmony_ci .enter = NULL } 103162306a36Sopenharmony_ci}; 103262306a36Sopenharmony_cistatic struct cpuidle_state tangier_cstates[] __initdata = { 103362306a36Sopenharmony_ci { 103462306a36Sopenharmony_ci .name = "C1", 103562306a36Sopenharmony_ci .desc = "MWAIT 0x00", 103662306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 103762306a36Sopenharmony_ci .exit_latency = 1, 103862306a36Sopenharmony_ci .target_residency = 4, 103962306a36Sopenharmony_ci .enter = &intel_idle, 104062306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 104162306a36Sopenharmony_ci { 104262306a36Sopenharmony_ci .name = "C4", 104362306a36Sopenharmony_ci .desc = "MWAIT 0x30", 104462306a36Sopenharmony_ci .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, 104562306a36Sopenharmony_ci .exit_latency = 100, 104662306a36Sopenharmony_ci .target_residency = 400, 104762306a36Sopenharmony_ci .enter = &intel_idle, 104862306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 104962306a36Sopenharmony_ci { 105062306a36Sopenharmony_ci .name = "C6", 105162306a36Sopenharmony_ci .desc = "MWAIT 0x52", 105262306a36Sopenharmony_ci .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, 105362306a36Sopenharmony_ci .exit_latency = 140, 105462306a36Sopenharmony_ci .target_residency = 560, 105562306a36Sopenharmony_ci .enter = &intel_idle, 105662306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 105762306a36Sopenharmony_ci { 105862306a36Sopenharmony_ci .name = "C7", 105962306a36Sopenharmony_ci .desc = "MWAIT 0x60", 106062306a36Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 106162306a36Sopenharmony_ci .exit_latency = 1200, 106262306a36Sopenharmony_ci .target_residency = 4000, 106362306a36Sopenharmony_ci .enter = &intel_idle, 106462306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 106562306a36Sopenharmony_ci { 106662306a36Sopenharmony_ci .name = "C9", 106762306a36Sopenharmony_ci .desc = "MWAIT 0x64", 106862306a36Sopenharmony_ci .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED, 106962306a36Sopenharmony_ci .exit_latency = 10000, 107062306a36Sopenharmony_ci .target_residency = 20000, 107162306a36Sopenharmony_ci .enter = &intel_idle, 107262306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 107362306a36Sopenharmony_ci { 107462306a36Sopenharmony_ci .enter = NULL } 107562306a36Sopenharmony_ci}; 107662306a36Sopenharmony_cistatic struct cpuidle_state avn_cstates[] __initdata = { 107762306a36Sopenharmony_ci { 107862306a36Sopenharmony_ci .name = "C1", 107962306a36Sopenharmony_ci .desc = "MWAIT 0x00", 108062306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 108162306a36Sopenharmony_ci .exit_latency = 2, 108262306a36Sopenharmony_ci .target_residency = 2, 108362306a36Sopenharmony_ci .enter = &intel_idle, 108462306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 108562306a36Sopenharmony_ci { 108662306a36Sopenharmony_ci .name = "C6", 108762306a36Sopenharmony_ci .desc = "MWAIT 0x51", 108862306a36Sopenharmony_ci .flags = MWAIT2flg(0x51) | CPUIDLE_FLAG_TLB_FLUSHED, 108962306a36Sopenharmony_ci .exit_latency = 15, 109062306a36Sopenharmony_ci .target_residency = 45, 109162306a36Sopenharmony_ci .enter = &intel_idle, 109262306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 109362306a36Sopenharmony_ci { 109462306a36Sopenharmony_ci .enter = NULL } 109562306a36Sopenharmony_ci}; 109662306a36Sopenharmony_cistatic struct cpuidle_state knl_cstates[] __initdata = { 109762306a36Sopenharmony_ci { 109862306a36Sopenharmony_ci .name = "C1", 109962306a36Sopenharmony_ci .desc = "MWAIT 0x00", 110062306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 110162306a36Sopenharmony_ci .exit_latency = 1, 110262306a36Sopenharmony_ci .target_residency = 2, 110362306a36Sopenharmony_ci .enter = &intel_idle, 110462306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle }, 110562306a36Sopenharmony_ci { 110662306a36Sopenharmony_ci .name = "C6", 110762306a36Sopenharmony_ci .desc = "MWAIT 0x10", 110862306a36Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 110962306a36Sopenharmony_ci .exit_latency = 120, 111062306a36Sopenharmony_ci .target_residency = 500, 111162306a36Sopenharmony_ci .enter = &intel_idle, 111262306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle }, 111362306a36Sopenharmony_ci { 111462306a36Sopenharmony_ci .enter = NULL } 111562306a36Sopenharmony_ci}; 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_cistatic struct cpuidle_state bxt_cstates[] __initdata = { 111862306a36Sopenharmony_ci { 111962306a36Sopenharmony_ci .name = "C1", 112062306a36Sopenharmony_ci .desc = "MWAIT 0x00", 112162306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 112262306a36Sopenharmony_ci .exit_latency = 2, 112362306a36Sopenharmony_ci .target_residency = 2, 112462306a36Sopenharmony_ci .enter = &intel_idle, 112562306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 112662306a36Sopenharmony_ci { 112762306a36Sopenharmony_ci .name = "C1E", 112862306a36Sopenharmony_ci .desc = "MWAIT 0x01", 112962306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 113062306a36Sopenharmony_ci .exit_latency = 10, 113162306a36Sopenharmony_ci .target_residency = 20, 113262306a36Sopenharmony_ci .enter = &intel_idle, 113362306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 113462306a36Sopenharmony_ci { 113562306a36Sopenharmony_ci .name = "C6", 113662306a36Sopenharmony_ci .desc = "MWAIT 0x20", 113762306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 113862306a36Sopenharmony_ci .exit_latency = 133, 113962306a36Sopenharmony_ci .target_residency = 133, 114062306a36Sopenharmony_ci .enter = &intel_idle, 114162306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 114262306a36Sopenharmony_ci { 114362306a36Sopenharmony_ci .name = "C7s", 114462306a36Sopenharmony_ci .desc = "MWAIT 0x31", 114562306a36Sopenharmony_ci .flags = MWAIT2flg(0x31) | CPUIDLE_FLAG_TLB_FLUSHED, 114662306a36Sopenharmony_ci .exit_latency = 155, 114762306a36Sopenharmony_ci .target_residency = 155, 114862306a36Sopenharmony_ci .enter = &intel_idle, 114962306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 115062306a36Sopenharmony_ci { 115162306a36Sopenharmony_ci .name = "C8", 115262306a36Sopenharmony_ci .desc = "MWAIT 0x40", 115362306a36Sopenharmony_ci .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, 115462306a36Sopenharmony_ci .exit_latency = 1000, 115562306a36Sopenharmony_ci .target_residency = 1000, 115662306a36Sopenharmony_ci .enter = &intel_idle, 115762306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 115862306a36Sopenharmony_ci { 115962306a36Sopenharmony_ci .name = "C9", 116062306a36Sopenharmony_ci .desc = "MWAIT 0x50", 116162306a36Sopenharmony_ci .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, 116262306a36Sopenharmony_ci .exit_latency = 2000, 116362306a36Sopenharmony_ci .target_residency = 2000, 116462306a36Sopenharmony_ci .enter = &intel_idle, 116562306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 116662306a36Sopenharmony_ci { 116762306a36Sopenharmony_ci .name = "C10", 116862306a36Sopenharmony_ci .desc = "MWAIT 0x60", 116962306a36Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 117062306a36Sopenharmony_ci .exit_latency = 10000, 117162306a36Sopenharmony_ci .target_residency = 10000, 117262306a36Sopenharmony_ci .enter = &intel_idle, 117362306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 117462306a36Sopenharmony_ci { 117562306a36Sopenharmony_ci .enter = NULL } 117662306a36Sopenharmony_ci}; 117762306a36Sopenharmony_ci 117862306a36Sopenharmony_cistatic struct cpuidle_state dnv_cstates[] __initdata = { 117962306a36Sopenharmony_ci { 118062306a36Sopenharmony_ci .name = "C1", 118162306a36Sopenharmony_ci .desc = "MWAIT 0x00", 118262306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 118362306a36Sopenharmony_ci .exit_latency = 2, 118462306a36Sopenharmony_ci .target_residency = 2, 118562306a36Sopenharmony_ci .enter = &intel_idle, 118662306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 118762306a36Sopenharmony_ci { 118862306a36Sopenharmony_ci .name = "C1E", 118962306a36Sopenharmony_ci .desc = "MWAIT 0x01", 119062306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 119162306a36Sopenharmony_ci .exit_latency = 10, 119262306a36Sopenharmony_ci .target_residency = 20, 119362306a36Sopenharmony_ci .enter = &intel_idle, 119462306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 119562306a36Sopenharmony_ci { 119662306a36Sopenharmony_ci .name = "C6", 119762306a36Sopenharmony_ci .desc = "MWAIT 0x20", 119862306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 119962306a36Sopenharmony_ci .exit_latency = 50, 120062306a36Sopenharmony_ci .target_residency = 500, 120162306a36Sopenharmony_ci .enter = &intel_idle, 120262306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 120362306a36Sopenharmony_ci { 120462306a36Sopenharmony_ci .enter = NULL } 120562306a36Sopenharmony_ci}; 120662306a36Sopenharmony_ci 120762306a36Sopenharmony_ci/* 120862306a36Sopenharmony_ci * Note, depending on HW and FW revision, SnowRidge SoC may or may not support 120962306a36Sopenharmony_ci * C6, and this is indicated in the CPUID mwait leaf. 121062306a36Sopenharmony_ci */ 121162306a36Sopenharmony_cistatic struct cpuidle_state snr_cstates[] __initdata = { 121262306a36Sopenharmony_ci { 121362306a36Sopenharmony_ci .name = "C1", 121462306a36Sopenharmony_ci .desc = "MWAIT 0x00", 121562306a36Sopenharmony_ci .flags = MWAIT2flg(0x00), 121662306a36Sopenharmony_ci .exit_latency = 2, 121762306a36Sopenharmony_ci .target_residency = 2, 121862306a36Sopenharmony_ci .enter = &intel_idle, 121962306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 122062306a36Sopenharmony_ci { 122162306a36Sopenharmony_ci .name = "C1E", 122262306a36Sopenharmony_ci .desc = "MWAIT 0x01", 122362306a36Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 122462306a36Sopenharmony_ci .exit_latency = 15, 122562306a36Sopenharmony_ci .target_residency = 25, 122662306a36Sopenharmony_ci .enter = &intel_idle, 122762306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 122862306a36Sopenharmony_ci { 122962306a36Sopenharmony_ci .name = "C6", 123062306a36Sopenharmony_ci .desc = "MWAIT 0x20", 123162306a36Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 123262306a36Sopenharmony_ci .exit_latency = 130, 123362306a36Sopenharmony_ci .target_residency = 500, 123462306a36Sopenharmony_ci .enter = &intel_idle, 123562306a36Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 123662306a36Sopenharmony_ci { 123762306a36Sopenharmony_ci .enter = NULL } 123862306a36Sopenharmony_ci}; 123962306a36Sopenharmony_ci 124062306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_nehalem __initconst = { 124162306a36Sopenharmony_ci .state_table = nehalem_cstates, 124262306a36Sopenharmony_ci .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, 124362306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 124462306a36Sopenharmony_ci}; 124562306a36Sopenharmony_ci 124662306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_nhx __initconst = { 124762306a36Sopenharmony_ci .state_table = nehalem_cstates, 124862306a36Sopenharmony_ci .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, 124962306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 125062306a36Sopenharmony_ci .use_acpi = true, 125162306a36Sopenharmony_ci}; 125262306a36Sopenharmony_ci 125362306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_atom __initconst = { 125462306a36Sopenharmony_ci .state_table = atom_cstates, 125562306a36Sopenharmony_ci}; 125662306a36Sopenharmony_ci 125762306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_tangier __initconst = { 125862306a36Sopenharmony_ci .state_table = tangier_cstates, 125962306a36Sopenharmony_ci}; 126062306a36Sopenharmony_ci 126162306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_lincroft __initconst = { 126262306a36Sopenharmony_ci .state_table = atom_cstates, 126362306a36Sopenharmony_ci .auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE, 126462306a36Sopenharmony_ci}; 126562306a36Sopenharmony_ci 126662306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_snb __initconst = { 126762306a36Sopenharmony_ci .state_table = snb_cstates, 126862306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 126962306a36Sopenharmony_ci}; 127062306a36Sopenharmony_ci 127162306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_snx __initconst = { 127262306a36Sopenharmony_ci .state_table = snb_cstates, 127362306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 127462306a36Sopenharmony_ci .use_acpi = true, 127562306a36Sopenharmony_ci}; 127662306a36Sopenharmony_ci 127762306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_byt __initconst = { 127862306a36Sopenharmony_ci .state_table = byt_cstates, 127962306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 128062306a36Sopenharmony_ci .byt_auto_demotion_disable_flag = true, 128162306a36Sopenharmony_ci}; 128262306a36Sopenharmony_ci 128362306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_cht __initconst = { 128462306a36Sopenharmony_ci .state_table = cht_cstates, 128562306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 128662306a36Sopenharmony_ci .byt_auto_demotion_disable_flag = true, 128762306a36Sopenharmony_ci}; 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_ivb __initconst = { 129062306a36Sopenharmony_ci .state_table = ivb_cstates, 129162306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 129262306a36Sopenharmony_ci}; 129362306a36Sopenharmony_ci 129462306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_ivt __initconst = { 129562306a36Sopenharmony_ci .state_table = ivt_cstates, 129662306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 129762306a36Sopenharmony_ci .use_acpi = true, 129862306a36Sopenharmony_ci}; 129962306a36Sopenharmony_ci 130062306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_hsw __initconst = { 130162306a36Sopenharmony_ci .state_table = hsw_cstates, 130262306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 130362306a36Sopenharmony_ci}; 130462306a36Sopenharmony_ci 130562306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_hsx __initconst = { 130662306a36Sopenharmony_ci .state_table = hsw_cstates, 130762306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 130862306a36Sopenharmony_ci .use_acpi = true, 130962306a36Sopenharmony_ci}; 131062306a36Sopenharmony_ci 131162306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_bdw __initconst = { 131262306a36Sopenharmony_ci .state_table = bdw_cstates, 131362306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 131462306a36Sopenharmony_ci}; 131562306a36Sopenharmony_ci 131662306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_bdx __initconst = { 131762306a36Sopenharmony_ci .state_table = bdw_cstates, 131862306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 131962306a36Sopenharmony_ci .use_acpi = true, 132062306a36Sopenharmony_ci}; 132162306a36Sopenharmony_ci 132262306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_skl __initconst = { 132362306a36Sopenharmony_ci .state_table = skl_cstates, 132462306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 132562306a36Sopenharmony_ci}; 132662306a36Sopenharmony_ci 132762306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_skx __initconst = { 132862306a36Sopenharmony_ci .state_table = skx_cstates, 132962306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 133062306a36Sopenharmony_ci .use_acpi = true, 133162306a36Sopenharmony_ci}; 133262306a36Sopenharmony_ci 133362306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_icx __initconst = { 133462306a36Sopenharmony_ci .state_table = icx_cstates, 133562306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 133662306a36Sopenharmony_ci .use_acpi = true, 133762306a36Sopenharmony_ci}; 133862306a36Sopenharmony_ci 133962306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_adl __initconst = { 134062306a36Sopenharmony_ci .state_table = adl_cstates, 134162306a36Sopenharmony_ci}; 134262306a36Sopenharmony_ci 134362306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_adl_l __initconst = { 134462306a36Sopenharmony_ci .state_table = adl_l_cstates, 134562306a36Sopenharmony_ci}; 134662306a36Sopenharmony_ci 134762306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_gmt __initconst = { 134862306a36Sopenharmony_ci .state_table = gmt_cstates, 134962306a36Sopenharmony_ci}; 135062306a36Sopenharmony_ci 135162306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_spr __initconst = { 135262306a36Sopenharmony_ci .state_table = spr_cstates, 135362306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 135462306a36Sopenharmony_ci .use_acpi = true, 135562306a36Sopenharmony_ci}; 135662306a36Sopenharmony_ci 135762306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_avn __initconst = { 135862306a36Sopenharmony_ci .state_table = avn_cstates, 135962306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 136062306a36Sopenharmony_ci .use_acpi = true, 136162306a36Sopenharmony_ci}; 136262306a36Sopenharmony_ci 136362306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_knl __initconst = { 136462306a36Sopenharmony_ci .state_table = knl_cstates, 136562306a36Sopenharmony_ci .use_acpi = true, 136662306a36Sopenharmony_ci}; 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_bxt __initconst = { 136962306a36Sopenharmony_ci .state_table = bxt_cstates, 137062306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 137162306a36Sopenharmony_ci}; 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_dnv __initconst = { 137462306a36Sopenharmony_ci .state_table = dnv_cstates, 137562306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 137662306a36Sopenharmony_ci .use_acpi = true, 137762306a36Sopenharmony_ci}; 137862306a36Sopenharmony_ci 137962306a36Sopenharmony_cistatic const struct idle_cpu idle_cpu_snr __initconst = { 138062306a36Sopenharmony_ci .state_table = snr_cstates, 138162306a36Sopenharmony_ci .disable_promotion_to_c1e = true, 138262306a36Sopenharmony_ci .use_acpi = true, 138362306a36Sopenharmony_ci}; 138462306a36Sopenharmony_ci 138562306a36Sopenharmony_cistatic const struct x86_cpu_id intel_idle_ids[] __initconst = { 138662306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EP, &idle_cpu_nhx), 138762306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(NEHALEM, &idle_cpu_nehalem), 138862306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_G, &idle_cpu_nehalem), 138962306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(WESTMERE, &idle_cpu_nehalem), 139062306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EP, &idle_cpu_nhx), 139162306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EX, &idle_cpu_nhx), 139262306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_BONNELL, &idle_cpu_atom), 139362306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_BONNELL_MID, &idle_cpu_lincroft), 139462306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EX, &idle_cpu_nhx), 139562306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE, &idle_cpu_snb), 139662306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE_X, &idle_cpu_snx), 139762306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_SALTWELL, &idle_cpu_atom), 139862306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT, &idle_cpu_byt), 139962306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_MID, &idle_cpu_tangier), 140062306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT, &idle_cpu_cht), 140162306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE, &idle_cpu_ivb), 140262306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE_X, &idle_cpu_ivt), 140362306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(HASWELL, &idle_cpu_hsw), 140462306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, &idle_cpu_hsx), 140562306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(HASWELL_L, &idle_cpu_hsw), 140662306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(HASWELL_G, &idle_cpu_hsw), 140762306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_D, &idle_cpu_avn), 140862306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(BROADWELL, &idle_cpu_bdw), 140962306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_G, &idle_cpu_bdw), 141062306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, &idle_cpu_bdx), 141162306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D, &idle_cpu_bdx), 141262306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, &idle_cpu_skl), 141362306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, &idle_cpu_skl), 141462306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, &idle_cpu_skl), 141562306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, &idle_cpu_skl), 141662306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &idle_cpu_skx), 141762306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &idle_cpu_icx), 141862306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &idle_cpu_icx), 141962306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &idle_cpu_adl), 142062306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &idle_cpu_adl_l), 142162306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_GRACEMONT, &idle_cpu_gmt), 142262306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &idle_cpu_spr), 142362306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, &idle_cpu_spr), 142462306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &idle_cpu_knl), 142562306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &idle_cpu_knl), 142662306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &idle_cpu_bxt), 142762306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS, &idle_cpu_bxt), 142862306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D, &idle_cpu_dnv), 142962306a36Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &idle_cpu_snr), 143062306a36Sopenharmony_ci {} 143162306a36Sopenharmony_ci}; 143262306a36Sopenharmony_ci 143362306a36Sopenharmony_cistatic const struct x86_cpu_id intel_mwait_ids[] __initconst = { 143462306a36Sopenharmony_ci X86_MATCH_VENDOR_FAM_FEATURE(INTEL, 6, X86_FEATURE_MWAIT, NULL), 143562306a36Sopenharmony_ci {} 143662306a36Sopenharmony_ci}; 143762306a36Sopenharmony_ci 143862306a36Sopenharmony_cistatic bool __init intel_idle_max_cstate_reached(int cstate) 143962306a36Sopenharmony_ci{ 144062306a36Sopenharmony_ci if (cstate + 1 > max_cstate) { 144162306a36Sopenharmony_ci pr_info("max_cstate %d reached\n", max_cstate); 144262306a36Sopenharmony_ci return true; 144362306a36Sopenharmony_ci } 144462306a36Sopenharmony_ci return false; 144562306a36Sopenharmony_ci} 144662306a36Sopenharmony_ci 144762306a36Sopenharmony_cistatic bool __init intel_idle_state_needs_timer_stop(struct cpuidle_state *state) 144862306a36Sopenharmony_ci{ 144962306a36Sopenharmony_ci unsigned long eax = flg2MWAIT(state->flags); 145062306a36Sopenharmony_ci 145162306a36Sopenharmony_ci if (boot_cpu_has(X86_FEATURE_ARAT)) 145262306a36Sopenharmony_ci return false; 145362306a36Sopenharmony_ci 145462306a36Sopenharmony_ci /* 145562306a36Sopenharmony_ci * Switch over to one-shot tick broadcast if the target C-state 145662306a36Sopenharmony_ci * is deeper than C1. 145762306a36Sopenharmony_ci */ 145862306a36Sopenharmony_ci return !!((eax >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK); 145962306a36Sopenharmony_ci} 146062306a36Sopenharmony_ci 146162306a36Sopenharmony_ci#ifdef CONFIG_ACPI_PROCESSOR_CSTATE 146262306a36Sopenharmony_ci#include <acpi/processor.h> 146362306a36Sopenharmony_ci 146462306a36Sopenharmony_cistatic bool no_acpi __read_mostly; 146562306a36Sopenharmony_cimodule_param(no_acpi, bool, 0444); 146662306a36Sopenharmony_ciMODULE_PARM_DESC(no_acpi, "Do not use ACPI _CST for building the idle states list"); 146762306a36Sopenharmony_ci 146862306a36Sopenharmony_cistatic bool force_use_acpi __read_mostly; /* No effect if no_acpi is set. */ 146962306a36Sopenharmony_cimodule_param_named(use_acpi, force_use_acpi, bool, 0444); 147062306a36Sopenharmony_ciMODULE_PARM_DESC(use_acpi, "Use ACPI _CST for building the idle states list"); 147162306a36Sopenharmony_ci 147262306a36Sopenharmony_cistatic struct acpi_processor_power acpi_state_table __initdata; 147362306a36Sopenharmony_ci 147462306a36Sopenharmony_ci/** 147562306a36Sopenharmony_ci * intel_idle_cst_usable - Check if the _CST information can be used. 147662306a36Sopenharmony_ci * 147762306a36Sopenharmony_ci * Check if all of the C-states listed by _CST in the max_cstate range are 147862306a36Sopenharmony_ci * ACPI_CSTATE_FFH, which means that they should be entered via MWAIT. 147962306a36Sopenharmony_ci */ 148062306a36Sopenharmony_cistatic bool __init intel_idle_cst_usable(void) 148162306a36Sopenharmony_ci{ 148262306a36Sopenharmony_ci int cstate, limit; 148362306a36Sopenharmony_ci 148462306a36Sopenharmony_ci limit = min_t(int, min_t(int, CPUIDLE_STATE_MAX, max_cstate + 1), 148562306a36Sopenharmony_ci acpi_state_table.count); 148662306a36Sopenharmony_ci 148762306a36Sopenharmony_ci for (cstate = 1; cstate < limit; cstate++) { 148862306a36Sopenharmony_ci struct acpi_processor_cx *cx = &acpi_state_table.states[cstate]; 148962306a36Sopenharmony_ci 149062306a36Sopenharmony_ci if (cx->entry_method != ACPI_CSTATE_FFH) 149162306a36Sopenharmony_ci return false; 149262306a36Sopenharmony_ci } 149362306a36Sopenharmony_ci 149462306a36Sopenharmony_ci return true; 149562306a36Sopenharmony_ci} 149662306a36Sopenharmony_ci 149762306a36Sopenharmony_cistatic bool __init intel_idle_acpi_cst_extract(void) 149862306a36Sopenharmony_ci{ 149962306a36Sopenharmony_ci unsigned int cpu; 150062306a36Sopenharmony_ci 150162306a36Sopenharmony_ci if (no_acpi) { 150262306a36Sopenharmony_ci pr_debug("Not allowed to use ACPI _CST\n"); 150362306a36Sopenharmony_ci return false; 150462306a36Sopenharmony_ci } 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_ci for_each_possible_cpu(cpu) { 150762306a36Sopenharmony_ci struct acpi_processor *pr = per_cpu(processors, cpu); 150862306a36Sopenharmony_ci 150962306a36Sopenharmony_ci if (!pr) 151062306a36Sopenharmony_ci continue; 151162306a36Sopenharmony_ci 151262306a36Sopenharmony_ci if (acpi_processor_evaluate_cst(pr->handle, cpu, &acpi_state_table)) 151362306a36Sopenharmony_ci continue; 151462306a36Sopenharmony_ci 151562306a36Sopenharmony_ci acpi_state_table.count++; 151662306a36Sopenharmony_ci 151762306a36Sopenharmony_ci if (!intel_idle_cst_usable()) 151862306a36Sopenharmony_ci continue; 151962306a36Sopenharmony_ci 152062306a36Sopenharmony_ci if (!acpi_processor_claim_cst_control()) 152162306a36Sopenharmony_ci break; 152262306a36Sopenharmony_ci 152362306a36Sopenharmony_ci return true; 152462306a36Sopenharmony_ci } 152562306a36Sopenharmony_ci 152662306a36Sopenharmony_ci acpi_state_table.count = 0; 152762306a36Sopenharmony_ci pr_debug("ACPI _CST not found or not usable\n"); 152862306a36Sopenharmony_ci return false; 152962306a36Sopenharmony_ci} 153062306a36Sopenharmony_ci 153162306a36Sopenharmony_cistatic void __init intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) 153262306a36Sopenharmony_ci{ 153362306a36Sopenharmony_ci int cstate, limit = min_t(int, CPUIDLE_STATE_MAX, acpi_state_table.count); 153462306a36Sopenharmony_ci 153562306a36Sopenharmony_ci /* 153662306a36Sopenharmony_ci * If limit > 0, intel_idle_cst_usable() has returned 'true', so all of 153762306a36Sopenharmony_ci * the interesting states are ACPI_CSTATE_FFH. 153862306a36Sopenharmony_ci */ 153962306a36Sopenharmony_ci for (cstate = 1; cstate < limit; cstate++) { 154062306a36Sopenharmony_ci struct acpi_processor_cx *cx; 154162306a36Sopenharmony_ci struct cpuidle_state *state; 154262306a36Sopenharmony_ci 154362306a36Sopenharmony_ci if (intel_idle_max_cstate_reached(cstate - 1)) 154462306a36Sopenharmony_ci break; 154562306a36Sopenharmony_ci 154662306a36Sopenharmony_ci cx = &acpi_state_table.states[cstate]; 154762306a36Sopenharmony_ci 154862306a36Sopenharmony_ci state = &drv->states[drv->state_count++]; 154962306a36Sopenharmony_ci 155062306a36Sopenharmony_ci snprintf(state->name, CPUIDLE_NAME_LEN, "C%d_ACPI", cstate); 155162306a36Sopenharmony_ci strscpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); 155262306a36Sopenharmony_ci state->exit_latency = cx->latency; 155362306a36Sopenharmony_ci /* 155462306a36Sopenharmony_ci * For C1-type C-states use the same number for both the exit 155562306a36Sopenharmony_ci * latency and target residency, because that is the case for 155662306a36Sopenharmony_ci * C1 in the majority of the static C-states tables above. 155762306a36Sopenharmony_ci * For the other types of C-states, however, set the target 155862306a36Sopenharmony_ci * residency to 3 times the exit latency which should lead to 155962306a36Sopenharmony_ci * a reasonable balance between energy-efficiency and 156062306a36Sopenharmony_ci * performance in the majority of interesting cases. 156162306a36Sopenharmony_ci */ 156262306a36Sopenharmony_ci state->target_residency = cx->latency; 156362306a36Sopenharmony_ci if (cx->type > ACPI_STATE_C1) 156462306a36Sopenharmony_ci state->target_residency *= 3; 156562306a36Sopenharmony_ci 156662306a36Sopenharmony_ci state->flags = MWAIT2flg(cx->address); 156762306a36Sopenharmony_ci if (cx->type > ACPI_STATE_C2) 156862306a36Sopenharmony_ci state->flags |= CPUIDLE_FLAG_TLB_FLUSHED; 156962306a36Sopenharmony_ci 157062306a36Sopenharmony_ci if (disabled_states_mask & BIT(cstate)) 157162306a36Sopenharmony_ci state->flags |= CPUIDLE_FLAG_OFF; 157262306a36Sopenharmony_ci 157362306a36Sopenharmony_ci if (intel_idle_state_needs_timer_stop(state)) 157462306a36Sopenharmony_ci state->flags |= CPUIDLE_FLAG_TIMER_STOP; 157562306a36Sopenharmony_ci 157662306a36Sopenharmony_ci state->enter = intel_idle; 157762306a36Sopenharmony_ci state->enter_s2idle = intel_idle_s2idle; 157862306a36Sopenharmony_ci } 157962306a36Sopenharmony_ci} 158062306a36Sopenharmony_ci 158162306a36Sopenharmony_cistatic bool __init intel_idle_off_by_default(u32 mwait_hint) 158262306a36Sopenharmony_ci{ 158362306a36Sopenharmony_ci int cstate, limit; 158462306a36Sopenharmony_ci 158562306a36Sopenharmony_ci /* 158662306a36Sopenharmony_ci * If there are no _CST C-states, do not disable any C-states by 158762306a36Sopenharmony_ci * default. 158862306a36Sopenharmony_ci */ 158962306a36Sopenharmony_ci if (!acpi_state_table.count) 159062306a36Sopenharmony_ci return false; 159162306a36Sopenharmony_ci 159262306a36Sopenharmony_ci limit = min_t(int, CPUIDLE_STATE_MAX, acpi_state_table.count); 159362306a36Sopenharmony_ci /* 159462306a36Sopenharmony_ci * If limit > 0, intel_idle_cst_usable() has returned 'true', so all of 159562306a36Sopenharmony_ci * the interesting states are ACPI_CSTATE_FFH. 159662306a36Sopenharmony_ci */ 159762306a36Sopenharmony_ci for (cstate = 1; cstate < limit; cstate++) { 159862306a36Sopenharmony_ci if (acpi_state_table.states[cstate].address == mwait_hint) 159962306a36Sopenharmony_ci return false; 160062306a36Sopenharmony_ci } 160162306a36Sopenharmony_ci return true; 160262306a36Sopenharmony_ci} 160362306a36Sopenharmony_ci#else /* !CONFIG_ACPI_PROCESSOR_CSTATE */ 160462306a36Sopenharmony_ci#define force_use_acpi (false) 160562306a36Sopenharmony_ci 160662306a36Sopenharmony_cistatic inline bool intel_idle_acpi_cst_extract(void) { return false; } 160762306a36Sopenharmony_cistatic inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { } 160862306a36Sopenharmony_cistatic inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; } 160962306a36Sopenharmony_ci#endif /* !CONFIG_ACPI_PROCESSOR_CSTATE */ 161062306a36Sopenharmony_ci 161162306a36Sopenharmony_ci/** 161262306a36Sopenharmony_ci * ivt_idle_state_table_update - Tune the idle states table for Ivy Town. 161362306a36Sopenharmony_ci * 161462306a36Sopenharmony_ci * Tune IVT multi-socket targets. 161562306a36Sopenharmony_ci * Assumption: num_sockets == (max_package_num + 1). 161662306a36Sopenharmony_ci */ 161762306a36Sopenharmony_cistatic void __init ivt_idle_state_table_update(void) 161862306a36Sopenharmony_ci{ 161962306a36Sopenharmony_ci /* IVT uses a different table for 1-2, 3-4, and > 4 sockets */ 162062306a36Sopenharmony_ci int cpu, package_num, num_sockets = 1; 162162306a36Sopenharmony_ci 162262306a36Sopenharmony_ci for_each_online_cpu(cpu) { 162362306a36Sopenharmony_ci package_num = topology_physical_package_id(cpu); 162462306a36Sopenharmony_ci if (package_num + 1 > num_sockets) { 162562306a36Sopenharmony_ci num_sockets = package_num + 1; 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci if (num_sockets > 4) { 162862306a36Sopenharmony_ci cpuidle_state_table = ivt_cstates_8s; 162962306a36Sopenharmony_ci return; 163062306a36Sopenharmony_ci } 163162306a36Sopenharmony_ci } 163262306a36Sopenharmony_ci } 163362306a36Sopenharmony_ci 163462306a36Sopenharmony_ci if (num_sockets > 2) 163562306a36Sopenharmony_ci cpuidle_state_table = ivt_cstates_4s; 163662306a36Sopenharmony_ci 163762306a36Sopenharmony_ci /* else, 1 and 2 socket systems use default ivt_cstates */ 163862306a36Sopenharmony_ci} 163962306a36Sopenharmony_ci 164062306a36Sopenharmony_ci/** 164162306a36Sopenharmony_ci * irtl_2_usec - IRTL to microseconds conversion. 164262306a36Sopenharmony_ci * @irtl: IRTL MSR value. 164362306a36Sopenharmony_ci * 164462306a36Sopenharmony_ci * Translate the IRTL (Interrupt Response Time Limit) MSR value to microseconds. 164562306a36Sopenharmony_ci */ 164662306a36Sopenharmony_cistatic unsigned long long __init irtl_2_usec(unsigned long long irtl) 164762306a36Sopenharmony_ci{ 164862306a36Sopenharmony_ci static const unsigned int irtl_ns_units[] __initconst = { 164962306a36Sopenharmony_ci 1, 32, 1024, 32768, 1048576, 33554432, 0, 0 165062306a36Sopenharmony_ci }; 165162306a36Sopenharmony_ci unsigned long long ns; 165262306a36Sopenharmony_ci 165362306a36Sopenharmony_ci if (!irtl) 165462306a36Sopenharmony_ci return 0; 165562306a36Sopenharmony_ci 165662306a36Sopenharmony_ci ns = irtl_ns_units[(irtl >> 10) & 0x7]; 165762306a36Sopenharmony_ci 165862306a36Sopenharmony_ci return div_u64((irtl & 0x3FF) * ns, NSEC_PER_USEC); 165962306a36Sopenharmony_ci} 166062306a36Sopenharmony_ci 166162306a36Sopenharmony_ci/** 166262306a36Sopenharmony_ci * bxt_idle_state_table_update - Fix up the Broxton idle states table. 166362306a36Sopenharmony_ci * 166462306a36Sopenharmony_ci * On BXT, trust the IRTL (Interrupt Response Time Limit) MSR to show the 166562306a36Sopenharmony_ci * definitive maximum latency and use the same value for target_residency. 166662306a36Sopenharmony_ci */ 166762306a36Sopenharmony_cistatic void __init bxt_idle_state_table_update(void) 166862306a36Sopenharmony_ci{ 166962306a36Sopenharmony_ci unsigned long long msr; 167062306a36Sopenharmony_ci unsigned int usec; 167162306a36Sopenharmony_ci 167262306a36Sopenharmony_ci rdmsrl(MSR_PKGC6_IRTL, msr); 167362306a36Sopenharmony_ci usec = irtl_2_usec(msr); 167462306a36Sopenharmony_ci if (usec) { 167562306a36Sopenharmony_ci bxt_cstates[2].exit_latency = usec; 167662306a36Sopenharmony_ci bxt_cstates[2].target_residency = usec; 167762306a36Sopenharmony_ci } 167862306a36Sopenharmony_ci 167962306a36Sopenharmony_ci rdmsrl(MSR_PKGC7_IRTL, msr); 168062306a36Sopenharmony_ci usec = irtl_2_usec(msr); 168162306a36Sopenharmony_ci if (usec) { 168262306a36Sopenharmony_ci bxt_cstates[3].exit_latency = usec; 168362306a36Sopenharmony_ci bxt_cstates[3].target_residency = usec; 168462306a36Sopenharmony_ci } 168562306a36Sopenharmony_ci 168662306a36Sopenharmony_ci rdmsrl(MSR_PKGC8_IRTL, msr); 168762306a36Sopenharmony_ci usec = irtl_2_usec(msr); 168862306a36Sopenharmony_ci if (usec) { 168962306a36Sopenharmony_ci bxt_cstates[4].exit_latency = usec; 169062306a36Sopenharmony_ci bxt_cstates[4].target_residency = usec; 169162306a36Sopenharmony_ci } 169262306a36Sopenharmony_ci 169362306a36Sopenharmony_ci rdmsrl(MSR_PKGC9_IRTL, msr); 169462306a36Sopenharmony_ci usec = irtl_2_usec(msr); 169562306a36Sopenharmony_ci if (usec) { 169662306a36Sopenharmony_ci bxt_cstates[5].exit_latency = usec; 169762306a36Sopenharmony_ci bxt_cstates[5].target_residency = usec; 169862306a36Sopenharmony_ci } 169962306a36Sopenharmony_ci 170062306a36Sopenharmony_ci rdmsrl(MSR_PKGC10_IRTL, msr); 170162306a36Sopenharmony_ci usec = irtl_2_usec(msr); 170262306a36Sopenharmony_ci if (usec) { 170362306a36Sopenharmony_ci bxt_cstates[6].exit_latency = usec; 170462306a36Sopenharmony_ci bxt_cstates[6].target_residency = usec; 170562306a36Sopenharmony_ci } 170662306a36Sopenharmony_ci 170762306a36Sopenharmony_ci} 170862306a36Sopenharmony_ci 170962306a36Sopenharmony_ci/** 171062306a36Sopenharmony_ci * sklh_idle_state_table_update - Fix up the Sky Lake idle states table. 171162306a36Sopenharmony_ci * 171262306a36Sopenharmony_ci * On SKL-H (model 0x5e) skip C8 and C9 if C10 is enabled and SGX disabled. 171362306a36Sopenharmony_ci */ 171462306a36Sopenharmony_cistatic void __init sklh_idle_state_table_update(void) 171562306a36Sopenharmony_ci{ 171662306a36Sopenharmony_ci unsigned long long msr; 171762306a36Sopenharmony_ci unsigned int eax, ebx, ecx, edx; 171862306a36Sopenharmony_ci 171962306a36Sopenharmony_ci 172062306a36Sopenharmony_ci /* if PC10 disabled via cmdline intel_idle.max_cstate=7 or shallower */ 172162306a36Sopenharmony_ci if (max_cstate <= 7) 172262306a36Sopenharmony_ci return; 172362306a36Sopenharmony_ci 172462306a36Sopenharmony_ci /* if PC10 not present in CPUID.MWAIT.EDX */ 172562306a36Sopenharmony_ci if ((mwait_substates & (0xF << 28)) == 0) 172662306a36Sopenharmony_ci return; 172762306a36Sopenharmony_ci 172862306a36Sopenharmony_ci rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr); 172962306a36Sopenharmony_ci 173062306a36Sopenharmony_ci /* PC10 is not enabled in PKG C-state limit */ 173162306a36Sopenharmony_ci if ((msr & 0xF) != 8) 173262306a36Sopenharmony_ci return; 173362306a36Sopenharmony_ci 173462306a36Sopenharmony_ci ecx = 0; 173562306a36Sopenharmony_ci cpuid(7, &eax, &ebx, &ecx, &edx); 173662306a36Sopenharmony_ci 173762306a36Sopenharmony_ci /* if SGX is present */ 173862306a36Sopenharmony_ci if (ebx & (1 << 2)) { 173962306a36Sopenharmony_ci 174062306a36Sopenharmony_ci rdmsrl(MSR_IA32_FEAT_CTL, msr); 174162306a36Sopenharmony_ci 174262306a36Sopenharmony_ci /* if SGX is enabled */ 174362306a36Sopenharmony_ci if (msr & (1 << 18)) 174462306a36Sopenharmony_ci return; 174562306a36Sopenharmony_ci } 174662306a36Sopenharmony_ci 174762306a36Sopenharmony_ci skl_cstates[5].flags |= CPUIDLE_FLAG_UNUSABLE; /* C8-SKL */ 174862306a36Sopenharmony_ci skl_cstates[6].flags |= CPUIDLE_FLAG_UNUSABLE; /* C9-SKL */ 174962306a36Sopenharmony_ci} 175062306a36Sopenharmony_ci 175162306a36Sopenharmony_ci/** 175262306a36Sopenharmony_ci * skx_idle_state_table_update - Adjust the Sky Lake/Cascade Lake 175362306a36Sopenharmony_ci * idle states table. 175462306a36Sopenharmony_ci */ 175562306a36Sopenharmony_cistatic void __init skx_idle_state_table_update(void) 175662306a36Sopenharmony_ci{ 175762306a36Sopenharmony_ci unsigned long long msr; 175862306a36Sopenharmony_ci 175962306a36Sopenharmony_ci rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr); 176062306a36Sopenharmony_ci 176162306a36Sopenharmony_ci /* 176262306a36Sopenharmony_ci * 000b: C0/C1 (no package C-state support) 176362306a36Sopenharmony_ci * 001b: C2 176462306a36Sopenharmony_ci * 010b: C6 (non-retention) 176562306a36Sopenharmony_ci * 011b: C6 (retention) 176662306a36Sopenharmony_ci * 111b: No Package C state limits. 176762306a36Sopenharmony_ci */ 176862306a36Sopenharmony_ci if ((msr & 0x7) < 2) { 176962306a36Sopenharmony_ci /* 177062306a36Sopenharmony_ci * Uses the CC6 + PC0 latency and 3 times of 177162306a36Sopenharmony_ci * latency for target_residency if the PC6 177262306a36Sopenharmony_ci * is disabled in BIOS. This is consistent 177362306a36Sopenharmony_ci * with how intel_idle driver uses _CST 177462306a36Sopenharmony_ci * to set the target_residency. 177562306a36Sopenharmony_ci */ 177662306a36Sopenharmony_ci skx_cstates[2].exit_latency = 92; 177762306a36Sopenharmony_ci skx_cstates[2].target_residency = 276; 177862306a36Sopenharmony_ci } 177962306a36Sopenharmony_ci} 178062306a36Sopenharmony_ci 178162306a36Sopenharmony_ci/** 178262306a36Sopenharmony_ci * adl_idle_state_table_update - Adjust AlderLake idle states table. 178362306a36Sopenharmony_ci */ 178462306a36Sopenharmony_cistatic void __init adl_idle_state_table_update(void) 178562306a36Sopenharmony_ci{ 178662306a36Sopenharmony_ci /* Check if user prefers C1 over C1E. */ 178762306a36Sopenharmony_ci if (preferred_states_mask & BIT(1) && !(preferred_states_mask & BIT(2))) { 178862306a36Sopenharmony_ci cpuidle_state_table[0].flags &= ~CPUIDLE_FLAG_UNUSABLE; 178962306a36Sopenharmony_ci cpuidle_state_table[1].flags |= CPUIDLE_FLAG_UNUSABLE; 179062306a36Sopenharmony_ci 179162306a36Sopenharmony_ci /* Disable C1E by clearing the "C1E promotion" bit. */ 179262306a36Sopenharmony_ci c1e_promotion = C1E_PROMOTION_DISABLE; 179362306a36Sopenharmony_ci return; 179462306a36Sopenharmony_ci } 179562306a36Sopenharmony_ci 179662306a36Sopenharmony_ci /* Make sure C1E is enabled by default */ 179762306a36Sopenharmony_ci c1e_promotion = C1E_PROMOTION_ENABLE; 179862306a36Sopenharmony_ci} 179962306a36Sopenharmony_ci 180062306a36Sopenharmony_ci/** 180162306a36Sopenharmony_ci * spr_idle_state_table_update - Adjust Sapphire Rapids idle states table. 180262306a36Sopenharmony_ci */ 180362306a36Sopenharmony_cistatic void __init spr_idle_state_table_update(void) 180462306a36Sopenharmony_ci{ 180562306a36Sopenharmony_ci unsigned long long msr; 180662306a36Sopenharmony_ci 180762306a36Sopenharmony_ci /* 180862306a36Sopenharmony_ci * By default, the C6 state assumes the worst-case scenario of package 180962306a36Sopenharmony_ci * C6. However, if PC6 is disabled, we update the numbers to match 181062306a36Sopenharmony_ci * core C6. 181162306a36Sopenharmony_ci */ 181262306a36Sopenharmony_ci rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr); 181362306a36Sopenharmony_ci 181462306a36Sopenharmony_ci /* Limit value 2 and above allow for PC6. */ 181562306a36Sopenharmony_ci if ((msr & 0x7) < 2) { 181662306a36Sopenharmony_ci spr_cstates[2].exit_latency = 190; 181762306a36Sopenharmony_ci spr_cstates[2].target_residency = 600; 181862306a36Sopenharmony_ci } 181962306a36Sopenharmony_ci} 182062306a36Sopenharmony_ci 182162306a36Sopenharmony_cistatic bool __init intel_idle_verify_cstate(unsigned int mwait_hint) 182262306a36Sopenharmony_ci{ 182362306a36Sopenharmony_ci unsigned int mwait_cstate = MWAIT_HINT2CSTATE(mwait_hint) + 1; 182462306a36Sopenharmony_ci unsigned int num_substates = (mwait_substates >> mwait_cstate * 4) & 182562306a36Sopenharmony_ci MWAIT_SUBSTATE_MASK; 182662306a36Sopenharmony_ci 182762306a36Sopenharmony_ci /* Ignore the C-state if there are NO sub-states in CPUID for it. */ 182862306a36Sopenharmony_ci if (num_substates == 0) 182962306a36Sopenharmony_ci return false; 183062306a36Sopenharmony_ci 183162306a36Sopenharmony_ci if (mwait_cstate > 2 && !boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) 183262306a36Sopenharmony_ci mark_tsc_unstable("TSC halts in idle states deeper than C2"); 183362306a36Sopenharmony_ci 183462306a36Sopenharmony_ci return true; 183562306a36Sopenharmony_ci} 183662306a36Sopenharmony_ci 183762306a36Sopenharmony_cistatic void state_update_enter_method(struct cpuidle_state *state, int cstate) 183862306a36Sopenharmony_ci{ 183962306a36Sopenharmony_ci if (state->flags & CPUIDLE_FLAG_INIT_XSTATE) { 184062306a36Sopenharmony_ci /* 184162306a36Sopenharmony_ci * Combining with XSTATE with IBRS or IRQ_ENABLE flags 184262306a36Sopenharmony_ci * is not currently supported but this driver. 184362306a36Sopenharmony_ci */ 184462306a36Sopenharmony_ci WARN_ON_ONCE(state->flags & CPUIDLE_FLAG_IBRS); 184562306a36Sopenharmony_ci WARN_ON_ONCE(state->flags & CPUIDLE_FLAG_IRQ_ENABLE); 184662306a36Sopenharmony_ci state->enter = intel_idle_xstate; 184762306a36Sopenharmony_ci return; 184862306a36Sopenharmony_ci } 184962306a36Sopenharmony_ci 185062306a36Sopenharmony_ci if (cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS) && 185162306a36Sopenharmony_ci state->flags & CPUIDLE_FLAG_IBRS) { 185262306a36Sopenharmony_ci /* 185362306a36Sopenharmony_ci * IBRS mitigation requires that C-states are entered 185462306a36Sopenharmony_ci * with interrupts disabled. 185562306a36Sopenharmony_ci */ 185662306a36Sopenharmony_ci WARN_ON_ONCE(state->flags & CPUIDLE_FLAG_IRQ_ENABLE); 185762306a36Sopenharmony_ci state->enter = intel_idle_ibrs; 185862306a36Sopenharmony_ci return; 185962306a36Sopenharmony_ci } 186062306a36Sopenharmony_ci 186162306a36Sopenharmony_ci if (state->flags & CPUIDLE_FLAG_IRQ_ENABLE) { 186262306a36Sopenharmony_ci state->enter = intel_idle_irq; 186362306a36Sopenharmony_ci return; 186462306a36Sopenharmony_ci } 186562306a36Sopenharmony_ci 186662306a36Sopenharmony_ci if (force_irq_on) { 186762306a36Sopenharmony_ci pr_info("forced intel_idle_irq for state %d\n", cstate); 186862306a36Sopenharmony_ci state->enter = intel_idle_irq; 186962306a36Sopenharmony_ci } 187062306a36Sopenharmony_ci} 187162306a36Sopenharmony_ci 187262306a36Sopenharmony_cistatic void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv) 187362306a36Sopenharmony_ci{ 187462306a36Sopenharmony_ci int cstate; 187562306a36Sopenharmony_ci 187662306a36Sopenharmony_ci switch (boot_cpu_data.x86_model) { 187762306a36Sopenharmony_ci case INTEL_FAM6_IVYBRIDGE_X: 187862306a36Sopenharmony_ci ivt_idle_state_table_update(); 187962306a36Sopenharmony_ci break; 188062306a36Sopenharmony_ci case INTEL_FAM6_ATOM_GOLDMONT: 188162306a36Sopenharmony_ci case INTEL_FAM6_ATOM_GOLDMONT_PLUS: 188262306a36Sopenharmony_ci bxt_idle_state_table_update(); 188362306a36Sopenharmony_ci break; 188462306a36Sopenharmony_ci case INTEL_FAM6_SKYLAKE: 188562306a36Sopenharmony_ci sklh_idle_state_table_update(); 188662306a36Sopenharmony_ci break; 188762306a36Sopenharmony_ci case INTEL_FAM6_SKYLAKE_X: 188862306a36Sopenharmony_ci skx_idle_state_table_update(); 188962306a36Sopenharmony_ci break; 189062306a36Sopenharmony_ci case INTEL_FAM6_SAPPHIRERAPIDS_X: 189162306a36Sopenharmony_ci case INTEL_FAM6_EMERALDRAPIDS_X: 189262306a36Sopenharmony_ci spr_idle_state_table_update(); 189362306a36Sopenharmony_ci break; 189462306a36Sopenharmony_ci case INTEL_FAM6_ALDERLAKE: 189562306a36Sopenharmony_ci case INTEL_FAM6_ALDERLAKE_L: 189662306a36Sopenharmony_ci case INTEL_FAM6_ATOM_GRACEMONT: 189762306a36Sopenharmony_ci adl_idle_state_table_update(); 189862306a36Sopenharmony_ci break; 189962306a36Sopenharmony_ci } 190062306a36Sopenharmony_ci 190162306a36Sopenharmony_ci for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) { 190262306a36Sopenharmony_ci struct cpuidle_state *state; 190362306a36Sopenharmony_ci unsigned int mwait_hint; 190462306a36Sopenharmony_ci 190562306a36Sopenharmony_ci if (intel_idle_max_cstate_reached(cstate)) 190662306a36Sopenharmony_ci break; 190762306a36Sopenharmony_ci 190862306a36Sopenharmony_ci if (!cpuidle_state_table[cstate].enter && 190962306a36Sopenharmony_ci !cpuidle_state_table[cstate].enter_s2idle) 191062306a36Sopenharmony_ci break; 191162306a36Sopenharmony_ci 191262306a36Sopenharmony_ci /* If marked as unusable, skip this state. */ 191362306a36Sopenharmony_ci if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_UNUSABLE) { 191462306a36Sopenharmony_ci pr_debug("state %s is disabled\n", 191562306a36Sopenharmony_ci cpuidle_state_table[cstate].name); 191662306a36Sopenharmony_ci continue; 191762306a36Sopenharmony_ci } 191862306a36Sopenharmony_ci 191962306a36Sopenharmony_ci mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags); 192062306a36Sopenharmony_ci if (!intel_idle_verify_cstate(mwait_hint)) 192162306a36Sopenharmony_ci continue; 192262306a36Sopenharmony_ci 192362306a36Sopenharmony_ci /* Structure copy. */ 192462306a36Sopenharmony_ci drv->states[drv->state_count] = cpuidle_state_table[cstate]; 192562306a36Sopenharmony_ci state = &drv->states[drv->state_count]; 192662306a36Sopenharmony_ci 192762306a36Sopenharmony_ci state_update_enter_method(state, cstate); 192862306a36Sopenharmony_ci 192962306a36Sopenharmony_ci 193062306a36Sopenharmony_ci if ((disabled_states_mask & BIT(drv->state_count)) || 193162306a36Sopenharmony_ci ((icpu->use_acpi || force_use_acpi) && 193262306a36Sopenharmony_ci intel_idle_off_by_default(mwait_hint) && 193362306a36Sopenharmony_ci !(state->flags & CPUIDLE_FLAG_ALWAYS_ENABLE))) 193462306a36Sopenharmony_ci state->flags |= CPUIDLE_FLAG_OFF; 193562306a36Sopenharmony_ci 193662306a36Sopenharmony_ci if (intel_idle_state_needs_timer_stop(state)) 193762306a36Sopenharmony_ci state->flags |= CPUIDLE_FLAG_TIMER_STOP; 193862306a36Sopenharmony_ci 193962306a36Sopenharmony_ci drv->state_count++; 194062306a36Sopenharmony_ci } 194162306a36Sopenharmony_ci 194262306a36Sopenharmony_ci if (icpu->byt_auto_demotion_disable_flag) { 194362306a36Sopenharmony_ci wrmsrl(MSR_CC6_DEMOTION_POLICY_CONFIG, 0); 194462306a36Sopenharmony_ci wrmsrl(MSR_MC6_DEMOTION_POLICY_CONFIG, 0); 194562306a36Sopenharmony_ci } 194662306a36Sopenharmony_ci} 194762306a36Sopenharmony_ci 194862306a36Sopenharmony_ci/** 194962306a36Sopenharmony_ci * intel_idle_cpuidle_driver_init - Create the list of available idle states. 195062306a36Sopenharmony_ci * @drv: cpuidle driver structure to initialize. 195162306a36Sopenharmony_ci */ 195262306a36Sopenharmony_cistatic void __init intel_idle_cpuidle_driver_init(struct cpuidle_driver *drv) 195362306a36Sopenharmony_ci{ 195462306a36Sopenharmony_ci cpuidle_poll_state_init(drv); 195562306a36Sopenharmony_ci 195662306a36Sopenharmony_ci if (disabled_states_mask & BIT(0)) 195762306a36Sopenharmony_ci drv->states[0].flags |= CPUIDLE_FLAG_OFF; 195862306a36Sopenharmony_ci 195962306a36Sopenharmony_ci drv->state_count = 1; 196062306a36Sopenharmony_ci 196162306a36Sopenharmony_ci if (icpu) 196262306a36Sopenharmony_ci intel_idle_init_cstates_icpu(drv); 196362306a36Sopenharmony_ci else 196462306a36Sopenharmony_ci intel_idle_init_cstates_acpi(drv); 196562306a36Sopenharmony_ci} 196662306a36Sopenharmony_ci 196762306a36Sopenharmony_cistatic void auto_demotion_disable(void) 196862306a36Sopenharmony_ci{ 196962306a36Sopenharmony_ci unsigned long long msr_bits; 197062306a36Sopenharmony_ci 197162306a36Sopenharmony_ci rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr_bits); 197262306a36Sopenharmony_ci msr_bits &= ~auto_demotion_disable_flags; 197362306a36Sopenharmony_ci wrmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr_bits); 197462306a36Sopenharmony_ci} 197562306a36Sopenharmony_ci 197662306a36Sopenharmony_cistatic void c1e_promotion_enable(void) 197762306a36Sopenharmony_ci{ 197862306a36Sopenharmony_ci unsigned long long msr_bits; 197962306a36Sopenharmony_ci 198062306a36Sopenharmony_ci rdmsrl(MSR_IA32_POWER_CTL, msr_bits); 198162306a36Sopenharmony_ci msr_bits |= 0x2; 198262306a36Sopenharmony_ci wrmsrl(MSR_IA32_POWER_CTL, msr_bits); 198362306a36Sopenharmony_ci} 198462306a36Sopenharmony_ci 198562306a36Sopenharmony_cistatic void c1e_promotion_disable(void) 198662306a36Sopenharmony_ci{ 198762306a36Sopenharmony_ci unsigned long long msr_bits; 198862306a36Sopenharmony_ci 198962306a36Sopenharmony_ci rdmsrl(MSR_IA32_POWER_CTL, msr_bits); 199062306a36Sopenharmony_ci msr_bits &= ~0x2; 199162306a36Sopenharmony_ci wrmsrl(MSR_IA32_POWER_CTL, msr_bits); 199262306a36Sopenharmony_ci} 199362306a36Sopenharmony_ci 199462306a36Sopenharmony_ci/** 199562306a36Sopenharmony_ci * intel_idle_cpu_init - Register the target CPU with the cpuidle core. 199662306a36Sopenharmony_ci * @cpu: CPU to initialize. 199762306a36Sopenharmony_ci * 199862306a36Sopenharmony_ci * Register a cpuidle device object for @cpu and update its MSRs in accordance 199962306a36Sopenharmony_ci * with the processor model flags. 200062306a36Sopenharmony_ci */ 200162306a36Sopenharmony_cistatic int intel_idle_cpu_init(unsigned int cpu) 200262306a36Sopenharmony_ci{ 200362306a36Sopenharmony_ci struct cpuidle_device *dev; 200462306a36Sopenharmony_ci 200562306a36Sopenharmony_ci dev = per_cpu_ptr(intel_idle_cpuidle_devices, cpu); 200662306a36Sopenharmony_ci dev->cpu = cpu; 200762306a36Sopenharmony_ci 200862306a36Sopenharmony_ci if (cpuidle_register_device(dev)) { 200962306a36Sopenharmony_ci pr_debug("cpuidle_register_device %d failed!\n", cpu); 201062306a36Sopenharmony_ci return -EIO; 201162306a36Sopenharmony_ci } 201262306a36Sopenharmony_ci 201362306a36Sopenharmony_ci if (auto_demotion_disable_flags) 201462306a36Sopenharmony_ci auto_demotion_disable(); 201562306a36Sopenharmony_ci 201662306a36Sopenharmony_ci if (c1e_promotion == C1E_PROMOTION_ENABLE) 201762306a36Sopenharmony_ci c1e_promotion_enable(); 201862306a36Sopenharmony_ci else if (c1e_promotion == C1E_PROMOTION_DISABLE) 201962306a36Sopenharmony_ci c1e_promotion_disable(); 202062306a36Sopenharmony_ci 202162306a36Sopenharmony_ci return 0; 202262306a36Sopenharmony_ci} 202362306a36Sopenharmony_ci 202462306a36Sopenharmony_cistatic int intel_idle_cpu_online(unsigned int cpu) 202562306a36Sopenharmony_ci{ 202662306a36Sopenharmony_ci struct cpuidle_device *dev; 202762306a36Sopenharmony_ci 202862306a36Sopenharmony_ci if (!boot_cpu_has(X86_FEATURE_ARAT)) 202962306a36Sopenharmony_ci tick_broadcast_enable(); 203062306a36Sopenharmony_ci 203162306a36Sopenharmony_ci /* 203262306a36Sopenharmony_ci * Some systems can hotplug a cpu at runtime after 203362306a36Sopenharmony_ci * the kernel has booted, we have to initialize the 203462306a36Sopenharmony_ci * driver in this case 203562306a36Sopenharmony_ci */ 203662306a36Sopenharmony_ci dev = per_cpu_ptr(intel_idle_cpuidle_devices, cpu); 203762306a36Sopenharmony_ci if (!dev->registered) 203862306a36Sopenharmony_ci return intel_idle_cpu_init(cpu); 203962306a36Sopenharmony_ci 204062306a36Sopenharmony_ci return 0; 204162306a36Sopenharmony_ci} 204262306a36Sopenharmony_ci 204362306a36Sopenharmony_ci/** 204462306a36Sopenharmony_ci * intel_idle_cpuidle_devices_uninit - Unregister all cpuidle devices. 204562306a36Sopenharmony_ci */ 204662306a36Sopenharmony_cistatic void __init intel_idle_cpuidle_devices_uninit(void) 204762306a36Sopenharmony_ci{ 204862306a36Sopenharmony_ci int i; 204962306a36Sopenharmony_ci 205062306a36Sopenharmony_ci for_each_online_cpu(i) 205162306a36Sopenharmony_ci cpuidle_unregister_device(per_cpu_ptr(intel_idle_cpuidle_devices, i)); 205262306a36Sopenharmony_ci} 205362306a36Sopenharmony_ci 205462306a36Sopenharmony_cistatic int __init intel_idle_init(void) 205562306a36Sopenharmony_ci{ 205662306a36Sopenharmony_ci const struct x86_cpu_id *id; 205762306a36Sopenharmony_ci unsigned int eax, ebx, ecx; 205862306a36Sopenharmony_ci int retval; 205962306a36Sopenharmony_ci 206062306a36Sopenharmony_ci /* Do not load intel_idle at all for now if idle= is passed */ 206162306a36Sopenharmony_ci if (boot_option_idle_override != IDLE_NO_OVERRIDE) 206262306a36Sopenharmony_ci return -ENODEV; 206362306a36Sopenharmony_ci 206462306a36Sopenharmony_ci if (max_cstate == 0) { 206562306a36Sopenharmony_ci pr_debug("disabled\n"); 206662306a36Sopenharmony_ci return -EPERM; 206762306a36Sopenharmony_ci } 206862306a36Sopenharmony_ci 206962306a36Sopenharmony_ci id = x86_match_cpu(intel_idle_ids); 207062306a36Sopenharmony_ci if (id) { 207162306a36Sopenharmony_ci if (!boot_cpu_has(X86_FEATURE_MWAIT)) { 207262306a36Sopenharmony_ci pr_debug("Please enable MWAIT in BIOS SETUP\n"); 207362306a36Sopenharmony_ci return -ENODEV; 207462306a36Sopenharmony_ci } 207562306a36Sopenharmony_ci } else { 207662306a36Sopenharmony_ci id = x86_match_cpu(intel_mwait_ids); 207762306a36Sopenharmony_ci if (!id) 207862306a36Sopenharmony_ci return -ENODEV; 207962306a36Sopenharmony_ci } 208062306a36Sopenharmony_ci 208162306a36Sopenharmony_ci if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) 208262306a36Sopenharmony_ci return -ENODEV; 208362306a36Sopenharmony_ci 208462306a36Sopenharmony_ci cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates); 208562306a36Sopenharmony_ci 208662306a36Sopenharmony_ci if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || 208762306a36Sopenharmony_ci !(ecx & CPUID5_ECX_INTERRUPT_BREAK) || 208862306a36Sopenharmony_ci !mwait_substates) 208962306a36Sopenharmony_ci return -ENODEV; 209062306a36Sopenharmony_ci 209162306a36Sopenharmony_ci pr_debug("MWAIT substates: 0x%x\n", mwait_substates); 209262306a36Sopenharmony_ci 209362306a36Sopenharmony_ci icpu = (const struct idle_cpu *)id->driver_data; 209462306a36Sopenharmony_ci if (icpu) { 209562306a36Sopenharmony_ci cpuidle_state_table = icpu->state_table; 209662306a36Sopenharmony_ci auto_demotion_disable_flags = icpu->auto_demotion_disable_flags; 209762306a36Sopenharmony_ci if (icpu->disable_promotion_to_c1e) 209862306a36Sopenharmony_ci c1e_promotion = C1E_PROMOTION_DISABLE; 209962306a36Sopenharmony_ci if (icpu->use_acpi || force_use_acpi) 210062306a36Sopenharmony_ci intel_idle_acpi_cst_extract(); 210162306a36Sopenharmony_ci } else if (!intel_idle_acpi_cst_extract()) { 210262306a36Sopenharmony_ci return -ENODEV; 210362306a36Sopenharmony_ci } 210462306a36Sopenharmony_ci 210562306a36Sopenharmony_ci pr_debug("v" INTEL_IDLE_VERSION " model 0x%X\n", 210662306a36Sopenharmony_ci boot_cpu_data.x86_model); 210762306a36Sopenharmony_ci 210862306a36Sopenharmony_ci intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device); 210962306a36Sopenharmony_ci if (!intel_idle_cpuidle_devices) 211062306a36Sopenharmony_ci return -ENOMEM; 211162306a36Sopenharmony_ci 211262306a36Sopenharmony_ci intel_idle_cpuidle_driver_init(&intel_idle_driver); 211362306a36Sopenharmony_ci 211462306a36Sopenharmony_ci retval = cpuidle_register_driver(&intel_idle_driver); 211562306a36Sopenharmony_ci if (retval) { 211662306a36Sopenharmony_ci struct cpuidle_driver *drv = cpuidle_get_driver(); 211762306a36Sopenharmony_ci printk(KERN_DEBUG pr_fmt("intel_idle yielding to %s\n"), 211862306a36Sopenharmony_ci drv ? drv->name : "none"); 211962306a36Sopenharmony_ci goto init_driver_fail; 212062306a36Sopenharmony_ci } 212162306a36Sopenharmony_ci 212262306a36Sopenharmony_ci retval = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "idle/intel:online", 212362306a36Sopenharmony_ci intel_idle_cpu_online, NULL); 212462306a36Sopenharmony_ci if (retval < 0) 212562306a36Sopenharmony_ci goto hp_setup_fail; 212662306a36Sopenharmony_ci 212762306a36Sopenharmony_ci pr_debug("Local APIC timer is reliable in %s\n", 212862306a36Sopenharmony_ci boot_cpu_has(X86_FEATURE_ARAT) ? "all C-states" : "C1"); 212962306a36Sopenharmony_ci 213062306a36Sopenharmony_ci return 0; 213162306a36Sopenharmony_ci 213262306a36Sopenharmony_cihp_setup_fail: 213362306a36Sopenharmony_ci intel_idle_cpuidle_devices_uninit(); 213462306a36Sopenharmony_ci cpuidle_unregister_driver(&intel_idle_driver); 213562306a36Sopenharmony_ciinit_driver_fail: 213662306a36Sopenharmony_ci free_percpu(intel_idle_cpuidle_devices); 213762306a36Sopenharmony_ci return retval; 213862306a36Sopenharmony_ci 213962306a36Sopenharmony_ci} 214062306a36Sopenharmony_cidevice_initcall(intel_idle_init); 214162306a36Sopenharmony_ci 214262306a36Sopenharmony_ci/* 214362306a36Sopenharmony_ci * We are not really modular, but we used to support that. Meaning we also 214462306a36Sopenharmony_ci * support "intel_idle.max_cstate=..." at boot and also a read-only export of 214562306a36Sopenharmony_ci * it at /sys/module/intel_idle/parameters/max_cstate -- so using module_param 214662306a36Sopenharmony_ci * is the easiest way (currently) to continue doing that. 214762306a36Sopenharmony_ci */ 214862306a36Sopenharmony_cimodule_param(max_cstate, int, 0444); 214962306a36Sopenharmony_ci/* 215062306a36Sopenharmony_ci * The positions of the bits that are set in this number are the indices of the 215162306a36Sopenharmony_ci * idle states to be disabled by default (as reflected by the names of the 215262306a36Sopenharmony_ci * corresponding idle state directories in sysfs, "state0", "state1" ... 215362306a36Sopenharmony_ci * "state<i>" ..., where <i> is the index of the given state). 215462306a36Sopenharmony_ci */ 215562306a36Sopenharmony_cimodule_param_named(states_off, disabled_states_mask, uint, 0444); 215662306a36Sopenharmony_ciMODULE_PARM_DESC(states_off, "Mask of disabled idle states"); 215762306a36Sopenharmony_ci/* 215862306a36Sopenharmony_ci * Some platforms come with mutually exclusive C-states, so that if one is 215962306a36Sopenharmony_ci * enabled, the other C-states must not be used. Example: C1 and C1E on 216062306a36Sopenharmony_ci * Sapphire Rapids platform. This parameter allows for selecting the 216162306a36Sopenharmony_ci * preferred C-states among the groups of mutually exclusive C-states - the 216262306a36Sopenharmony_ci * selected C-states will be registered, the other C-states from the mutually 216362306a36Sopenharmony_ci * exclusive group won't be registered. If the platform has no mutually 216462306a36Sopenharmony_ci * exclusive C-states, this parameter has no effect. 216562306a36Sopenharmony_ci */ 216662306a36Sopenharmony_cimodule_param_named(preferred_cstates, preferred_states_mask, uint, 0444); 216762306a36Sopenharmony_ciMODULE_PARM_DESC(preferred_cstates, "Mask of preferred idle states"); 216862306a36Sopenharmony_ci/* 216962306a36Sopenharmony_ci * Debugging option that forces the driver to enter all C-states with 217062306a36Sopenharmony_ci * interrupts enabled. Does not apply to C-states with 217162306a36Sopenharmony_ci * 'CPUIDLE_FLAG_INIT_XSTATE' and 'CPUIDLE_FLAG_IBRS' flags. 217262306a36Sopenharmony_ci */ 217362306a36Sopenharmony_cimodule_param(force_irq_on, bool, 0444); 2174