1 /* 2 * processor_throttling.c - Throttling submodule of the ACPI processor driver 3 * 4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 6 * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de> 7 * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> 8 * - Added processor hotplug support 9 * 10 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 2 of the License, or (at 15 * your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, but 18 * WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 * General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License along 23 * with this program; if not, write to the Free Software Foundation, Inc., 24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 25 * 26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 27 */ 28 29 #include <linux/kernel.h> 30 #include <linux/module.h> 31 #include <linux/init.h> 32 #include <linux/cpufreq.h> 33 #include <linux/proc_fs.h> 34 #include <linux/seq_file.h> 35 36 #include <asm/io.h> 37 #include <asm/uaccess.h> 38 39 #include <acpi/acpi_bus.h> 40 #include <acpi/processor.h> 41 42 #define ACPI_PROCESSOR_COMPONENT 0x01000000 43 #define ACPI_PROCESSOR_CLASS "processor" 44 #define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver" 45 #define _COMPONENT ACPI_PROCESSOR_COMPONENT 46 ACPI_MODULE_NAME ("acpi_processor") 47 48 49 /* -------------------------------------------------------------------------- 50 Throttling Control 51 -------------------------------------------------------------------------- */ 52 53 static int 54 acpi_processor_get_throttling ( 55 struct acpi_processor *pr) 56 { 57 int state = 0; 58 u32 value = 0; 59 u32 duty_mask = 0; 60 u32 duty_value = 0; 61 62 ACPI_FUNCTION_TRACE("acpi_processor_get_throttling"); 63 64 if (!pr) 65 return_VALUE(-EINVAL); 66 67 if (!pr->flags.throttling) 68 return_VALUE(-ENODEV); 69 70 pr->throttling.state = 0; 71 72 duty_mask = pr->throttling.state_count - 1; 73 74 duty_mask <<= pr->throttling.duty_offset; 75 76 local_irq_disable(); 77 78 value = inl(pr->throttling.address); 79 80 /* 81 * Compute the current throttling state when throttling is enabled 82 * (bit 4 is on). 83 */ 84 if (value & 0x10) { 85 duty_value = value & duty_mask; 86 duty_value >>= pr->throttling.duty_offset; 87 88 if (duty_value) 89 state = pr->throttling.state_count-duty_value; 90 } 91 92 pr->throttling.state = state; 93 94 local_irq_enable(); 95 96 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 97 "Throttling state is T%d (%d%% throttling applied)\n", 98 state, pr->throttling.states[state].performance)); 99 100 return_VALUE(0); 101 } 102 103 104 int acpi_processor_set_throttling ( 105 struct acpi_processor *pr, 106 int state) 107 { 108 u32 value = 0; 109 u32 duty_mask = 0; 110 u32 duty_value = 0; 111 112 ACPI_FUNCTION_TRACE("acpi_processor_set_throttling"); 113 114 if (!pr) 115 return_VALUE(-EINVAL); 116 117 if ((state < 0) || (state > (pr->throttling.state_count - 1))) 118 return_VALUE(-EINVAL); 119 120 if (!pr->flags.throttling) 121 return_VALUE(-ENODEV); 122 123 if (state == pr->throttling.state) 124 return_VALUE(0); 125 126 /* 127 * Calculate the duty_value and duty_mask. 128 */ 129 if (state) { 130 duty_value = pr->throttling.state_count - state; 131 132 duty_value <<= pr->throttling.duty_offset; 133 134 /* Used to clear all duty_value bits */ 135 duty_mask = pr->throttling.state_count - 1; 136 137 duty_mask <<= acpi_fadt.duty_offset; 138 duty_mask = ~duty_mask; 139 } 140 141 local_irq_disable(); 142 143 /* 144 * Disable throttling by writing a 0 to bit 4. Note that we must 145 * turn it off before you can change the duty_value. 146 */ 147 value = inl(pr->throttling.address); 148 if (value & 0x10) { 149 value &= 0xFFFFFFEF; 150 outl(value, pr->throttling.address); 151 } 152 153 /* 154 * Write the new duty_value and then enable throttling. Note 155 * that a state value of 0 leaves throttling disabled. 156 */ 157 if (state) { 158 value &= duty_mask; 159 value |= duty_value; 160 outl(value, pr->throttling.address); 161 162 value |= 0x00000010; 163 outl(value, pr->throttling.address); 164 } 165 166 pr->throttling.state = state; 167 168 local_irq_enable(); 169 170 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 171 "Throttling state set to T%d (%d%%)\n", state, 172 (pr->throttling.states[state].performance?pr->throttling.states[state].performance/10:0))); 173 174 return_VALUE(0); 175 } 176 177 178 int 179 acpi_processor_get_throttling_info ( 180 struct acpi_processor *pr) 181 { 182 int result = 0; 183 int step = 0; 184 int i = 0; 185 186 ACPI_FUNCTION_TRACE("acpi_processor_get_throttling_info"); 187 188 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 189 "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n", 190 pr->throttling.address, 191 pr->throttling.duty_offset, 192 pr->throttling.duty_width)); 193 194 if (!pr) 195 return_VALUE(-EINVAL); 196 197 /* TBD: Support ACPI 2.0 objects */ 198 199 if (!pr->throttling.address) { 200 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n")); 201 return_VALUE(0); 202 } 203 else if (!pr->throttling.duty_width) { 204 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n")); 205 return_VALUE(0); 206 } 207 /* TBD: Support duty_cycle values that span bit 4. */ 208 else if ((pr->throttling.duty_offset 209 + pr->throttling.duty_width) > 4) { 210 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "duty_cycle spans bit 4\n")); 211 return_VALUE(0); 212 } 213 214 /* 215 * PIIX4 Errata: We don't support throttling on the original PIIX4. 216 * This shouldn't be an issue as few (if any) mobile systems ever 217 * used this part. 218 */ 219 if (errata.piix4.throttle) { 220 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 221 "Throttling not supported on PIIX4 A- or B-step\n")); 222 return_VALUE(0); 223 } 224 225 pr->throttling.state_count = 1 << acpi_fadt.duty_width; 226 227 /* 228 * Compute state values. Note that throttling displays a linear power/ 229 * performance relationship (at 50% performance the CPU will consume 230 * 50% power). Values are in 1/10th of a percent to preserve accuracy. 231 */ 232 233 step = (1000 / pr->throttling.state_count); 234 235 for (i=0; i<pr->throttling.state_count; i++) { 236 pr->throttling.states[i].performance = step * i; 237 pr->throttling.states[i].power = step * i; 238 } 239 240 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n", 241 pr->throttling.state_count)); 242 243 pr->flags.throttling = 1; 244 245 /* 246 * Disable throttling (if enabled). We'll let subsequent policy (e.g. 247 * thermal) decide to lower performance if it so chooses, but for now 248 * we'll crank up the speed. 249 */ 250 251 result = acpi_processor_get_throttling(pr); 252 if (result) 253 goto end; 254 255 if (pr->throttling.state) { 256 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabling throttling (was T%d)\n", 257 pr->throttling.state)); 258 result = acpi_processor_set_throttling(pr, 0); 259 if (result) 260 goto end; 261 } 262 263 end: 264 if (result) 265 pr->flags.throttling = 0; 266 267 return_VALUE(result); 268 } 269 270 271 /* proc interface */ 272 273 static int acpi_processor_throttling_seq_show(struct seq_file *seq, void *offset) 274 { 275 struct acpi_processor *pr = (struct acpi_processor *)seq->private; 276 int i = 0; 277 int result = 0; 278 279 ACPI_FUNCTION_TRACE("acpi_processor_throttling_seq_show"); 280 281 if (!pr) 282 goto end; 283 284 if (!(pr->throttling.state_count > 0)) { 285 seq_puts(seq, "<not supported>\n"); 286 goto end; 287 } 288 289 result = acpi_processor_get_throttling(pr); 290 291 if (result) { 292 seq_puts(seq, "Could not determine current throttling state.\n"); 293 goto end; 294 } 295 296 seq_printf(seq, "state count: %d\n" 297 "active state: T%d\n", 298 pr->throttling.state_count, 299 pr->throttling.state); 300 301 seq_puts(seq, "states:\n"); 302 for (i = 0; i < pr->throttling.state_count; i++) 303 seq_printf(seq, " %cT%d: %02d%%\n", 304 (i == pr->throttling.state?'*':' '), i, 305 (pr->throttling.states[i].performance?pr->throttling.states[i].performance/10:0)); 306 307 end: 308 return_VALUE(0); 309 } 310 311 static int acpi_processor_throttling_open_fs(struct inode *inode, struct file *file) 312 { 313 return single_open(file, acpi_processor_throttling_seq_show, 314 PDE(inode)->data); 315 } 316 317 ssize_t acpi_processor_write_throttling ( 318 struct file *file, 319 const char __user *buffer, 320 size_t count, 321 loff_t *data) 322 { 323 int result = 0; 324 struct seq_file *m = (struct seq_file *)file->private_data; 325 struct acpi_processor *pr = (struct acpi_processor *)m->private; 326 char state_string[12] = {'\0'}; 327 328 ACPI_FUNCTION_TRACE("acpi_processor_write_throttling"); 329 330 if (!pr || (count > sizeof(state_string) - 1)) 331 return_VALUE(-EINVAL); 332 333 if (copy_from_user(state_string, buffer, count)) 334 return_VALUE(-EFAULT); 335 336 state_string[count] = '\0'; 337 338 result = acpi_processor_set_throttling(pr, 339 simple_strtoul(state_string, NULL, 0)); 340 if (result) 341 return_VALUE(result); 342 343 return_VALUE(count); 344 } 345 346 struct file_operations acpi_processor_throttling_fops = { 347 .open = acpi_processor_throttling_open_fs, 348 .read = seq_read, 349 .llseek = seq_lseek, 350 .release = single_release, 351 }; 352