18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * intel_idle.c - native hardware idle loop for modern Intel processors 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2013 - 2020, Intel Corporation. 68c2ecf20Sopenharmony_ci * Len Brown <len.brown@intel.com> 78c2ecf20Sopenharmony_ci * Rafael J. Wysocki <rafael.j.wysocki@intel.com> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci/* 118c2ecf20Sopenharmony_ci * intel_idle is a cpuidle driver that loads on all Intel CPUs with MWAIT 128c2ecf20Sopenharmony_ci * in lieu of the legacy ACPI processor_idle driver. The intent is to 138c2ecf20Sopenharmony_ci * make Linux more efficient on these processors, as intel_idle knows 148c2ecf20Sopenharmony_ci * more than ACPI, as well as make Linux more immune to ACPI BIOS bugs. 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* 188c2ecf20Sopenharmony_ci * Design Assumptions 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * All CPUs have same idle states as boot CPU 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * Chipset BM_STS (bus master status) bit is a NOP 238c2ecf20Sopenharmony_ci * for preventing entry into deep C-states 248c2ecf20Sopenharmony_ci * 258c2ecf20Sopenharmony_ci * CPU will flush caches as needed when entering a C-state via MWAIT 268c2ecf20Sopenharmony_ci * (in contrast to entering ACPI C3, in which case the WBINVD 278c2ecf20Sopenharmony_ci * instruction needs to be executed to flush the caches) 288c2ecf20Sopenharmony_ci */ 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* 318c2ecf20Sopenharmony_ci * Known limitations 328c2ecf20Sopenharmony_ci * 338c2ecf20Sopenharmony_ci * ACPI has a .suspend hack to turn off deep c-statees during suspend 348c2ecf20Sopenharmony_ci * to avoid complications with the lapic timer workaround. 358c2ecf20Sopenharmony_ci * Have not seen issues with suspend, but may need same workaround here. 368c2ecf20Sopenharmony_ci * 378c2ecf20Sopenharmony_ci */ 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci/* un-comment DEBUG to enable pr_debug() statements */ 408c2ecf20Sopenharmony_ci#define DEBUG 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#include <linux/acpi.h> 458c2ecf20Sopenharmony_ci#include <linux/kernel.h> 468c2ecf20Sopenharmony_ci#include <linux/cpuidle.h> 478c2ecf20Sopenharmony_ci#include <linux/tick.h> 488c2ecf20Sopenharmony_ci#include <trace/events/power.h> 498c2ecf20Sopenharmony_ci#include <linux/sched.h> 508c2ecf20Sopenharmony_ci#include <linux/sched/smt.h> 518c2ecf20Sopenharmony_ci#include <linux/notifier.h> 528c2ecf20Sopenharmony_ci#include <linux/cpu.h> 538c2ecf20Sopenharmony_ci#include <linux/moduleparam.h> 548c2ecf20Sopenharmony_ci#include <asm/cpu_device_id.h> 558c2ecf20Sopenharmony_ci#include <asm/intel-family.h> 568c2ecf20Sopenharmony_ci#include <asm/nospec-branch.h> 578c2ecf20Sopenharmony_ci#include <asm/mwait.h> 588c2ecf20Sopenharmony_ci#include <asm/msr.h> 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci#define INTEL_IDLE_VERSION "0.5.1" 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_cistatic struct cpuidle_driver intel_idle_driver = { 638c2ecf20Sopenharmony_ci .name = "intel_idle", 648c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 658c2ecf20Sopenharmony_ci}; 668c2ecf20Sopenharmony_ci/* intel_idle.max_cstate=0 disables driver */ 678c2ecf20Sopenharmony_cistatic int max_cstate = CPUIDLE_STATE_MAX - 1; 688c2ecf20Sopenharmony_cistatic unsigned int disabled_states_mask; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic struct cpuidle_device __percpu *intel_idle_cpuidle_devices; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cistatic unsigned long auto_demotion_disable_flags; 738c2ecf20Sopenharmony_cistatic bool disable_promotion_to_c1e; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistruct idle_cpu { 768c2ecf20Sopenharmony_ci struct cpuidle_state *state_table; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci /* 798c2ecf20Sopenharmony_ci * Hardware C-state auto-demotion may not always be optimal. 808c2ecf20Sopenharmony_ci * Indicate which enable bits to clear here. 818c2ecf20Sopenharmony_ci */ 828c2ecf20Sopenharmony_ci unsigned long auto_demotion_disable_flags; 838c2ecf20Sopenharmony_ci bool byt_auto_demotion_disable_flag; 848c2ecf20Sopenharmony_ci bool disable_promotion_to_c1e; 858c2ecf20Sopenharmony_ci bool use_acpi; 868c2ecf20Sopenharmony_ci}; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistatic const struct idle_cpu *icpu __initdata; 898c2ecf20Sopenharmony_cistatic struct cpuidle_state *cpuidle_state_table __initdata; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_cistatic unsigned int mwait_substates __initdata; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci/* 948c2ecf20Sopenharmony_ci * Enable this state by default even if the ACPI _CST does not list it. 958c2ecf20Sopenharmony_ci */ 968c2ecf20Sopenharmony_ci#define CPUIDLE_FLAG_ALWAYS_ENABLE BIT(15) 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci/* 998c2ecf20Sopenharmony_ci * Disable IBRS across idle (when KERNEL_IBRS), is exclusive vs IRQ_ENABLE 1008c2ecf20Sopenharmony_ci * above. 1018c2ecf20Sopenharmony_ci */ 1028c2ecf20Sopenharmony_ci#define CPUIDLE_FLAG_IBRS BIT(16) 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci/* 1058c2ecf20Sopenharmony_ci * MWAIT takes an 8-bit "hint" in EAX "suggesting" 1068c2ecf20Sopenharmony_ci * the C-state (top nibble) and sub-state (bottom nibble) 1078c2ecf20Sopenharmony_ci * 0x00 means "MWAIT(C1)", 0x10 means "MWAIT(C2)" etc. 1088c2ecf20Sopenharmony_ci * 1098c2ecf20Sopenharmony_ci * We store the hint at the top of our "flags" for each state. 1108c2ecf20Sopenharmony_ci */ 1118c2ecf20Sopenharmony_ci#define flg2MWAIT(flags) (((flags) >> 24) & 0xFF) 1128c2ecf20Sopenharmony_ci#define MWAIT2flg(eax) ((eax & 0xFF) << 24) 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci/** 1158c2ecf20Sopenharmony_ci * intel_idle - Ask the processor to enter the given idle state. 1168c2ecf20Sopenharmony_ci * @dev: cpuidle device of the target CPU. 1178c2ecf20Sopenharmony_ci * @drv: cpuidle driver (assumed to point to intel_idle_driver). 1188c2ecf20Sopenharmony_ci * @index: Target idle state index. 1198c2ecf20Sopenharmony_ci * 1208c2ecf20Sopenharmony_ci * Use the MWAIT instruction to notify the processor that the CPU represented by 1218c2ecf20Sopenharmony_ci * @dev is idle and it can try to enter the idle state corresponding to @index. 1228c2ecf20Sopenharmony_ci * 1238c2ecf20Sopenharmony_ci * If the local APIC timer is not known to be reliable in the target idle state, 1248c2ecf20Sopenharmony_ci * enable one-shot tick broadcasting for the target CPU before executing MWAIT. 1258c2ecf20Sopenharmony_ci * 1268c2ecf20Sopenharmony_ci * Optionally call leave_mm() for the target CPU upfront to avoid wakeups due to 1278c2ecf20Sopenharmony_ci * flushing user TLBs. 1288c2ecf20Sopenharmony_ci * 1298c2ecf20Sopenharmony_ci * Must be called under local_irq_disable(). 1308c2ecf20Sopenharmony_ci */ 1318c2ecf20Sopenharmony_cistatic __cpuidle int intel_idle(struct cpuidle_device *dev, 1328c2ecf20Sopenharmony_ci struct cpuidle_driver *drv, int index) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci struct cpuidle_state *state = &drv->states[index]; 1358c2ecf20Sopenharmony_ci unsigned long eax = flg2MWAIT(state->flags); 1368c2ecf20Sopenharmony_ci unsigned long ecx = 1; /* break on interrupt flag */ 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci mwait_idle_with_hints(eax, ecx); 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci return index; 1418c2ecf20Sopenharmony_ci} 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_cistatic __cpuidle int intel_idle_ibrs(struct cpuidle_device *dev, 1448c2ecf20Sopenharmony_ci struct cpuidle_driver *drv, int index) 1458c2ecf20Sopenharmony_ci{ 1468c2ecf20Sopenharmony_ci bool smt_active = sched_smt_active(); 1478c2ecf20Sopenharmony_ci u64 spec_ctrl = spec_ctrl_current(); 1488c2ecf20Sopenharmony_ci int ret; 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci if (smt_active) 1518c2ecf20Sopenharmony_ci wrmsrl(MSR_IA32_SPEC_CTRL, 0); 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci ret = intel_idle(dev, drv, index); 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci if (smt_active) 1568c2ecf20Sopenharmony_ci wrmsrl(MSR_IA32_SPEC_CTRL, spec_ctrl); 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci return ret; 1598c2ecf20Sopenharmony_ci} 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci/** 1628c2ecf20Sopenharmony_ci * intel_idle_s2idle - Ask the processor to enter the given idle state. 1638c2ecf20Sopenharmony_ci * @dev: cpuidle device of the target CPU. 1648c2ecf20Sopenharmony_ci * @drv: cpuidle driver (assumed to point to intel_idle_driver). 1658c2ecf20Sopenharmony_ci * @index: Target idle state index. 1668c2ecf20Sopenharmony_ci * 1678c2ecf20Sopenharmony_ci * Use the MWAIT instruction to notify the processor that the CPU represented by 1688c2ecf20Sopenharmony_ci * @dev is idle and it can try to enter the idle state corresponding to @index. 1698c2ecf20Sopenharmony_ci * 1708c2ecf20Sopenharmony_ci * Invoked as a suspend-to-idle callback routine with frozen user space, frozen 1718c2ecf20Sopenharmony_ci * scheduler tick and suspended scheduler clock on the target CPU. 1728c2ecf20Sopenharmony_ci */ 1738c2ecf20Sopenharmony_cistatic __cpuidle int intel_idle_s2idle(struct cpuidle_device *dev, 1748c2ecf20Sopenharmony_ci struct cpuidle_driver *drv, int index) 1758c2ecf20Sopenharmony_ci{ 1768c2ecf20Sopenharmony_ci unsigned long eax = flg2MWAIT(drv->states[index].flags); 1778c2ecf20Sopenharmony_ci unsigned long ecx = 1; /* break on interrupt flag */ 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci mwait_idle_with_hints(eax, ecx); 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci return 0; 1828c2ecf20Sopenharmony_ci} 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci/* 1858c2ecf20Sopenharmony_ci * States are indexed by the cstate number, 1868c2ecf20Sopenharmony_ci * which is also the index into the MWAIT hint array. 1878c2ecf20Sopenharmony_ci * Thus C0 is a dummy. 1888c2ecf20Sopenharmony_ci */ 1898c2ecf20Sopenharmony_cistatic struct cpuidle_state nehalem_cstates[] __initdata = { 1908c2ecf20Sopenharmony_ci { 1918c2ecf20Sopenharmony_ci .name = "C1", 1928c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 1938c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 1948c2ecf20Sopenharmony_ci .exit_latency = 3, 1958c2ecf20Sopenharmony_ci .target_residency = 6, 1968c2ecf20Sopenharmony_ci .enter = &intel_idle, 1978c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 1988c2ecf20Sopenharmony_ci { 1998c2ecf20Sopenharmony_ci .name = "C1E", 2008c2ecf20Sopenharmony_ci .desc = "MWAIT 0x01", 2018c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 2028c2ecf20Sopenharmony_ci .exit_latency = 10, 2038c2ecf20Sopenharmony_ci .target_residency = 20, 2048c2ecf20Sopenharmony_ci .enter = &intel_idle, 2058c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 2068c2ecf20Sopenharmony_ci { 2078c2ecf20Sopenharmony_ci .name = "C3", 2088c2ecf20Sopenharmony_ci .desc = "MWAIT 0x10", 2098c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 2108c2ecf20Sopenharmony_ci .exit_latency = 20, 2118c2ecf20Sopenharmony_ci .target_residency = 80, 2128c2ecf20Sopenharmony_ci .enter = &intel_idle, 2138c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 2148c2ecf20Sopenharmony_ci { 2158c2ecf20Sopenharmony_ci .name = "C6", 2168c2ecf20Sopenharmony_ci .desc = "MWAIT 0x20", 2178c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 2188c2ecf20Sopenharmony_ci .exit_latency = 200, 2198c2ecf20Sopenharmony_ci .target_residency = 800, 2208c2ecf20Sopenharmony_ci .enter = &intel_idle, 2218c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 2228c2ecf20Sopenharmony_ci { 2238c2ecf20Sopenharmony_ci .enter = NULL } 2248c2ecf20Sopenharmony_ci}; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_cistatic struct cpuidle_state snb_cstates[] __initdata = { 2278c2ecf20Sopenharmony_ci { 2288c2ecf20Sopenharmony_ci .name = "C1", 2298c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 2308c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 2318c2ecf20Sopenharmony_ci .exit_latency = 2, 2328c2ecf20Sopenharmony_ci .target_residency = 2, 2338c2ecf20Sopenharmony_ci .enter = &intel_idle, 2348c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 2358c2ecf20Sopenharmony_ci { 2368c2ecf20Sopenharmony_ci .name = "C1E", 2378c2ecf20Sopenharmony_ci .desc = "MWAIT 0x01", 2388c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 2398c2ecf20Sopenharmony_ci .exit_latency = 10, 2408c2ecf20Sopenharmony_ci .target_residency = 20, 2418c2ecf20Sopenharmony_ci .enter = &intel_idle, 2428c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 2438c2ecf20Sopenharmony_ci { 2448c2ecf20Sopenharmony_ci .name = "C3", 2458c2ecf20Sopenharmony_ci .desc = "MWAIT 0x10", 2468c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 2478c2ecf20Sopenharmony_ci .exit_latency = 80, 2488c2ecf20Sopenharmony_ci .target_residency = 211, 2498c2ecf20Sopenharmony_ci .enter = &intel_idle, 2508c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 2518c2ecf20Sopenharmony_ci { 2528c2ecf20Sopenharmony_ci .name = "C6", 2538c2ecf20Sopenharmony_ci .desc = "MWAIT 0x20", 2548c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 2558c2ecf20Sopenharmony_ci .exit_latency = 104, 2568c2ecf20Sopenharmony_ci .target_residency = 345, 2578c2ecf20Sopenharmony_ci .enter = &intel_idle, 2588c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 2598c2ecf20Sopenharmony_ci { 2608c2ecf20Sopenharmony_ci .name = "C7", 2618c2ecf20Sopenharmony_ci .desc = "MWAIT 0x30", 2628c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, 2638c2ecf20Sopenharmony_ci .exit_latency = 109, 2648c2ecf20Sopenharmony_ci .target_residency = 345, 2658c2ecf20Sopenharmony_ci .enter = &intel_idle, 2668c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 2678c2ecf20Sopenharmony_ci { 2688c2ecf20Sopenharmony_ci .enter = NULL } 2698c2ecf20Sopenharmony_ci}; 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_cistatic struct cpuidle_state byt_cstates[] __initdata = { 2728c2ecf20Sopenharmony_ci { 2738c2ecf20Sopenharmony_ci .name = "C1", 2748c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 2758c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 2768c2ecf20Sopenharmony_ci .exit_latency = 1, 2778c2ecf20Sopenharmony_ci .target_residency = 1, 2788c2ecf20Sopenharmony_ci .enter = &intel_idle, 2798c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 2808c2ecf20Sopenharmony_ci { 2818c2ecf20Sopenharmony_ci .name = "C6N", 2828c2ecf20Sopenharmony_ci .desc = "MWAIT 0x58", 2838c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED, 2848c2ecf20Sopenharmony_ci .exit_latency = 300, 2858c2ecf20Sopenharmony_ci .target_residency = 275, 2868c2ecf20Sopenharmony_ci .enter = &intel_idle, 2878c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 2888c2ecf20Sopenharmony_ci { 2898c2ecf20Sopenharmony_ci .name = "C6S", 2908c2ecf20Sopenharmony_ci .desc = "MWAIT 0x52", 2918c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, 2928c2ecf20Sopenharmony_ci .exit_latency = 500, 2938c2ecf20Sopenharmony_ci .target_residency = 560, 2948c2ecf20Sopenharmony_ci .enter = &intel_idle, 2958c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 2968c2ecf20Sopenharmony_ci { 2978c2ecf20Sopenharmony_ci .name = "C7", 2988c2ecf20Sopenharmony_ci .desc = "MWAIT 0x60", 2998c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 3008c2ecf20Sopenharmony_ci .exit_latency = 1200, 3018c2ecf20Sopenharmony_ci .target_residency = 4000, 3028c2ecf20Sopenharmony_ci .enter = &intel_idle, 3038c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 3048c2ecf20Sopenharmony_ci { 3058c2ecf20Sopenharmony_ci .name = "C7S", 3068c2ecf20Sopenharmony_ci .desc = "MWAIT 0x64", 3078c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED, 3088c2ecf20Sopenharmony_ci .exit_latency = 10000, 3098c2ecf20Sopenharmony_ci .target_residency = 20000, 3108c2ecf20Sopenharmony_ci .enter = &intel_idle, 3118c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 3128c2ecf20Sopenharmony_ci { 3138c2ecf20Sopenharmony_ci .enter = NULL } 3148c2ecf20Sopenharmony_ci}; 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_cistatic struct cpuidle_state cht_cstates[] __initdata = { 3178c2ecf20Sopenharmony_ci { 3188c2ecf20Sopenharmony_ci .name = "C1", 3198c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 3208c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 3218c2ecf20Sopenharmony_ci .exit_latency = 1, 3228c2ecf20Sopenharmony_ci .target_residency = 1, 3238c2ecf20Sopenharmony_ci .enter = &intel_idle, 3248c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 3258c2ecf20Sopenharmony_ci { 3268c2ecf20Sopenharmony_ci .name = "C6N", 3278c2ecf20Sopenharmony_ci .desc = "MWAIT 0x58", 3288c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED, 3298c2ecf20Sopenharmony_ci .exit_latency = 80, 3308c2ecf20Sopenharmony_ci .target_residency = 275, 3318c2ecf20Sopenharmony_ci .enter = &intel_idle, 3328c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 3338c2ecf20Sopenharmony_ci { 3348c2ecf20Sopenharmony_ci .name = "C6S", 3358c2ecf20Sopenharmony_ci .desc = "MWAIT 0x52", 3368c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, 3378c2ecf20Sopenharmony_ci .exit_latency = 200, 3388c2ecf20Sopenharmony_ci .target_residency = 560, 3398c2ecf20Sopenharmony_ci .enter = &intel_idle, 3408c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 3418c2ecf20Sopenharmony_ci { 3428c2ecf20Sopenharmony_ci .name = "C7", 3438c2ecf20Sopenharmony_ci .desc = "MWAIT 0x60", 3448c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 3458c2ecf20Sopenharmony_ci .exit_latency = 1200, 3468c2ecf20Sopenharmony_ci .target_residency = 4000, 3478c2ecf20Sopenharmony_ci .enter = &intel_idle, 3488c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 3498c2ecf20Sopenharmony_ci { 3508c2ecf20Sopenharmony_ci .name = "C7S", 3518c2ecf20Sopenharmony_ci .desc = "MWAIT 0x64", 3528c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED, 3538c2ecf20Sopenharmony_ci .exit_latency = 10000, 3548c2ecf20Sopenharmony_ci .target_residency = 20000, 3558c2ecf20Sopenharmony_ci .enter = &intel_idle, 3568c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 3578c2ecf20Sopenharmony_ci { 3588c2ecf20Sopenharmony_ci .enter = NULL } 3598c2ecf20Sopenharmony_ci}; 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_cistatic struct cpuidle_state ivb_cstates[] __initdata = { 3628c2ecf20Sopenharmony_ci { 3638c2ecf20Sopenharmony_ci .name = "C1", 3648c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 3658c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 3668c2ecf20Sopenharmony_ci .exit_latency = 1, 3678c2ecf20Sopenharmony_ci .target_residency = 1, 3688c2ecf20Sopenharmony_ci .enter = &intel_idle, 3698c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 3708c2ecf20Sopenharmony_ci { 3718c2ecf20Sopenharmony_ci .name = "C1E", 3728c2ecf20Sopenharmony_ci .desc = "MWAIT 0x01", 3738c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 3748c2ecf20Sopenharmony_ci .exit_latency = 10, 3758c2ecf20Sopenharmony_ci .target_residency = 20, 3768c2ecf20Sopenharmony_ci .enter = &intel_idle, 3778c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 3788c2ecf20Sopenharmony_ci { 3798c2ecf20Sopenharmony_ci .name = "C3", 3808c2ecf20Sopenharmony_ci .desc = "MWAIT 0x10", 3818c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 3828c2ecf20Sopenharmony_ci .exit_latency = 59, 3838c2ecf20Sopenharmony_ci .target_residency = 156, 3848c2ecf20Sopenharmony_ci .enter = &intel_idle, 3858c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 3868c2ecf20Sopenharmony_ci { 3878c2ecf20Sopenharmony_ci .name = "C6", 3888c2ecf20Sopenharmony_ci .desc = "MWAIT 0x20", 3898c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 3908c2ecf20Sopenharmony_ci .exit_latency = 80, 3918c2ecf20Sopenharmony_ci .target_residency = 300, 3928c2ecf20Sopenharmony_ci .enter = &intel_idle, 3938c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 3948c2ecf20Sopenharmony_ci { 3958c2ecf20Sopenharmony_ci .name = "C7", 3968c2ecf20Sopenharmony_ci .desc = "MWAIT 0x30", 3978c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, 3988c2ecf20Sopenharmony_ci .exit_latency = 87, 3998c2ecf20Sopenharmony_ci .target_residency = 300, 4008c2ecf20Sopenharmony_ci .enter = &intel_idle, 4018c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 4028c2ecf20Sopenharmony_ci { 4038c2ecf20Sopenharmony_ci .enter = NULL } 4048c2ecf20Sopenharmony_ci}; 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_cistatic struct cpuidle_state ivt_cstates[] __initdata = { 4078c2ecf20Sopenharmony_ci { 4088c2ecf20Sopenharmony_ci .name = "C1", 4098c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 4108c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 4118c2ecf20Sopenharmony_ci .exit_latency = 1, 4128c2ecf20Sopenharmony_ci .target_residency = 1, 4138c2ecf20Sopenharmony_ci .enter = &intel_idle, 4148c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 4158c2ecf20Sopenharmony_ci { 4168c2ecf20Sopenharmony_ci .name = "C1E", 4178c2ecf20Sopenharmony_ci .desc = "MWAIT 0x01", 4188c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 4198c2ecf20Sopenharmony_ci .exit_latency = 10, 4208c2ecf20Sopenharmony_ci .target_residency = 80, 4218c2ecf20Sopenharmony_ci .enter = &intel_idle, 4228c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 4238c2ecf20Sopenharmony_ci { 4248c2ecf20Sopenharmony_ci .name = "C3", 4258c2ecf20Sopenharmony_ci .desc = "MWAIT 0x10", 4268c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 4278c2ecf20Sopenharmony_ci .exit_latency = 59, 4288c2ecf20Sopenharmony_ci .target_residency = 156, 4298c2ecf20Sopenharmony_ci .enter = &intel_idle, 4308c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 4318c2ecf20Sopenharmony_ci { 4328c2ecf20Sopenharmony_ci .name = "C6", 4338c2ecf20Sopenharmony_ci .desc = "MWAIT 0x20", 4348c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 4358c2ecf20Sopenharmony_ci .exit_latency = 82, 4368c2ecf20Sopenharmony_ci .target_residency = 300, 4378c2ecf20Sopenharmony_ci .enter = &intel_idle, 4388c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 4398c2ecf20Sopenharmony_ci { 4408c2ecf20Sopenharmony_ci .enter = NULL } 4418c2ecf20Sopenharmony_ci}; 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_cistatic struct cpuidle_state ivt_cstates_4s[] __initdata = { 4448c2ecf20Sopenharmony_ci { 4458c2ecf20Sopenharmony_ci .name = "C1", 4468c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 4478c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 4488c2ecf20Sopenharmony_ci .exit_latency = 1, 4498c2ecf20Sopenharmony_ci .target_residency = 1, 4508c2ecf20Sopenharmony_ci .enter = &intel_idle, 4518c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 4528c2ecf20Sopenharmony_ci { 4538c2ecf20Sopenharmony_ci .name = "C1E", 4548c2ecf20Sopenharmony_ci .desc = "MWAIT 0x01", 4558c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 4568c2ecf20Sopenharmony_ci .exit_latency = 10, 4578c2ecf20Sopenharmony_ci .target_residency = 250, 4588c2ecf20Sopenharmony_ci .enter = &intel_idle, 4598c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 4608c2ecf20Sopenharmony_ci { 4618c2ecf20Sopenharmony_ci .name = "C3", 4628c2ecf20Sopenharmony_ci .desc = "MWAIT 0x10", 4638c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 4648c2ecf20Sopenharmony_ci .exit_latency = 59, 4658c2ecf20Sopenharmony_ci .target_residency = 300, 4668c2ecf20Sopenharmony_ci .enter = &intel_idle, 4678c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 4688c2ecf20Sopenharmony_ci { 4698c2ecf20Sopenharmony_ci .name = "C6", 4708c2ecf20Sopenharmony_ci .desc = "MWAIT 0x20", 4718c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 4728c2ecf20Sopenharmony_ci .exit_latency = 84, 4738c2ecf20Sopenharmony_ci .target_residency = 400, 4748c2ecf20Sopenharmony_ci .enter = &intel_idle, 4758c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 4768c2ecf20Sopenharmony_ci { 4778c2ecf20Sopenharmony_ci .enter = NULL } 4788c2ecf20Sopenharmony_ci}; 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_cistatic struct cpuidle_state ivt_cstates_8s[] __initdata = { 4818c2ecf20Sopenharmony_ci { 4828c2ecf20Sopenharmony_ci .name = "C1", 4838c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 4848c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 4858c2ecf20Sopenharmony_ci .exit_latency = 1, 4868c2ecf20Sopenharmony_ci .target_residency = 1, 4878c2ecf20Sopenharmony_ci .enter = &intel_idle, 4888c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 4898c2ecf20Sopenharmony_ci { 4908c2ecf20Sopenharmony_ci .name = "C1E", 4918c2ecf20Sopenharmony_ci .desc = "MWAIT 0x01", 4928c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 4938c2ecf20Sopenharmony_ci .exit_latency = 10, 4948c2ecf20Sopenharmony_ci .target_residency = 500, 4958c2ecf20Sopenharmony_ci .enter = &intel_idle, 4968c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 4978c2ecf20Sopenharmony_ci { 4988c2ecf20Sopenharmony_ci .name = "C3", 4998c2ecf20Sopenharmony_ci .desc = "MWAIT 0x10", 5008c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 5018c2ecf20Sopenharmony_ci .exit_latency = 59, 5028c2ecf20Sopenharmony_ci .target_residency = 600, 5038c2ecf20Sopenharmony_ci .enter = &intel_idle, 5048c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 5058c2ecf20Sopenharmony_ci { 5068c2ecf20Sopenharmony_ci .name = "C6", 5078c2ecf20Sopenharmony_ci .desc = "MWAIT 0x20", 5088c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 5098c2ecf20Sopenharmony_ci .exit_latency = 88, 5108c2ecf20Sopenharmony_ci .target_residency = 700, 5118c2ecf20Sopenharmony_ci .enter = &intel_idle, 5128c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 5138c2ecf20Sopenharmony_ci { 5148c2ecf20Sopenharmony_ci .enter = NULL } 5158c2ecf20Sopenharmony_ci}; 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_cistatic struct cpuidle_state hsw_cstates[] __initdata = { 5188c2ecf20Sopenharmony_ci { 5198c2ecf20Sopenharmony_ci .name = "C1", 5208c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 5218c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 5228c2ecf20Sopenharmony_ci .exit_latency = 2, 5238c2ecf20Sopenharmony_ci .target_residency = 2, 5248c2ecf20Sopenharmony_ci .enter = &intel_idle, 5258c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 5268c2ecf20Sopenharmony_ci { 5278c2ecf20Sopenharmony_ci .name = "C1E", 5288c2ecf20Sopenharmony_ci .desc = "MWAIT 0x01", 5298c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 5308c2ecf20Sopenharmony_ci .exit_latency = 10, 5318c2ecf20Sopenharmony_ci .target_residency = 20, 5328c2ecf20Sopenharmony_ci .enter = &intel_idle, 5338c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 5348c2ecf20Sopenharmony_ci { 5358c2ecf20Sopenharmony_ci .name = "C3", 5368c2ecf20Sopenharmony_ci .desc = "MWAIT 0x10", 5378c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 5388c2ecf20Sopenharmony_ci .exit_latency = 33, 5398c2ecf20Sopenharmony_ci .target_residency = 100, 5408c2ecf20Sopenharmony_ci .enter = &intel_idle, 5418c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 5428c2ecf20Sopenharmony_ci { 5438c2ecf20Sopenharmony_ci .name = "C6", 5448c2ecf20Sopenharmony_ci .desc = "MWAIT 0x20", 5458c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 5468c2ecf20Sopenharmony_ci .exit_latency = 133, 5478c2ecf20Sopenharmony_ci .target_residency = 400, 5488c2ecf20Sopenharmony_ci .enter = &intel_idle, 5498c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 5508c2ecf20Sopenharmony_ci { 5518c2ecf20Sopenharmony_ci .name = "C7s", 5528c2ecf20Sopenharmony_ci .desc = "MWAIT 0x32", 5538c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TLB_FLUSHED, 5548c2ecf20Sopenharmony_ci .exit_latency = 166, 5558c2ecf20Sopenharmony_ci .target_residency = 500, 5568c2ecf20Sopenharmony_ci .enter = &intel_idle, 5578c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 5588c2ecf20Sopenharmony_ci { 5598c2ecf20Sopenharmony_ci .name = "C8", 5608c2ecf20Sopenharmony_ci .desc = "MWAIT 0x40", 5618c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, 5628c2ecf20Sopenharmony_ci .exit_latency = 300, 5638c2ecf20Sopenharmony_ci .target_residency = 900, 5648c2ecf20Sopenharmony_ci .enter = &intel_idle, 5658c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 5668c2ecf20Sopenharmony_ci { 5678c2ecf20Sopenharmony_ci .name = "C9", 5688c2ecf20Sopenharmony_ci .desc = "MWAIT 0x50", 5698c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, 5708c2ecf20Sopenharmony_ci .exit_latency = 600, 5718c2ecf20Sopenharmony_ci .target_residency = 1800, 5728c2ecf20Sopenharmony_ci .enter = &intel_idle, 5738c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 5748c2ecf20Sopenharmony_ci { 5758c2ecf20Sopenharmony_ci .name = "C10", 5768c2ecf20Sopenharmony_ci .desc = "MWAIT 0x60", 5778c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 5788c2ecf20Sopenharmony_ci .exit_latency = 2600, 5798c2ecf20Sopenharmony_ci .target_residency = 7700, 5808c2ecf20Sopenharmony_ci .enter = &intel_idle, 5818c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 5828c2ecf20Sopenharmony_ci { 5838c2ecf20Sopenharmony_ci .enter = NULL } 5848c2ecf20Sopenharmony_ci}; 5858c2ecf20Sopenharmony_cistatic struct cpuidle_state bdw_cstates[] __initdata = { 5868c2ecf20Sopenharmony_ci { 5878c2ecf20Sopenharmony_ci .name = "C1", 5888c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 5898c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 5908c2ecf20Sopenharmony_ci .exit_latency = 2, 5918c2ecf20Sopenharmony_ci .target_residency = 2, 5928c2ecf20Sopenharmony_ci .enter = &intel_idle, 5938c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 5948c2ecf20Sopenharmony_ci { 5958c2ecf20Sopenharmony_ci .name = "C1E", 5968c2ecf20Sopenharmony_ci .desc = "MWAIT 0x01", 5978c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 5988c2ecf20Sopenharmony_ci .exit_latency = 10, 5998c2ecf20Sopenharmony_ci .target_residency = 20, 6008c2ecf20Sopenharmony_ci .enter = &intel_idle, 6018c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 6028c2ecf20Sopenharmony_ci { 6038c2ecf20Sopenharmony_ci .name = "C3", 6048c2ecf20Sopenharmony_ci .desc = "MWAIT 0x10", 6058c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 6068c2ecf20Sopenharmony_ci .exit_latency = 40, 6078c2ecf20Sopenharmony_ci .target_residency = 100, 6088c2ecf20Sopenharmony_ci .enter = &intel_idle, 6098c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 6108c2ecf20Sopenharmony_ci { 6118c2ecf20Sopenharmony_ci .name = "C6", 6128c2ecf20Sopenharmony_ci .desc = "MWAIT 0x20", 6138c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 6148c2ecf20Sopenharmony_ci .exit_latency = 133, 6158c2ecf20Sopenharmony_ci .target_residency = 400, 6168c2ecf20Sopenharmony_ci .enter = &intel_idle, 6178c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 6188c2ecf20Sopenharmony_ci { 6198c2ecf20Sopenharmony_ci .name = "C7s", 6208c2ecf20Sopenharmony_ci .desc = "MWAIT 0x32", 6218c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TLB_FLUSHED, 6228c2ecf20Sopenharmony_ci .exit_latency = 166, 6238c2ecf20Sopenharmony_ci .target_residency = 500, 6248c2ecf20Sopenharmony_ci .enter = &intel_idle, 6258c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 6268c2ecf20Sopenharmony_ci { 6278c2ecf20Sopenharmony_ci .name = "C8", 6288c2ecf20Sopenharmony_ci .desc = "MWAIT 0x40", 6298c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, 6308c2ecf20Sopenharmony_ci .exit_latency = 300, 6318c2ecf20Sopenharmony_ci .target_residency = 900, 6328c2ecf20Sopenharmony_ci .enter = &intel_idle, 6338c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 6348c2ecf20Sopenharmony_ci { 6358c2ecf20Sopenharmony_ci .name = "C9", 6368c2ecf20Sopenharmony_ci .desc = "MWAIT 0x50", 6378c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, 6388c2ecf20Sopenharmony_ci .exit_latency = 600, 6398c2ecf20Sopenharmony_ci .target_residency = 1800, 6408c2ecf20Sopenharmony_ci .enter = &intel_idle, 6418c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 6428c2ecf20Sopenharmony_ci { 6438c2ecf20Sopenharmony_ci .name = "C10", 6448c2ecf20Sopenharmony_ci .desc = "MWAIT 0x60", 6458c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 6468c2ecf20Sopenharmony_ci .exit_latency = 2600, 6478c2ecf20Sopenharmony_ci .target_residency = 7700, 6488c2ecf20Sopenharmony_ci .enter = &intel_idle, 6498c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 6508c2ecf20Sopenharmony_ci { 6518c2ecf20Sopenharmony_ci .enter = NULL } 6528c2ecf20Sopenharmony_ci}; 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_cistatic struct cpuidle_state skl_cstates[] __initdata = { 6558c2ecf20Sopenharmony_ci { 6568c2ecf20Sopenharmony_ci .name = "C1", 6578c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 6588c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 6598c2ecf20Sopenharmony_ci .exit_latency = 2, 6608c2ecf20Sopenharmony_ci .target_residency = 2, 6618c2ecf20Sopenharmony_ci .enter = &intel_idle, 6628c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 6638c2ecf20Sopenharmony_ci { 6648c2ecf20Sopenharmony_ci .name = "C1E", 6658c2ecf20Sopenharmony_ci .desc = "MWAIT 0x01", 6668c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 6678c2ecf20Sopenharmony_ci .exit_latency = 10, 6688c2ecf20Sopenharmony_ci .target_residency = 20, 6698c2ecf20Sopenharmony_ci .enter = &intel_idle, 6708c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 6718c2ecf20Sopenharmony_ci { 6728c2ecf20Sopenharmony_ci .name = "C3", 6738c2ecf20Sopenharmony_ci .desc = "MWAIT 0x10", 6748c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 6758c2ecf20Sopenharmony_ci .exit_latency = 70, 6768c2ecf20Sopenharmony_ci .target_residency = 100, 6778c2ecf20Sopenharmony_ci .enter = &intel_idle, 6788c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 6798c2ecf20Sopenharmony_ci { 6808c2ecf20Sopenharmony_ci .name = "C6", 6818c2ecf20Sopenharmony_ci .desc = "MWAIT 0x20", 6828c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 6838c2ecf20Sopenharmony_ci .exit_latency = 85, 6848c2ecf20Sopenharmony_ci .target_residency = 200, 6858c2ecf20Sopenharmony_ci .enter = &intel_idle, 6868c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 6878c2ecf20Sopenharmony_ci { 6888c2ecf20Sopenharmony_ci .name = "C7s", 6898c2ecf20Sopenharmony_ci .desc = "MWAIT 0x33", 6908c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x33) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 6918c2ecf20Sopenharmony_ci .exit_latency = 124, 6928c2ecf20Sopenharmony_ci .target_residency = 800, 6938c2ecf20Sopenharmony_ci .enter = &intel_idle, 6948c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 6958c2ecf20Sopenharmony_ci { 6968c2ecf20Sopenharmony_ci .name = "C8", 6978c2ecf20Sopenharmony_ci .desc = "MWAIT 0x40", 6988c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 6998c2ecf20Sopenharmony_ci .exit_latency = 200, 7008c2ecf20Sopenharmony_ci .target_residency = 800, 7018c2ecf20Sopenharmony_ci .enter = &intel_idle, 7028c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 7038c2ecf20Sopenharmony_ci { 7048c2ecf20Sopenharmony_ci .name = "C9", 7058c2ecf20Sopenharmony_ci .desc = "MWAIT 0x50", 7068c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 7078c2ecf20Sopenharmony_ci .exit_latency = 480, 7088c2ecf20Sopenharmony_ci .target_residency = 5000, 7098c2ecf20Sopenharmony_ci .enter = &intel_idle, 7108c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 7118c2ecf20Sopenharmony_ci { 7128c2ecf20Sopenharmony_ci .name = "C10", 7138c2ecf20Sopenharmony_ci .desc = "MWAIT 0x60", 7148c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 7158c2ecf20Sopenharmony_ci .exit_latency = 890, 7168c2ecf20Sopenharmony_ci .target_residency = 5000, 7178c2ecf20Sopenharmony_ci .enter = &intel_idle, 7188c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 7198c2ecf20Sopenharmony_ci { 7208c2ecf20Sopenharmony_ci .enter = NULL } 7218c2ecf20Sopenharmony_ci}; 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_cistatic struct cpuidle_state skx_cstates[] __initdata = { 7248c2ecf20Sopenharmony_ci { 7258c2ecf20Sopenharmony_ci .name = "C1", 7268c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 7278c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 7288c2ecf20Sopenharmony_ci .exit_latency = 2, 7298c2ecf20Sopenharmony_ci .target_residency = 2, 7308c2ecf20Sopenharmony_ci .enter = &intel_idle, 7318c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 7328c2ecf20Sopenharmony_ci { 7338c2ecf20Sopenharmony_ci .name = "C1E", 7348c2ecf20Sopenharmony_ci .desc = "MWAIT 0x01", 7358c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 7368c2ecf20Sopenharmony_ci .exit_latency = 10, 7378c2ecf20Sopenharmony_ci .target_residency = 20, 7388c2ecf20Sopenharmony_ci .enter = &intel_idle, 7398c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 7408c2ecf20Sopenharmony_ci { 7418c2ecf20Sopenharmony_ci .name = "C6", 7428c2ecf20Sopenharmony_ci .desc = "MWAIT 0x20", 7438c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, 7448c2ecf20Sopenharmony_ci .exit_latency = 133, 7458c2ecf20Sopenharmony_ci .target_residency = 600, 7468c2ecf20Sopenharmony_ci .enter = &intel_idle, 7478c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 7488c2ecf20Sopenharmony_ci { 7498c2ecf20Sopenharmony_ci .enter = NULL } 7508c2ecf20Sopenharmony_ci}; 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_cistatic struct cpuidle_state icx_cstates[] __initdata = { 7538c2ecf20Sopenharmony_ci { 7548c2ecf20Sopenharmony_ci .name = "C1", 7558c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 7568c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 7578c2ecf20Sopenharmony_ci .exit_latency = 1, 7588c2ecf20Sopenharmony_ci .target_residency = 1, 7598c2ecf20Sopenharmony_ci .enter = &intel_idle, 7608c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 7618c2ecf20Sopenharmony_ci { 7628c2ecf20Sopenharmony_ci .name = "C1E", 7638c2ecf20Sopenharmony_ci .desc = "MWAIT 0x01", 7648c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 7658c2ecf20Sopenharmony_ci .exit_latency = 4, 7668c2ecf20Sopenharmony_ci .target_residency = 4, 7678c2ecf20Sopenharmony_ci .enter = &intel_idle, 7688c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 7698c2ecf20Sopenharmony_ci { 7708c2ecf20Sopenharmony_ci .name = "C6", 7718c2ecf20Sopenharmony_ci .desc = "MWAIT 0x20", 7728c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 7738c2ecf20Sopenharmony_ci .exit_latency = 128, 7748c2ecf20Sopenharmony_ci .target_residency = 384, 7758c2ecf20Sopenharmony_ci .enter = &intel_idle, 7768c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 7778c2ecf20Sopenharmony_ci { 7788c2ecf20Sopenharmony_ci .enter = NULL } 7798c2ecf20Sopenharmony_ci}; 7808c2ecf20Sopenharmony_ci 7818c2ecf20Sopenharmony_cistatic struct cpuidle_state atom_cstates[] __initdata = { 7828c2ecf20Sopenharmony_ci { 7838c2ecf20Sopenharmony_ci .name = "C1E", 7848c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 7858c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 7868c2ecf20Sopenharmony_ci .exit_latency = 10, 7878c2ecf20Sopenharmony_ci .target_residency = 20, 7888c2ecf20Sopenharmony_ci .enter = &intel_idle, 7898c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 7908c2ecf20Sopenharmony_ci { 7918c2ecf20Sopenharmony_ci .name = "C2", 7928c2ecf20Sopenharmony_ci .desc = "MWAIT 0x10", 7938c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x10), 7948c2ecf20Sopenharmony_ci .exit_latency = 20, 7958c2ecf20Sopenharmony_ci .target_residency = 80, 7968c2ecf20Sopenharmony_ci .enter = &intel_idle, 7978c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 7988c2ecf20Sopenharmony_ci { 7998c2ecf20Sopenharmony_ci .name = "C4", 8008c2ecf20Sopenharmony_ci .desc = "MWAIT 0x30", 8018c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, 8028c2ecf20Sopenharmony_ci .exit_latency = 100, 8038c2ecf20Sopenharmony_ci .target_residency = 400, 8048c2ecf20Sopenharmony_ci .enter = &intel_idle, 8058c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 8068c2ecf20Sopenharmony_ci { 8078c2ecf20Sopenharmony_ci .name = "C6", 8088c2ecf20Sopenharmony_ci .desc = "MWAIT 0x52", 8098c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, 8108c2ecf20Sopenharmony_ci .exit_latency = 140, 8118c2ecf20Sopenharmony_ci .target_residency = 560, 8128c2ecf20Sopenharmony_ci .enter = &intel_idle, 8138c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 8148c2ecf20Sopenharmony_ci { 8158c2ecf20Sopenharmony_ci .enter = NULL } 8168c2ecf20Sopenharmony_ci}; 8178c2ecf20Sopenharmony_cistatic struct cpuidle_state tangier_cstates[] __initdata = { 8188c2ecf20Sopenharmony_ci { 8198c2ecf20Sopenharmony_ci .name = "C1", 8208c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 8218c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 8228c2ecf20Sopenharmony_ci .exit_latency = 1, 8238c2ecf20Sopenharmony_ci .target_residency = 4, 8248c2ecf20Sopenharmony_ci .enter = &intel_idle, 8258c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 8268c2ecf20Sopenharmony_ci { 8278c2ecf20Sopenharmony_ci .name = "C4", 8288c2ecf20Sopenharmony_ci .desc = "MWAIT 0x30", 8298c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, 8308c2ecf20Sopenharmony_ci .exit_latency = 100, 8318c2ecf20Sopenharmony_ci .target_residency = 400, 8328c2ecf20Sopenharmony_ci .enter = &intel_idle, 8338c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 8348c2ecf20Sopenharmony_ci { 8358c2ecf20Sopenharmony_ci .name = "C6", 8368c2ecf20Sopenharmony_ci .desc = "MWAIT 0x52", 8378c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, 8388c2ecf20Sopenharmony_ci .exit_latency = 140, 8398c2ecf20Sopenharmony_ci .target_residency = 560, 8408c2ecf20Sopenharmony_ci .enter = &intel_idle, 8418c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 8428c2ecf20Sopenharmony_ci { 8438c2ecf20Sopenharmony_ci .name = "C7", 8448c2ecf20Sopenharmony_ci .desc = "MWAIT 0x60", 8458c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 8468c2ecf20Sopenharmony_ci .exit_latency = 1200, 8478c2ecf20Sopenharmony_ci .target_residency = 4000, 8488c2ecf20Sopenharmony_ci .enter = &intel_idle, 8498c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 8508c2ecf20Sopenharmony_ci { 8518c2ecf20Sopenharmony_ci .name = "C9", 8528c2ecf20Sopenharmony_ci .desc = "MWAIT 0x64", 8538c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED, 8548c2ecf20Sopenharmony_ci .exit_latency = 10000, 8558c2ecf20Sopenharmony_ci .target_residency = 20000, 8568c2ecf20Sopenharmony_ci .enter = &intel_idle, 8578c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 8588c2ecf20Sopenharmony_ci { 8598c2ecf20Sopenharmony_ci .enter = NULL } 8608c2ecf20Sopenharmony_ci}; 8618c2ecf20Sopenharmony_cistatic struct cpuidle_state avn_cstates[] __initdata = { 8628c2ecf20Sopenharmony_ci { 8638c2ecf20Sopenharmony_ci .name = "C1", 8648c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 8658c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 8668c2ecf20Sopenharmony_ci .exit_latency = 2, 8678c2ecf20Sopenharmony_ci .target_residency = 2, 8688c2ecf20Sopenharmony_ci .enter = &intel_idle, 8698c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 8708c2ecf20Sopenharmony_ci { 8718c2ecf20Sopenharmony_ci .name = "C6", 8728c2ecf20Sopenharmony_ci .desc = "MWAIT 0x51", 8738c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x51) | CPUIDLE_FLAG_TLB_FLUSHED, 8748c2ecf20Sopenharmony_ci .exit_latency = 15, 8758c2ecf20Sopenharmony_ci .target_residency = 45, 8768c2ecf20Sopenharmony_ci .enter = &intel_idle, 8778c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 8788c2ecf20Sopenharmony_ci { 8798c2ecf20Sopenharmony_ci .enter = NULL } 8808c2ecf20Sopenharmony_ci}; 8818c2ecf20Sopenharmony_cistatic struct cpuidle_state knl_cstates[] __initdata = { 8828c2ecf20Sopenharmony_ci { 8838c2ecf20Sopenharmony_ci .name = "C1", 8848c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 8858c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 8868c2ecf20Sopenharmony_ci .exit_latency = 1, 8878c2ecf20Sopenharmony_ci .target_residency = 2, 8888c2ecf20Sopenharmony_ci .enter = &intel_idle, 8898c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle }, 8908c2ecf20Sopenharmony_ci { 8918c2ecf20Sopenharmony_ci .name = "C6", 8928c2ecf20Sopenharmony_ci .desc = "MWAIT 0x10", 8938c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, 8948c2ecf20Sopenharmony_ci .exit_latency = 120, 8958c2ecf20Sopenharmony_ci .target_residency = 500, 8968c2ecf20Sopenharmony_ci .enter = &intel_idle, 8978c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle }, 8988c2ecf20Sopenharmony_ci { 8998c2ecf20Sopenharmony_ci .enter = NULL } 9008c2ecf20Sopenharmony_ci}; 9018c2ecf20Sopenharmony_ci 9028c2ecf20Sopenharmony_cistatic struct cpuidle_state bxt_cstates[] __initdata = { 9038c2ecf20Sopenharmony_ci { 9048c2ecf20Sopenharmony_ci .name = "C1", 9058c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 9068c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 9078c2ecf20Sopenharmony_ci .exit_latency = 2, 9088c2ecf20Sopenharmony_ci .target_residency = 2, 9098c2ecf20Sopenharmony_ci .enter = &intel_idle, 9108c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 9118c2ecf20Sopenharmony_ci { 9128c2ecf20Sopenharmony_ci .name = "C1E", 9138c2ecf20Sopenharmony_ci .desc = "MWAIT 0x01", 9148c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 9158c2ecf20Sopenharmony_ci .exit_latency = 10, 9168c2ecf20Sopenharmony_ci .target_residency = 20, 9178c2ecf20Sopenharmony_ci .enter = &intel_idle, 9188c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 9198c2ecf20Sopenharmony_ci { 9208c2ecf20Sopenharmony_ci .name = "C6", 9218c2ecf20Sopenharmony_ci .desc = "MWAIT 0x20", 9228c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 9238c2ecf20Sopenharmony_ci .exit_latency = 133, 9248c2ecf20Sopenharmony_ci .target_residency = 133, 9258c2ecf20Sopenharmony_ci .enter = &intel_idle, 9268c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 9278c2ecf20Sopenharmony_ci { 9288c2ecf20Sopenharmony_ci .name = "C7s", 9298c2ecf20Sopenharmony_ci .desc = "MWAIT 0x31", 9308c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x31) | CPUIDLE_FLAG_TLB_FLUSHED, 9318c2ecf20Sopenharmony_ci .exit_latency = 155, 9328c2ecf20Sopenharmony_ci .target_residency = 155, 9338c2ecf20Sopenharmony_ci .enter = &intel_idle, 9348c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 9358c2ecf20Sopenharmony_ci { 9368c2ecf20Sopenharmony_ci .name = "C8", 9378c2ecf20Sopenharmony_ci .desc = "MWAIT 0x40", 9388c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, 9398c2ecf20Sopenharmony_ci .exit_latency = 1000, 9408c2ecf20Sopenharmony_ci .target_residency = 1000, 9418c2ecf20Sopenharmony_ci .enter = &intel_idle, 9428c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 9438c2ecf20Sopenharmony_ci { 9448c2ecf20Sopenharmony_ci .name = "C9", 9458c2ecf20Sopenharmony_ci .desc = "MWAIT 0x50", 9468c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, 9478c2ecf20Sopenharmony_ci .exit_latency = 2000, 9488c2ecf20Sopenharmony_ci .target_residency = 2000, 9498c2ecf20Sopenharmony_ci .enter = &intel_idle, 9508c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 9518c2ecf20Sopenharmony_ci { 9528c2ecf20Sopenharmony_ci .name = "C10", 9538c2ecf20Sopenharmony_ci .desc = "MWAIT 0x60", 9548c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, 9558c2ecf20Sopenharmony_ci .exit_latency = 10000, 9568c2ecf20Sopenharmony_ci .target_residency = 10000, 9578c2ecf20Sopenharmony_ci .enter = &intel_idle, 9588c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 9598c2ecf20Sopenharmony_ci { 9608c2ecf20Sopenharmony_ci .enter = NULL } 9618c2ecf20Sopenharmony_ci}; 9628c2ecf20Sopenharmony_ci 9638c2ecf20Sopenharmony_cistatic struct cpuidle_state dnv_cstates[] __initdata = { 9648c2ecf20Sopenharmony_ci { 9658c2ecf20Sopenharmony_ci .name = "C1", 9668c2ecf20Sopenharmony_ci .desc = "MWAIT 0x00", 9678c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x00), 9688c2ecf20Sopenharmony_ci .exit_latency = 2, 9698c2ecf20Sopenharmony_ci .target_residency = 2, 9708c2ecf20Sopenharmony_ci .enter = &intel_idle, 9718c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 9728c2ecf20Sopenharmony_ci { 9738c2ecf20Sopenharmony_ci .name = "C1E", 9748c2ecf20Sopenharmony_ci .desc = "MWAIT 0x01", 9758c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE, 9768c2ecf20Sopenharmony_ci .exit_latency = 10, 9778c2ecf20Sopenharmony_ci .target_residency = 20, 9788c2ecf20Sopenharmony_ci .enter = &intel_idle, 9798c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 9808c2ecf20Sopenharmony_ci { 9818c2ecf20Sopenharmony_ci .name = "C6", 9828c2ecf20Sopenharmony_ci .desc = "MWAIT 0x20", 9838c2ecf20Sopenharmony_ci .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, 9848c2ecf20Sopenharmony_ci .exit_latency = 50, 9858c2ecf20Sopenharmony_ci .target_residency = 500, 9868c2ecf20Sopenharmony_ci .enter = &intel_idle, 9878c2ecf20Sopenharmony_ci .enter_s2idle = intel_idle_s2idle, }, 9888c2ecf20Sopenharmony_ci { 9898c2ecf20Sopenharmony_ci .enter = NULL } 9908c2ecf20Sopenharmony_ci}; 9918c2ecf20Sopenharmony_ci 9928c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_nehalem __initconst = { 9938c2ecf20Sopenharmony_ci .state_table = nehalem_cstates, 9948c2ecf20Sopenharmony_ci .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, 9958c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 9968c2ecf20Sopenharmony_ci}; 9978c2ecf20Sopenharmony_ci 9988c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_nhx __initconst = { 9998c2ecf20Sopenharmony_ci .state_table = nehalem_cstates, 10008c2ecf20Sopenharmony_ci .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, 10018c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10028c2ecf20Sopenharmony_ci .use_acpi = true, 10038c2ecf20Sopenharmony_ci}; 10048c2ecf20Sopenharmony_ci 10058c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_atom __initconst = { 10068c2ecf20Sopenharmony_ci .state_table = atom_cstates, 10078c2ecf20Sopenharmony_ci}; 10088c2ecf20Sopenharmony_ci 10098c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_tangier __initconst = { 10108c2ecf20Sopenharmony_ci .state_table = tangier_cstates, 10118c2ecf20Sopenharmony_ci}; 10128c2ecf20Sopenharmony_ci 10138c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_lincroft __initconst = { 10148c2ecf20Sopenharmony_ci .state_table = atom_cstates, 10158c2ecf20Sopenharmony_ci .auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE, 10168c2ecf20Sopenharmony_ci}; 10178c2ecf20Sopenharmony_ci 10188c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_snb __initconst = { 10198c2ecf20Sopenharmony_ci .state_table = snb_cstates, 10208c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10218c2ecf20Sopenharmony_ci}; 10228c2ecf20Sopenharmony_ci 10238c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_snx __initconst = { 10248c2ecf20Sopenharmony_ci .state_table = snb_cstates, 10258c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10268c2ecf20Sopenharmony_ci .use_acpi = true, 10278c2ecf20Sopenharmony_ci}; 10288c2ecf20Sopenharmony_ci 10298c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_byt __initconst = { 10308c2ecf20Sopenharmony_ci .state_table = byt_cstates, 10318c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10328c2ecf20Sopenharmony_ci .byt_auto_demotion_disable_flag = true, 10338c2ecf20Sopenharmony_ci}; 10348c2ecf20Sopenharmony_ci 10358c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_cht __initconst = { 10368c2ecf20Sopenharmony_ci .state_table = cht_cstates, 10378c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10388c2ecf20Sopenharmony_ci .byt_auto_demotion_disable_flag = true, 10398c2ecf20Sopenharmony_ci}; 10408c2ecf20Sopenharmony_ci 10418c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_ivb __initconst = { 10428c2ecf20Sopenharmony_ci .state_table = ivb_cstates, 10438c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10448c2ecf20Sopenharmony_ci}; 10458c2ecf20Sopenharmony_ci 10468c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_ivt __initconst = { 10478c2ecf20Sopenharmony_ci .state_table = ivt_cstates, 10488c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10498c2ecf20Sopenharmony_ci .use_acpi = true, 10508c2ecf20Sopenharmony_ci}; 10518c2ecf20Sopenharmony_ci 10528c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_hsw __initconst = { 10538c2ecf20Sopenharmony_ci .state_table = hsw_cstates, 10548c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10558c2ecf20Sopenharmony_ci}; 10568c2ecf20Sopenharmony_ci 10578c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_hsx __initconst = { 10588c2ecf20Sopenharmony_ci .state_table = hsw_cstates, 10598c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10608c2ecf20Sopenharmony_ci .use_acpi = true, 10618c2ecf20Sopenharmony_ci}; 10628c2ecf20Sopenharmony_ci 10638c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_bdw __initconst = { 10648c2ecf20Sopenharmony_ci .state_table = bdw_cstates, 10658c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10668c2ecf20Sopenharmony_ci}; 10678c2ecf20Sopenharmony_ci 10688c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_bdx __initconst = { 10698c2ecf20Sopenharmony_ci .state_table = bdw_cstates, 10708c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10718c2ecf20Sopenharmony_ci .use_acpi = true, 10728c2ecf20Sopenharmony_ci}; 10738c2ecf20Sopenharmony_ci 10748c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_skl __initconst = { 10758c2ecf20Sopenharmony_ci .state_table = skl_cstates, 10768c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10778c2ecf20Sopenharmony_ci}; 10788c2ecf20Sopenharmony_ci 10798c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_skx __initconst = { 10808c2ecf20Sopenharmony_ci .state_table = skx_cstates, 10818c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10828c2ecf20Sopenharmony_ci .use_acpi = true, 10838c2ecf20Sopenharmony_ci}; 10848c2ecf20Sopenharmony_ci 10858c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_icx __initconst = { 10868c2ecf20Sopenharmony_ci .state_table = icx_cstates, 10878c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10888c2ecf20Sopenharmony_ci .use_acpi = true, 10898c2ecf20Sopenharmony_ci}; 10908c2ecf20Sopenharmony_ci 10918c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_avn __initconst = { 10928c2ecf20Sopenharmony_ci .state_table = avn_cstates, 10938c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 10948c2ecf20Sopenharmony_ci .use_acpi = true, 10958c2ecf20Sopenharmony_ci}; 10968c2ecf20Sopenharmony_ci 10978c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_knl __initconst = { 10988c2ecf20Sopenharmony_ci .state_table = knl_cstates, 10998c2ecf20Sopenharmony_ci .use_acpi = true, 11008c2ecf20Sopenharmony_ci}; 11018c2ecf20Sopenharmony_ci 11028c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_bxt __initconst = { 11038c2ecf20Sopenharmony_ci .state_table = bxt_cstates, 11048c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 11058c2ecf20Sopenharmony_ci}; 11068c2ecf20Sopenharmony_ci 11078c2ecf20Sopenharmony_cistatic const struct idle_cpu idle_cpu_dnv __initconst = { 11088c2ecf20Sopenharmony_ci .state_table = dnv_cstates, 11098c2ecf20Sopenharmony_ci .disable_promotion_to_c1e = true, 11108c2ecf20Sopenharmony_ci .use_acpi = true, 11118c2ecf20Sopenharmony_ci}; 11128c2ecf20Sopenharmony_ci 11138c2ecf20Sopenharmony_cistatic const struct x86_cpu_id intel_idle_ids[] __initconst = { 11148c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EP, &idle_cpu_nhx), 11158c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(NEHALEM, &idle_cpu_nehalem), 11168c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_G, &idle_cpu_nehalem), 11178c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(WESTMERE, &idle_cpu_nehalem), 11188c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EP, &idle_cpu_nhx), 11198c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EX, &idle_cpu_nhx), 11208c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_BONNELL, &idle_cpu_atom), 11218c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_BONNELL_MID, &idle_cpu_lincroft), 11228c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EX, &idle_cpu_nhx), 11238c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE, &idle_cpu_snb), 11248c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE_X, &idle_cpu_snx), 11258c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_SALTWELL, &idle_cpu_atom), 11268c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT, &idle_cpu_byt), 11278c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_MID, &idle_cpu_tangier), 11288c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT, &idle_cpu_cht), 11298c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE, &idle_cpu_ivb), 11308c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE_X, &idle_cpu_ivt), 11318c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(HASWELL, &idle_cpu_hsw), 11328c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X, &idle_cpu_hsx), 11338c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(HASWELL_L, &idle_cpu_hsw), 11348c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(HASWELL_G, &idle_cpu_hsw), 11358c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_D, &idle_cpu_avn), 11368c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(BROADWELL, &idle_cpu_bdw), 11378c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_G, &idle_cpu_bdw), 11388c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, &idle_cpu_bdx), 11398c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D, &idle_cpu_bdx), 11408c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, &idle_cpu_skl), 11418c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, &idle_cpu_skl), 11428c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, &idle_cpu_skl), 11438c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, &idle_cpu_skl), 11448c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &idle_cpu_skx), 11458c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &idle_cpu_icx), 11468c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &idle_cpu_knl), 11478c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &idle_cpu_knl), 11488c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &idle_cpu_bxt), 11498c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS, &idle_cpu_bxt), 11508c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D, &idle_cpu_dnv), 11518c2ecf20Sopenharmony_ci X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &idle_cpu_dnv), 11528c2ecf20Sopenharmony_ci {} 11538c2ecf20Sopenharmony_ci}; 11548c2ecf20Sopenharmony_ci 11558c2ecf20Sopenharmony_cistatic const struct x86_cpu_id intel_mwait_ids[] __initconst = { 11568c2ecf20Sopenharmony_ci X86_MATCH_VENDOR_FAM_FEATURE(INTEL, 6, X86_FEATURE_MWAIT, NULL), 11578c2ecf20Sopenharmony_ci {} 11588c2ecf20Sopenharmony_ci}; 11598c2ecf20Sopenharmony_ci 11608c2ecf20Sopenharmony_cistatic bool __init intel_idle_max_cstate_reached(int cstate) 11618c2ecf20Sopenharmony_ci{ 11628c2ecf20Sopenharmony_ci if (cstate + 1 > max_cstate) { 11638c2ecf20Sopenharmony_ci pr_info("max_cstate %d reached\n", max_cstate); 11648c2ecf20Sopenharmony_ci return true; 11658c2ecf20Sopenharmony_ci } 11668c2ecf20Sopenharmony_ci return false; 11678c2ecf20Sopenharmony_ci} 11688c2ecf20Sopenharmony_ci 11698c2ecf20Sopenharmony_cistatic bool __init intel_idle_state_needs_timer_stop(struct cpuidle_state *state) 11708c2ecf20Sopenharmony_ci{ 11718c2ecf20Sopenharmony_ci unsigned long eax = flg2MWAIT(state->flags); 11728c2ecf20Sopenharmony_ci 11738c2ecf20Sopenharmony_ci if (boot_cpu_has(X86_FEATURE_ARAT)) 11748c2ecf20Sopenharmony_ci return false; 11758c2ecf20Sopenharmony_ci 11768c2ecf20Sopenharmony_ci /* 11778c2ecf20Sopenharmony_ci * Switch over to one-shot tick broadcast if the target C-state 11788c2ecf20Sopenharmony_ci * is deeper than C1. 11798c2ecf20Sopenharmony_ci */ 11808c2ecf20Sopenharmony_ci return !!((eax >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK); 11818c2ecf20Sopenharmony_ci} 11828c2ecf20Sopenharmony_ci 11838c2ecf20Sopenharmony_ci#ifdef CONFIG_ACPI_PROCESSOR_CSTATE 11848c2ecf20Sopenharmony_ci#include <acpi/processor.h> 11858c2ecf20Sopenharmony_ci 11868c2ecf20Sopenharmony_cistatic bool no_acpi __read_mostly; 11878c2ecf20Sopenharmony_cimodule_param(no_acpi, bool, 0444); 11888c2ecf20Sopenharmony_ciMODULE_PARM_DESC(no_acpi, "Do not use ACPI _CST for building the idle states list"); 11898c2ecf20Sopenharmony_ci 11908c2ecf20Sopenharmony_cistatic bool force_use_acpi __read_mostly; /* No effect if no_acpi is set. */ 11918c2ecf20Sopenharmony_cimodule_param_named(use_acpi, force_use_acpi, bool, 0444); 11928c2ecf20Sopenharmony_ciMODULE_PARM_DESC(use_acpi, "Use ACPI _CST for building the idle states list"); 11938c2ecf20Sopenharmony_ci 11948c2ecf20Sopenharmony_cistatic struct acpi_processor_power acpi_state_table __initdata; 11958c2ecf20Sopenharmony_ci 11968c2ecf20Sopenharmony_ci/** 11978c2ecf20Sopenharmony_ci * intel_idle_cst_usable - Check if the _CST information can be used. 11988c2ecf20Sopenharmony_ci * 11998c2ecf20Sopenharmony_ci * Check if all of the C-states listed by _CST in the max_cstate range are 12008c2ecf20Sopenharmony_ci * ACPI_CSTATE_FFH, which means that they should be entered via MWAIT. 12018c2ecf20Sopenharmony_ci */ 12028c2ecf20Sopenharmony_cistatic bool __init intel_idle_cst_usable(void) 12038c2ecf20Sopenharmony_ci{ 12048c2ecf20Sopenharmony_ci int cstate, limit; 12058c2ecf20Sopenharmony_ci 12068c2ecf20Sopenharmony_ci limit = min_t(int, min_t(int, CPUIDLE_STATE_MAX, max_cstate + 1), 12078c2ecf20Sopenharmony_ci acpi_state_table.count); 12088c2ecf20Sopenharmony_ci 12098c2ecf20Sopenharmony_ci for (cstate = 1; cstate < limit; cstate++) { 12108c2ecf20Sopenharmony_ci struct acpi_processor_cx *cx = &acpi_state_table.states[cstate]; 12118c2ecf20Sopenharmony_ci 12128c2ecf20Sopenharmony_ci if (cx->entry_method != ACPI_CSTATE_FFH) 12138c2ecf20Sopenharmony_ci return false; 12148c2ecf20Sopenharmony_ci } 12158c2ecf20Sopenharmony_ci 12168c2ecf20Sopenharmony_ci return true; 12178c2ecf20Sopenharmony_ci} 12188c2ecf20Sopenharmony_ci 12198c2ecf20Sopenharmony_cistatic bool __init intel_idle_acpi_cst_extract(void) 12208c2ecf20Sopenharmony_ci{ 12218c2ecf20Sopenharmony_ci unsigned int cpu; 12228c2ecf20Sopenharmony_ci 12238c2ecf20Sopenharmony_ci if (no_acpi) { 12248c2ecf20Sopenharmony_ci pr_debug("Not allowed to use ACPI _CST\n"); 12258c2ecf20Sopenharmony_ci return false; 12268c2ecf20Sopenharmony_ci } 12278c2ecf20Sopenharmony_ci 12288c2ecf20Sopenharmony_ci for_each_possible_cpu(cpu) { 12298c2ecf20Sopenharmony_ci struct acpi_processor *pr = per_cpu(processors, cpu); 12308c2ecf20Sopenharmony_ci 12318c2ecf20Sopenharmony_ci if (!pr) 12328c2ecf20Sopenharmony_ci continue; 12338c2ecf20Sopenharmony_ci 12348c2ecf20Sopenharmony_ci if (acpi_processor_evaluate_cst(pr->handle, cpu, &acpi_state_table)) 12358c2ecf20Sopenharmony_ci continue; 12368c2ecf20Sopenharmony_ci 12378c2ecf20Sopenharmony_ci acpi_state_table.count++; 12388c2ecf20Sopenharmony_ci 12398c2ecf20Sopenharmony_ci if (!intel_idle_cst_usable()) 12408c2ecf20Sopenharmony_ci continue; 12418c2ecf20Sopenharmony_ci 12428c2ecf20Sopenharmony_ci if (!acpi_processor_claim_cst_control()) 12438c2ecf20Sopenharmony_ci break; 12448c2ecf20Sopenharmony_ci 12458c2ecf20Sopenharmony_ci return true; 12468c2ecf20Sopenharmony_ci } 12478c2ecf20Sopenharmony_ci 12488c2ecf20Sopenharmony_ci acpi_state_table.count = 0; 12498c2ecf20Sopenharmony_ci pr_debug("ACPI _CST not found or not usable\n"); 12508c2ecf20Sopenharmony_ci return false; 12518c2ecf20Sopenharmony_ci} 12528c2ecf20Sopenharmony_ci 12538c2ecf20Sopenharmony_cistatic void __init intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) 12548c2ecf20Sopenharmony_ci{ 12558c2ecf20Sopenharmony_ci int cstate, limit = min_t(int, CPUIDLE_STATE_MAX, acpi_state_table.count); 12568c2ecf20Sopenharmony_ci 12578c2ecf20Sopenharmony_ci /* 12588c2ecf20Sopenharmony_ci * If limit > 0, intel_idle_cst_usable() has returned 'true', so all of 12598c2ecf20Sopenharmony_ci * the interesting states are ACPI_CSTATE_FFH. 12608c2ecf20Sopenharmony_ci */ 12618c2ecf20Sopenharmony_ci for (cstate = 1; cstate < limit; cstate++) { 12628c2ecf20Sopenharmony_ci struct acpi_processor_cx *cx; 12638c2ecf20Sopenharmony_ci struct cpuidle_state *state; 12648c2ecf20Sopenharmony_ci 12658c2ecf20Sopenharmony_ci if (intel_idle_max_cstate_reached(cstate - 1)) 12668c2ecf20Sopenharmony_ci break; 12678c2ecf20Sopenharmony_ci 12688c2ecf20Sopenharmony_ci cx = &acpi_state_table.states[cstate]; 12698c2ecf20Sopenharmony_ci 12708c2ecf20Sopenharmony_ci state = &drv->states[drv->state_count++]; 12718c2ecf20Sopenharmony_ci 12728c2ecf20Sopenharmony_ci snprintf(state->name, CPUIDLE_NAME_LEN, "C%d_ACPI", cstate); 12738c2ecf20Sopenharmony_ci strlcpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); 12748c2ecf20Sopenharmony_ci state->exit_latency = cx->latency; 12758c2ecf20Sopenharmony_ci /* 12768c2ecf20Sopenharmony_ci * For C1-type C-states use the same number for both the exit 12778c2ecf20Sopenharmony_ci * latency and target residency, because that is the case for 12788c2ecf20Sopenharmony_ci * C1 in the majority of the static C-states tables above. 12798c2ecf20Sopenharmony_ci * For the other types of C-states, however, set the target 12808c2ecf20Sopenharmony_ci * residency to 3 times the exit latency which should lead to 12818c2ecf20Sopenharmony_ci * a reasonable balance between energy-efficiency and 12828c2ecf20Sopenharmony_ci * performance in the majority of interesting cases. 12838c2ecf20Sopenharmony_ci */ 12848c2ecf20Sopenharmony_ci state->target_residency = cx->latency; 12858c2ecf20Sopenharmony_ci if (cx->type > ACPI_STATE_C1) 12868c2ecf20Sopenharmony_ci state->target_residency *= 3; 12878c2ecf20Sopenharmony_ci 12888c2ecf20Sopenharmony_ci state->flags = MWAIT2flg(cx->address); 12898c2ecf20Sopenharmony_ci if (cx->type > ACPI_STATE_C2) 12908c2ecf20Sopenharmony_ci state->flags |= CPUIDLE_FLAG_TLB_FLUSHED; 12918c2ecf20Sopenharmony_ci 12928c2ecf20Sopenharmony_ci if (disabled_states_mask & BIT(cstate)) 12938c2ecf20Sopenharmony_ci state->flags |= CPUIDLE_FLAG_OFF; 12948c2ecf20Sopenharmony_ci 12958c2ecf20Sopenharmony_ci if (intel_idle_state_needs_timer_stop(state)) 12968c2ecf20Sopenharmony_ci state->flags |= CPUIDLE_FLAG_TIMER_STOP; 12978c2ecf20Sopenharmony_ci 12988c2ecf20Sopenharmony_ci state->enter = intel_idle; 12998c2ecf20Sopenharmony_ci state->enter_s2idle = intel_idle_s2idle; 13008c2ecf20Sopenharmony_ci } 13018c2ecf20Sopenharmony_ci} 13028c2ecf20Sopenharmony_ci 13038c2ecf20Sopenharmony_cistatic bool __init intel_idle_off_by_default(u32 mwait_hint) 13048c2ecf20Sopenharmony_ci{ 13058c2ecf20Sopenharmony_ci int cstate, limit; 13068c2ecf20Sopenharmony_ci 13078c2ecf20Sopenharmony_ci /* 13088c2ecf20Sopenharmony_ci * If there are no _CST C-states, do not disable any C-states by 13098c2ecf20Sopenharmony_ci * default. 13108c2ecf20Sopenharmony_ci */ 13118c2ecf20Sopenharmony_ci if (!acpi_state_table.count) 13128c2ecf20Sopenharmony_ci return false; 13138c2ecf20Sopenharmony_ci 13148c2ecf20Sopenharmony_ci limit = min_t(int, CPUIDLE_STATE_MAX, acpi_state_table.count); 13158c2ecf20Sopenharmony_ci /* 13168c2ecf20Sopenharmony_ci * If limit > 0, intel_idle_cst_usable() has returned 'true', so all of 13178c2ecf20Sopenharmony_ci * the interesting states are ACPI_CSTATE_FFH. 13188c2ecf20Sopenharmony_ci */ 13198c2ecf20Sopenharmony_ci for (cstate = 1; cstate < limit; cstate++) { 13208c2ecf20Sopenharmony_ci if (acpi_state_table.states[cstate].address == mwait_hint) 13218c2ecf20Sopenharmony_ci return false; 13228c2ecf20Sopenharmony_ci } 13238c2ecf20Sopenharmony_ci return true; 13248c2ecf20Sopenharmony_ci} 13258c2ecf20Sopenharmony_ci#else /* !CONFIG_ACPI_PROCESSOR_CSTATE */ 13268c2ecf20Sopenharmony_ci#define force_use_acpi (false) 13278c2ecf20Sopenharmony_ci 13288c2ecf20Sopenharmony_cistatic inline bool intel_idle_acpi_cst_extract(void) { return false; } 13298c2ecf20Sopenharmony_cistatic inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { } 13308c2ecf20Sopenharmony_cistatic inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; } 13318c2ecf20Sopenharmony_ci#endif /* !CONFIG_ACPI_PROCESSOR_CSTATE */ 13328c2ecf20Sopenharmony_ci 13338c2ecf20Sopenharmony_ci/** 13348c2ecf20Sopenharmony_ci * ivt_idle_state_table_update - Tune the idle states table for Ivy Town. 13358c2ecf20Sopenharmony_ci * 13368c2ecf20Sopenharmony_ci * Tune IVT multi-socket targets. 13378c2ecf20Sopenharmony_ci * Assumption: num_sockets == (max_package_num + 1). 13388c2ecf20Sopenharmony_ci */ 13398c2ecf20Sopenharmony_cistatic void __init ivt_idle_state_table_update(void) 13408c2ecf20Sopenharmony_ci{ 13418c2ecf20Sopenharmony_ci /* IVT uses a different table for 1-2, 3-4, and > 4 sockets */ 13428c2ecf20Sopenharmony_ci int cpu, package_num, num_sockets = 1; 13438c2ecf20Sopenharmony_ci 13448c2ecf20Sopenharmony_ci for_each_online_cpu(cpu) { 13458c2ecf20Sopenharmony_ci package_num = topology_physical_package_id(cpu); 13468c2ecf20Sopenharmony_ci if (package_num + 1 > num_sockets) { 13478c2ecf20Sopenharmony_ci num_sockets = package_num + 1; 13488c2ecf20Sopenharmony_ci 13498c2ecf20Sopenharmony_ci if (num_sockets > 4) { 13508c2ecf20Sopenharmony_ci cpuidle_state_table = ivt_cstates_8s; 13518c2ecf20Sopenharmony_ci return; 13528c2ecf20Sopenharmony_ci } 13538c2ecf20Sopenharmony_ci } 13548c2ecf20Sopenharmony_ci } 13558c2ecf20Sopenharmony_ci 13568c2ecf20Sopenharmony_ci if (num_sockets > 2) 13578c2ecf20Sopenharmony_ci cpuidle_state_table = ivt_cstates_4s; 13588c2ecf20Sopenharmony_ci 13598c2ecf20Sopenharmony_ci /* else, 1 and 2 socket systems use default ivt_cstates */ 13608c2ecf20Sopenharmony_ci} 13618c2ecf20Sopenharmony_ci 13628c2ecf20Sopenharmony_ci/** 13638c2ecf20Sopenharmony_ci * irtl_2_usec - IRTL to microseconds conversion. 13648c2ecf20Sopenharmony_ci * @irtl: IRTL MSR value. 13658c2ecf20Sopenharmony_ci * 13668c2ecf20Sopenharmony_ci * Translate the IRTL (Interrupt Response Time Limit) MSR value to microseconds. 13678c2ecf20Sopenharmony_ci */ 13688c2ecf20Sopenharmony_cistatic unsigned long long __init irtl_2_usec(unsigned long long irtl) 13698c2ecf20Sopenharmony_ci{ 13708c2ecf20Sopenharmony_ci static const unsigned int irtl_ns_units[] __initconst = { 13718c2ecf20Sopenharmony_ci 1, 32, 1024, 32768, 1048576, 33554432, 0, 0 13728c2ecf20Sopenharmony_ci }; 13738c2ecf20Sopenharmony_ci unsigned long long ns; 13748c2ecf20Sopenharmony_ci 13758c2ecf20Sopenharmony_ci if (!irtl) 13768c2ecf20Sopenharmony_ci return 0; 13778c2ecf20Sopenharmony_ci 13788c2ecf20Sopenharmony_ci ns = irtl_ns_units[(irtl >> 10) & 0x7]; 13798c2ecf20Sopenharmony_ci 13808c2ecf20Sopenharmony_ci return div_u64((irtl & 0x3FF) * ns, NSEC_PER_USEC); 13818c2ecf20Sopenharmony_ci} 13828c2ecf20Sopenharmony_ci 13838c2ecf20Sopenharmony_ci/** 13848c2ecf20Sopenharmony_ci * bxt_idle_state_table_update - Fix up the Broxton idle states table. 13858c2ecf20Sopenharmony_ci * 13868c2ecf20Sopenharmony_ci * On BXT, trust the IRTL (Interrupt Response Time Limit) MSR to show the 13878c2ecf20Sopenharmony_ci * definitive maximum latency and use the same value for target_residency. 13888c2ecf20Sopenharmony_ci */ 13898c2ecf20Sopenharmony_cistatic void __init bxt_idle_state_table_update(void) 13908c2ecf20Sopenharmony_ci{ 13918c2ecf20Sopenharmony_ci unsigned long long msr; 13928c2ecf20Sopenharmony_ci unsigned int usec; 13938c2ecf20Sopenharmony_ci 13948c2ecf20Sopenharmony_ci rdmsrl(MSR_PKGC6_IRTL, msr); 13958c2ecf20Sopenharmony_ci usec = irtl_2_usec(msr); 13968c2ecf20Sopenharmony_ci if (usec) { 13978c2ecf20Sopenharmony_ci bxt_cstates[2].exit_latency = usec; 13988c2ecf20Sopenharmony_ci bxt_cstates[2].target_residency = usec; 13998c2ecf20Sopenharmony_ci } 14008c2ecf20Sopenharmony_ci 14018c2ecf20Sopenharmony_ci rdmsrl(MSR_PKGC7_IRTL, msr); 14028c2ecf20Sopenharmony_ci usec = irtl_2_usec(msr); 14038c2ecf20Sopenharmony_ci if (usec) { 14048c2ecf20Sopenharmony_ci bxt_cstates[3].exit_latency = usec; 14058c2ecf20Sopenharmony_ci bxt_cstates[3].target_residency = usec; 14068c2ecf20Sopenharmony_ci } 14078c2ecf20Sopenharmony_ci 14088c2ecf20Sopenharmony_ci rdmsrl(MSR_PKGC8_IRTL, msr); 14098c2ecf20Sopenharmony_ci usec = irtl_2_usec(msr); 14108c2ecf20Sopenharmony_ci if (usec) { 14118c2ecf20Sopenharmony_ci bxt_cstates[4].exit_latency = usec; 14128c2ecf20Sopenharmony_ci bxt_cstates[4].target_residency = usec; 14138c2ecf20Sopenharmony_ci } 14148c2ecf20Sopenharmony_ci 14158c2ecf20Sopenharmony_ci rdmsrl(MSR_PKGC9_IRTL, msr); 14168c2ecf20Sopenharmony_ci usec = irtl_2_usec(msr); 14178c2ecf20Sopenharmony_ci if (usec) { 14188c2ecf20Sopenharmony_ci bxt_cstates[5].exit_latency = usec; 14198c2ecf20Sopenharmony_ci bxt_cstates[5].target_residency = usec; 14208c2ecf20Sopenharmony_ci } 14218c2ecf20Sopenharmony_ci 14228c2ecf20Sopenharmony_ci rdmsrl(MSR_PKGC10_IRTL, msr); 14238c2ecf20Sopenharmony_ci usec = irtl_2_usec(msr); 14248c2ecf20Sopenharmony_ci if (usec) { 14258c2ecf20Sopenharmony_ci bxt_cstates[6].exit_latency = usec; 14268c2ecf20Sopenharmony_ci bxt_cstates[6].target_residency = usec; 14278c2ecf20Sopenharmony_ci } 14288c2ecf20Sopenharmony_ci 14298c2ecf20Sopenharmony_ci} 14308c2ecf20Sopenharmony_ci 14318c2ecf20Sopenharmony_ci/** 14328c2ecf20Sopenharmony_ci * sklh_idle_state_table_update - Fix up the Sky Lake idle states table. 14338c2ecf20Sopenharmony_ci * 14348c2ecf20Sopenharmony_ci * On SKL-H (model 0x5e) skip C8 and C9 if C10 is enabled and SGX disabled. 14358c2ecf20Sopenharmony_ci */ 14368c2ecf20Sopenharmony_cistatic void __init sklh_idle_state_table_update(void) 14378c2ecf20Sopenharmony_ci{ 14388c2ecf20Sopenharmony_ci unsigned long long msr; 14398c2ecf20Sopenharmony_ci unsigned int eax, ebx, ecx, edx; 14408c2ecf20Sopenharmony_ci 14418c2ecf20Sopenharmony_ci 14428c2ecf20Sopenharmony_ci /* if PC10 disabled via cmdline intel_idle.max_cstate=7 or shallower */ 14438c2ecf20Sopenharmony_ci if (max_cstate <= 7) 14448c2ecf20Sopenharmony_ci return; 14458c2ecf20Sopenharmony_ci 14468c2ecf20Sopenharmony_ci /* if PC10 not present in CPUID.MWAIT.EDX */ 14478c2ecf20Sopenharmony_ci if ((mwait_substates & (0xF << 28)) == 0) 14488c2ecf20Sopenharmony_ci return; 14498c2ecf20Sopenharmony_ci 14508c2ecf20Sopenharmony_ci rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr); 14518c2ecf20Sopenharmony_ci 14528c2ecf20Sopenharmony_ci /* PC10 is not enabled in PKG C-state limit */ 14538c2ecf20Sopenharmony_ci if ((msr & 0xF) != 8) 14548c2ecf20Sopenharmony_ci return; 14558c2ecf20Sopenharmony_ci 14568c2ecf20Sopenharmony_ci ecx = 0; 14578c2ecf20Sopenharmony_ci cpuid(7, &eax, &ebx, &ecx, &edx); 14588c2ecf20Sopenharmony_ci 14598c2ecf20Sopenharmony_ci /* if SGX is present */ 14608c2ecf20Sopenharmony_ci if (ebx & (1 << 2)) { 14618c2ecf20Sopenharmony_ci 14628c2ecf20Sopenharmony_ci rdmsrl(MSR_IA32_FEAT_CTL, msr); 14638c2ecf20Sopenharmony_ci 14648c2ecf20Sopenharmony_ci /* if SGX is enabled */ 14658c2ecf20Sopenharmony_ci if (msr & (1 << 18)) 14668c2ecf20Sopenharmony_ci return; 14678c2ecf20Sopenharmony_ci } 14688c2ecf20Sopenharmony_ci 14698c2ecf20Sopenharmony_ci skl_cstates[5].flags |= CPUIDLE_FLAG_UNUSABLE; /* C8-SKL */ 14708c2ecf20Sopenharmony_ci skl_cstates[6].flags |= CPUIDLE_FLAG_UNUSABLE; /* C9-SKL */ 14718c2ecf20Sopenharmony_ci} 14728c2ecf20Sopenharmony_ci 14738c2ecf20Sopenharmony_cistatic bool __init intel_idle_verify_cstate(unsigned int mwait_hint) 14748c2ecf20Sopenharmony_ci{ 14758c2ecf20Sopenharmony_ci unsigned int mwait_cstate = MWAIT_HINT2CSTATE(mwait_hint) + 1; 14768c2ecf20Sopenharmony_ci unsigned int num_substates = (mwait_substates >> mwait_cstate * 4) & 14778c2ecf20Sopenharmony_ci MWAIT_SUBSTATE_MASK; 14788c2ecf20Sopenharmony_ci 14798c2ecf20Sopenharmony_ci /* Ignore the C-state if there are NO sub-states in CPUID for it. */ 14808c2ecf20Sopenharmony_ci if (num_substates == 0) 14818c2ecf20Sopenharmony_ci return false; 14828c2ecf20Sopenharmony_ci 14838c2ecf20Sopenharmony_ci if (mwait_cstate > 2 && !boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) 14848c2ecf20Sopenharmony_ci mark_tsc_unstable("TSC halts in idle states deeper than C2"); 14858c2ecf20Sopenharmony_ci 14868c2ecf20Sopenharmony_ci return true; 14878c2ecf20Sopenharmony_ci} 14888c2ecf20Sopenharmony_ci 14898c2ecf20Sopenharmony_cistatic void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv) 14908c2ecf20Sopenharmony_ci{ 14918c2ecf20Sopenharmony_ci int cstate; 14928c2ecf20Sopenharmony_ci 14938c2ecf20Sopenharmony_ci switch (boot_cpu_data.x86_model) { 14948c2ecf20Sopenharmony_ci case INTEL_FAM6_IVYBRIDGE_X: 14958c2ecf20Sopenharmony_ci ivt_idle_state_table_update(); 14968c2ecf20Sopenharmony_ci break; 14978c2ecf20Sopenharmony_ci case INTEL_FAM6_ATOM_GOLDMONT: 14988c2ecf20Sopenharmony_ci case INTEL_FAM6_ATOM_GOLDMONT_PLUS: 14998c2ecf20Sopenharmony_ci bxt_idle_state_table_update(); 15008c2ecf20Sopenharmony_ci break; 15018c2ecf20Sopenharmony_ci case INTEL_FAM6_SKYLAKE: 15028c2ecf20Sopenharmony_ci sklh_idle_state_table_update(); 15038c2ecf20Sopenharmony_ci break; 15048c2ecf20Sopenharmony_ci } 15058c2ecf20Sopenharmony_ci 15068c2ecf20Sopenharmony_ci for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) { 15078c2ecf20Sopenharmony_ci unsigned int mwait_hint; 15088c2ecf20Sopenharmony_ci 15098c2ecf20Sopenharmony_ci if (intel_idle_max_cstate_reached(cstate)) 15108c2ecf20Sopenharmony_ci break; 15118c2ecf20Sopenharmony_ci 15128c2ecf20Sopenharmony_ci if (!cpuidle_state_table[cstate].enter && 15138c2ecf20Sopenharmony_ci !cpuidle_state_table[cstate].enter_s2idle) 15148c2ecf20Sopenharmony_ci break; 15158c2ecf20Sopenharmony_ci 15168c2ecf20Sopenharmony_ci /* If marked as unusable, skip this state. */ 15178c2ecf20Sopenharmony_ci if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_UNUSABLE) { 15188c2ecf20Sopenharmony_ci pr_debug("state %s is disabled\n", 15198c2ecf20Sopenharmony_ci cpuidle_state_table[cstate].name); 15208c2ecf20Sopenharmony_ci continue; 15218c2ecf20Sopenharmony_ci } 15228c2ecf20Sopenharmony_ci 15238c2ecf20Sopenharmony_ci mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags); 15248c2ecf20Sopenharmony_ci if (!intel_idle_verify_cstate(mwait_hint)) 15258c2ecf20Sopenharmony_ci continue; 15268c2ecf20Sopenharmony_ci 15278c2ecf20Sopenharmony_ci /* Structure copy. */ 15288c2ecf20Sopenharmony_ci drv->states[drv->state_count] = cpuidle_state_table[cstate]; 15298c2ecf20Sopenharmony_ci 15308c2ecf20Sopenharmony_ci if (cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS) && 15318c2ecf20Sopenharmony_ci cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_IBRS) { 15328c2ecf20Sopenharmony_ci drv->states[drv->state_count].enter = intel_idle_ibrs; 15338c2ecf20Sopenharmony_ci } 15348c2ecf20Sopenharmony_ci 15358c2ecf20Sopenharmony_ci if ((disabled_states_mask & BIT(drv->state_count)) || 15368c2ecf20Sopenharmony_ci ((icpu->use_acpi || force_use_acpi) && 15378c2ecf20Sopenharmony_ci intel_idle_off_by_default(mwait_hint) && 15388c2ecf20Sopenharmony_ci !(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_ALWAYS_ENABLE))) 15398c2ecf20Sopenharmony_ci drv->states[drv->state_count].flags |= CPUIDLE_FLAG_OFF; 15408c2ecf20Sopenharmony_ci 15418c2ecf20Sopenharmony_ci if (intel_idle_state_needs_timer_stop(&drv->states[drv->state_count])) 15428c2ecf20Sopenharmony_ci drv->states[drv->state_count].flags |= CPUIDLE_FLAG_TIMER_STOP; 15438c2ecf20Sopenharmony_ci 15448c2ecf20Sopenharmony_ci drv->state_count++; 15458c2ecf20Sopenharmony_ci } 15468c2ecf20Sopenharmony_ci 15478c2ecf20Sopenharmony_ci if (icpu->byt_auto_demotion_disable_flag) { 15488c2ecf20Sopenharmony_ci wrmsrl(MSR_CC6_DEMOTION_POLICY_CONFIG, 0); 15498c2ecf20Sopenharmony_ci wrmsrl(MSR_MC6_DEMOTION_POLICY_CONFIG, 0); 15508c2ecf20Sopenharmony_ci } 15518c2ecf20Sopenharmony_ci} 15528c2ecf20Sopenharmony_ci 15538c2ecf20Sopenharmony_ci/** 15548c2ecf20Sopenharmony_ci * intel_idle_cpuidle_driver_init - Create the list of available idle states. 15558c2ecf20Sopenharmony_ci * @drv: cpuidle driver structure to initialize. 15568c2ecf20Sopenharmony_ci */ 15578c2ecf20Sopenharmony_cistatic void __init intel_idle_cpuidle_driver_init(struct cpuidle_driver *drv) 15588c2ecf20Sopenharmony_ci{ 15598c2ecf20Sopenharmony_ci cpuidle_poll_state_init(drv); 15608c2ecf20Sopenharmony_ci 15618c2ecf20Sopenharmony_ci if (disabled_states_mask & BIT(0)) 15628c2ecf20Sopenharmony_ci drv->states[0].flags |= CPUIDLE_FLAG_OFF; 15638c2ecf20Sopenharmony_ci 15648c2ecf20Sopenharmony_ci drv->state_count = 1; 15658c2ecf20Sopenharmony_ci 15668c2ecf20Sopenharmony_ci if (icpu) 15678c2ecf20Sopenharmony_ci intel_idle_init_cstates_icpu(drv); 15688c2ecf20Sopenharmony_ci else 15698c2ecf20Sopenharmony_ci intel_idle_init_cstates_acpi(drv); 15708c2ecf20Sopenharmony_ci} 15718c2ecf20Sopenharmony_ci 15728c2ecf20Sopenharmony_cistatic void auto_demotion_disable(void) 15738c2ecf20Sopenharmony_ci{ 15748c2ecf20Sopenharmony_ci unsigned long long msr_bits; 15758c2ecf20Sopenharmony_ci 15768c2ecf20Sopenharmony_ci rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr_bits); 15778c2ecf20Sopenharmony_ci msr_bits &= ~auto_demotion_disable_flags; 15788c2ecf20Sopenharmony_ci wrmsrl(MSR_PKG_CST_CONFIG_CONTROL, msr_bits); 15798c2ecf20Sopenharmony_ci} 15808c2ecf20Sopenharmony_ci 15818c2ecf20Sopenharmony_cistatic void c1e_promotion_disable(void) 15828c2ecf20Sopenharmony_ci{ 15838c2ecf20Sopenharmony_ci unsigned long long msr_bits; 15848c2ecf20Sopenharmony_ci 15858c2ecf20Sopenharmony_ci rdmsrl(MSR_IA32_POWER_CTL, msr_bits); 15868c2ecf20Sopenharmony_ci msr_bits &= ~0x2; 15878c2ecf20Sopenharmony_ci wrmsrl(MSR_IA32_POWER_CTL, msr_bits); 15888c2ecf20Sopenharmony_ci} 15898c2ecf20Sopenharmony_ci 15908c2ecf20Sopenharmony_ci/** 15918c2ecf20Sopenharmony_ci * intel_idle_cpu_init - Register the target CPU with the cpuidle core. 15928c2ecf20Sopenharmony_ci * @cpu: CPU to initialize. 15938c2ecf20Sopenharmony_ci * 15948c2ecf20Sopenharmony_ci * Register a cpuidle device object for @cpu and update its MSRs in accordance 15958c2ecf20Sopenharmony_ci * with the processor model flags. 15968c2ecf20Sopenharmony_ci */ 15978c2ecf20Sopenharmony_cistatic int intel_idle_cpu_init(unsigned int cpu) 15988c2ecf20Sopenharmony_ci{ 15998c2ecf20Sopenharmony_ci struct cpuidle_device *dev; 16008c2ecf20Sopenharmony_ci 16018c2ecf20Sopenharmony_ci dev = per_cpu_ptr(intel_idle_cpuidle_devices, cpu); 16028c2ecf20Sopenharmony_ci dev->cpu = cpu; 16038c2ecf20Sopenharmony_ci 16048c2ecf20Sopenharmony_ci if (cpuidle_register_device(dev)) { 16058c2ecf20Sopenharmony_ci pr_debug("cpuidle_register_device %d failed!\n", cpu); 16068c2ecf20Sopenharmony_ci return -EIO; 16078c2ecf20Sopenharmony_ci } 16088c2ecf20Sopenharmony_ci 16098c2ecf20Sopenharmony_ci if (auto_demotion_disable_flags) 16108c2ecf20Sopenharmony_ci auto_demotion_disable(); 16118c2ecf20Sopenharmony_ci 16128c2ecf20Sopenharmony_ci if (disable_promotion_to_c1e) 16138c2ecf20Sopenharmony_ci c1e_promotion_disable(); 16148c2ecf20Sopenharmony_ci 16158c2ecf20Sopenharmony_ci return 0; 16168c2ecf20Sopenharmony_ci} 16178c2ecf20Sopenharmony_ci 16188c2ecf20Sopenharmony_cistatic int intel_idle_cpu_online(unsigned int cpu) 16198c2ecf20Sopenharmony_ci{ 16208c2ecf20Sopenharmony_ci struct cpuidle_device *dev; 16218c2ecf20Sopenharmony_ci 16228c2ecf20Sopenharmony_ci if (!boot_cpu_has(X86_FEATURE_ARAT)) 16238c2ecf20Sopenharmony_ci tick_broadcast_enable(); 16248c2ecf20Sopenharmony_ci 16258c2ecf20Sopenharmony_ci /* 16268c2ecf20Sopenharmony_ci * Some systems can hotplug a cpu at runtime after 16278c2ecf20Sopenharmony_ci * the kernel has booted, we have to initialize the 16288c2ecf20Sopenharmony_ci * driver in this case 16298c2ecf20Sopenharmony_ci */ 16308c2ecf20Sopenharmony_ci dev = per_cpu_ptr(intel_idle_cpuidle_devices, cpu); 16318c2ecf20Sopenharmony_ci if (!dev->registered) 16328c2ecf20Sopenharmony_ci return intel_idle_cpu_init(cpu); 16338c2ecf20Sopenharmony_ci 16348c2ecf20Sopenharmony_ci return 0; 16358c2ecf20Sopenharmony_ci} 16368c2ecf20Sopenharmony_ci 16378c2ecf20Sopenharmony_ci/** 16388c2ecf20Sopenharmony_ci * intel_idle_cpuidle_devices_uninit - Unregister all cpuidle devices. 16398c2ecf20Sopenharmony_ci */ 16408c2ecf20Sopenharmony_cistatic void __init intel_idle_cpuidle_devices_uninit(void) 16418c2ecf20Sopenharmony_ci{ 16428c2ecf20Sopenharmony_ci int i; 16438c2ecf20Sopenharmony_ci 16448c2ecf20Sopenharmony_ci for_each_online_cpu(i) 16458c2ecf20Sopenharmony_ci cpuidle_unregister_device(per_cpu_ptr(intel_idle_cpuidle_devices, i)); 16468c2ecf20Sopenharmony_ci} 16478c2ecf20Sopenharmony_ci 16488c2ecf20Sopenharmony_cistatic int __init intel_idle_init(void) 16498c2ecf20Sopenharmony_ci{ 16508c2ecf20Sopenharmony_ci const struct x86_cpu_id *id; 16518c2ecf20Sopenharmony_ci unsigned int eax, ebx, ecx; 16528c2ecf20Sopenharmony_ci int retval; 16538c2ecf20Sopenharmony_ci 16548c2ecf20Sopenharmony_ci /* Do not load intel_idle at all for now if idle= is passed */ 16558c2ecf20Sopenharmony_ci if (boot_option_idle_override != IDLE_NO_OVERRIDE) 16568c2ecf20Sopenharmony_ci return -ENODEV; 16578c2ecf20Sopenharmony_ci 16588c2ecf20Sopenharmony_ci if (max_cstate == 0) { 16598c2ecf20Sopenharmony_ci pr_debug("disabled\n"); 16608c2ecf20Sopenharmony_ci return -EPERM; 16618c2ecf20Sopenharmony_ci } 16628c2ecf20Sopenharmony_ci 16638c2ecf20Sopenharmony_ci id = x86_match_cpu(intel_idle_ids); 16648c2ecf20Sopenharmony_ci if (id) { 16658c2ecf20Sopenharmony_ci if (!boot_cpu_has(X86_FEATURE_MWAIT)) { 16668c2ecf20Sopenharmony_ci pr_debug("Please enable MWAIT in BIOS SETUP\n"); 16678c2ecf20Sopenharmony_ci return -ENODEV; 16688c2ecf20Sopenharmony_ci } 16698c2ecf20Sopenharmony_ci } else { 16708c2ecf20Sopenharmony_ci id = x86_match_cpu(intel_mwait_ids); 16718c2ecf20Sopenharmony_ci if (!id) 16728c2ecf20Sopenharmony_ci return -ENODEV; 16738c2ecf20Sopenharmony_ci } 16748c2ecf20Sopenharmony_ci 16758c2ecf20Sopenharmony_ci if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) 16768c2ecf20Sopenharmony_ci return -ENODEV; 16778c2ecf20Sopenharmony_ci 16788c2ecf20Sopenharmony_ci cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates); 16798c2ecf20Sopenharmony_ci 16808c2ecf20Sopenharmony_ci if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || 16818c2ecf20Sopenharmony_ci !(ecx & CPUID5_ECX_INTERRUPT_BREAK) || 16828c2ecf20Sopenharmony_ci !mwait_substates) 16838c2ecf20Sopenharmony_ci return -ENODEV; 16848c2ecf20Sopenharmony_ci 16858c2ecf20Sopenharmony_ci pr_debug("MWAIT substates: 0x%x\n", mwait_substates); 16868c2ecf20Sopenharmony_ci 16878c2ecf20Sopenharmony_ci icpu = (const struct idle_cpu *)id->driver_data; 16888c2ecf20Sopenharmony_ci if (icpu) { 16898c2ecf20Sopenharmony_ci cpuidle_state_table = icpu->state_table; 16908c2ecf20Sopenharmony_ci auto_demotion_disable_flags = icpu->auto_demotion_disable_flags; 16918c2ecf20Sopenharmony_ci disable_promotion_to_c1e = icpu->disable_promotion_to_c1e; 16928c2ecf20Sopenharmony_ci if (icpu->use_acpi || force_use_acpi) 16938c2ecf20Sopenharmony_ci intel_idle_acpi_cst_extract(); 16948c2ecf20Sopenharmony_ci } else if (!intel_idle_acpi_cst_extract()) { 16958c2ecf20Sopenharmony_ci return -ENODEV; 16968c2ecf20Sopenharmony_ci } 16978c2ecf20Sopenharmony_ci 16988c2ecf20Sopenharmony_ci pr_debug("v" INTEL_IDLE_VERSION " model 0x%X\n", 16998c2ecf20Sopenharmony_ci boot_cpu_data.x86_model); 17008c2ecf20Sopenharmony_ci 17018c2ecf20Sopenharmony_ci intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device); 17028c2ecf20Sopenharmony_ci if (!intel_idle_cpuidle_devices) 17038c2ecf20Sopenharmony_ci return -ENOMEM; 17048c2ecf20Sopenharmony_ci 17058c2ecf20Sopenharmony_ci intel_idle_cpuidle_driver_init(&intel_idle_driver); 17068c2ecf20Sopenharmony_ci 17078c2ecf20Sopenharmony_ci retval = cpuidle_register_driver(&intel_idle_driver); 17088c2ecf20Sopenharmony_ci if (retval) { 17098c2ecf20Sopenharmony_ci struct cpuidle_driver *drv = cpuidle_get_driver(); 17108c2ecf20Sopenharmony_ci printk(KERN_DEBUG pr_fmt("intel_idle yielding to %s\n"), 17118c2ecf20Sopenharmony_ci drv ? drv->name : "none"); 17128c2ecf20Sopenharmony_ci goto init_driver_fail; 17138c2ecf20Sopenharmony_ci } 17148c2ecf20Sopenharmony_ci 17158c2ecf20Sopenharmony_ci retval = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "idle/intel:online", 17168c2ecf20Sopenharmony_ci intel_idle_cpu_online, NULL); 17178c2ecf20Sopenharmony_ci if (retval < 0) 17188c2ecf20Sopenharmony_ci goto hp_setup_fail; 17198c2ecf20Sopenharmony_ci 17208c2ecf20Sopenharmony_ci pr_debug("Local APIC timer is reliable in %s\n", 17218c2ecf20Sopenharmony_ci boot_cpu_has(X86_FEATURE_ARAT) ? "all C-states" : "C1"); 17228c2ecf20Sopenharmony_ci 17238c2ecf20Sopenharmony_ci return 0; 17248c2ecf20Sopenharmony_ci 17258c2ecf20Sopenharmony_cihp_setup_fail: 17268c2ecf20Sopenharmony_ci intel_idle_cpuidle_devices_uninit(); 17278c2ecf20Sopenharmony_ci cpuidle_unregister_driver(&intel_idle_driver); 17288c2ecf20Sopenharmony_ciinit_driver_fail: 17298c2ecf20Sopenharmony_ci free_percpu(intel_idle_cpuidle_devices); 17308c2ecf20Sopenharmony_ci return retval; 17318c2ecf20Sopenharmony_ci 17328c2ecf20Sopenharmony_ci} 17338c2ecf20Sopenharmony_cidevice_initcall(intel_idle_init); 17348c2ecf20Sopenharmony_ci 17358c2ecf20Sopenharmony_ci/* 17368c2ecf20Sopenharmony_ci * We are not really modular, but we used to support that. Meaning we also 17378c2ecf20Sopenharmony_ci * support "intel_idle.max_cstate=..." at boot and also a read-only export of 17388c2ecf20Sopenharmony_ci * it at /sys/module/intel_idle/parameters/max_cstate -- so using module_param 17398c2ecf20Sopenharmony_ci * is the easiest way (currently) to continue doing that. 17408c2ecf20Sopenharmony_ci */ 17418c2ecf20Sopenharmony_cimodule_param(max_cstate, int, 0444); 17428c2ecf20Sopenharmony_ci/* 17438c2ecf20Sopenharmony_ci * The positions of the bits that are set in this number are the indices of the 17448c2ecf20Sopenharmony_ci * idle states to be disabled by default (as reflected by the names of the 17458c2ecf20Sopenharmony_ci * corresponding idle state directories in sysfs, "state0", "state1" ... 17468c2ecf20Sopenharmony_ci * "state<i>" ..., where <i> is the index of the given state). 17478c2ecf20Sopenharmony_ci */ 17488c2ecf20Sopenharmony_cimodule_param_named(states_off, disabled_states_mask, uint, 0444); 17498c2ecf20Sopenharmony_ciMODULE_PARM_DESC(states_off, "Mask of disabled idle states"); 1750