| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1 | /* | 
 | 2 |  * intel_idle.c - native hardware idle loop for modern Intel processors | 
 | 3 |  * | 
| Len Brown | fab04b2 | 2013-11-09 00:30:17 -0500 | [diff] [blame] | 4 |  * Copyright (c) 2013, Intel Corporation. | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 5 |  * Len Brown <len.brown@intel.com> | 
 | 6 |  * | 
 | 7 |  * This program is free software; you can redistribute it and/or modify it | 
 | 8 |  * under the terms and conditions of the GNU General Public License, | 
 | 9 |  * version 2, as published by the Free Software Foundation. | 
 | 10 |  * | 
 | 11 |  * This program is distributed in the hope it will be useful, but WITHOUT | 
 | 12 |  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
 | 13 |  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | 
 | 14 |  * more details. | 
 | 15 |  * | 
 | 16 |  * You should have received a copy of the GNU General Public License along with | 
 | 17 |  * this program; if not, write to the Free Software Foundation, Inc., | 
 | 18 |  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | 
 | 19 |  */ | 
 | 20 |  | 
 | 21 | /* | 
 | 22 |  * intel_idle is a cpuidle driver that loads on specific Intel processors | 
 | 23 |  * in lieu of the legacy ACPI processor_idle driver.  The intent is to | 
 | 24 |  * make Linux more efficient on these processors, as intel_idle knows | 
 | 25 |  * more than ACPI, as well as make Linux more immune to ACPI BIOS bugs. | 
 | 26 |  */ | 
 | 27 |  | 
 | 28 | /* | 
 | 29 |  * Design Assumptions | 
 | 30 |  * | 
 | 31 |  * All CPUs have same idle states as boot CPU | 
 | 32 |  * | 
 | 33 |  * Chipset BM_STS (bus master status) bit is a NOP | 
 | 34 |  *	for preventing entry into deep C-stats | 
 | 35 |  */ | 
 | 36 |  | 
 | 37 | /* | 
 | 38 |  * Known limitations | 
 | 39 |  * | 
 | 40 |  * The driver currently initializes for_each_online_cpu() upon modprobe. | 
 | 41 |  * It it unaware of subsequent processors hot-added to the system. | 
 | 42 |  * This means that if you boot with maxcpus=n and later online | 
 | 43 |  * processors above n, those processors will use C1 only. | 
 | 44 |  * | 
 | 45 |  * ACPI has a .suspend hack to turn off deep c-statees during suspend | 
 | 46 |  * to avoid complications with the lapic timer workaround. | 
 | 47 |  * Have not seen issues with suspend, but may need same workaround here. | 
 | 48 |  * | 
 | 49 |  * There is currently no kernel-based automatic probing/loading mechanism | 
 | 50 |  * if the driver is built as a module. | 
 | 51 |  */ | 
 | 52 |  | 
 | 53 | /* un-comment DEBUG to enable pr_debug() statements */ | 
 | 54 | #define DEBUG | 
 | 55 |  | 
 | 56 | #include <linux/kernel.h> | 
 | 57 | #include <linux/cpuidle.h> | 
| Thomas Gleixner | 76962ca | 2015-04-03 02:02:34 +0200 | [diff] [blame] | 58 | #include <linux/tick.h> | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 59 | #include <trace/events/power.h> | 
 | 60 | #include <linux/sched.h> | 
| Shaohua Li | 2a2d31c | 2011-01-10 09:38:12 +0800 | [diff] [blame] | 61 | #include <linux/notifier.h> | 
 | 62 | #include <linux/cpu.h> | 
| Paul Gortmaker | 7c52d55 | 2011-05-27 12:33:10 -0400 | [diff] [blame] | 63 | #include <linux/module.h> | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 64 | #include <asm/cpu_device_id.h> | 
| H. Peter Anvin | bc83ccc | 2010-09-17 15:36:40 -0700 | [diff] [blame] | 65 | #include <asm/mwait.h> | 
| Len Brown | 14796fc | 2011-01-18 20:48:27 -0500 | [diff] [blame] | 66 | #include <asm/msr.h> | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 67 |  | 
 | 68 | #define INTEL_IDLE_VERSION "0.4" | 
 | 69 | #define PREFIX "intel_idle: " | 
 | 70 |  | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 71 | static struct cpuidle_driver intel_idle_driver = { | 
 | 72 | 	.name = "intel_idle", | 
 | 73 | 	.owner = THIS_MODULE, | 
 | 74 | }; | 
 | 75 | /* intel_idle.max_cstate=0 disables driver */ | 
| Len Brown | 137ecc7 | 2013-02-01 21:35:35 -0500 | [diff] [blame] | 76 | static int max_cstate = CPUIDLE_STATE_MAX - 1; | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 77 |  | 
| Len Brown | c423628 | 2010-05-28 02:22:03 -0400 | [diff] [blame] | 78 | static unsigned int mwait_substates; | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 79 |  | 
| Shaohua Li | 2a2d31c | 2011-01-10 09:38:12 +0800 | [diff] [blame] | 80 | #define LAPIC_TIMER_ALWAYS_RELIABLE 0xFFFFFFFF | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 81 | /* Reliable LAPIC Timer States, bit 1 for C1 etc.  */ | 
| Len Brown | d13780d | 2010-07-07 00:12:03 -0400 | [diff] [blame] | 82 | static unsigned int lapic_timer_reliable_states = (1 << 1);	 /* Default to only C1 */ | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 83 |  | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 84 | struct idle_cpu { | 
 | 85 | 	struct cpuidle_state *state_table; | 
 | 86 |  | 
 | 87 | 	/* | 
 | 88 | 	 * Hardware C-state auto-demotion may not always be optimal. | 
 | 89 | 	 * Indicate which enable bits to clear here. | 
 | 90 | 	 */ | 
 | 91 | 	unsigned long auto_demotion_disable_flags; | 
| Len Brown | 8c058d53 | 2014-07-31 15:21:24 -0400 | [diff] [blame] | 92 | 	bool byt_auto_demotion_disable_flag; | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 93 | 	bool disable_promotion_to_c1e; | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 94 | }; | 
 | 95 |  | 
 | 96 | static const struct idle_cpu *icpu; | 
| Namhyung Kim | 3265eba | 2010-08-08 03:10:03 +0900 | [diff] [blame] | 97 | static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; | 
| Deepthi Dharwar | 46bcfad | 2011-10-28 16:20:42 +0530 | [diff] [blame] | 98 | static int intel_idle(struct cpuidle_device *dev, | 
 | 99 | 			struct cpuidle_driver *drv, int index); | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 100 | static void intel_idle_freeze(struct cpuidle_device *dev, | 
 | 101 | 			      struct cpuidle_driver *drv, int index); | 
| Daniel Lezcano | 25ac776 | 2012-07-05 15:23:25 +0200 | [diff] [blame] | 102 | static int intel_idle_cpu_init(int cpu); | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 103 |  | 
 | 104 | static struct cpuidle_state *cpuidle_state_table; | 
 | 105 |  | 
 | 106 | /* | 
| Len Brown | 956d033 | 2011-01-12 02:51:20 -0500 | [diff] [blame] | 107 |  * Set this flag for states where the HW flushes the TLB for us | 
 | 108 |  * and so we don't need cross-calls to keep it consistent. | 
 | 109 |  * If this flag is set, SW flushes the TLB, so even if the | 
 | 110 |  * HW doesn't do the flushing, this flag is safe to use. | 
 | 111 |  */ | 
 | 112 | #define CPUIDLE_FLAG_TLB_FLUSHED	0x10000 | 
 | 113 |  | 
 | 114 | /* | 
| Len Brown | b1beab4 | 2013-01-31 19:55:37 -0500 | [diff] [blame] | 115 |  * MWAIT takes an 8-bit "hint" in EAX "suggesting" | 
 | 116 |  * the C-state (top nibble) and sub-state (bottom nibble) | 
 | 117 |  * 0x00 means "MWAIT(C1)", 0x10 means "MWAIT(C2)" etc. | 
 | 118 |  * | 
 | 119 |  * We store the hint at the top of our "flags" for each state. | 
 | 120 |  */ | 
 | 121 | #define flg2MWAIT(flags) (((flags) >> 24) & 0xFF) | 
 | 122 | #define MWAIT2flg(eax) ((eax & 0xFF) << 24) | 
 | 123 |  | 
 | 124 | /* | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 125 |  * States are indexed by the cstate number, | 
 | 126 |  * which is also the index into the MWAIT hint array. | 
 | 127 |  * Thus C0 is a dummy. | 
 | 128 |  */ | 
