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>
34 #include <linux/compiler.h>
35 #include <linux/sched.h> /* current */
37 #include <asm/delay.h>
38 #include <asm/uaccess.h>
40 #include <linux/acpi.h>
41 #include <acpi/processor.h>
43 #include "speedstep-est-common.h"
45 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg)
47 MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
48 MODULE_DESCRIPTION("ACPI Processor P-States Driver");
49 MODULE_LICENSE("GPL");
52 struct cpufreq_acpi_io
{
53 struct acpi_processor_performance acpi_data
;
54 struct cpufreq_frequency_table
*freq_table
;
58 static struct cpufreq_acpi_io
*acpi_io_data
[NR_CPUS
];
60 static struct cpufreq_driver acpi_cpufreq_driver
;
62 static unsigned int acpi_pstate_strict
;
65 acpi_processor_write_port(
72 } else if (bit_width
<= 16) {
74 } else if (bit_width
<= 32) {
83 acpi_processor_read_port(
91 } else if (bit_width
<= 16) {
93 } else if (bit_width
<= 32) {
102 acpi_processor_set_performance (
103 struct cpufreq_acpi_io
*data
,
112 struct cpufreq_freqs cpufreq_freqs
;
113 cpumask_t saved_mask
;
116 dprintk("acpi_processor_set_performance\n");
119 * TBD: Use something other than set_cpus_allowed.
120 * As set_cpus_allowed is a bit racy,
121 * with any other set_cpus_allowed for this process.
123 saved_mask
= current
->cpus_allowed
;
124 set_cpus_allowed(current
, cpumask_of_cpu(cpu
));
125 if (smp_processor_id() != cpu
) {
129 if (state
== data
->acpi_data
.state
) {
130 if (unlikely(data
->resume
)) {
131 dprintk("Called after resume, resetting to P%d\n", state
);
134 dprintk("Already at target state (P%d)\n", state
);
140 dprintk("Transitioning from P%d to P%d\n",
141 data
->acpi_data
.state
, state
);
143 /* cpufreq frequency struct */
144 cpufreq_freqs
.cpu
= cpu
;
145 cpufreq_freqs
.old
= data
->freq_table
[data
->acpi_data
.state
].frequency
;
146 cpufreq_freqs
.new = data
->freq_table
[state
].frequency
;
149 cpufreq_notify_transition(&cpufreq_freqs
, CPUFREQ_PRECHANGE
);
152 * First we write the target state's 'control' value to the
156 port
= data
->acpi_data
.control_register
.address
;
157 bit_width
= data
->acpi_data
.control_register
.bit_width
;
158 value
= (u32
) data
->acpi_data
.states
[state
].control
;
160 dprintk("Writing 0x%08x to port 0x%04x\n", value
, port
);
162 ret
= acpi_processor_write_port(port
, bit_width
, value
);
164 dprintk("Invalid port width 0x%04x\n", bit_width
);
170 * Assume the write went through when acpi_pstate_strict is not used.
171 * As read status_register is an expensive operation and there
172 * are no specific error cases where an IO port write will fail.
174 if (acpi_pstate_strict
) {
175 /* Then we read the 'status_register' and compare the value
176 * with the target state's 'status' to make sure the
177 * transition was successful.
178 * Note that we'll poll for up to 1ms (100 cycles of 10us)
182 port
= data
->acpi_data
.status_register
.address
;
183 bit_width
= data
->acpi_data
.status_register
.bit_width
;
185 dprintk("Looking for 0x%08x from port 0x%04x\n",
186 (u32
) data
->acpi_data
.states
[state
].status
, port
);
188 for (i
=0; i
<100; i
++) {
189 ret
= acpi_processor_read_port(port
, bit_width
, &value
);
191 dprintk("Invalid port width 0x%04x\n", bit_width
);
195 if (value
== (u32
) data
->acpi_data
.states
[state
].status
)
201 value
= (u32
) data
->acpi_data
.states
[state
].status
;
205 cpufreq_notify_transition(&cpufreq_freqs
, CPUFREQ_POSTCHANGE
);
207 if (unlikely(value
!= (u32
) data
->acpi_data
.states
[state
].status
)) {
208 unsigned int tmp
= cpufreq_freqs
.new;
209 cpufreq_freqs
.new = cpufreq_freqs
.old
;
210 cpufreq_freqs
.old
= tmp
;
211 cpufreq_notify_transition(&cpufreq_freqs
, CPUFREQ_PRECHANGE
);
212 cpufreq_notify_transition(&cpufreq_freqs
, CPUFREQ_POSTCHANGE
);
213 printk(KERN_WARNING
"acpi-cpufreq: Transition failed\n");
218 dprintk("Transition successful after %d microseconds\n", i
* 10);
220 data
->acpi_data
.state
= state
;
224 set_cpus_allowed(current
, saved_mask
);
230 acpi_cpufreq_target (
231 struct cpufreq_policy
*policy
,
232 unsigned int target_freq
,
233 unsigned int relation
)
235 struct cpufreq_acpi_io
*data
= acpi_io_data
[policy
->cpu
];
236 unsigned int next_state
= 0;
237 unsigned int result
= 0;
239 dprintk("acpi_cpufreq_setpolicy\n");
241 result
= cpufreq_frequency_table_target(policy
,
249 result
= acpi_processor_set_performance (data
, policy
->cpu
, next_state
);
256 acpi_cpufreq_verify (
257 struct cpufreq_policy
*policy
)
259 unsigned int result
= 0;
260 struct cpufreq_acpi_io
*data
= acpi_io_data
[policy
->cpu
];
262 dprintk("acpi_cpufreq_verify\n");
264 result
= cpufreq_frequency_table_verify(policy
,
272 acpi_cpufreq_guess_freq (
273 struct cpufreq_acpi_io
*data
,
277 /* search the closest match to cpu_khz */
280 unsigned long freqn
= data
->acpi_data
.states
[0].core_frequency
* 1000;
282 for (i
=0; i
< (data
->acpi_data
.state_count
- 1); i
++) {
284 freqn
= data
->acpi_data
.states
[i
+1].core_frequency
* 1000;
285 if ((2 * cpu_khz
) > (freqn
+ freq
)) {
286 data
->acpi_data
.state
= i
;
290 data
->acpi_data
.state
= data
->acpi_data
.state_count
- 1;
293 /* assume CPU is at P0... */
294 data
->acpi_data
.state
= 0;
295 return data
->acpi_data
.states
[0].core_frequency
* 1000;
301 * acpi_processor_cpu_init_pdc_est - let BIOS know about the SMP capabilities
303 * @perf: processor-specific acpi_io_data struct
304 * @cpu: CPU being initialized
306 * To avoid issues with legacy OSes, some BIOSes require to be informed of
307 * the SMP capabilities of OS P-state driver. Here we set the bits in _PDC
308 * accordingly, for Enhanced Speedstep. Actual call to _PDC is done in
309 * driver/acpi/processor.c
312 acpi_processor_cpu_init_pdc_est(
313 struct acpi_processor_performance
*perf
,
315 struct acpi_object_list
*obj_list
318 union acpi_object
*obj
;
320 struct cpuinfo_x86
*c
= cpu_data
+ cpu
;
321 dprintk("acpi_processor_cpu_init_pdc_est\n");
323 if (!cpu_has(c
, X86_FEATURE_EST
))
326 /* Initialize pdc. It will be used later. */
330 if (!(obj_list
->count
&& obj_list
->pointer
))
333 obj
= obj_list
->pointer
;
334 if ((obj
->buffer
.length
== 12) && obj
->buffer
.pointer
) {
335 buf
= (u32
*)obj
->buffer
.pointer
;
336 buf
[0] = ACPI_PDC_REVISION_ID
;
338 buf
[2] = ACPI_PDC_EST_CAPABILITY_SMP
;
339 perf
->pdc
= obj_list
;
345 /* CPU specific PDC initialization */
347 acpi_processor_cpu_init_pdc(
348 struct acpi_processor_performance
*perf
,
350 struct acpi_object_list
*obj_list
353 struct cpuinfo_x86
*c
= cpu_data
+ cpu
;
354 dprintk("acpi_processor_cpu_init_pdc\n");
356 if (cpu_has(c
, X86_FEATURE_EST
))
357 acpi_processor_cpu_init_pdc_est(perf
, cpu
, obj_list
);
363 acpi_cpufreq_cpu_init (
364 struct cpufreq_policy
*policy
)
367 unsigned int cpu
= policy
->cpu
;
368 struct cpufreq_acpi_io
*data
;
369 unsigned int result
= 0;
371 union acpi_object arg0
= {ACPI_TYPE_BUFFER
};
373 struct acpi_object_list arg_list
= {1, &arg0
};
375 dprintk("acpi_cpufreq_cpu_init\n");
376 /* setup arg_list for _PDC settings */
377 arg0
.buffer
.length
= 12;
378 arg0
.buffer
.pointer
= (u8
*) arg0_buf
;
380 data
= kzalloc(sizeof(struct cpufreq_acpi_io
), GFP_KERNEL
);
384 acpi_io_data
[cpu
] = data
;
386 acpi_processor_cpu_init_pdc(&data
->acpi_data
, cpu
, &arg_list
);
387 result
= acpi_processor_register_performance(&data
->acpi_data
, cpu
);
388 data
->acpi_data
.pdc
= NULL
;
393 if (is_const_loops_cpu(cpu
)) {
394 acpi_cpufreq_driver
.flags
|= CPUFREQ_CONST_LOOPS
;
397 /* capability check */
398 if (data
->acpi_data
.state_count
<= 1) {
399 dprintk("No P-States\n");
403 if ((data
->acpi_data
.control_register
.space_id
!= ACPI_ADR_SPACE_SYSTEM_IO
) ||
404 (data
->acpi_data
.status_register
.space_id
!= ACPI_ADR_SPACE_SYSTEM_IO
)) {
405 dprintk("Unsupported address space [%d, %d]\n",
406 (u32
) (data
->acpi_data
.control_register
.space_id
),
407 (u32
) (data
->acpi_data
.status_register
.space_id
));
412 /* alloc freq_table */
413 data
->freq_table
= kmalloc(sizeof(struct cpufreq_frequency_table
) * (data
->acpi_data
.state_count
+ 1), GFP_KERNEL
);
414 if (!data
->freq_table
) {
419 /* detect transition latency */
420 policy
->cpuinfo
.transition_latency
= 0;
421 for (i
=0; i
<data
->acpi_data
.state_count
; i
++) {
422 if ((data
->acpi_data
.states
[i
].transition_latency
* 1000) > policy
->cpuinfo
.transition_latency
)
423 policy
->cpuinfo
.transition_latency
= data
->acpi_data
.states
[i
].transition_latency
* 1000;
425 policy
->governor
= CPUFREQ_DEFAULT_GOVERNOR
;
427 /* The current speed is unknown and not detectable by ACPI... */
428 policy
->cur
= acpi_cpufreq_guess_freq(data
, policy
->cpu
);
431 for (i
=0; i
<=data
->acpi_data
.state_count
; i
++)
433 data
->freq_table
[i
].index
= i
;
434 if (i
<data
->acpi_data
.state_count
)
435 data
->freq_table
[i
].frequency
= data
->acpi_data
.states
[i
].core_frequency
* 1000;
437 data
->freq_table
[i
].frequency
= CPUFREQ_TABLE_END
;
440 result
= cpufreq_frequency_table_cpuinfo(policy
, data
->freq_table
);
445 /* notify BIOS that we exist */
446 acpi_processor_notify_smm(THIS_MODULE
);
448 printk(KERN_INFO
"acpi-cpufreq: CPU%u - ACPI performance management activated.\n",
450 for (i
= 0; i
< data
->acpi_data
.state_count
; i
++)
451 dprintk(" %cP%d: %d MHz, %d mW, %d uS\n",
452 (i
== data
->acpi_data
.state
?'*':' '), i
,
453 (u32
) data
->acpi_data
.states
[i
].core_frequency
,
454 (u32
) data
->acpi_data
.states
[i
].power
,
455 (u32
) data
->acpi_data
.states
[i
].transition_latency
);
457 cpufreq_frequency_table_get_attr(data
->freq_table
, policy
->cpu
);
460 * the first call to ->target() should result in us actually
461 * writing something to the appropriate registers.
468 kfree(data
->freq_table
);
470 acpi_processor_unregister_performance(&data
->acpi_data
, cpu
);
473 acpi_io_data
[cpu
] = NULL
;
480 acpi_cpufreq_cpu_exit (
481 struct cpufreq_policy
*policy
)
483 struct cpufreq_acpi_io
*data
= acpi_io_data
[policy
->cpu
];
486 dprintk("acpi_cpufreq_cpu_exit\n");
489 cpufreq_frequency_table_put_attr(policy
->cpu
);
490 acpi_io_data
[policy
->cpu
] = NULL
;
491 acpi_processor_unregister_performance(&data
->acpi_data
, policy
->cpu
);
499 acpi_cpufreq_resume (
500 struct cpufreq_policy
*policy
)
502 struct cpufreq_acpi_io
*data
= acpi_io_data
[policy
->cpu
];
505 dprintk("acpi_cpufreq_resume\n");
513 static struct freq_attr
* acpi_cpufreq_attr
[] = {
514 &cpufreq_freq_attr_scaling_available_freqs
,
518 static struct cpufreq_driver acpi_cpufreq_driver
= {
519 .verify
= acpi_cpufreq_verify
,
520 .target
= acpi_cpufreq_target
,
521 .init
= acpi_cpufreq_cpu_init
,
522 .exit
= acpi_cpufreq_cpu_exit
,
523 .resume
= acpi_cpufreq_resume
,
524 .name
= "acpi-cpufreq",
525 .owner
= THIS_MODULE
,
526 .attr
= acpi_cpufreq_attr
,
531 acpi_cpufreq_init (void)
535 dprintk("acpi_cpufreq_init\n");
537 result
= cpufreq_register_driver(&acpi_cpufreq_driver
);
544 acpi_cpufreq_exit (void)
546 dprintk("acpi_cpufreq_exit\n");
548 cpufreq_unregister_driver(&acpi_cpufreq_driver
);
553 module_param(acpi_pstate_strict
, uint
, 0644);
554 MODULE_PARM_DESC(acpi_pstate_strict
, "value 0 or non-zero. non-zero -> strict ACPI checks are performed during frequency changes.");
556 late_initcall(acpi_cpufreq_init
);
557 module_exit(acpi_cpufreq_exit
);
559 MODULE_ALIAS("acpi");