2 * cpu.c - Processor handling
4 * Copyright (C) 2000 Andrew Henroid
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <linux/config.h>
22 #include <linux/kernel.h>
24 #include <linux/acpi.h>
28 #define _COMPONENT OS_DEPENDENT
31 unsigned long acpi_c2_exit_latency
= ACPI_INFINITE
;
32 unsigned long acpi_c3_exit_latency
= ACPI_INFINITE
;
33 unsigned long acpi_c2_enter_latency
= ACPI_INFINITE
;
34 unsigned long acpi_c3_enter_latency
= ACPI_INFINITE
;
36 static unsigned long acpi_pblk
= ACPI_INVALID
;
37 static int acpi_c2_tested
= 0;
38 static int acpi_c3_tested
= 0;
39 static int acpi_max_c_state
= 1;
40 static int acpi_pm_tmr_len
;
43 * Clear busmaster activity flag
46 acpi_clear_bm_activity(void)
48 acpi_hw_register_bit_access(ACPI_WRITE
, ACPI_MTX_LOCK
, BM_STS
, 0);
52 * Returns 1 if there has been busmaster activity
55 acpi_bm_activity(void)
57 return acpi_hw_register_bit_access(ACPI_READ
, ACPI_MTX_LOCK
, BM_STS
);
61 * Set system to sleep through busmaster requests
64 acpi_sleep_on_busmaster(void)
66 acpi_hw_register_bit_access (ACPI_WRITE
, ACPI_MTX_LOCK
, BM_RLD
, 1);
70 * Set system to wake on busmaster requests
73 acpi_wake_on_busmaster(void)
75 acpi_hw_register_bit_access (ACPI_WRITE
, ACPI_MTX_LOCK
, BM_RLD
, 0);
79 acpi_read_pm_timer(void)
81 return acpi_hw_register_read(ACPI_MTX_LOCK
, PM_TIMER
);
85 * Do a compare, accounting for 24/32bit rollover
88 acpi_compare_pm_timers(u32 first
, u32 second
)
91 return (second
- first
);
93 if (acpi_pm_tmr_len
== 24)
94 return (second
+ (0xFFFFFF - first
));
96 return (second
+ (0xFFFFFFFF - first
));
101 * Idle loop (uniprocessor only)
106 static int sleep_level
= 1;
107 FADT_DESCRIPTOR
*fadt
= &acpi_fadt
;
110 || (STRNCMP(fadt
->header
.signature
, ACPI_FADT_SIGNATURE
, ACPI_SIG_LEN
) != 0)
111 || !fadt
->Xpm_tmr_blk
.address
113 goto not_initialized
;
116 * start from the previous sleep level..
119 || acpi_max_c_state
< 2)
123 || acpi_max_c_state
< 3)
128 if (!acpi_c3_tested
) {
129 DEBUG_PRINT(ACPI_INFO
, ("C3 works\n"));
132 acpi_wake_on_busmaster();
133 if (fadt
->Xpm2_cnt_blk
.address
)
134 goto sleep3_with_arbiter
;
141 if (current
->need_resched
)
143 if (acpi_bm_activity())
146 time
= acpi_read_pm_timer();
147 inb(acpi_pblk
+ ACPI_P_LVL3
);
148 /* Dummy read, force synchronization with the PMU */
149 acpi_read_pm_timer();
150 diff
= acpi_compare_pm_timers(time
, acpi_read_pm_timer());
153 if (diff
< acpi_c3_exit_latency
)
163 if (current
->need_resched
)
165 if (acpi_bm_activity())
168 time
= acpi_read_pm_timer();
170 /* Disable arbiter, park on CPU */
171 acpi_hw_register_bit_access(ACPI_WRITE
, ACPI_MTX_LOCK
, ARB_DIS
, 1);
172 inb(acpi_pblk
+ ACPI_P_LVL3
);
173 /* Dummy read, force synchronization with the PMU */
174 acpi_read_pm_timer();
175 diff
= acpi_compare_pm_timers(time
, acpi_read_pm_timer());
176 /* Enable arbiter again.. */
177 acpi_hw_register_bit_access(ACPI_WRITE
, ACPI_MTX_LOCK
, ARB_DIS
, 0);
180 if (diff
< acpi_c3_exit_latency
)
186 if (!acpi_c2_tested
) {
187 DEBUG_PRINT(ACPI_INFO
, ("C2 works\n"));
190 acpi_wake_on_busmaster(); /* Required to track BM activity.. */
196 if (current
->need_resched
)
199 time
= acpi_read_pm_timer();
200 inb(acpi_pblk
+ ACPI_P_LVL2
);
201 /* Dummy read, force synchronization with the PMU */
202 acpi_read_pm_timer();
203 diff
= acpi_compare_pm_timers(time
, acpi_read_pm_timer());
206 if (diff
< acpi_c2_exit_latency
)
208 if (acpi_bm_activity()) {
209 acpi_clear_bm_activity();
212 if (diff
> acpi_c3_enter_latency
213 && acpi_max_c_state
>= 3)
219 acpi_sleep_on_busmaster();
225 if (current
->need_resched
)
227 time
= acpi_read_pm_timer();
229 diff
= acpi_compare_pm_timers(time
, acpi_read_pm_timer());
230 if (diff
> acpi_c2_enter_latency
231 && acpi_max_c_state
>= 2)
238 if (current
->need_resched
)
248 * Get processor information
251 acpi_found_cpu(ACPI_HANDLE handle
, u32 level
, void *ctx
, void **value
)
254 ACPI_CX_STATE lat
[4];
255 ACPI_CPU_THROTTLING_STATE throttle
[ACPI_MAX_THROTTLE
];
259 buf
.length
= sizeof(obj
);
261 if (!ACPI_SUCCESS(acpi_evaluate_object(handle
, NULL
, NULL
, &buf
)))
264 DEBUG_PRINT(ACPI_INFO
, ("PBLK %d @ 0x%04x:%d\n",
265 obj
.processor
.proc_id
,
266 obj
.processor
.pblk_address
,
267 obj
.processor
.pblk_length
));
269 if (acpi_pblk
!= ACPI_INVALID
270 || !obj
.processor
.pblk_address
271 || obj
.processor
.pblk_length
!= 6)
274 acpi_pblk
= obj
.processor
.pblk_address
;
276 buf
.length
= sizeof(lat
);
278 if (!ACPI_SUCCESS(acpi_get_processor_cx_info(handle
, &buf
)))
281 if (lat
[2].latency
< MAX_CX_STATE_LATENCY
) {
282 printk(KERN_INFO
"ACPI: System firmware supports: C2");
283 acpi_c2_exit_latency
= lat
[2].latency
;
284 acpi_max_c_state
= 2;
286 if (lat
[3].latency
< MAX_CX_STATE_LATENCY
) {
288 acpi_c3_exit_latency
= lat
[3].latency
;
289 acpi_max_c_state
= 3;
294 memset(throttle
, 0, sizeof(throttle
));
295 buf
.length
= sizeof(throttle
);
296 buf
.pointer
= throttle
;
298 if (!ACPI_SUCCESS(acpi_get_processor_throttling_info(handle
, &buf
)))
301 for (i
= 0, count
= 0; i
< ACPI_MAX_THROTTLE
; i
++) {
302 if (throttle
[i
].percent_of_clock
)
306 /* 0% throttled really doesn't count */
310 DEBUG_PRINT(ACPI_INFO
, ("%d throttling states\n", count
));
317 acpi_pm_timer_init(void)
319 FADT_DESCRIPTOR
*fadt
= &acpi_fadt
;
321 if (fadt
->tmr_val_ext
) {
322 acpi_pm_tmr_len
= 32;
324 acpi_pm_tmr_len
= 24;
327 DEBUG_PRINT(ACPI_INFO
, ("PM Timer width: %d bits\n", acpi_pm_tmr_len
));
335 acpi_walk_namespace(ACPI_TYPE_PROCESSOR
,
342 acpi_pm_timer_init();
346 if (smp_num_cpus
== 1)