| Jiang Liu | ba0dc81 | 2014-01-09 15:30:26 +0800 | [diff] [blame] | 129 | static struct cpuidle_state nehalem_cstates[] = { | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 130 | 	{ | 
| Thomas Renninger | 15e123e | 2011-02-27 22:36:43 +0100 | [diff] [blame] | 131 | 		.name = "C1-NHM", | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 132 | 		.desc = "MWAIT 0x00", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 133 | 		.flags = MWAIT2flg(0x00), | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 134 | 		.exit_latency = 3, | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 135 | 		.target_residency = 6, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 136 | 		.enter = &intel_idle, | 
 | 137 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 138 | 	{ | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 139 | 		.name = "C1E-NHM", | 
 | 140 | 		.desc = "MWAIT 0x01", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 141 | 		.flags = MWAIT2flg(0x01), | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 142 | 		.exit_latency = 10, | 
 | 143 | 		.target_residency = 20, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 144 | 		.enter = &intel_idle, | 
 | 145 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 146 | 	{ | 
| Thomas Renninger | 15e123e | 2011-02-27 22:36:43 +0100 | [diff] [blame] | 147 | 		.name = "C3-NHM", | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 148 | 		.desc = "MWAIT 0x10", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 149 | 		.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 150 | 		.exit_latency = 20, | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 151 | 		.target_residency = 80, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 152 | 		.enter = &intel_idle, | 
 | 153 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 154 | 	{ | 
| Thomas Renninger | 15e123e | 2011-02-27 22:36:43 +0100 | [diff] [blame] | 155 | 		.name = "C6-NHM", | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 156 | 		.desc = "MWAIT 0x20", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 157 | 		.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 158 | 		.exit_latency = 200, | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 159 | 		.target_residency = 800, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 160 | 		.enter = &intel_idle, | 
 | 161 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 162 | 	{ | 
 | 163 | 		.enter = NULL } | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 164 | }; | 
 | 165 |  | 
| Jiang Liu | ba0dc81 | 2014-01-09 15:30:26 +0800 | [diff] [blame] | 166 | static struct cpuidle_state snb_cstates[] = { | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 167 | 	{ | 
| Thomas Renninger | 15e123e | 2011-02-27 22:36:43 +0100 | [diff] [blame] | 168 | 		.name = "C1-SNB", | 
| Len Brown | d13780d | 2010-07-07 00:12:03 -0400 | [diff] [blame] | 169 | 		.desc = "MWAIT 0x00", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 170 | 		.flags = MWAIT2flg(0x00), | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 171 | 		.exit_latency = 2, | 
 | 172 | 		.target_residency = 2, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 173 | 		.enter = &intel_idle, | 
 | 174 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 175 | 	{ | 
 | 176 | 		.name = "C1E-SNB", | 
 | 177 | 		.desc = "MWAIT 0x01", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 178 | 		.flags = MWAIT2flg(0x01), | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 179 | 		.exit_latency = 10, | 
 | 180 | 		.target_residency = 20, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 181 | 		.enter = &intel_idle, | 
 | 182 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 183 | 	{ | 
| Thomas Renninger | 15e123e | 2011-02-27 22:36:43 +0100 | [diff] [blame] | 184 | 		.name = "C3-SNB", | 
| Len Brown | d13780d | 2010-07-07 00:12:03 -0400 | [diff] [blame] | 185 | 		.desc = "MWAIT 0x10", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 186 | 		.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | d13780d | 2010-07-07 00:12:03 -0400 | [diff] [blame] | 187 | 		.exit_latency = 80, | 
| Len Brown | ddbd550 | 2010-12-13 18:28:22 -0500 | [diff] [blame] | 188 | 		.target_residency = 211, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 189 | 		.enter = &intel_idle, | 
 | 190 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 191 | 	{ | 
| Thomas Renninger | 15e123e | 2011-02-27 22:36:43 +0100 | [diff] [blame] | 192 | 		.name = "C6-SNB", | 
| Len Brown | d13780d | 2010-07-07 00:12:03 -0400 | [diff] [blame] | 193 | 		.desc = "MWAIT 0x20", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 194 | 		.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | d13780d | 2010-07-07 00:12:03 -0400 | [diff] [blame] | 195 | 		.exit_latency = 104, | 
| Len Brown | ddbd550 | 2010-12-13 18:28:22 -0500 | [diff] [blame] | 196 | 		.target_residency = 345, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 197 | 		.enter = &intel_idle, | 
 | 198 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 199 | 	{ | 
| Thomas Renninger | 15e123e | 2011-02-27 22:36:43 +0100 | [diff] [blame] | 200 | 		.name = "C7-SNB", | 
| Len Brown | d13780d | 2010-07-07 00:12:03 -0400 | [diff] [blame] | 201 | 		.desc = "MWAIT 0x30", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 202 | 		.flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | d13780d | 2010-07-07 00:12:03 -0400 | [diff] [blame] | 203 | 		.exit_latency = 109, | 
| Len Brown | ddbd550 | 2010-12-13 18:28:22 -0500 | [diff] [blame] | 204 | 		.target_residency = 345, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 205 | 		.enter = &intel_idle, | 
 | 206 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 207 | 	{ | 
 | 208 | 		.enter = NULL } | 
| Len Brown | d13780d | 2010-07-07 00:12:03 -0400 | [diff] [blame] | 209 | }; | 
 | 210 |  | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 211 | static struct cpuidle_state byt_cstates[] = { | 
 | 212 | 	{ | 
 | 213 | 		.name = "C1-BYT", | 
 | 214 | 		.desc = "MWAIT 0x00", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 215 | 		.flags = MWAIT2flg(0x00), | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 216 | 		.exit_latency = 1, | 
 | 217 | 		.target_residency = 1, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 218 | 		.enter = &intel_idle, | 
 | 219 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 220 | 	{ | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 221 | 		.name = "C6N-BYT", | 
 | 222 | 		.desc = "MWAIT 0x58", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 223 | 		.flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | d7ef767 | 2015-03-24 23:23:20 -0400 | [diff] [blame] | 224 | 		.exit_latency = 300, | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 225 | 		.target_residency = 275, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 226 | 		.enter = &intel_idle, | 
 | 227 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 228 | 	{ | 
 | 229 | 		.name = "C6S-BYT", | 
 | 230 | 		.desc = "MWAIT 0x52", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 231 | 		.flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | d7ef767 | 2015-03-24 23:23:20 -0400 | [diff] [blame] | 232 | 		.exit_latency = 500, | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 233 | 		.target_residency = 560, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 234 | 		.enter = &intel_idle, | 
 | 235 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 236 | 	{ | 
 | 237 | 		.name = "C7-BYT", | 
 | 238 | 		.desc = "MWAIT 0x60", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 239 | 		.flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 240 | 		.exit_latency = 1200, | 
| Len Brown | d7ef767 | 2015-03-24 23:23:20 -0400 | [diff] [blame] | 241 | 		.target_residency = 4000, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 242 | 		.enter = &intel_idle, | 
 | 243 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 244 | 	{ | 
 | 245 | 		.name = "C7S-BYT", | 
 | 246 | 		.desc = "MWAIT 0x64", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 247 | 		.flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 248 | 		.exit_latency = 10000, | 
 | 249 | 		.target_residency = 20000, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 250 | 		.enter = &intel_idle, | 
 | 251 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 252 | 	{ | 
 | 253 | 		.enter = NULL } | 
 | 254 | }; | 
 | 255 |  | 
| Len Brown | cab07a5 | 2015-03-27 20:54:01 -0400 | [diff] [blame] | 256 | static struct cpuidle_state cht_cstates[] = { | 
 | 257 | 	{ | 
 | 258 | 		.name = "C1-CHT", | 
 | 259 | 		.desc = "MWAIT 0x00", | 
 | 260 | 		.flags = MWAIT2flg(0x00), | 
 | 261 | 		.exit_latency = 1, | 
 | 262 | 		.target_residency = 1, | 
 | 263 | 		.enter = &intel_idle, | 
 | 264 | 		.enter_freeze = intel_idle_freeze, }, | 
 | 265 | 	{ | 
 | 266 | 		.name = "C6N-CHT", | 
 | 267 | 		.desc = "MWAIT 0x58", | 
 | 268 | 		.flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TLB_FLUSHED, | 
 | 269 | 		.exit_latency = 80, | 
 | 270 | 		.target_residency = 275, | 
 | 271 | 		.enter = &intel_idle, | 
 | 272 | 		.enter_freeze = intel_idle_freeze, }, | 
 | 273 | 	{ | 
 | 274 | 		.name = "C6S-CHT", | 
 | 275 | 		.desc = "MWAIT 0x52", | 
 | 276 | 		.flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, | 
 | 277 | 		.exit_latency = 200, | 
 | 278 | 		.target_residency = 560, | 
 | 279 | 		.enter = &intel_idle, | 
 | 280 | 		.enter_freeze = intel_idle_freeze, }, | 
 | 281 | 	{ | 
 | 282 | 		.name = "C7-CHT", | 
 | 283 | 		.desc = "MWAIT 0x60", | 
 | 284 | 		.flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, | 
 | 285 | 		.exit_latency = 1200, | 
 | 286 | 		.target_residency = 4000, | 
 | 287 | 		.enter = &intel_idle, | 
 | 288 | 		.enter_freeze = intel_idle_freeze, }, | 
 | 289 | 	{ | 
 | 290 | 		.name = "C7S-CHT", | 
 | 291 | 		.desc = "MWAIT 0x64", | 
 | 292 | 		.flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TLB_FLUSHED, | 
 | 293 | 		.exit_latency = 10000, | 
 | 294 | 		.target_residency = 20000, | 
 | 295 | 		.enter = &intel_idle, | 
 | 296 | 		.enter_freeze = intel_idle_freeze, }, | 
 | 297 | 	{ | 
 | 298 | 		.enter = NULL } | 
 | 299 | }; | 
 | 300 |  | 
| Jiang Liu | ba0dc81 | 2014-01-09 15:30:26 +0800 | [diff] [blame] | 301 | static struct cpuidle_state ivb_cstates[] = { | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 302 | 	{ | 
| Len Brown | 6edab08 | 2012-06-01 19:45:32 -0400 | [diff] [blame] | 303 | 		.name = "C1-IVB", | 
 | 304 | 		.desc = "MWAIT 0x00", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 305 | 		.flags = MWAIT2flg(0x00), | 
| Len Brown | 6edab08 | 2012-06-01 19:45:32 -0400 | [diff] [blame] | 306 | 		.exit_latency = 1, | 
 | 307 | 		.target_residency = 1, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 308 | 		.enter = &intel_idle, | 
 | 309 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 310 | 	{ | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 311 | 		.name = "C1E-IVB", | 
 | 312 | 		.desc = "MWAIT 0x01", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 313 | 		.flags = MWAIT2flg(0x01), | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 314 | 		.exit_latency = 10, | 
 | 315 | 		.target_residency = 20, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 316 | 		.enter = &intel_idle, | 
 | 317 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 318 | 	{ | 
| Len Brown | 6edab08 | 2012-06-01 19:45:32 -0400 | [diff] [blame] | 319 | 		.name = "C3-IVB", | 
 | 320 | 		.desc = "MWAIT 0x10", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 321 | 		.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 6edab08 | 2012-06-01 19:45:32 -0400 | [diff] [blame] | 322 | 		.exit_latency = 59, | 
 | 323 | 		.target_residency = 156, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 324 | 		.enter = &intel_idle, | 
 | 325 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 326 | 	{ | 
| Len Brown | 6edab08 | 2012-06-01 19:45:32 -0400 | [diff] [blame] | 327 | 		.name = "C6-IVB", | 
 | 328 | 		.desc = "MWAIT 0x20", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 329 | 		.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 6edab08 | 2012-06-01 19:45:32 -0400 | [diff] [blame] | 330 | 		.exit_latency = 80, | 
 | 331 | 		.target_residency = 300, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 332 | 		.enter = &intel_idle, | 
 | 333 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 334 | 	{ | 
| Len Brown | 6edab08 | 2012-06-01 19:45:32 -0400 | [diff] [blame] | 335 | 		.name = "C7-IVB", | 
 | 336 | 		.desc = "MWAIT 0x30", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 337 | 		.flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 6edab08 | 2012-06-01 19:45:32 -0400 | [diff] [blame] | 338 | 		.exit_latency = 87, | 
 | 339 | 		.target_residency = 300, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 340 | 		.enter = &intel_idle, | 
 | 341 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 342 | 	{ | 
 | 343 | 		.enter = NULL } | 
| Len Brown | 6edab08 | 2012-06-01 19:45:32 -0400 | [diff] [blame] | 344 | }; | 
 | 345 |  | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 346 | static struct cpuidle_state ivt_cstates[] = { | 
 | 347 | 	{ | 
 | 348 | 		.name = "C1-IVT", | 
 | 349 | 		.desc = "MWAIT 0x00", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 350 | 		.flags = MWAIT2flg(0x00), | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 351 | 		.exit_latency = 1, | 
 | 352 | 		.target_residency = 1, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 353 | 		.enter = &intel_idle, | 
 | 354 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 355 | 	{ | 
 | 356 | 		.name = "C1E-IVT", | 
 | 357 | 		.desc = "MWAIT 0x01", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 358 | 		.flags = MWAIT2flg(0x01), | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 359 | 		.exit_latency = 10, | 
 | 360 | 		.target_residency = 80, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 361 | 		.enter = &intel_idle, | 
 | 362 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 363 | 	{ | 
 | 364 | 		.name = "C3-IVT", | 
 | 365 | 		.desc = "MWAIT 0x10", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 366 | 		.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 367 | 		.exit_latency = 59, | 
 | 368 | 		.target_residency = 156, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 369 | 		.enter = &intel_idle, | 
 | 370 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 371 | 	{ | 
 | 372 | 		.name = "C6-IVT", | 
 | 373 | 		.desc = "MWAIT 0x20", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 374 | 		.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 375 | 		.exit_latency = 82, | 
 | 376 | 		.target_residency = 300, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 377 | 		.enter = &intel_idle, | 
 | 378 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 379 | 	{ | 
 | 380 | 		.enter = NULL } | 
 | 381 | }; | 
 | 382 |  | 
 | 383 | static struct cpuidle_state ivt_cstates_4s[] = { | 
 | 384 | 	{ | 
 | 385 | 		.name = "C1-IVT-4S", | 
 | 386 | 		.desc = "MWAIT 0x00", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 387 | 		.flags = MWAIT2flg(0x00), | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 388 | 		.exit_latency = 1, | 
 | 389 | 		.target_residency = 1, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 390 | 		.enter = &intel_idle, | 
 | 391 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 392 | 	{ | 
 | 393 | 		.name = "C1E-IVT-4S", | 
 | 394 | 		.desc = "MWAIT 0x01", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 395 | 		.flags = MWAIT2flg(0x01), | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 396 | 		.exit_latency = 10, | 
 | 397 | 		.target_residency = 250, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 398 | 		.enter = &intel_idle, | 
 | 399 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 400 | 	{ | 
 | 401 | 		.name = "C3-IVT-4S", | 
 | 402 | 		.desc = "MWAIT 0x10", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 403 | 		.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 404 | 		.exit_latency = 59, | 
 | 405 | 		.target_residency = 300, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 406 | 		.enter = &intel_idle, | 
 | 407 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 408 | 	{ | 
 | 409 | 		.name = "C6-IVT-4S", | 
 | 410 | 		.desc = "MWAIT 0x20", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 411 | 		.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 412 | 		.exit_latency = 84, | 
 | 413 | 		.target_residency = 400, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 414 | 		.enter = &intel_idle, | 
 | 415 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 416 | 	{ | 
 | 417 | 		.enter = NULL } | 
 | 418 | }; | 
 | 419 |  | 
 | 420 | static struct cpuidle_state ivt_cstates_8s[] = { | 
 | 421 | 	{ | 
 | 422 | 		.name = "C1-IVT-8S", | 
 | 423 | 		.desc = "MWAIT 0x00", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 424 | 		.flags = MWAIT2flg(0x00), | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 425 | 		.exit_latency = 1, | 
 | 426 | 		.target_residency = 1, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 427 | 		.enter = &intel_idle, | 
 | 428 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 429 | 	{ | 
 | 430 | 		.name = "C1E-IVT-8S", | 
 | 431 | 		.desc = "MWAIT 0x01", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 432 | 		.flags = MWAIT2flg(0x01), | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 433 | 		.exit_latency = 10, | 
 | 434 | 		.target_residency = 500, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 435 | 		.enter = &intel_idle, | 
 | 436 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 437 | 	{ | 
 | 438 | 		.name = "C3-IVT-8S", | 
 | 439 | 		.desc = "MWAIT 0x10", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 440 | 		.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 441 | 		.exit_latency = 59, | 
 | 442 | 		.target_residency = 600, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 443 | 		.enter = &intel_idle, | 
 | 444 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 445 | 	{ | 
 | 446 | 		.name = "C6-IVT-8S", | 
 | 447 | 		.desc = "MWAIT 0x20", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 448 | 		.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 449 | 		.exit_latency = 88, | 
 | 450 | 		.target_residency = 700, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 451 | 		.enter = &intel_idle, | 
 | 452 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 453 | 	{ | 
 | 454 | 		.enter = NULL } | 
 | 455 | }; | 
 | 456 |  | 
| Jiang Liu | ba0dc81 | 2014-01-09 15:30:26 +0800 | [diff] [blame] | 457 | static struct cpuidle_state hsw_cstates[] = { | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 458 | 	{ | 
| Len Brown | 85a4d2d | 2013-01-31 14:40:49 -0500 | [diff] [blame] | 459 | 		.name = "C1-HSW", | 
 | 460 | 		.desc = "MWAIT 0x00", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 461 | 		.flags = MWAIT2flg(0x00), | 
| Len Brown | 85a4d2d | 2013-01-31 14:40:49 -0500 | [diff] [blame] | 462 | 		.exit_latency = 2, | 
 | 463 | 		.target_residency = 2, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 464 | 		.enter = &intel_idle, | 
 | 465 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 466 | 	{ | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 467 | 		.name = "C1E-HSW", | 
 | 468 | 		.desc = "MWAIT 0x01", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 469 | 		.flags = MWAIT2flg(0x01), | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 470 | 		.exit_latency = 10, | 
 | 471 | 		.target_residency = 20, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 472 | 		.enter = &intel_idle, | 
 | 473 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 474 | 	{ | 
| Len Brown | 85a4d2d | 2013-01-31 14:40:49 -0500 | [diff] [blame] | 475 | 		.name = "C3-HSW", | 
 | 476 | 		.desc = "MWAIT 0x10", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 477 | 		.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 85a4d2d | 2013-01-31 14:40:49 -0500 | [diff] [blame] | 478 | 		.exit_latency = 33, | 
 | 479 | 		.target_residency = 100, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 480 | 		.enter = &intel_idle, | 
 | 481 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 482 | 	{ | 
| Len Brown | 85a4d2d | 2013-01-31 14:40:49 -0500 | [diff] [blame] | 483 | 		.name = "C6-HSW", | 
 | 484 | 		.desc = "MWAIT 0x20", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 485 | 		.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 85a4d2d | 2013-01-31 14:40:49 -0500 | [diff] [blame] | 486 | 		.exit_latency = 133, | 
 | 487 | 		.target_residency = 400, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 488 | 		.enter = &intel_idle, | 
 | 489 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 490 | 	{ | 
| Len Brown | 85a4d2d | 2013-01-31 14:40:49 -0500 | [diff] [blame] | 491 | 		.name = "C7s-HSW", | 
 | 492 | 		.desc = "MWAIT 0x32", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 493 | 		.flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 85a4d2d | 2013-01-31 14:40:49 -0500 | [diff] [blame] | 494 | 		.exit_latency = 166, | 
 | 495 | 		.target_residency = 500, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 496 | 		.enter = &intel_idle, | 
 | 497 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 498 | 	{ | 
| Len Brown | 86239ce | 2013-02-27 13:18:50 -0500 | [diff] [blame] | 499 | 		.name = "C8-HSW", | 
 | 500 | 		.desc = "MWAIT 0x40", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 501 | 		.flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 86239ce | 2013-02-27 13:18:50 -0500 | [diff] [blame] | 502 | 		.exit_latency = 300, | 
 | 503 | 		.target_residency = 900, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 504 | 		.enter = &intel_idle, | 
 | 505 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 86239ce | 2013-02-27 13:18:50 -0500 | [diff] [blame] | 506 | 	{ | 
 | 507 | 		.name = "C9-HSW", | 
 | 508 | 		.desc = "MWAIT 0x50", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 509 | 		.flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 86239ce | 2013-02-27 13:18:50 -0500 | [diff] [blame] | 510 | 		.exit_latency = 600, | 
 | 511 | 		.target_residency = 1800, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 512 | 		.enter = &intel_idle, | 
 | 513 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 86239ce | 2013-02-27 13:18:50 -0500 | [diff] [blame] | 514 | 	{ | 
 | 515 | 		.name = "C10-HSW", | 
 | 516 | 		.desc = "MWAIT 0x60", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 517 | 		.flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 86239ce | 2013-02-27 13:18:50 -0500 | [diff] [blame] | 518 | 		.exit_latency = 2600, | 
 | 519 | 		.target_residency = 7700, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 520 | 		.enter = &intel_idle, | 
 | 521 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | 86239ce | 2013-02-27 13:18:50 -0500 | [diff] [blame] | 522 | 	{ | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 523 | 		.enter = NULL } | 
| Len Brown | 85a4d2d | 2013-01-31 14:40:49 -0500 | [diff] [blame] | 524 | }; | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 525 | static struct cpuidle_state bdw_cstates[] = { | 
 | 526 | 	{ | 
 | 527 | 		.name = "C1-BDW", | 
 | 528 | 		.desc = "MWAIT 0x00", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 529 | 		.flags = MWAIT2flg(0x00), | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 530 | 		.exit_latency = 2, | 
 | 531 | 		.target_residency = 2, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 532 | 		.enter = &intel_idle, | 
 | 533 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 534 | 	{ | 
 | 535 | 		.name = "C1E-BDW", | 
 | 536 | 		.desc = "MWAIT 0x01", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 537 | 		.flags = MWAIT2flg(0x01), | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 538 | 		.exit_latency = 10, | 
 | 539 | 		.target_residency = 20, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 540 | 		.enter = &intel_idle, | 
 | 541 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 542 | 	{ | 
 | 543 | 		.name = "C3-BDW", | 
 | 544 | 		.desc = "MWAIT 0x10", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 545 | 		.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 546 | 		.exit_latency = 40, | 
 | 547 | 		.target_residency = 100, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 548 | 		.enter = &intel_idle, | 
 | 549 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 550 | 	{ | 
 | 551 | 		.name = "C6-BDW", | 
 | 552 | 		.desc = "MWAIT 0x20", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 553 | 		.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 554 | 		.exit_latency = 133, | 
 | 555 | 		.target_residency = 400, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 556 | 		.enter = &intel_idle, | 
 | 557 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 558 | 	{ | 
 | 559 | 		.name = "C7s-BDW", | 
 | 560 | 		.desc = "MWAIT 0x32", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 561 | 		.flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 562 | 		.exit_latency = 166, | 
 | 563 | 		.target_residency = 500, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 564 | 		.enter = &intel_idle, | 
 | 565 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 566 | 	{ | 
 | 567 | 		.name = "C8-BDW", | 
 | 568 | 		.desc = "MWAIT 0x40", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 569 | 		.flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 570 | 		.exit_latency = 300, | 
 | 571 | 		.target_residency = 900, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 572 | 		.enter = &intel_idle, | 
 | 573 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 574 | 	{ | 
 | 575 | 		.name = "C9-BDW", | 
 | 576 | 		.desc = "MWAIT 0x50", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 577 | 		.flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 578 | 		.exit_latency = 600, | 
 | 579 | 		.target_residency = 1800, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 580 | 		.enter = &intel_idle, | 
 | 581 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 582 | 	{ | 
 | 583 | 		.name = "C10-BDW", | 
 | 584 | 		.desc = "MWAIT 0x60", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 585 | 		.flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 586 | 		.exit_latency = 2600, | 
 | 587 | 		.target_residency = 7700, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 588 | 		.enter = &intel_idle, | 
 | 589 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 590 | 	{ | 
 | 591 | 		.enter = NULL } | 
 | 592 | }; | 
| Len Brown | 85a4d2d | 2013-01-31 14:40:49 -0500 | [diff] [blame] | 593 |  | 
| Len Brown | 493f133 | 2015-03-25 23:20:37 -0400 | [diff] [blame] | 594 | static struct cpuidle_state skl_cstates[] = { | 
 | 595 | 	{ | 
 | 596 | 		.name = "C1-SKL", | 
 | 597 | 		.desc = "MWAIT 0x00", | 
 | 598 | 		.flags = MWAIT2flg(0x00), | 
 | 599 | 		.exit_latency = 2, | 
 | 600 | 		.target_residency = 2, | 
 | 601 | 		.enter = &intel_idle, | 
 | 602 | 		.enter_freeze = intel_idle_freeze, }, | 
 | 603 | 	{ | 
 | 604 | 		.name = "C1E-SKL", | 
 | 605 | 		.desc = "MWAIT 0x01", | 
 | 606 | 		.flags = MWAIT2flg(0x01), | 
 | 607 | 		.exit_latency = 10, | 
 | 608 | 		.target_residency = 20, | 
 | 609 | 		.enter = &intel_idle, | 
 | 610 | 		.enter_freeze = intel_idle_freeze, }, | 
 | 611 | 	{ | 
 | 612 | 		.name = "C3-SKL", | 
 | 613 | 		.desc = "MWAIT 0x10", | 
 | 614 | 		.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, | 
 | 615 | 		.exit_latency = 70, | 
 | 616 | 		.target_residency = 100, | 
 | 617 | 		.enter = &intel_idle, | 
 | 618 | 		.enter_freeze = intel_idle_freeze, }, | 
 | 619 | 	{ | 
 | 620 | 		.name = "C6-SKL", | 
 | 621 | 		.desc = "MWAIT 0x20", | 
 | 622 | 		.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 135919a | 2015-09-09 13:35:05 -0400 | [diff] [blame] | 623 | 		.exit_latency = 85, | 
| Len Brown | 493f133 | 2015-03-25 23:20:37 -0400 | [diff] [blame] | 624 | 		.target_residency = 200, | 
 | 625 | 		.enter = &intel_idle, | 
 | 626 | 		.enter_freeze = intel_idle_freeze, }, | 
 | 627 | 	{ | 
 | 628 | 		.name = "C7s-SKL", | 
 | 629 | 		.desc = "MWAIT 0x33", | 
 | 630 | 		.flags = MWAIT2flg(0x33) | CPUIDLE_FLAG_TLB_FLUSHED, | 
 | 631 | 		.exit_latency = 124, | 
 | 632 | 		.target_residency = 800, | 
 | 633 | 		.enter = &intel_idle, | 
 | 634 | 		.enter_freeze = intel_idle_freeze, }, | 
 | 635 | 	{ | 
 | 636 | 		.name = "C8-SKL", | 
 | 637 | 		.desc = "MWAIT 0x40", | 
 | 638 | 		.flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 135919a | 2015-09-09 13:35:05 -0400 | [diff] [blame] | 639 | 		.exit_latency = 200, | 
| Len Brown | 493f133 | 2015-03-25 23:20:37 -0400 | [diff] [blame] | 640 | 		.target_residency = 800, | 
 | 641 | 		.enter = &intel_idle, | 
 | 642 | 		.enter_freeze = intel_idle_freeze, }, | 
 | 643 | 	{ | 
| Len Brown | 135919a | 2015-09-09 13:35:05 -0400 | [diff] [blame] | 644 | 		.name = "C9-SKL", | 
 | 645 | 		.desc = "MWAIT 0x50", | 
 | 646 | 		.flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, | 
 | 647 | 		.exit_latency = 480, | 
 | 648 | 		.target_residency = 5000, | 
 | 649 | 		.enter = &intel_idle, | 
 | 650 | 		.enter_freeze = intel_idle_freeze, }, | 
 | 651 | 	{ | 
| Len Brown | 493f133 | 2015-03-25 23:20:37 -0400 | [diff] [blame] | 652 | 		.name = "C10-SKL", | 
 | 653 | 		.desc = "MWAIT 0x60", | 
 | 654 | 		.flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, | 
 | 655 | 		.exit_latency = 890, | 
 | 656 | 		.target_residency = 5000, | 
 | 657 | 		.enter = &intel_idle, | 
 | 658 | 		.enter_freeze = intel_idle_freeze, }, | 
 | 659 | 	{ | 
 | 660 | 		.enter = NULL } | 
 | 661 | }; | 
 | 662 |  | 
| Jiang Liu | ba0dc81 | 2014-01-09 15:30:26 +0800 | [diff] [blame] | 663 | static struct cpuidle_state atom_cstates[] = { | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 664 | 	{ | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 665 | 		.name = "C1E-ATM", | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 666 | 		.desc = "MWAIT 0x00", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 667 | 		.flags = MWAIT2flg(0x00), | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 668 | 		.exit_latency = 10, | 
 | 669 | 		.target_residency = 20, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 670 | 		.enter = &intel_idle, | 
 | 671 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 672 | 	{ | 
| Thomas Renninger | 15e123e | 2011-02-27 22:36:43 +0100 | [diff] [blame] | 673 | 		.name = "C2-ATM", | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 674 | 		.desc = "MWAIT 0x10", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 675 | 		.flags = MWAIT2flg(0x10), | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 676 | 		.exit_latency = 20, | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 677 | 		.target_residency = 80, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 678 | 		.enter = &intel_idle, | 
 | 679 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 680 | 	{ | 
| Thomas Renninger | 15e123e | 2011-02-27 22:36:43 +0100 | [diff] [blame] | 681 | 		.name = "C4-ATM", | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 682 | 		.desc = "MWAIT 0x30", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 683 | 		.flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 684 | 		.exit_latency = 100, | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 685 | 		.target_residency = 400, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 686 | 		.enter = &intel_idle, | 
 | 687 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 688 | 	{ | 
| Thomas Renninger | 15e123e | 2011-02-27 22:36:43 +0100 | [diff] [blame] | 689 | 		.name = "C6-ATM", | 
| Len Brown | 7fcca7d | 2010-10-05 13:43:14 -0400 | [diff] [blame] | 690 | 		.desc = "MWAIT 0x52", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 691 | 		.flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | 7fcca7d | 2010-10-05 13:43:14 -0400 | [diff] [blame] | 692 | 		.exit_latency = 140, | 
| Len Brown | 7fcca7d | 2010-10-05 13:43:14 -0400 | [diff] [blame] | 693 | 		.target_residency = 560, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 694 | 		.enter = &intel_idle, | 
 | 695 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 696 | 	{ | 
 | 697 | 		.enter = NULL } | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 698 | }; | 
| Jiang Liu | 8839099 | 2014-01-09 15:30:27 +0800 | [diff] [blame] | 699 | static struct cpuidle_state avn_cstates[] = { | 
| Len Brown | fab04b2 | 2013-11-09 00:30:17 -0500 | [diff] [blame] | 700 | 	{ | 
 | 701 | 		.name = "C1-AVN", | 
 | 702 | 		.desc = "MWAIT 0x00", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 703 | 		.flags = MWAIT2flg(0x00), | 
| Len Brown | fab04b2 | 2013-11-09 00:30:17 -0500 | [diff] [blame] | 704 | 		.exit_latency = 2, | 
 | 705 | 		.target_residency = 2, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 706 | 		.enter = &intel_idle, | 
 | 707 | 		.enter_freeze = intel_idle_freeze, }, | 
| Len Brown | fab04b2 | 2013-11-09 00:30:17 -0500 | [diff] [blame] | 708 | 	{ | 
 | 709 | 		.name = "C6-AVN", | 
 | 710 | 		.desc = "MWAIT 0x51", | 
| Daniel Lezcano | b82b6cc | 2014-11-12 16:03:50 +0100 | [diff] [blame] | 711 | 		.flags = MWAIT2flg(0x51) | CPUIDLE_FLAG_TLB_FLUSHED, | 
| Len Brown | fab04b2 | 2013-11-09 00:30:17 -0500 | [diff] [blame] | 712 | 		.exit_latency = 15, | 
 | 713 | 		.target_residency = 45, | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 714 | 		.enter = &intel_idle, | 
 | 715 | 		.enter_freeze = intel_idle_freeze, }, | 
| Jiang Liu | 8839099 | 2014-01-09 15:30:27 +0800 | [diff] [blame] | 716 | 	{ | 
 | 717 | 		.enter = NULL } | 
| Len Brown | fab04b2 | 2013-11-09 00:30:17 -0500 | [diff] [blame] | 718 | }; | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 719 |  | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 720 | /** | 
 | 721 |  * intel_idle | 
 | 722 |  * @dev: cpuidle_device | 
| Deepthi Dharwar | 46bcfad | 2011-10-28 16:20:42 +0530 | [diff] [blame] | 723 |  * @drv: cpuidle driver | 
| Deepthi Dharwar | e978aa7 | 2011-10-28 16:20:09 +0530 | [diff] [blame] | 724 |  * @index: index of cpuidle state | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 725 |  * | 
| Yanmin Zhang | 63ff07b | 2012-01-10 15:48:21 -0800 | [diff] [blame] | 726 |  * Must be called under local_irq_disable(). | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 727 |  */ | 
| Deepthi Dharwar | 46bcfad | 2011-10-28 16:20:42 +0530 | [diff] [blame] | 728 | static int intel_idle(struct cpuidle_device *dev, | 
 | 729 | 		struct cpuidle_driver *drv, int index) | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 730 | { | 
 | 731 | 	unsigned long ecx = 1; /* break on interrupt flag */ | 
| Deepthi Dharwar | 46bcfad | 2011-10-28 16:20:42 +0530 | [diff] [blame] | 732 | 	struct cpuidle_state *state = &drv->states[index]; | 
| Len Brown | b1beab4 | 2013-01-31 19:55:37 -0500 | [diff] [blame] | 733 | 	unsigned long eax = flg2MWAIT(state->flags); | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 734 | 	unsigned int cstate; | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 735 | 	int cpu = smp_processor_id(); | 
 | 736 |  | 
 | 737 | 	cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1; | 
 | 738 |  | 
| Suresh Siddha | 6110a1f | 2010-09-30 21:19:07 -0400 | [diff] [blame] | 739 | 	/* | 
| Len Brown | c8381cc | 2010-10-15 20:43:06 -0400 | [diff] [blame] | 740 | 	 * leave_mm() to avoid costly and often unnecessary wakeups | 
 | 741 | 	 * for flushing the user TLB's associated with the active mm. | 
| Suresh Siddha | 6110a1f | 2010-09-30 21:19:07 -0400 | [diff] [blame] | 742 | 	 */ | 
| Len Brown | c8381cc | 2010-10-15 20:43:06 -0400 | [diff] [blame] | 743 | 	if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED) | 
| Suresh Siddha | 6110a1f | 2010-09-30 21:19:07 -0400 | [diff] [blame] | 744 | 		leave_mm(cpu); | 
 | 745 |  | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 746 | 	if (!(lapic_timer_reliable_states & (1 << (cstate)))) | 
| Thomas Gleixner | f6cee19 | 2015-04-03 02:14:23 +0200 | [diff] [blame] | 747 | 		tick_broadcast_enter(); | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 748 |  | 
| Peter Zijlstra | 1682425 | 2013-12-12 15:08:36 +0100 | [diff] [blame] | 749 | 	mwait_idle_with_hints(eax, ecx); | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 750 |  | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 751 | 	if (!(lapic_timer_reliable_states & (1 << (cstate)))) | 
| Thomas Gleixner | f6cee19 | 2015-04-03 02:14:23 +0200 | [diff] [blame] | 752 | 		tick_broadcast_exit(); | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 753 |  | 
| Deepthi Dharwar | e978aa7 | 2011-10-28 16:20:09 +0530 | [diff] [blame] | 754 | 	return index; | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 755 | } | 
 | 756 |  | 
| Rafael J. Wysocki | 5fe2e52 | 2015-02-11 05:04:17 +0100 | [diff] [blame] | 757 | /** | 
 | 758 |  * intel_idle_freeze - simplified "enter" callback routine for suspend-to-idle | 
 | 759 |  * @dev: cpuidle_device | 
 | 760 |  * @drv: cpuidle driver | 
 | 761 |  * @index: state index | 
 | 762 |  */ | 
 | 763 | static void intel_idle_freeze(struct cpuidle_device *dev, | 
 | 764 | 			     struct cpuidle_driver *drv, int index) | 
 | 765 | { | 
 | 766 | 	unsigned long ecx = 1; /* break on interrupt flag */ | 
 | 767 | 	unsigned long eax = flg2MWAIT(drv->states[index].flags); | 
 | 768 |  | 
 | 769 | 	mwait_idle_with_hints(eax, ecx); | 
 | 770 | } | 
 | 771 |  | 
| Shaohua Li | 2a2d31c | 2011-01-10 09:38:12 +0800 | [diff] [blame] | 772 | static void __setup_broadcast_timer(void *arg) | 
 | 773 | { | 
| Thomas Gleixner | 76962ca | 2015-04-03 02:02:34 +0200 | [diff] [blame] | 774 | 	unsigned long on = (unsigned long)arg; | 
| Shaohua Li | 2a2d31c | 2011-01-10 09:38:12 +0800 | [diff] [blame] | 775 |  | 
| Thomas Gleixner | 76962ca | 2015-04-03 02:02:34 +0200 | [diff] [blame] | 776 | 	if (on) | 
 | 777 | 		tick_broadcast_enable(); | 
 | 778 | 	else | 
 | 779 | 		tick_broadcast_disable(); | 
| Shaohua Li | 2a2d31c | 2011-01-10 09:38:12 +0800 | [diff] [blame] | 780 | } | 
 | 781 |  | 
| Daniel Lezcano | 25ac776 | 2012-07-05 15:23:25 +0200 | [diff] [blame] | 782 | static int cpu_hotplug_notify(struct notifier_block *n, | 
 | 783 | 			      unsigned long action, void *hcpu) | 
| Shaohua Li | 2a2d31c | 2011-01-10 09:38:12 +0800 | [diff] [blame] | 784 | { | 
 | 785 | 	int hotcpu = (unsigned long)hcpu; | 
| Daniel Lezcano | 25ac776 | 2012-07-05 15:23:25 +0200 | [diff] [blame] | 786 | 	struct cpuidle_device *dev; | 
| Shaohua Li | 2a2d31c | 2011-01-10 09:38:12 +0800 | [diff] [blame] | 787 |  | 
| Prarit Bhargava | e240145 | 2013-10-23 09:44:51 -0400 | [diff] [blame] | 788 | 	switch (action & ~CPU_TASKS_FROZEN) { | 
| Shaohua Li | 2a2d31c | 2011-01-10 09:38:12 +0800 | [diff] [blame] | 789 | 	case CPU_ONLINE: | 
| Daniel Lezcano | 25ac776 | 2012-07-05 15:23:25 +0200 | [diff] [blame] | 790 |  | 
 | 791 | 		if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) | 
 | 792 | 			smp_call_function_single(hotcpu, __setup_broadcast_timer, | 
 | 793 | 						 (void *)true, 1); | 
 | 794 |  | 
 | 795 | 		/* | 
 | 796 | 		 * Some systems can hotplug a cpu at runtime after | 
 | 797 | 		 * the kernel has booted, we have to initialize the | 
 | 798 | 		 * driver in this case | 
 | 799 | 		 */ | 
 | 800 | 		dev = per_cpu_ptr(intel_idle_cpuidle_devices, hotcpu); | 
 | 801 | 		if (!dev->registered) | 
 | 802 | 			intel_idle_cpu_init(hotcpu); | 
 | 803 |  | 
| Shaohua Li | 2a2d31c | 2011-01-10 09:38:12 +0800 | [diff] [blame] | 804 | 		break; | 
| Shaohua Li | 2a2d31c | 2011-01-10 09:38:12 +0800 | [diff] [blame] | 805 | 	} | 
 | 806 | 	return NOTIFY_OK; | 
 | 807 | } | 
 | 808 |  | 
| Daniel Lezcano | 25ac776 | 2012-07-05 15:23:25 +0200 | [diff] [blame] | 809 | static struct notifier_block cpu_hotplug_notifier = { | 
 | 810 | 	.notifier_call = cpu_hotplug_notify, | 
| Shaohua Li | 2a2d31c | 2011-01-10 09:38:12 +0800 | [diff] [blame] | 811 | }; | 
 | 812 |  | 
| Len Brown | 14796fc | 2011-01-18 20:48:27 -0500 | [diff] [blame] | 813 | static void auto_demotion_disable(void *dummy) | 
 | 814 | { | 
 | 815 | 	unsigned long long msr_bits; | 
 | 816 |  | 
 | 817 | 	rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 818 | 	msr_bits &= ~(icpu->auto_demotion_disable_flags); | 
| Len Brown | 14796fc | 2011-01-18 20:48:27 -0500 | [diff] [blame] | 819 | 	wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); | 
 | 820 | } | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 821 | static void c1e_promotion_disable(void *dummy) | 
 | 822 | { | 
 | 823 | 	unsigned long long msr_bits; | 
 | 824 |  | 
 | 825 | 	rdmsrl(MSR_IA32_POWER_CTL, msr_bits); | 
 | 826 | 	msr_bits &= ~0x2; | 
 | 827 | 	wrmsrl(MSR_IA32_POWER_CTL, msr_bits); | 
 | 828 | } | 
| Len Brown | 14796fc | 2011-01-18 20:48:27 -0500 | [diff] [blame] | 829 |  | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 830 | static const struct idle_cpu idle_cpu_nehalem = { | 
 | 831 | 	.state_table = nehalem_cstates, | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 832 | 	.auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 833 | 	.disable_promotion_to_c1e = true, | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 834 | }; | 
 | 835 |  | 
 | 836 | static const struct idle_cpu idle_cpu_atom = { | 
 | 837 | 	.state_table = atom_cstates, | 
 | 838 | }; | 
 | 839 |  | 
 | 840 | static const struct idle_cpu idle_cpu_lincroft = { | 
 | 841 | 	.state_table = atom_cstates, | 
 | 842 | 	.auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE, | 
 | 843 | }; | 
 | 844 |  | 
 | 845 | static const struct idle_cpu idle_cpu_snb = { | 
 | 846 | 	.state_table = snb_cstates, | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 847 | 	.disable_promotion_to_c1e = true, | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 848 | }; | 
 | 849 |  | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 850 | static const struct idle_cpu idle_cpu_byt = { | 
 | 851 | 	.state_table = byt_cstates, | 
 | 852 | 	.disable_promotion_to_c1e = true, | 
| Len Brown | 8c058d53 | 2014-07-31 15:21:24 -0400 | [diff] [blame] | 853 | 	.byt_auto_demotion_disable_flag = true, | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 854 | }; | 
 | 855 |  | 
| Len Brown | cab07a5 | 2015-03-27 20:54:01 -0400 | [diff] [blame] | 856 | static const struct idle_cpu idle_cpu_cht = { | 
 | 857 | 	.state_table = cht_cstates, | 
 | 858 | 	.disable_promotion_to_c1e = true, | 
 | 859 | 	.byt_auto_demotion_disable_flag = true, | 
 | 860 | }; | 
 | 861 |  | 
| Len Brown | 6edab08 | 2012-06-01 19:45:32 -0400 | [diff] [blame] | 862 | static const struct idle_cpu idle_cpu_ivb = { | 
 | 863 | 	.state_table = ivb_cstates, | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 864 | 	.disable_promotion_to_c1e = true, | 
| Len Brown | 6edab08 | 2012-06-01 19:45:32 -0400 | [diff] [blame] | 865 | }; | 
 | 866 |  | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 867 | static const struct idle_cpu idle_cpu_ivt = { | 
 | 868 | 	.state_table = ivt_cstates, | 
 | 869 | 	.disable_promotion_to_c1e = true, | 
 | 870 | }; | 
 | 871 |  | 
| Len Brown | 85a4d2d | 2013-01-31 14:40:49 -0500 | [diff] [blame] | 872 | static const struct idle_cpu idle_cpu_hsw = { | 
 | 873 | 	.state_table = hsw_cstates, | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 874 | 	.disable_promotion_to_c1e = true, | 
| Len Brown | 85a4d2d | 2013-01-31 14:40:49 -0500 | [diff] [blame] | 875 | }; | 
 | 876 |  | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 877 | static const struct idle_cpu idle_cpu_bdw = { | 
 | 878 | 	.state_table = bdw_cstates, | 
 | 879 | 	.disable_promotion_to_c1e = true, | 
 | 880 | }; | 
 | 881 |  | 
| Len Brown | 493f133 | 2015-03-25 23:20:37 -0400 | [diff] [blame] | 882 | static const struct idle_cpu idle_cpu_skl = { | 
 | 883 | 	.state_table = skl_cstates, | 
 | 884 | 	.disable_promotion_to_c1e = true, | 
 | 885 | }; | 
 | 886 |  | 
 | 887 |  | 
| Len Brown | fab04b2 | 2013-11-09 00:30:17 -0500 | [diff] [blame] | 888 | static const struct idle_cpu idle_cpu_avn = { | 
 | 889 | 	.state_table = avn_cstates, | 
 | 890 | 	.disable_promotion_to_c1e = true, | 
 | 891 | }; | 
 | 892 |  | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 893 | #define ICPU(model, cpu) \ | 
 | 894 | 	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu } | 
 | 895 |  | 
| Mathias Krause | d5cdc3c | 2015-03-25 22:15:14 +0100 | [diff] [blame] | 896 | static const struct x86_cpu_id intel_idle_ids[] __initconst = { | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 897 | 	ICPU(0x1a, idle_cpu_nehalem), | 
 | 898 | 	ICPU(0x1e, idle_cpu_nehalem), | 
 | 899 | 	ICPU(0x1f, idle_cpu_nehalem), | 
| Ben Hutchings | 8bf1193 | 2012-02-16 04:13:14 +0000 | [diff] [blame] | 900 | 	ICPU(0x25, idle_cpu_nehalem), | 
 | 901 | 	ICPU(0x2c, idle_cpu_nehalem), | 
 | 902 | 	ICPU(0x2e, idle_cpu_nehalem), | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 903 | 	ICPU(0x1c, idle_cpu_atom), | 
 | 904 | 	ICPU(0x26, idle_cpu_lincroft), | 
| Ben Hutchings | 8bf1193 | 2012-02-16 04:13:14 +0000 | [diff] [blame] | 905 | 	ICPU(0x2f, idle_cpu_nehalem), | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 906 | 	ICPU(0x2a, idle_cpu_snb), | 
 | 907 | 	ICPU(0x2d, idle_cpu_snb), | 
| Jan Kiszka | acead1b | 2014-01-25 22:24:22 +0100 | [diff] [blame] | 908 | 	ICPU(0x36, idle_cpu_atom), | 
| Len Brown | 718987d | 2014-02-14 02:30:00 -0500 | [diff] [blame] | 909 | 	ICPU(0x37, idle_cpu_byt), | 
| Len Brown | cab07a5 | 2015-03-27 20:54:01 -0400 | [diff] [blame] | 910 | 	ICPU(0x4c, idle_cpu_cht), | 
| Len Brown | 6edab08 | 2012-06-01 19:45:32 -0400 | [diff] [blame] | 911 | 	ICPU(0x3a, idle_cpu_ivb), | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 912 | 	ICPU(0x3e, idle_cpu_ivt), | 
| Len Brown | 85a4d2d | 2013-01-31 14:40:49 -0500 | [diff] [blame] | 913 | 	ICPU(0x3c, idle_cpu_hsw), | 
 | 914 | 	ICPU(0x3f, idle_cpu_hsw), | 
 | 915 | 	ICPU(0x45, idle_cpu_hsw), | 
| Len Brown | 0b15841 | 2013-03-15 10:55:31 -0400 | [diff] [blame] | 916 | 	ICPU(0x46, idle_cpu_hsw), | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 917 | 	ICPU(0x4d, idle_cpu_avn), | 
 | 918 | 	ICPU(0x3d, idle_cpu_bdw), | 
| Len Brown | bea5707 | 2015-02-10 15:42:03 -0500 | [diff] [blame] | 919 | 	ICPU(0x47, idle_cpu_bdw), | 
| Len Brown | a138b56 | 2014-02-04 23:56:40 -0500 | [diff] [blame] | 920 | 	ICPU(0x4f, idle_cpu_bdw), | 
 | 921 | 	ICPU(0x56, idle_cpu_bdw), | 
| Len Brown | 493f133 | 2015-03-25 23:20:37 -0400 | [diff] [blame] | 922 | 	ICPU(0x4e, idle_cpu_skl), | 
 | 923 | 	ICPU(0x5e, idle_cpu_skl), | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 924 | 	{} | 
 | 925 | }; | 
 | 926 | MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); | 
 | 927 |  | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 928 | /* | 
 | 929 |  * intel_idle_probe() | 
 | 930 |  */ | 
| Bartlomiej Zolnierkiewicz | 00f3e75 | 2013-08-30 12:27:45 +0200 | [diff] [blame] | 931 | static int __init intel_idle_probe(void) | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 932 | { | 
| Len Brown | c423628 | 2010-05-28 02:22:03 -0400 | [diff] [blame] | 933 | 	unsigned int eax, ebx, ecx; | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 934 | 	const struct x86_cpu_id *id; | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 935 |  | 
 | 936 | 	if (max_cstate == 0) { | 
 | 937 | 		pr_debug(PREFIX "disabled\n"); | 
 | 938 | 		return -EPERM; | 
 | 939 | 	} | 
 | 940 |  | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 941 | 	id = x86_match_cpu(intel_idle_ids); | 
 | 942 | 	if (!id) { | 
 | 943 | 		if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | 
 | 944 | 		    boot_cpu_data.x86 == 6) | 
 | 945 | 			pr_debug(PREFIX "does not run on family %d model %d\n", | 
 | 946 | 				boot_cpu_data.x86, boot_cpu_data.x86_model); | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 947 | 		return -ENODEV; | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 948 | 	} | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 949 |  | 
 | 950 | 	if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) | 
 | 951 | 		return -ENODEV; | 
 | 952 |  | 
| Len Brown | c423628 | 2010-05-28 02:22:03 -0400 | [diff] [blame] | 953 | 	cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates); | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 954 |  | 
 | 955 | 	if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || | 
| Thomas Renninger | 5c2a9f0 | 2011-12-04 22:17:29 +0100 | [diff] [blame] | 956 | 	    !(ecx & CPUID5_ECX_INTERRUPT_BREAK) || | 
 | 957 | 	    !mwait_substates) | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 958 | 			return -ENODEV; | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 959 |  | 
| Len Brown | c423628 | 2010-05-28 02:22:03 -0400 | [diff] [blame] | 960 | 	pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 961 |  | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 962 | 	icpu = (const struct idle_cpu *)id->driver_data; | 
 | 963 | 	cpuidle_state_table = icpu->state_table; | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 964 |  | 
| Len Brown | 56b9aea | 2010-12-02 01:19:32 -0500 | [diff] [blame] | 965 | 	if (boot_cpu_has(X86_FEATURE_ARAT))	/* Always Reliable APIC Timer */ | 
| Shaohua Li | 2a2d31c | 2011-01-10 09:38:12 +0800 | [diff] [blame] | 966 | 		lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE; | 
| Daniel Lezcano | 25ac776 | 2012-07-05 15:23:25 +0200 | [diff] [blame] | 967 | 	else | 
| Shaohua Li | 39a74fd | 2012-01-10 15:48:19 -0800 | [diff] [blame] | 968 | 		on_each_cpu(__setup_broadcast_timer, (void *)true, 1); | 
| Daniel Lezcano | 25ac776 | 2012-07-05 15:23:25 +0200 | [diff] [blame] | 969 |  | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 970 | 	pr_debug(PREFIX "v" INTEL_IDLE_VERSION | 
 | 971 | 		" model 0x%X\n", boot_cpu_data.x86_model); | 
 | 972 |  | 
 | 973 | 	pr_debug(PREFIX "lapic_timer_reliable_states 0x%x\n", | 
 | 974 | 		lapic_timer_reliable_states); | 
 | 975 | 	return 0; | 
 | 976 | } | 
 | 977 |  | 
 | 978 | /* | 
 | 979 |  * intel_idle_cpuidle_devices_uninit() | 
 | 980 |  * unregister, free cpuidle_devices | 
 | 981 |  */ | 
 | 982 | static void intel_idle_cpuidle_devices_uninit(void) | 
 | 983 | { | 
 | 984 | 	int i; | 
 | 985 | 	struct cpuidle_device *dev; | 
 | 986 |  | 
 | 987 | 	for_each_online_cpu(i) { | 
 | 988 | 		dev = per_cpu_ptr(intel_idle_cpuidle_devices, i); | 
 | 989 | 		cpuidle_unregister_device(dev); | 
 | 990 | 	} | 
 | 991 |  | 
 | 992 | 	free_percpu(intel_idle_cpuidle_devices); | 
 | 993 | 	return; | 
 | 994 | } | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 995 |  | 
 | 996 | /* | 
 | 997 |  * intel_idle_state_table_update() | 
 | 998 |  * | 
 | 999 |  * Update the default state_table for this CPU-id | 
 | 1000 |  * | 
 | 1001 |  * Currently used to access tuned IVT multi-socket targets | 
 | 1002 |  * Assumption: num_sockets == (max_package_num + 1) | 
 | 1003 |  */ | 
 | 1004 | void intel_idle_state_table_update(void) | 
 | 1005 | { | 
 | 1006 | 	/* IVT uses a different table for 1-2, 3-4, and > 4 sockets */ | 
 | 1007 | 	if (boot_cpu_data.x86_model == 0x3e) { /* IVT */ | 
 | 1008 | 		int cpu, package_num, num_sockets = 1; | 
 | 1009 |  | 
 | 1010 | 		for_each_online_cpu(cpu) { | 
 | 1011 | 			package_num = topology_physical_package_id(cpu); | 
 | 1012 | 			if (package_num + 1 > num_sockets) { | 
 | 1013 | 				num_sockets = package_num + 1; | 
 | 1014 |  | 
| Christoph Jaeger | d27dca4 | 2014-04-12 19:57:30 +0200 | [diff] [blame] | 1015 | 				if (num_sockets > 4) { | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 1016 | 					cpuidle_state_table = ivt_cstates_8s; | 
 | 1017 | 					return; | 
| Christoph Jaeger | d27dca4 | 2014-04-12 19:57:30 +0200 | [diff] [blame] | 1018 | 				} | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 1019 | 			} | 
 | 1020 | 		} | 
 | 1021 |  | 
 | 1022 | 		if (num_sockets > 2) | 
 | 1023 | 			cpuidle_state_table = ivt_cstates_4s; | 
 | 1024 | 		/* else, 1 and 2 socket systems use default ivt_cstates */ | 
 | 1025 | 	} | 
 | 1026 | 	return; | 
 | 1027 | } | 
 | 1028 |  | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1029 | /* | 
| Deepthi Dharwar | 46bcfad | 2011-10-28 16:20:42 +0530 | [diff] [blame] | 1030 |  * intel_idle_cpuidle_driver_init() | 
 | 1031 |  * allocate, initialize cpuidle_states | 
 | 1032 |  */ | 
| Bartlomiej Zolnierkiewicz | 00f3e75 | 2013-08-30 12:27:45 +0200 | [diff] [blame] | 1033 | static int __init intel_idle_cpuidle_driver_init(void) | 
| Deepthi Dharwar | 46bcfad | 2011-10-28 16:20:42 +0530 | [diff] [blame] | 1034 | { | 
 | 1035 | 	int cstate; | 
 | 1036 | 	struct cpuidle_driver *drv = &intel_idle_driver; | 
 | 1037 |  | 
| Len Brown | 0138d8f | 2014-04-04 01:21:07 -0400 | [diff] [blame] | 1038 | 	intel_idle_state_table_update(); | 
 | 1039 |  | 
| Deepthi Dharwar | 46bcfad | 2011-10-28 16:20:42 +0530 | [diff] [blame] | 1040 | 	drv->state_count = 1; | 
 | 1041 |  | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 1042 | 	for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) { | 
| Len Brown | 24bfa95 | 2014-02-14 00:50:34 -0500 | [diff] [blame] | 1043 | 		int num_substates, mwait_hint, mwait_cstate; | 
| Deepthi Dharwar | 46bcfad | 2011-10-28 16:20:42 +0530 | [diff] [blame] | 1044 |  | 
| Len Brown | 7dd0e0a | 2015-05-27 17:11:37 -0400 | [diff] [blame] | 1045 | 		if ((cpuidle_state_table[cstate].enter == NULL) && | 
 | 1046 | 		    (cpuidle_state_table[cstate].enter_freeze == NULL)) | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 1047 | 			break; | 
 | 1048 |  | 
 | 1049 | 		if (cstate + 1 > max_cstate) { | 
| Deepthi Dharwar | 46bcfad | 2011-10-28 16:20:42 +0530 | [diff] [blame] | 1050 | 			printk(PREFIX "max_cstate %d reached\n", | 
 | 1051 | 				max_cstate); | 
 | 1052 | 			break; | 
 | 1053 | 		} | 
 | 1054 |  | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 1055 | 		mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags); | 
 | 1056 | 		mwait_cstate = MWAIT_HINT2CSTATE(mwait_hint); | 
| Deepthi Dharwar | 46bcfad | 2011-10-28 16:20:42 +0530 | [diff] [blame] | 1057 |  | 
| Len Brown | 24bfa95 | 2014-02-14 00:50:34 -0500 | [diff] [blame] | 1058 | 		/* number of sub-states for this state in CPUID.MWAIT */ | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 1059 | 		num_substates = (mwait_substates >> ((mwait_cstate + 1) * 4)) | 
 | 1060 | 					& MWAIT_SUBSTATE_MASK; | 
 | 1061 |  | 
| Len Brown | 24bfa95 | 2014-02-14 00:50:34 -0500 | [diff] [blame] | 1062 | 		/* if NO sub-states for this state in CPUID, skip it */ | 
 | 1063 | 		if (num_substates == 0) | 
| Len Brown | e022e7e | 2013-02-01 23:37:30 -0500 | [diff] [blame] | 1064 | 			continue; | 
 | 1065 |  | 
 | 1066 | 		if (((mwait_cstate + 1) > 2) && | 
| Deepthi Dharwar | 46bcfad | 2011-10-28 16:20:42 +0530 | [diff] [blame] | 1067 | 			!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) | 
 | 1068 | 			mark_tsc_unstable("TSC halts in idle" | 
 | 1069 | 					" states deeper than C2"); | 
 | 1070 |  | 
 | 1071 | 		drv->states[drv->state_count] =	/* structure copy */ | 
 | 1072 | 			cpuidle_state_table[cstate]; | 
 | 1073 |  | 
 | 1074 | 		drv->state_count += 1; | 
 | 1075 | 	} | 
 | 1076 |  | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 1077 | 	if (icpu->auto_demotion_disable_flags) | 
| Shaohua Li | 39a74fd | 2012-01-10 15:48:19 -0800 | [diff] [blame] | 1078 | 		on_each_cpu(auto_demotion_disable, NULL, 1); | 
| Deepthi Dharwar | 46bcfad | 2011-10-28 16:20:42 +0530 | [diff] [blame] | 1079 |  | 
| Len Brown | 8c058d53 | 2014-07-31 15:21:24 -0400 | [diff] [blame] | 1080 | 	if (icpu->byt_auto_demotion_disable_flag) { | 
 | 1081 | 		wrmsrl(MSR_CC6_DEMOTION_POLICY_CONFIG, 0); | 
 | 1082 | 		wrmsrl(MSR_MC6_DEMOTION_POLICY_CONFIG, 0); | 
 | 1083 | 	} | 
 | 1084 |  | 
| Len Brown | 32e9518 | 2013-02-02 01:31:56 -0500 | [diff] [blame] | 1085 | 	if (icpu->disable_promotion_to_c1e)	/* each-cpu is redundant */ | 
 | 1086 | 		on_each_cpu(c1e_promotion_disable, NULL, 1); | 
 | 1087 |  | 
| Deepthi Dharwar | 46bcfad | 2011-10-28 16:20:42 +0530 | [diff] [blame] | 1088 | 	return 0; | 
 | 1089 | } | 
 | 1090 |  | 
 | 1091 |  | 
 | 1092 | /* | 
| Thomas Renninger | 65b7f83 | 2012-01-17 22:40:08 +0100 | [diff] [blame] | 1093 |  * intel_idle_cpu_init() | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1094 |  * allocate, initialize, register cpuidle_devices | 
| Thomas Renninger | 65b7f83 | 2012-01-17 22:40:08 +0100 | [diff] [blame] | 1095 |  * @cpu: cpu/core to initialize | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1096 |  */ | 
| Daniel Lezcano | 25ac776 | 2012-07-05 15:23:25 +0200 | [diff] [blame] | 1097 | static int intel_idle_cpu_init(int cpu) | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1098 | { | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1099 | 	struct cpuidle_device *dev; | 
 | 1100 |  | 
| Thomas Renninger | 65b7f83 | 2012-01-17 22:40:08 +0100 | [diff] [blame] | 1101 | 	dev = per_cpu_ptr(intel_idle_cpuidle_devices, cpu); | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1102 |  | 
| Thomas Renninger | 65b7f83 | 2012-01-17 22:40:08 +0100 | [diff] [blame] | 1103 | 	dev->cpu = cpu; | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1104 |  | 
| Thomas Renninger | 65b7f83 | 2012-01-17 22:40:08 +0100 | [diff] [blame] | 1105 | 	if (cpuidle_register_device(dev)) { | 
 | 1106 | 		pr_debug(PREFIX "cpuidle_register_device %d failed!\n", cpu); | 
 | 1107 | 		intel_idle_cpuidle_devices_uninit(); | 
 | 1108 | 		return -EIO; | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1109 | 	} | 
 | 1110 |  | 
| Andi Kleen | b66b8b9 | 2012-01-26 00:09:07 +0100 | [diff] [blame] | 1111 | 	if (icpu->auto_demotion_disable_flags) | 
| Thomas Renninger | 65b7f83 | 2012-01-17 22:40:08 +0100 | [diff] [blame] | 1112 | 		smp_call_function_single(cpu, auto_demotion_disable, NULL, 1); | 
 | 1113 |  | 
| Bartlomiej Zolnierkiewicz | dbf87ab | 2013-12-20 19:47:28 +0100 | [diff] [blame] | 1114 | 	if (icpu->disable_promotion_to_c1e) | 
 | 1115 | 		smp_call_function_single(cpu, c1e_promotion_disable, NULL, 1); | 
 | 1116 |  | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1117 | 	return 0; | 
 | 1118 | } | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1119 |  | 
 | 1120 | static int __init intel_idle_init(void) | 
 | 1121 | { | 
| Thomas Renninger | 65b7f83 | 2012-01-17 22:40:08 +0100 | [diff] [blame] | 1122 | 	int retval, i; | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1123 |  | 
| Thomas Renninger | d189604 | 2010-11-03 17:06:14 +0100 | [diff] [blame] | 1124 | 	/* Do not load intel_idle at all for now if idle= is passed */ | 
 | 1125 | 	if (boot_option_idle_override != IDLE_NO_OVERRIDE) | 
 | 1126 | 		return -ENODEV; | 
 | 1127 |  | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1128 | 	retval = intel_idle_probe(); | 
 | 1129 | 	if (retval) | 
 | 1130 | 		return retval; | 
 | 1131 |  | 
| Deepthi Dharwar | 46bcfad | 2011-10-28 16:20:42 +0530 | [diff] [blame] | 1132 | 	intel_idle_cpuidle_driver_init(); | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1133 | 	retval = cpuidle_register_driver(&intel_idle_driver); | 
 | 1134 | 	if (retval) { | 
| Konrad Rzeszutek Wilk | 3735d52 | 2012-08-16 22:06:55 +0200 | [diff] [blame] | 1135 | 		struct cpuidle_driver *drv = cpuidle_get_driver(); | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1136 | 		printk(KERN_DEBUG PREFIX "intel_idle yielding to %s", | 
| Konrad Rzeszutek Wilk | 3735d52 | 2012-08-16 22:06:55 +0200 | [diff] [blame] | 1137 | 			drv ? drv->name : "none"); | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1138 | 		return retval; | 
 | 1139 | 	} | 
 | 1140 |  | 
| Thomas Renninger | 65b7f83 | 2012-01-17 22:40:08 +0100 | [diff] [blame] | 1141 | 	intel_idle_cpuidle_devices = alloc_percpu(struct cpuidle_device); | 
 | 1142 | 	if (intel_idle_cpuidle_devices == NULL) | 
 | 1143 | 		return -ENOMEM; | 
 | 1144 |  | 
| Srivatsa S. Bhat | 07494d5 | 2014-03-11 02:10:30 +0530 | [diff] [blame] | 1145 | 	cpu_notifier_register_begin(); | 
 | 1146 |  | 
| Thomas Renninger | 65b7f83 | 2012-01-17 22:40:08 +0100 | [diff] [blame] | 1147 | 	for_each_online_cpu(i) { | 
 | 1148 | 		retval = intel_idle_cpu_init(i); | 
 | 1149 | 		if (retval) { | 
| Srivatsa S. Bhat | 07494d5 | 2014-03-11 02:10:30 +0530 | [diff] [blame] | 1150 | 			cpu_notifier_register_done(); | 
| Thomas Renninger | 65b7f83 | 2012-01-17 22:40:08 +0100 | [diff] [blame] | 1151 | 			cpuidle_unregister_driver(&intel_idle_driver); | 
 | 1152 | 			return retval; | 
 | 1153 | 		} | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1154 | 	} | 
| Srivatsa S. Bhat | 07494d5 | 2014-03-11 02:10:30 +0530 | [diff] [blame] | 1155 | 	__register_cpu_notifier(&cpu_hotplug_notifier); | 
 | 1156 |  | 
 | 1157 | 	cpu_notifier_register_done(); | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1158 |  | 
 | 1159 | 	return 0; | 
 | 1160 | } | 
 | 1161 |  | 
 | 1162 | static void __exit intel_idle_exit(void) | 
 | 1163 | { | 
 | 1164 | 	intel_idle_cpuidle_devices_uninit(); | 
 | 1165 | 	cpuidle_unregister_driver(&intel_idle_driver); | 
 | 1166 |  | 
| Srivatsa S. Bhat | 07494d5 | 2014-03-11 02:10:30 +0530 | [diff] [blame] | 1167 | 	cpu_notifier_register_begin(); | 
| Daniel Lezcano | 25ac776 | 2012-07-05 15:23:25 +0200 | [diff] [blame] | 1168 |  | 
 | 1169 | 	if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) | 
| Shaohua Li | 39a74fd | 2012-01-10 15:48:19 -0800 | [diff] [blame] | 1170 | 		on_each_cpu(__setup_broadcast_timer, (void *)false, 1); | 
| Srivatsa S. Bhat | 07494d5 | 2014-03-11 02:10:30 +0530 | [diff] [blame] | 1171 | 	__unregister_cpu_notifier(&cpu_hotplug_notifier); | 
 | 1172 |  | 
 | 1173 | 	cpu_notifier_register_done(); | 
| Shaohua Li | 2a2d31c | 2011-01-10 09:38:12 +0800 | [diff] [blame] | 1174 |  | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1175 | 	return; | 
 | 1176 | } | 
 | 1177 |  | 
 | 1178 | module_init(intel_idle_init); | 
 | 1179 | module_exit(intel_idle_exit); | 
 | 1180 |  | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1181 | module_param(max_cstate, int, 0444); | 
| Len Brown | 2671717 | 2010-03-08 14:07:30 -0500 | [diff] [blame] | 1182 |  | 
 | 1183 | MODULE_AUTHOR("Len Brown <len.brown@intel.com>"); | 
 | 1184 | MODULE_DESCRIPTION("Cpuidle driver for Intel Hardware v" INTEL_IDLE_VERSION); | 
 | 1185 | MODULE_LICENSE("GPL"); |