2 * acpi-cpufreq.c - ACPI Processor P-States Driver ($Revision: 1.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) 2002 - 2004 Dominik Brodowski <linux@brodo.de>
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 #include <linux/config.h>
28 #include <linux/kernel.h>
29 #include <linux/module.h>
30 #include <linux/init.h>
31 #include <linux/cpufreq.h>
32 #include <linux/proc_fs.h>
33 #include <linux/seq_file.h>
35 #include <asm/delay.h>
36 #include <asm/uaccess.h>
38 #include <linux/acpi.h>
39 #include <acpi/processor.h>
41 #include "speedstep-est-common.h"
43 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg)
45 MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
46 MODULE_DESCRIPTION("ACPI Processor P-States Driver");
47 MODULE_LICENSE("GPL");
50 struct cpufreq_acpi_io
{
51 struct acpi_processor_performance acpi_data
;
52 struct cpufreq_frequency_table
*freq_table
;
56 static struct cpufreq_acpi_io
*acpi_io_data
[NR_CPUS
];
58 static struct cpufreq_driver acpi_cpufreq_driver
;
61 acpi_processor_write_port(
68 } else if (bit_width
<= 16) {
70 } else if (bit_width
<= 32) {
79 acpi_processor_read_port(
87 } else if (bit_width
<= 16) {
89 } else if (bit_width
<= 32) {
98 acpi_processor_set_performance (
99 struct cpufreq_acpi_io
*data
,
108 struct cpufreq_freqs cpufreq_freqs
;
109 cpumask_t saved_mask
;
112 dprintk("acpi_processor_set_performance\n");
115 * TBD: Use something other than set_cpus_allowed.
116 * As set_cpus_allowed is a bit racy,
117 * with any other set_cpus_allowed for this process.
119 saved_mask
= current
->cpus_allowed
;
120 set_cpus_allowed(current
, cpumask_of_cpu(cpu
));
121 if (smp_processor_id() != cpu
) {
125 if (state
== data
->acpi_data
.state
) {
126 if (unlikely(data
->resume
)) {
127 dprintk("Called after resume, resetting to P%d\n", state
);
130 dprintk("Already at target state (P%d)\n", state
);
136 dprintk("Transitioning from P%d to P%d\n",
137 data
->acpi_data
.state
, state
);
139 /* cpufreq frequency struct */
140 cpufreq_freqs
.cpu
= cpu
;
141 cpufreq_freqs
.old
= data
->freq_table
[data
->acpi_data
.state
].frequency
;
142 cpufreq_freqs
.new = data
->freq_table
[state
].frequency
;
145 cpufreq_notify_transition(&cpufreq_freqs
, CPUFREQ_PRECHANGE
);
148 * First we write the target state's 'control' value to the
152 port
= data
->acpi_data
.control_register
.address
;
153 bit_width
= data
->acpi_data
.control_register
.bit_width
;
154 value
= (u32
) data
->acpi_data
.states
[state
].control
;
156 dprintk("Writing 0x%08x to port 0x%04x\n", value
, port
);
158 ret
= acpi_processor_write_port(port
, bit_width
, value
);
160 dprintk("Invalid port width 0x%04x\n", bit_width
);
166 * Then we read the 'status_register' and compare the value with the
167 * target state's 'status' to make sure the transition was successful.
168 * Note that we'll poll for up to 1ms (100 cycles of 10us) before
172 port
= data
->acpi_data
.status_register
.address
;
173 bit_width
= data
->acpi_data
.status_register
.bit_width
;
175 dprintk("Looking for 0x%08x from port 0x%04x\n",
176 (u32
) data
->acpi_data
.states
[state
].status
, port
);
178 for (i
=0; i
<100; i
++) {
179 ret
= acpi_processor_read_port(port
, bit_width
, &value
);
181 dprintk("Invalid port width 0x%04x\n", bit_width
);
185 if (value
== (u32
) data
->acpi_data
.states
[state
].status
)
191 cpufreq_notify_transition(&cpufreq_freqs
, CPUFREQ_POSTCHANGE
);
193 if (value
!= (u32
) data
->acpi_data
.states
[state
].status
) {
194 unsigned int tmp
= cpufreq_freqs
.new;
195 cpufreq_freqs
.new = cpufreq_freqs
.old
;
196 cpufreq_freqs
.old
= tmp
;
197 cpufreq_notify_transition(&cpufreq_freqs
, CPUFREQ_PRECHANGE
);
198 cpufreq_notify_transition(&cpufreq_freqs
, CPUFREQ_POSTCHANGE
);
199 printk(KERN_WARNING
"acpi-cpufreq: Transition failed\n");
204 dprintk("Transition successful after %d microseconds\n", i
* 10);
206 data
->acpi_data
.state
= state
;
210 set_cpus_allowed(current
, saved_mask
);
216 acpi_cpufreq_target (
217 struct cpufreq_policy
*policy
,
218 unsigned int target_freq
,
219 unsigned int relation
)
221 struct cpufreq_acpi_io
*data
= acpi_io_data
[policy
->cpu
];
222 unsigned int next_state
= 0;
223 unsigned int result
= 0;
225 dprintk("acpi_cpufreq_setpolicy\n");
227 result
= cpufreq_frequency_table_target(policy
,
235 result
= acpi_processor_set_performance (data
, policy
->cpu
, next_state
);
242 acpi_cpufreq_verify (
243 struct cpufreq_policy
*policy
)
245 unsigned int result
= 0;
246 struct cpufreq_acpi_io
*data
= acpi_io_data
[policy
->cpu
];
248 dprintk("acpi_cpufreq_verify\n");
250 result
= cpufreq_frequency_table_verify(policy
,
258 acpi_cpufreq_guess_freq (
259 struct cpufreq_acpi_io
*data
,
263 /* search the closest match to cpu_khz */
266 unsigned long freqn
= data
->acpi_data
.states
[0].core_frequency
* 1000;
268 for (i
=0; i
< (data
->acpi_data
.state_count
- 1); i
++) {
270 freqn
= data
->acpi_data
.states
[i
+1].core_frequency
* 1000;
271 if ((2 * cpu_khz
) > (freqn
+ freq
)) {
272 data
->acpi_data
.state
= i
;
276 data
->acpi_data
.state
= data
->acpi_data
.state_count
- 1;
279 /* assume CPU is at P0... */
280 data
->acpi_data
.state
= 0;
281 return data
->acpi_data
.states
[0].core_frequency
* 1000;
287 * acpi_processor_cpu_init_pdc_est - let BIOS know about the SMP capabilities
289 * @perf: processor-specific acpi_io_data struct
290 * @cpu: CPU being initialized
292 * To avoid issues with legacy OSes, some BIOSes require to be informed of
293 * the SMP capabilities of OS P-state driver. Here we set the bits in _PDC
294 * accordingly, for Enhanced Speedstep. Actual call to _PDC is done in
295 * driver/acpi/processor.c
298 acpi_processor_cpu_init_pdc_est(
299 struct acpi_processor_performance
*perf
,
301 struct acpi_object_list
*obj_list
304 union acpi_object
*obj
;
306 struct cpuinfo_x86
*c
= cpu_data
+ cpu
;
307 dprintk("acpi_processor_cpu_init_pdc_est\n");
309 if (!cpu_has(c
, X86_FEATURE_EST
))
312 /* Initialize pdc. It will be used later. */
316 if (!(obj_list
->count
&& obj_list
->pointer
))
319 obj
= obj_list
->pointer
;
320 if ((obj
->buffer
.length
== 12) && obj
->buffer
.pointer
) {
321 buf
= (u32
*)obj
->buffer
.pointer
;
322 buf
[0] = ACPI_PDC_REVISION_ID
;
324 buf
[2] = ACPI_PDC_EST_CAPABILITY_SMP
;
325 perf
->pdc
= obj_list
;
331 /* CPU specific PDC initialization */
333 acpi_processor_cpu_init_pdc(
334 struct acpi_processor_performance
*perf
,
336 struct acpi_object_list
*obj_list
339 struct cpuinfo_x86
*c
= cpu_data
+ cpu
;
340 dprintk("acpi_processor_cpu_init_pdc\n");
342 if (cpu_has(c
, X86_FEATURE_EST
))
343 acpi_processor_cpu_init_pdc_est(perf
, cpu
, obj_list
);
349 acpi_cpufreq_cpu_init (
350 struct cpufreq_policy
*policy
)
353 unsigned int cpu
= policy
->cpu
;
354 struct cpufreq_acpi_io
*data
;
355 unsigned int result
= 0;
357 union acpi_object arg0
= {ACPI_TYPE_BUFFER
};
359 struct acpi_object_list arg_list
= {1, &arg0
};
361 dprintk("acpi_cpufreq_cpu_init\n");
362 /* setup arg_list for _PDC settings */
363 arg0
.buffer
.length
= 12;
364 arg0
.buffer
.pointer
= (u8
*) arg0_buf
;
366 data
= kmalloc(sizeof(struct cpufreq_acpi_io
), GFP_KERNEL
);
369 memset(data
, 0, sizeof(struct cpufreq_acpi_io
));
371 acpi_io_data
[cpu
] = data
;
373 acpi_processor_cpu_init_pdc(&data
->acpi_data
, cpu
, &arg_list
);
374 result
= acpi_processor_register_performance(&data
->acpi_data
, cpu
);
375 data
->acpi_data
.pdc
= NULL
;
380 if (is_const_loops_cpu(cpu
)) {
381 acpi_cpufreq_driver
.flags
|= CPUFREQ_CONST_LOOPS
;
384 /* capability check */
385 if (data
->acpi_data
.state_count
<= 1) {
386 dprintk("No P-States\n");
390 if ((data
->acpi_data
.control_register
.space_id
!= ACPI_ADR_SPACE_SYSTEM_IO
) ||
391 (data
->acpi_data
.status_register
.space_id
!= ACPI_ADR_SPACE_SYSTEM_IO
)) {
392 dprintk("Unsupported address space [%d, %d]\n",
393 (u32
) (data
->acpi_data
.control_register
.space_id
),
394 (u32
) (data
->acpi_data
.status_register
.space_id
));
399 /* alloc freq_table */
400 data
->freq_table
= kmalloc(sizeof(struct cpufreq_frequency_table
) * (data
->acpi_data
.state_count
+ 1), GFP_KERNEL
);
401 if (!data
->freq_table
) {
406 /* detect transition latency */
407 policy
->cpuinfo
.transition_latency
= 0;
408 for (i
=0; i
<data
->acpi_data
.state_count
; i
++) {
409 if ((data
->acpi_data
.states
[i
].transition_latency
* 1000) > policy
->cpuinfo
.transition_latency
)
410 policy
->cpuinfo
.transition_latency
= data
->acpi_data
.states
[i
].transition_latency
* 1000;
412 policy
->governor
= CPUFREQ_DEFAULT_GOVERNOR
;
414 /* The current speed is unknown and not detectable by ACPI... */
415 policy
->cur
= acpi_cpufreq_guess_freq(data
, policy
->cpu
);
418 for (i
=0; i
<=data
->acpi_data
.state_count
; i
++)
420 data
->freq_table
[i
].index
= i
;
421 if (i
<data
->acpi_data
.state_count
)
422 data
->freq_table
[i
].frequency
= data
->acpi_data
.states
[i
].core_frequency
* 1000;
424 data
->freq_table
[i
].frequency
= CPUFREQ_TABLE_END
;
427 result
= cpufreq_frequency_table_cpuinfo(policy
, data
->freq_table
);
432 /* notify BIOS that we exist */
433 acpi_processor_notify_smm(THIS_MODULE
);
435 printk(KERN_INFO
"acpi-cpufreq: CPU%u - ACPI performance management activated.\n",
437 for (i
= 0; i
< data
->acpi_data
.state_count
; i
++)
438 dprintk(" %cP%d: %d MHz, %d mW, %d uS\n",
439 (i
== data
->acpi_data
.state
?'*':' '), i
,
440 (u32
) data
->acpi_data
.states
[i
].core_frequency
,
441 (u32
) data
->acpi_data
.states
[i
].power
,
442 (u32
) data
->acpi_data
.states
[i
].transition_latency
);
444 cpufreq_frequency_table_get_attr(data
->freq_table
, policy
->cpu
);
448 kfree(data
->freq_table
);
450 acpi_processor_unregister_performance(&data
->acpi_data
, cpu
);
453 acpi_io_data
[cpu
] = NULL
;
460 acpi_cpufreq_cpu_exit (
461 struct cpufreq_policy
*policy
)
463 struct cpufreq_acpi_io
*data
= acpi_io_data
[policy
->cpu
];
466 dprintk("acpi_cpufreq_cpu_exit\n");
469 cpufreq_frequency_table_put_attr(policy
->cpu
);
470 acpi_io_data
[policy
->cpu
] = NULL
;
471 acpi_processor_unregister_performance(&data
->acpi_data
, policy
->cpu
);
479 acpi_cpufreq_resume (
480 struct cpufreq_policy
*policy
)
482 struct cpufreq_acpi_io
*data
= acpi_io_data
[policy
->cpu
];
485 dprintk("acpi_cpufreq_resume\n");
493 static struct freq_attr
* acpi_cpufreq_attr
[] = {
494 &cpufreq_freq_attr_scaling_available_freqs
,
498 static struct cpufreq_driver acpi_cpufreq_driver
= {
499 .verify
= acpi_cpufreq_verify
,
500 .target
= acpi_cpufreq_target
,
501 .init
= acpi_cpufreq_cpu_init
,
502 .exit
= acpi_cpufreq_cpu_exit
,
503 .resume
= acpi_cpufreq_resume
,
504 .name
= "acpi-cpufreq",
505 .owner
= THIS_MODULE
,
506 .attr
= acpi_cpufreq_attr
,
511 acpi_cpufreq_init (void)
515 dprintk("acpi_cpufreq_init\n");
517 result
= cpufreq_register_driver(&acpi_cpufreq_driver
);
524 acpi_cpufreq_exit (void)
526 dprintk("acpi_cpufreq_exit\n");
528 cpufreq_unregister_driver(&acpi_cpufreq_driver
);
534 late_initcall(acpi_cpufreq_init
);
535 module_exit(acpi_cpufreq_exit
);
537 MODULE_ALIAS("acpi");