diff options
-rw-r--r-- | arch/ppc/platforms/pmac_cpufreq.c | 236 | ||||
-rw-r--r-- | arch/ppc/platforms/pmac_feature.c | 26 | ||||
-rw-r--r-- | arch/ppc/syslib/open_pic.c | 5 | ||||
-rw-r--r-- | include/asm-ppc/open_pic.h | 1 | ||||
-rw-r--r-- | include/asm-ppc/reg.h | 1 |
5 files changed, 194 insertions, 75 deletions
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c index 9c85f9ca1cfb..f7fb2786cd50 100644 --- a/arch/ppc/platforms/pmac_cpufreq.c +++ b/arch/ppc/platforms/pmac_cpufreq.c | |||
@@ -1,13 +1,18 @@ | |||
1 | /* | 1 | /* |
2 | * arch/ppc/platforms/pmac_cpufreq.c | 2 | * arch/ppc/platforms/pmac_cpufreq.c |
3 | * | 3 | * |
4 | * Copyright (C) 2002 - 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org> | 4 | * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org> |
5 | * Copyright (C) 2004 John Steele Scott <toojays@toojays.net> | 5 | * Copyright (C) 2004 John Steele Scott <toojays@toojays.net> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | * | 10 | * |
11 | * TODO: Need a big cleanup here. Basically, we need to have different | ||
12 | * cpufreq_driver structures for the different type of HW instead of the | ||
13 | * current mess. We also need to better deal with the detection of the | ||
14 | * type of machine. | ||
15 | * | ||
11 | */ | 16 | */ |
12 | 17 | ||
13 | #include <linux/config.h> | 18 | #include <linux/config.h> |
@@ -35,6 +40,7 @@ | |||
35 | #include <asm/time.h> | 40 | #include <asm/time.h> |
36 | #include <asm/system.h> | 41 | #include <asm/system.h> |
37 | #include <asm/open_pic.h> | 42 | #include <asm/open_pic.h> |
43 | #include <asm/keylargo.h> | ||
38 | 44 | ||
39 | /* WARNING !!! This will cause calibrate_delay() to be called, | 45 | /* WARNING !!! This will cause calibrate_delay() to be called, |
40 | * but this is an __init function ! So you MUST go edit | 46 | * but this is an __init function ! So you MUST go edit |
@@ -61,11 +67,13 @@ extern void low_sleep_handler(void); | |||
61 | static unsigned int low_freq; | 67 | static unsigned int low_freq; |
62 | static unsigned int hi_freq; | 68 | static unsigned int hi_freq; |
63 | static unsigned int cur_freq; | 69 | static unsigned int cur_freq; |
70 | static unsigned int sleep_freq; | ||
64 | 71 | ||
65 | /* | 72 | /* |
66 | * Different models uses different mecanisms to switch the frequency | 73 | * Different models uses different mecanisms to switch the frequency |
67 | */ | 74 | */ |
68 | static int (*set_speed_proc)(int low_speed); | 75 | static int (*set_speed_proc)(int low_speed); |
76 | static unsigned int (*get_speed_proc)(void); | ||
69 | 77 | ||
70 | /* | 78 | /* |
71 | * Some definitions used by the various speedprocs | 79 | * Some definitions used by the various speedprocs |
@@ -73,6 +81,8 @@ static int (*set_speed_proc)(int low_speed); | |||
73 | static u32 voltage_gpio; | 81 | static u32 voltage_gpio; |
74 | static u32 frequency_gpio; | 82 | static u32 frequency_gpio; |
75 | static u32 slew_done_gpio; | 83 | static u32 slew_done_gpio; |
84 | static int no_schedule; | ||
85 | static int has_cpu_l2lve; | ||
76 | 86 | ||
77 | 87 | ||
78 | #define PMAC_CPU_LOW_SPEED 1 | 88 | #define PMAC_CPU_LOW_SPEED 1 |
@@ -90,6 +100,14 @@ static struct cpufreq_frequency_table pmac_cpu_freqs[] = { | |||
90 | {0, CPUFREQ_TABLE_END}, | 100 | {0, CPUFREQ_TABLE_END}, |
91 | }; | 101 | }; |
92 | 102 | ||
103 | static inline void local_delay(unsigned long ms) | ||
104 | { | ||
105 | if (no_schedule) | ||
106 | mdelay(ms); | ||
107 | else | ||
108 | msleep(ms); | ||
109 | } | ||
110 | |||
93 | static inline void wakeup_decrementer(void) | 111 | static inline void wakeup_decrementer(void) |
94 | { | 112 | { |
95 | set_dec(tb_ticks_per_jiffy); | 113 | set_dec(tb_ticks_per_jiffy); |
@@ -118,20 +136,48 @@ static inline void debug_calc_bogomips(void) | |||
118 | */ | 136 | */ |
119 | static int __pmac cpu_750fx_cpu_speed(int low_speed) | 137 | static int __pmac cpu_750fx_cpu_speed(int low_speed) |
120 | { | 138 | { |
121 | #ifdef DEBUG_FREQ | 139 | u32 hid2; |
122 | printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); | 140 | |
123 | #endif | 141 | if (low_speed == 0) { |
142 | /* ramping up, set voltage first */ | ||
143 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); | ||
144 | /* Make sure we sleep for at least 1ms */ | ||
145 | local_delay(10); | ||
146 | |||
147 | /* tweak L2 for high voltage */ | ||
148 | if (has_cpu_l2lve) { | ||
149 | hid2 = mfspr(SPRN_HID2); | ||
150 | hid2 &= ~0x2000; | ||
151 | mtspr(SPRN_HID2, hid2); | ||
152 | } | ||
153 | } | ||
124 | #ifdef CONFIG_6xx | 154 | #ifdef CONFIG_6xx |
125 | low_choose_750fx_pll(low_speed); | 155 | low_choose_750fx_pll(low_speed); |
126 | #endif | 156 | #endif |
127 | #ifdef DEBUG_FREQ | 157 | if (low_speed == 1) { |
128 | printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1)); | 158 | /* tweak L2 for low voltage */ |
129 | debug_calc_bogomips(); | 159 | if (has_cpu_l2lve) { |
130 | #endif | 160 | hid2 = mfspr(SPRN_HID2); |
161 | hid2 |= 0x2000; | ||
162 | mtspr(SPRN_HID2, hid2); | ||
163 | } | ||
164 | |||
165 | /* ramping down, set voltage last */ | ||
166 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); | ||
167 | local_delay(10); | ||
168 | } | ||
131 | 169 | ||
132 | return 0; | 170 | return 0; |
133 | } | 171 | } |
134 | 172 | ||
173 | static unsigned int __pmac cpu_750fx_get_cpu_speed(void) | ||
174 | { | ||
175 | if (mfspr(SPRN_HID1) & HID1_PS) | ||
176 | return low_freq; | ||
177 | else | ||
178 | return hi_freq; | ||
179 | } | ||
180 | |||
135 | /* Switch CPU speed using DFS */ | 181 | /* Switch CPU speed using DFS */ |
136 | static int __pmac dfs_set_cpu_speed(int low_speed) | 182 | static int __pmac dfs_set_cpu_speed(int low_speed) |
137 | { | 183 | { |
@@ -139,22 +185,25 @@ static int __pmac dfs_set_cpu_speed(int low_speed) | |||
139 | /* ramping up, set voltage first */ | 185 | /* ramping up, set voltage first */ |
140 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); | 186 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); |
141 | /* Make sure we sleep for at least 1ms */ | 187 | /* Make sure we sleep for at least 1ms */ |
142 | msleep(1); | 188 | local_delay(1); |
143 | } | 189 | } |
144 | 190 | ||
145 | /* set frequency */ | 191 | /* set frequency */ |
192 | #ifdef CONFIG_6xx | ||
146 | low_choose_7447a_dfs(low_speed); | 193 | low_choose_7447a_dfs(low_speed); |
194 | #endif | ||
195 | udelay(100); | ||
147 | 196 | ||
148 | if (low_speed == 1) { | 197 | if (low_speed == 1) { |
149 | /* ramping down, set voltage last */ | 198 | /* ramping down, set voltage last */ |
150 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); | 199 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); |
151 | msleep(1); | 200 | local_delay(1); |
152 | } | 201 | } |
153 | 202 | ||
154 | return 0; | 203 | return 0; |
155 | } | 204 | } |
156 | 205 | ||
157 | static unsigned int __pmac dfs_get_cpu_speed(unsigned int cpu) | 206 | static unsigned int __pmac dfs_get_cpu_speed(void) |
158 | { | 207 | { |
159 | if (mfspr(SPRN_HID1) & HID1_DFS) | 208 | if (mfspr(SPRN_HID1) & HID1_DFS) |
160 | return low_freq; | 209 | return low_freq; |
@@ -167,30 +216,35 @@ static unsigned int __pmac dfs_get_cpu_speed(unsigned int cpu) | |||
167 | */ | 216 | */ |
168 | static int __pmac gpios_set_cpu_speed(int low_speed) | 217 | static int __pmac gpios_set_cpu_speed(int low_speed) |
169 | { | 218 | { |
170 | int gpio; | 219 | int gpio, timeout = 0; |
171 | 220 | ||
172 | /* If ramping up, set voltage first */ | 221 | /* If ramping up, set voltage first */ |
173 | if (low_speed == 0) { | 222 | if (low_speed == 0) { |
174 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); | 223 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05); |
175 | /* Delay is way too big but it's ok, we schedule */ | 224 | /* Delay is way too big but it's ok, we schedule */ |
176 | msleep(10); | 225 | local_delay(10); |
177 | } | 226 | } |
178 | 227 | ||
179 | /* Set frequency */ | 228 | /* Set frequency */ |
229 | gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0); | ||
230 | if (low_speed == ((gpio & 0x01) == 0)) | ||
231 | goto skip; | ||
232 | |||
180 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio, | 233 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio, |
181 | low_speed ? 0x04 : 0x05); | 234 | low_speed ? 0x04 : 0x05); |
182 | udelay(200); | 235 | udelay(200); |
183 | do { | 236 | do { |
184 | set_current_state(TASK_UNINTERRUPTIBLE); | 237 | if (++timeout > 100) |
185 | schedule_timeout(1); | 238 | break; |
239 | local_delay(1); | ||
186 | gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0); | 240 | gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0); |
187 | } while((gpio & 0x02) == 0); | 241 | } while((gpio & 0x02) == 0); |
188 | 242 | skip: | |
189 | /* If ramping down, set voltage last */ | 243 | /* If ramping down, set voltage last */ |
190 | if (low_speed == 1) { | 244 | if (low_speed == 1) { |
191 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); | 245 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04); |
192 | /* Delay is way too big but it's ok, we schedule */ | 246 | /* Delay is way too big but it's ok, we schedule */ |
193 | msleep(10); | 247 | local_delay(10); |
194 | } | 248 | } |
195 | 249 | ||
196 | #ifdef DEBUG_FREQ | 250 | #ifdef DEBUG_FREQ |
@@ -207,6 +261,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed) | |||
207 | struct adb_request req; | 261 | struct adb_request req; |
208 | unsigned long save_l2cr; | 262 | unsigned long save_l2cr; |
209 | unsigned long save_l3cr; | 263 | unsigned long save_l3cr; |
264 | unsigned int pic_prio; | ||
265 | unsigned long flags; | ||
210 | 266 | ||
211 | preempt_disable(); | 267 | preempt_disable(); |
212 | 268 | ||
@@ -214,7 +270,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed) | |||
214 | printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); | 270 | printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); |
215 | #endif | 271 | #endif |
216 | /* Disable all interrupt sources on openpic */ | 272 | /* Disable all interrupt sources on openpic */ |
217 | openpic_set_priority(0xf); | 273 | pic_prio = openpic_get_priority(); |
274 | openpic_set_priority(0xf); | ||
218 | 275 | ||
219 | /* Make sure the decrementer won't interrupt us */ | 276 | /* Make sure the decrementer won't interrupt us */ |
220 | asm volatile("mtdec %0" : : "r" (0x7fffffff)); | 277 | asm volatile("mtdec %0" : : "r" (0x7fffffff)); |
@@ -224,7 +281,7 @@ static int __pmac pmu_set_cpu_speed(int low_speed) | |||
224 | asm volatile("mtdec %0" : : "r" (0x7fffffff)); | 281 | asm volatile("mtdec %0" : : "r" (0x7fffffff)); |
225 | 282 | ||
226 | /* We can now disable MSR_EE */ | 283 | /* We can now disable MSR_EE */ |
227 | local_irq_disable(); | 284 | local_irq_save(flags); |
228 | 285 | ||
229 | /* Giveup the FPU & vec */ | 286 | /* Giveup the FPU & vec */ |
230 | enable_kernel_fp(); | 287 | enable_kernel_fp(); |
@@ -277,10 +334,10 @@ static int __pmac pmu_set_cpu_speed(int low_speed) | |||
277 | wakeup_decrementer(); | 334 | wakeup_decrementer(); |
278 | 335 | ||
279 | /* Restore interrupts */ | 336 | /* Restore interrupts */ |
280 | openpic_set_priority(0); | 337 | openpic_set_priority(pic_prio); |
281 | 338 | ||
282 | /* Let interrupts flow again ... */ | 339 | /* Let interrupts flow again ... */ |
283 | local_irq_enable(); | 340 | local_irq_restore(flags); |
284 | 341 | ||
285 | #ifdef DEBUG_FREQ | 342 | #ifdef DEBUG_FREQ |
286 | debug_calc_bogomips(); | 343 | debug_calc_bogomips(); |
@@ -291,9 +348,11 @@ static int __pmac pmu_set_cpu_speed(int low_speed) | |||
291 | return 0; | 348 | return 0; |
292 | } | 349 | } |
293 | 350 | ||
294 | static int __pmac do_set_cpu_speed(int speed_mode) | 351 | static int __pmac do_set_cpu_speed(int speed_mode, int notify) |
295 | { | 352 | { |
296 | struct cpufreq_freqs freqs; | 353 | struct cpufreq_freqs freqs; |
354 | unsigned long l3cr; | ||
355 | static unsigned long prev_l3cr; | ||
297 | 356 | ||
298 | freqs.old = cur_freq; | 357 | freqs.old = cur_freq; |
299 | freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; | 358 | freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; |
@@ -302,14 +361,35 @@ static int __pmac do_set_cpu_speed(int speed_mode) | |||
302 | if (freqs.old == freqs.new) | 361 | if (freqs.old == freqs.new) |
303 | return 0; | 362 | return 0; |
304 | 363 | ||
305 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 364 | if (notify) |
365 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
366 | if (speed_mode == PMAC_CPU_LOW_SPEED && | ||
367 | cpu_has_feature(CPU_FTR_L3CR)) { | ||
368 | l3cr = _get_L3CR(); | ||
369 | if (l3cr & L3CR_L3E) { | ||
370 | prev_l3cr = l3cr; | ||
371 | _set_L3CR(0); | ||
372 | } | ||
373 | } | ||
306 | set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED); | 374 | set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED); |
307 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 375 | if (speed_mode == PMAC_CPU_HIGH_SPEED && |
376 | cpu_has_feature(CPU_FTR_L3CR)) { | ||
377 | l3cr = _get_L3CR(); | ||
378 | if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr) | ||
379 | _set_L3CR(prev_l3cr); | ||
380 | } | ||
381 | if (notify) | ||
382 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
308 | cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; | 383 | cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; |
309 | 384 | ||
310 | return 0; | 385 | return 0; |
311 | } | 386 | } |
312 | 387 | ||
388 | static unsigned int __pmac pmac_cpufreq_get_speed(unsigned int cpu) | ||
389 | { | ||
390 | return cur_freq; | ||
391 | } | ||
392 | |||
313 | static int __pmac pmac_cpufreq_verify(struct cpufreq_policy *policy) | 393 | static int __pmac pmac_cpufreq_verify(struct cpufreq_policy *policy) |
314 | { | 394 | { |
315 | return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs); | 395 | return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs); |
@@ -325,7 +405,7 @@ static int __pmac pmac_cpufreq_target( struct cpufreq_policy *policy, | |||
325 | target_freq, relation, &newstate)) | 405 | target_freq, relation, &newstate)) |
326 | return -EINVAL; | 406 | return -EINVAL; |
327 | 407 | ||
328 | return do_set_cpu_speed(newstate); | 408 | return do_set_cpu_speed(newstate, 1); |
329 | } | 409 | } |
330 | 410 | ||
331 | unsigned int __pmac pmac_get_one_cpufreq(int i) | 411 | unsigned int __pmac pmac_get_one_cpufreq(int i) |
@@ -349,19 +429,65 @@ static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
349 | static u32 __pmac read_gpio(struct device_node *np) | 429 | static u32 __pmac read_gpio(struct device_node *np) |
350 | { | 430 | { |
351 | u32 *reg = (u32 *)get_property(np, "reg", NULL); | 431 | u32 *reg = (u32 *)get_property(np, "reg", NULL); |
432 | u32 offset; | ||
352 | 433 | ||
353 | if (reg == NULL) | 434 | if (reg == NULL) |
354 | return 0; | 435 | return 0; |
355 | /* That works for all keylargos but shall be fixed properly | 436 | /* That works for all keylargos but shall be fixed properly |
356 | * some day... | 437 | * some day... The problem is that it seems we can't rely |
438 | * on the "reg" property of the GPIO nodes, they are either | ||
439 | * relative to the base of KeyLargo or to the base of the | ||
440 | * GPIO space, and the device-tree doesn't help. | ||
441 | */ | ||
442 | offset = *reg; | ||
443 | if (offset < KEYLARGO_GPIO_LEVELS0) | ||
444 | offset += KEYLARGO_GPIO_LEVELS0; | ||
445 | return offset; | ||
446 | } | ||
447 | |||
448 | static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state) | ||
449 | { | ||
450 | /* Ok, this could be made a bit smarter, but let's be robust for now. We | ||
451 | * always force a speed change to high speed before sleep, to make sure | ||
452 | * we have appropriate voltage and/or bus speed for the wakeup process, | ||
453 | * and to make sure our loops_per_jiffies are "good enough", that is will | ||
454 | * not cause too short delays if we sleep in low speed and wake in high | ||
455 | * speed.. | ||
357 | */ | 456 | */ |
358 | return 0x50 + (*reg); | 457 | no_schedule = 1; |
458 | sleep_freq = cur_freq; | ||
459 | if (cur_freq == low_freq) | ||
460 | do_set_cpu_speed(PMAC_CPU_HIGH_SPEED, 0); | ||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | static int __pmac pmac_cpufreq_resume(struct cpufreq_policy *policy) | ||
465 | { | ||
466 | /* If we resume, first check if we have a get() function */ | ||
467 | if (get_speed_proc) | ||
468 | cur_freq = get_speed_proc(); | ||
469 | else | ||
470 | cur_freq = 0; | ||
471 | |||
472 | /* We don't, hrm... we don't really know our speed here, best | ||
473 | * is that we force a switch to whatever it was, which is | ||
474 | * probably high speed due to our suspend() routine | ||
475 | */ | ||
476 | do_set_cpu_speed(sleep_freq == low_freq ? PMAC_CPU_LOW_SPEED | ||
477 | : PMAC_CPU_HIGH_SPEED, 0); | ||
478 | |||
479 | no_schedule = 0; | ||
480 | return 0; | ||
359 | } | 481 | } |
360 | 482 | ||
361 | static struct cpufreq_driver pmac_cpufreq_driver = { | 483 | static struct cpufreq_driver pmac_cpufreq_driver = { |
362 | .verify = pmac_cpufreq_verify, | 484 | .verify = pmac_cpufreq_verify, |
363 | .target = pmac_cpufreq_target, | 485 | .target = pmac_cpufreq_target, |
486 | .get = pmac_cpufreq_get_speed, | ||
364 | .init = pmac_cpufreq_cpu_init, | 487 | .init = pmac_cpufreq_cpu_init, |
488 | .suspend = pmac_cpufreq_suspend, | ||
489 | .resume = pmac_cpufreq_resume, | ||
490 | .flags = CPUFREQ_PM_NO_WARN, | ||
365 | .name = "powermac", | 491 | .name = "powermac", |
366 | .owner = THIS_MODULE, | 492 | .owner = THIS_MODULE, |
367 | }; | 493 | }; |
@@ -461,14 +587,14 @@ static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) | |||
461 | static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode) | 587 | static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode) |
462 | { | 588 | { |
463 | struct device_node *volt_gpio_np; | 589 | struct device_node *volt_gpio_np; |
464 | u32 *reg; | ||
465 | struct cpufreq_driver *driver = &pmac_cpufreq_driver; | ||
466 | 590 | ||
467 | /* Look for voltage GPIO */ | 591 | if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) |
592 | return 1; | ||
593 | |||
468 | volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select"); | 594 | volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select"); |
469 | reg = (u32 *)get_property(volt_gpio_np, "reg", NULL); | 595 | if (volt_gpio_np) |
470 | voltage_gpio = *reg; | 596 | voltage_gpio = read_gpio(volt_gpio_np); |
471 | if (!volt_gpio_np){ | 597 | if (!voltage_gpio){ |
472 | printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n"); | 598 | printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n"); |
473 | return 1; | 599 | return 1; |
474 | } | 600 | } |
@@ -478,9 +604,37 @@ static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode) | |||
478 | low_freq = cur_freq/2; | 604 | low_freq = cur_freq/2; |
479 | 605 | ||
480 | /* Read actual frequency from CPU */ | 606 | /* Read actual frequency from CPU */ |
481 | driver->get = dfs_get_cpu_speed; | 607 | cur_freq = dfs_get_cpu_speed(); |
482 | cur_freq = driver->get(0); | ||
483 | set_speed_proc = dfs_set_cpu_speed; | 608 | set_speed_proc = dfs_set_cpu_speed; |
609 | get_speed_proc = dfs_get_cpu_speed; | ||
610 | |||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | static int __pmac pmac_cpufreq_init_750FX(struct device_node *cpunode) | ||
615 | { | ||
616 | struct device_node *volt_gpio_np; | ||
617 | u32 pvr, *value; | ||
618 | |||
619 | if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) | ||
620 | return 1; | ||
621 | |||
622 | hi_freq = cur_freq; | ||
623 | value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL); | ||
624 | if (!value) | ||
625 | return 1; | ||
626 | low_freq = (*value) / 1000; | ||
627 | |||
628 | volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select"); | ||
629 | if (volt_gpio_np) | ||
630 | voltage_gpio = read_gpio(volt_gpio_np); | ||
631 | |||
632 | pvr = mfspr(SPRN_PVR); | ||
633 | has_cpu_l2lve = !((pvr & 0xf00) == 0x100); | ||
634 | |||
635 | set_speed_proc = cpu_750fx_cpu_speed; | ||
636 | get_speed_proc = cpu_750fx_get_cpu_speed; | ||
637 | cur_freq = cpu_750fx_get_cpu_speed(); | ||
484 | 638 | ||
485 | return 0; | 639 | return 0; |
486 | } | 640 | } |
@@ -543,16 +697,8 @@ static int __init pmac_cpufreq_setup(void) | |||
543 | set_speed_proc = pmu_set_cpu_speed; | 697 | set_speed_proc = pmu_set_cpu_speed; |
544 | } | 698 | } |
545 | /* Else check for 750FX */ | 699 | /* Else check for 750FX */ |
546 | else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000) { | 700 | else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000) |
547 | if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) | 701 | pmac_cpufreq_init_750FX(cpunode); |
548 | goto out; | ||
549 | hi_freq = cur_freq; | ||
550 | value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL); | ||
551 | if (!value) | ||
552 | goto out; | ||
553 | low_freq = (*value) / 1000; | ||
554 | set_speed_proc = cpu_750fx_cpu_speed; | ||
555 | } | ||
556 | out: | 702 | out: |
557 | if (set_speed_proc == NULL) | 703 | if (set_speed_proc == NULL) |
558 | return -ENODEV; | 704 | return -ENODEV; |
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c index 8e60550863a6..eda9c80746a4 100644 --- a/arch/ppc/platforms/pmac_feature.c +++ b/arch/ppc/platforms/pmac_feature.c | |||
@@ -1779,32 +1779,6 @@ core99_sleep_state(struct device_node* node, long param, long value) | |||
1779 | if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) | 1779 | if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) |
1780 | return -EPERM; | 1780 | return -EPERM; |
1781 | 1781 | ||
1782 | #ifdef CONFIG_CPU_FREQ_PMAC | ||
1783 | /* XXX should be elsewhere */ | ||
1784 | if (machine_is_compatible("PowerBook6,5") || | ||
1785 | machine_is_compatible("PowerBook6,4") || | ||
1786 | machine_is_compatible("PowerBook5,5") || | ||
1787 | machine_is_compatible("PowerBook5,4")) { | ||
1788 | struct device_node *volt_gpio_np; | ||
1789 | u32 *reg = NULL; | ||
1790 | |||
1791 | volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select"); | ||
1792 | if (volt_gpio_np != NULL) | ||
1793 | reg = (u32 *)get_property(volt_gpio_np, "reg", NULL); | ||
1794 | if (reg != NULL) { | ||
1795 | /* Set the CPU voltage high if sleeping */ | ||
1796 | if (value == 1) { | ||
1797 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, | ||
1798 | *reg, 0x05); | ||
1799 | } else if (value == 0 && (mfspr(SPRN_HID1) & HID1_DFS)) { | ||
1800 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, | ||
1801 | *reg, 0x04); | ||
1802 | } | ||
1803 | mdelay(2); | ||
1804 | } | ||
1805 | } | ||
1806 | #endif /* CONFIG_CPU_FREQ_PMAC */ | ||
1807 | |||
1808 | if (value == 1) | 1782 | if (value == 1) |
1809 | return core99_sleep(); | 1783 | return core99_sleep(); |
1810 | else if (value == 0) | 1784 | else if (value == 0) |
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index 406f36a8a681..7619e16fccae 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c | |||
@@ -78,7 +78,6 @@ static void openpic_mapirq(u_int irq, cpumask_t cpumask, cpumask_t keepmask); | |||
78 | */ | 78 | */ |
79 | #ifdef notused | 79 | #ifdef notused |
80 | static void openpic_enable_8259_pass_through(void); | 80 | static void openpic_enable_8259_pass_through(void); |
81 | static u_int openpic_get_priority(void); | ||
82 | static u_int openpic_get_spurious(void); | 81 | static u_int openpic_get_spurious(void); |
83 | static void openpic_set_sense(u_int irq, int sense); | 82 | static void openpic_set_sense(u_int irq, int sense); |
84 | #endif /* notused */ | 83 | #endif /* notused */ |
@@ -465,8 +464,7 @@ void openpic_eoi(void) | |||
465 | (void)openpic_read(&OpenPIC->THIS_CPU.EOI); | 464 | (void)openpic_read(&OpenPIC->THIS_CPU.EOI); |
466 | } | 465 | } |
467 | 466 | ||
468 | #ifdef notused | 467 | u_int openpic_get_priority(void) |
469 | static u_int openpic_get_priority(void) | ||
470 | { | 468 | { |
471 | DECL_THIS_CPU; | 469 | DECL_THIS_CPU; |
472 | 470 | ||
@@ -474,7 +472,6 @@ static u_int openpic_get_priority(void) | |||
474 | return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority, | 472 | return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority, |
475 | OPENPIC_CURRENT_TASK_PRIORITY_MASK); | 473 | OPENPIC_CURRENT_TASK_PRIORITY_MASK); |
476 | } | 474 | } |
477 | #endif /* notused */ | ||
478 | 475 | ||
479 | void openpic_set_priority(u_int pri) | 476 | void openpic_set_priority(u_int pri) |
480 | { | 477 | { |
diff --git a/include/asm-ppc/open_pic.h b/include/asm-ppc/open_pic.h index 58545e4cdbc0..dbe853319741 100644 --- a/include/asm-ppc/open_pic.h +++ b/include/asm-ppc/open_pic.h | |||
@@ -56,6 +56,7 @@ extern void smp_openpic_message_pass(int target, int msg, unsigned long data, | |||
56 | int wait); | 56 | int wait); |
57 | extern void openpic_set_k2_cascade(int irq); | 57 | extern void openpic_set_k2_cascade(int irq); |
58 | extern void openpic_set_priority(u_int pri); | 58 | extern void openpic_set_priority(u_int pri); |
59 | extern u_int openpic_get_priority(void); | ||
59 | 60 | ||
60 | extern inline int openpic_to_irq(int irq) | 61 | extern inline int openpic_to_irq(int irq) |
61 | { | 62 | { |
diff --git a/include/asm-ppc/reg.h b/include/asm-ppc/reg.h index 3372dee36a8c..c418aab7cd34 100644 --- a/include/asm-ppc/reg.h +++ b/include/asm-ppc/reg.h | |||
@@ -181,6 +181,7 @@ | |||
181 | #define HID1_PC3 (1<<13) /* 7450 PLL_CFG[3] */ | 181 | #define HID1_PC3 (1<<13) /* 7450 PLL_CFG[3] */ |
182 | #define HID1_SYNCBE (1<<11) /* 7450 ABE for sync, eieio */ | 182 | #define HID1_SYNCBE (1<<11) /* 7450 ABE for sync, eieio */ |
183 | #define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */ | 183 | #define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */ |
184 | #define HID1_PS (1<<16) /* 750FX PLL selection */ | ||
184 | #define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */ | 185 | #define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */ |
185 | #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ | 186 | #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ |
186 | #define SPRN_HID4 0x3F4 /* 970 HID4 */ | 187 | #define SPRN_HID4 0x3F4 /* 970 HID4 */ |