2 * cpufreq driver for Enhanced SpeedStep, as found in Intel's Pentium
3 * M (part of the Centrino chipset).
5 * Despite the "SpeedStep" in the name, this is almost entirely unlike
6 * traditional SpeedStep.
8 * Modelled on speedstep.c
10 * Copyright (C) 2003 Jeremy Fitzhardinge <jeremy@goop.org>
12 * WARNING WARNING WARNING
14 * This driver manipulates the PERF_CTL MSR, which is only somewhat
15 * documented. While it seems to work on my laptop, it has not been
16 * tested anywhere else, and it may not work for you, do strange
17 * things or simply crash.
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/init.h>
23 #include <linux/cpufreq.h>
24 #include <linux/config.h>
27 #include <asm/processor.h>
28 #include <asm/cpufeature.h>
30 #define PFX "speedstep-centrino: "
31 #define MAINTAINER "Jeremy Fitzhardinge <jeremy@goop.org>"
33 /*#define CENTRINO_DEBUG*/
36 #define dprintk(msg...) printk(msg)
38 #define dprintk(msg...) do { } while(0)
43 const char *model_name;
44 unsigned max_freq; /* max clock in kHz */
46 struct cpufreq_frequency_table *op_points; /* clock/voltage pairs */
49 /* Operating points for current CPU */
50 static struct cpu_model *centrino_model;
52 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE
54 /* Computes the correct form for IA32_PERF_CTL MSR for a particular
55 frequency/voltage operating point; frequency in MHz, volts in mV.
56 This is stored as "index" in the structure. */
59 .frequency = (mhz) * 1000, \
60 .index = (((mhz)/100) << 8) | ((mv - 700) / 16) \
64 * These voltage tables were derived from the Intel Pentium M
65 * datasheet, document 25261202.pdf, Table 5. I have verified they
66 * are consistent with my IBM ThinkPad X31, which has a 1.3GHz Pentium
70 /* Ultra Low Voltage Intel Pentium M processor 900MHz */
71 static struct cpufreq_frequency_table op_900[] =
76 { .frequency = CPUFREQ_TABLE_END }
79 /* Ultra Low Voltage Intel Pentium M processor 1000MHz */
80 static struct cpufreq_frequency_table op_1000[] =
86 { .frequency = CPUFREQ_TABLE_END }
89 /* Low Voltage Intel Pentium M processor 1.10GHz */
90 static struct cpufreq_frequency_table op_1100[] =
97 { .frequency = CPUFREQ_TABLE_END }
101 /* Low Voltage Intel Pentium M processor 1.20GHz */
102 static struct cpufreq_frequency_table op_1200[] =
110 { .frequency = CPUFREQ_TABLE_END }
113 /* Intel Pentium M processor 1.30GHz */
114 static struct cpufreq_frequency_table op_1300[] =
121 { .frequency = CPUFREQ_TABLE_END }
124 /* Intel Pentium M processor 1.40GHz */
125 static struct cpufreq_frequency_table op_1400[] =
132 { .frequency = CPUFREQ_TABLE_END }
135 /* Intel Pentium M processor 1.50GHz */
136 static struct cpufreq_frequency_table op_1500[] =
144 { .frequency = CPUFREQ_TABLE_END }
147 /* Intel Pentium M processor 1.60GHz */
148 static struct cpufreq_frequency_table op_1600[] =
156 { .frequency = CPUFREQ_TABLE_END }
159 /* Intel Pentium M processor 1.70GHz */
160 static struct cpufreq_frequency_table op_1700[] =
168 { .frequency = CPUFREQ_TABLE_END }
172 #define _CPU(max, name) \
173 { "Intel(R) Pentium(R) M processor " name "MHz", (max)*1000, op_##max }
174 #define CPU(max) _CPU(max, #max)
176 /* CPU models, their operating frequency range, and freq/voltage
178 static struct cpu_model models[] =
193 static int centrino_cpu_init_table(struct cpufreq_policy *policy)
195 struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
196 struct cpu_model *model;
198 for(model = models; model->model_name != NULL; model++)
199 if (strcmp(cpu->x86_model_id, model->model_name) == 0)
201 if (model->model_name == NULL) {
202 printk(KERN_INFO PFX "no support for CPU model \"%s\": "
203 "send /proc/cpuinfo to " MAINTAINER "\n",
208 centrino_model = model;
210 printk(KERN_INFO PFX "found \"%s\": max frequency: %dkHz\n",
211 model->model_name, model->max_freq);
217 static inline int centrino_cpu_init_table(struct cpufreq_policy *policy) { return -ENODEV; }
218 #endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE */
220 /* Extract clock in kHz from PERF_CTL value */
221 static unsigned extract_clock(unsigned msr)
223 msr = (msr >> 8) & 0xff;
227 /* Return the current CPU frequency in kHz */
228 static unsigned get_cur_freq(void)
232 rdmsr(MSR_IA32_PERF_STATUS, l, h);
233 return extract_clock(l);
237 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
239 static struct acpi_processor_performance p;
241 #include <linux/acpi.h>
242 #include <acpi/processor.h>
244 #define ACPI_PDC_CAPABILITY_ENHANCED_SPEEDSTEP 0x1
247 * centrino_cpu_init_acpi - register with ACPI P-States library
249 * Register with the ACPI P-States library (part of drivers/acpi/processor.c)
250 * in order to determine correct frequency and voltage pairings by reading
251 * the _PSS of the ACPI DSDT or SSDT tables.
253 static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
255 union acpi_object arg0 = {ACPI_TYPE_BUFFER};
257 struct acpi_object_list arg_list = {1, &arg0};
258 unsigned long cur_freq;
262 arg0.buffer.length = 12;
263 arg0.buffer.pointer = (u8 *) arg0_buf;
264 arg0_buf[0] = ACPI_PDC_REVISION_ID;
266 arg0_buf[2] = ACPI_PDC_CAPABILITY_ENHANCED_SPEEDSTEP;
270 /* register with ACPI core */
271 if (acpi_processor_register_performance(&p, 0))
274 /* verify the acpi_data */
275 if (p.state_count <= 1) {
276 printk(KERN_DEBUG "No P-States\n");
281 if ((p.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
282 (p.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
283 printk(KERN_DEBUG "Invalid control/status registers\n");
288 for (i=0; i<p.state_count; i++) {
289 if (p.states[i].control != p.states[i].status) {
290 printk(KERN_DEBUG "Different control and status values\n");
295 if (!p.states[i].core_frequency) {
296 printk(KERN_DEBUG "Zero core frequency\n");
301 if (extract_clock(p.states[i].control) !=
302 (p.states[i].core_frequency * 1000)) {
303 printk(KERN_DEBUG "Invalid encoded frequency\n");
309 centrino_model = kmalloc(sizeof(struct cpu_model), GFP_KERNEL);
310 if (!centrino_model) {
314 memset(centrino_model, 0, sizeof(struct cpu_model));
316 centrino_model->model_name=NULL;
317 centrino_model->max_freq = p.states[0].core_frequency * 1000;
318 centrino_model->op_points = kmalloc(sizeof(struct cpufreq_frequency_table) *
319 (p.state_count + 1), GFP_KERNEL);
320 if (!centrino_model->op_points) {
325 cur_freq = get_cur_freq();
327 for (i=0; i<p.state_count; i++) {
328 centrino_model->op_points[i].index = p.states[i].control;
329 centrino_model->op_points[i].frequency = p.states[i].core_frequency * 1000;
330 if (cur_freq == centrino_model->op_points[i].frequency)
333 centrino_model->op_points[p.state_count].frequency = CPUFREQ_TABLE_END;
338 kfree(centrino_model);
340 acpi_processor_unregister_performance(&p, 0);
344 static inline int centrino_cpu_init_acpi(struct cpufreq_policy *policy) { return -ENODEV; }
347 static int centrino_cpu_init(struct cpufreq_policy *policy)
349 struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
354 if (policy->cpu != 0)
357 if (!cpu_has(cpu, X86_FEATURE_EST))
360 /* Only Intel Pentium M stepping 5 for now - add new CPUs as
361 they appear after making sure they use PERF_CTL in the same
363 if (cpu->x86_vendor != X86_VENDOR_INTEL ||
365 cpu->x86_model != 9 ||
366 cpu->x86_mask != 5) {
367 printk(KERN_INFO PFX "found unsupported CPU with Enhanced SpeedStep: "
368 "send /proc/cpuinfo to " MAINTAINER "\n");
372 if (centrino_cpu_init_acpi(policy)) {
373 if (centrino_cpu_init_table(policy)) {
378 /* Check to see if Enhanced SpeedStep is enabled, and try to
380 rdmsr(MSR_IA32_MISC_ENABLE, l, h);
382 if (!(l & (1<<16))) {
384 wrmsr(MSR_IA32_MISC_ENABLE, l, h);
386 /* check to see if it stuck */
387 rdmsr(MSR_IA32_MISC_ENABLE, l, h);
388 if (!(l & (1<<16))) {
389 printk(KERN_INFO PFX "couldn't enable Enhanced SpeedStep\n");
394 freq = get_cur_freq();
396 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
397 policy->cpuinfo.transition_latency = 10; /* 10uS transition latency */
400 dprintk(KERN_INFO PFX "centrino_cpu_init: policy=%d cur=%dkHz\n",
401 policy->policy, policy->cur);
403 ret = cpufreq_frequency_table_cpuinfo(policy, centrino_model->op_points);
407 cpufreq_frequency_table_get_attr(centrino_model->op_points, policy->cpu);
412 static int centrino_cpu_exit(struct cpufreq_policy *policy)
417 cpufreq_frequency_table_put_attr(policy->cpu);
419 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
420 if (!centrino_model->model_name) {
421 acpi_processor_unregister_performance(&p, 0);
422 kfree(centrino_model->op_points);
423 kfree(centrino_model);
427 centrino_model = NULL;
433 * centrino_verify - verifies a new CPUFreq policy
434 * @policy: new policy
436 * Limit must be within this model's frequency range at least one
439 static int centrino_verify (struct cpufreq_policy *policy)
441 return cpufreq_frequency_table_verify(policy, centrino_model->op_points);
445 * centrino_setpolicy - set a new CPUFreq policy
446 * @policy: new policy
447 * @target_freq: the target frequency
448 * @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
450 * Sets a new CPUFreq policy.
452 static int centrino_target (struct cpufreq_policy *policy,
453 unsigned int target_freq,
454 unsigned int relation)
456 unsigned int newstate = 0;
457 unsigned int msr, oldmsr, h;
458 struct cpufreq_freqs freqs;
460 if (centrino_model == NULL)
463 if (cpufreq_frequency_table_target(policy, centrino_model->op_points, target_freq,
464 relation, &newstate))
467 msr = centrino_model->op_points[newstate].index;
468 rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);
470 if (msr == (oldmsr & 0xffff))
473 /* Hm, old frequency can either be the last value we put in
474 PERF_CTL, or whatever it is now. The trouble is that TM2
475 can change it behind our back, which means we never get to
476 see the speed change. Reading back the current speed would
477 tell us something happened, but it may leave the things on
478 the notifier chain confused; we therefore stick to using
479 the last programmed speed rather than the current speed for
482 TODO: work out how the TCC interrupts work, and try to
483 catch the CPU changing things under us.
486 freqs.old = extract_clock(oldmsr);
487 freqs.new = extract_clock(msr);
489 dprintk(KERN_INFO PFX "target=%dkHz old=%d new=%d msr=%04x\n",
490 target_freq, freqs.old, freqs.new, msr);
492 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
494 /* all but 16 LSB are "reserved", so treat them with
500 wrmsr(MSR_IA32_PERF_CTL, oldmsr, h);
502 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
507 static struct freq_attr* centrino_attr[] = {
508 &cpufreq_freq_attr_scaling_available_freqs,
512 static struct cpufreq_driver centrino_driver = {
513 .name = "centrino", /* should be speedstep-centrino,
514 but there's a 16 char limit */
515 .init = centrino_cpu_init,
516 .exit = centrino_cpu_exit,
517 .verify = centrino_verify,
518 .target = centrino_target,
519 .attr = centrino_attr,
520 .owner = THIS_MODULE,
525 * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
527 * Initializes the Enhanced SpeedStep support. Returns -ENODEV on
528 * unsupported devices, -ENOENT if there's no voltage table for this
529 * particular CPU model, -EINVAL on problems during initiatization,
530 * and zero on success.
532 * This is quite picky. Not only does the CPU have to advertise the
533 * "est" flag in the cpuid capability flags, we look for a specific
534 * CPU model and stepping, and we need to have the exact model name in
535 * our voltage tables. That is, be paranoid about not releasing
536 * someone's valuable magic smoke.
538 static int __init centrino_init(void)
540 struct cpuinfo_x86 *cpu = cpu_data;
542 if (!cpu_has(cpu, X86_FEATURE_EST))
545 return cpufreq_register_driver(¢rino_driver);
548 static void __exit centrino_exit(void)
550 cpufreq_unregister_driver(¢rino_driver);
553 MODULE_AUTHOR ("Jeremy Fitzhardinge <jeremy@goop.org>");
554 MODULE_DESCRIPTION ("Enhanced SpeedStep driver for Intel Pentium M processors.");
555 MODULE_LICENSE ("GPL");
557 late_initcall(centrino_init);
558 module_exit(centrino_exit);