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