diff options
author | Paul Mackerras <paulus@samba.org> | 2005-10-22 02:02:39 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-10-22 02:02:39 -0400 |
commit | 35499c0195e46f479cf6ac16ad8d3f394b5fcc10 (patch) | |
tree | 25660acd2425de5236a1eff7a25dc931e6f86492 /arch/powerpc/platforms/powermac/setup.c | |
parent | b6ba92819dc1304a4e5a0bf06b297c657b58168a (diff) |
powerpc: Merge in 64-bit powermac support.
This brings in a lot of changes from arch/ppc64/kernel/pmac_*.c to
arch/powerpc/platforms/powermac/*.c and makes various minor tweaks
elsewhere. On the powermac we now initialize ppc_md by copying
the whole pmac_md structure into it, which required some changes in
the ordering of initializations of individual fields of it.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/powermac/setup.c')
-rw-r--r-- | arch/powerpc/platforms/powermac/setup.c | 458 |
1 files changed, 314 insertions, 144 deletions
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 0bad53fa36ef..da0cb165dfc6 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c | |||
@@ -1,11 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * arch/ppc/platforms/setup.c | 2 | * Powermac setup and early boot code plus other random bits. |
3 | * | 3 | * |
4 | * PowerPC version | 4 | * PowerPC version |
5 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | 5 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) |
6 | * | 6 | * |
7 | * Adapted for Power Macintosh by Paul Mackerras | 7 | * Adapted for Power Macintosh by Paul Mackerras |
8 | * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) | 8 | * Copyright (C) 1996 Paul Mackerras (paulus@samba.org) |
9 | * | 9 | * |
10 | * Derived from "arch/alpha/kernel/setup.c" | 10 | * Derived from "arch/alpha/kernel/setup.c" |
11 | * Copyright (C) 1995 Linus Torvalds | 11 | * Copyright (C) 1995 Linus Torvalds |
@@ -65,13 +65,16 @@ | |||
65 | #include <asm/mediabay.h> | 65 | #include <asm/mediabay.h> |
66 | #include <asm/machdep.h> | 66 | #include <asm/machdep.h> |
67 | #include <asm/dma.h> | 67 | #include <asm/dma.h> |
68 | #include <asm/bootx.h> | ||
69 | #include <asm/cputable.h> | 68 | #include <asm/cputable.h> |
70 | #include <asm/btext.h> | 69 | #include <asm/btext.h> |
71 | #include <asm/pmac_feature.h> | 70 | #include <asm/pmac_feature.h> |
72 | #include <asm/time.h> | 71 | #include <asm/time.h> |
73 | #include <asm/of_device.h> | 72 | #include <asm/of_device.h> |
74 | #include <asm/mmu_context.h> | 73 | #include <asm/mmu_context.h> |
74 | #include <asm/iommu.h> | ||
75 | #include <asm/smu.h> | ||
76 | #include <asm/pmc.h> | ||
77 | #include <asm/mpic.h> | ||
75 | 78 | ||
76 | #include "pmac.h" | 79 | #include "pmac.h" |
77 | 80 | ||
@@ -88,16 +91,24 @@ int pmac_newworld = 1; | |||
88 | static int current_root_goodness = -1; | 91 | static int current_root_goodness = -1; |
89 | 92 | ||
90 | extern int pmac_newworld; | 93 | extern int pmac_newworld; |
94 | extern struct machdep_calls pmac_md; | ||
91 | 95 | ||
92 | #define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ | 96 | #define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ |
93 | 97 | ||
94 | extern void zs_kgdb_hook(int tty_num); | 98 | #ifdef CONFIG_PPC64 |
95 | static void ohare_init(void); | 99 | #include <asm/udbg.h> |
96 | #ifdef CONFIG_BOOTX_TEXT | 100 | int sccdbg; |
97 | static void pmac_progress(char *s, unsigned short hex); | ||
98 | #endif | 101 | #endif |
99 | 102 | ||
103 | extern void zs_kgdb_hook(int tty_num); | ||
104 | |||
100 | sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN; | 105 | sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN; |
106 | EXPORT_SYMBOL(sys_ctrler); | ||
107 | |||
108 | #ifdef CONFIG_PMAC_SMU | ||
109 | unsigned long smu_cmdbuf_abs; | ||
110 | EXPORT_SYMBOL(smu_cmdbuf_abs); | ||
111 | #endif | ||
101 | 112 | ||
102 | #ifdef CONFIG_SMP | 113 | #ifdef CONFIG_SMP |
103 | extern struct smp_ops_t psurge_smp_ops; | 114 | extern struct smp_ops_t psurge_smp_ops; |
@@ -191,44 +202,69 @@ static void pmac_show_percpuinfo(struct seq_file *m, int i) | |||
191 | return; | 202 | return; |
192 | } | 203 | } |
193 | #endif /* CONFIG_CPU_FREQ_PMAC */ | 204 | #endif /* CONFIG_CPU_FREQ_PMAC */ |
205 | #ifdef CONFIG_PPC32 | ||
194 | of_show_percpuinfo(m, i); | 206 | of_show_percpuinfo(m, i); |
207 | #endif | ||
195 | } | 208 | } |
196 | 209 | ||
197 | static volatile u32 *sysctrl_regs; | 210 | #ifndef CONFIG_ADB_CUDA |
211 | int find_via_cuda(void) | ||
212 | { | ||
213 | if (!find_devices("via-cuda")) | ||
214 | return 0; | ||
215 | printk("WARNING ! Your machine is CUDA-based but your kernel\n"); | ||
216 | printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n"); | ||
217 | return 0; | ||
218 | } | ||
219 | #endif | ||
198 | 220 | ||
199 | void __init | 221 | #ifndef CONFIG_ADB_PMU |
200 | pmac_setup_arch(void) | 222 | int find_via_pmu(void) |
201 | { | 223 | { |
202 | struct device_node *cpu; | 224 | if (!find_devices("via-pmu")) |
203 | int *fp; | 225 | return 0; |
204 | unsigned long pvr; | 226 | printk("WARNING ! Your machine is PMU-based but your kernel\n"); |
227 | printk(" wasn't compiled with CONFIG_ADB_PMU option !\n"); | ||
228 | return; | ||
229 | } | ||
230 | #endif | ||
205 | 231 | ||
206 | pvr = PVR_VER(mfspr(SPRN_PVR)); | 232 | #ifndef CONFIG_PMAC_SMU |
233 | int smu_init(void) | ||
234 | { | ||
235 | /* should check and warn if SMU is present */ | ||
236 | return 0; | ||
237 | } | ||
238 | #endif | ||
207 | 239 | ||
208 | /* Set loops_per_jiffy to a half-way reasonable value, | 240 | #ifdef CONFIG_PPC32 |
209 | for use until calibrate_delay gets called. */ | 241 | static volatile u32 *sysctrl_regs; |
210 | cpu = find_type_devices("cpu"); | ||
211 | if (cpu != 0) { | ||
212 | fp = (int *) get_property(cpu, "clock-frequency", NULL); | ||
213 | if (fp != 0) { | ||
214 | if (pvr == 4 || pvr >= 8) | ||
215 | /* 604, G3, G4 etc. */ | ||
216 | loops_per_jiffy = *fp / HZ; | ||
217 | else | ||
218 | /* 601, 603, etc. */ | ||
219 | loops_per_jiffy = *fp / (2*HZ); | ||
220 | } else | ||
221 | loops_per_jiffy = 50000000 / HZ; | ||
222 | } | ||
223 | 242 | ||
243 | static void __init ohare_init(void) | ||
244 | { | ||
224 | /* this area has the CPU identification register | 245 | /* this area has the CPU identification register |
225 | and some registers used by smp boards */ | 246 | and some registers used by smp boards */ |
226 | sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000); | 247 | sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000); |
227 | ohare_init(); | ||
228 | 248 | ||
229 | /* Lookup PCI hosts */ | 249 | /* |
230 | pmac_find_bridges(); | 250 | * Turn on the L2 cache. |
251 | * We assume that we have a PSX memory controller iff | ||
252 | * we have an ohare I/O controller. | ||
253 | */ | ||
254 | if (find_devices("ohare") != NULL) { | ||
255 | if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) { | ||
256 | if (sysctrl_regs[4] & 0x10) | ||
257 | sysctrl_regs[4] |= 0x04000020; | ||
258 | else | ||
259 | sysctrl_regs[4] |= 0x04000000; | ||
260 | if(has_l2cache) | ||
261 | printk(KERN_INFO "Level 2 cache enabled\n"); | ||
262 | } | ||
263 | } | ||
264 | } | ||
231 | 265 | ||
266 | static void __init l2cr_init(void) | ||
267 | { | ||
232 | /* Checks "l2cr-value" property in the registry */ | 268 | /* Checks "l2cr-value" property in the registry */ |
233 | if (cpu_has_feature(CPU_FTR_L2CR)) { | 269 | if (cpu_has_feature(CPU_FTR_L2CR)) { |
234 | struct device_node *np = find_devices("cpus"); | 270 | struct device_node *np = find_devices("cpus"); |
@@ -247,68 +283,90 @@ pmac_setup_arch(void) | |||
247 | } | 283 | } |
248 | 284 | ||
249 | if (ppc_override_l2cr) | 285 | if (ppc_override_l2cr) |
250 | printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n", | 286 | printk(KERN_INFO "L2CR overridden (0x%x), " |
251 | ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000) | 287 | "backside cache is %s\n", |
288 | ppc_override_l2cr_value, | ||
289 | (ppc_override_l2cr_value & 0x80000000) | ||
252 | ? "enabled" : "disabled"); | 290 | ? "enabled" : "disabled"); |
291 | } | ||
292 | #endif | ||
293 | |||
294 | void __init pmac_setup_arch(void) | ||
295 | { | ||
296 | struct device_node *cpu; | ||
297 | int *fp; | ||
298 | unsigned long pvr; | ||
299 | |||
300 | pvr = PVR_VER(mfspr(SPRN_PVR)); | ||
301 | |||
302 | /* Set loops_per_jiffy to a half-way reasonable value, | ||
303 | for use until calibrate_delay gets called. */ | ||
304 | loops_per_jiffy = 50000000 / HZ; | ||
305 | cpu = of_find_node_by_type(NULL, "cpu"); | ||
306 | if (cpu != NULL) { | ||
307 | fp = (int *) get_property(cpu, "clock-frequency", NULL); | ||
308 | if (fp != NULL) { | ||
309 | if (pvr >= 0x30 && pvr < 0x80) | ||
310 | /* PPC970 etc. */ | ||
311 | loops_per_jiffy = *fp / (3 * HZ); | ||
312 | else if (pvr == 4 || pvr >= 8) | ||
313 | /* 604, G3, G4 etc. */ | ||
314 | loops_per_jiffy = *fp / HZ; | ||
315 | else | ||
316 | /* 601, 603, etc. */ | ||
317 | loops_per_jiffy = *fp / (2 * HZ); | ||
318 | } | ||
319 | of_node_put(cpu); | ||
320 | } | ||
321 | |||
322 | /* Lookup PCI hosts */ | ||
323 | pmac_pci_init(); | ||
324 | |||
325 | #ifdef CONFIG_PPC32 | ||
326 | ohare_init(); | ||
327 | l2cr_init(); | ||
328 | #endif /* CONFIG_PPC32 */ | ||
329 | |||
330 | #ifdef CONFIG_PPC64 | ||
331 | /* Probe motherboard chipset */ | ||
332 | /* this is done earlier in setup_arch for 32-bit */ | ||
333 | pmac_feature_init(); | ||
334 | |||
335 | /* We can NAP */ | ||
336 | powersave_nap = 1; | ||
337 | printk(KERN_INFO "Using native/NAP idle loop\n"); | ||
338 | #endif | ||
253 | 339 | ||
254 | #ifdef CONFIG_KGDB | 340 | #ifdef CONFIG_KGDB |
255 | zs_kgdb_hook(0); | 341 | zs_kgdb_hook(0); |
256 | #endif | 342 | #endif |
257 | 343 | ||
258 | #ifdef CONFIG_ADB_CUDA | ||
259 | find_via_cuda(); | 344 | find_via_cuda(); |
260 | #else | ||
261 | if (find_devices("via-cuda")) { | ||
262 | printk("WARNING ! Your machine is Cuda based but your kernel\n"); | ||
263 | printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n"); | ||
264 | } | ||
265 | #endif | ||
266 | #ifdef CONFIG_ADB_PMU | ||
267 | find_via_pmu(); | 345 | find_via_pmu(); |
268 | #else | 346 | smu_init(); |
269 | if (find_devices("via-pmu")) { | 347 | |
270 | printk("WARNING ! Your machine is PMU based but your kernel\n"); | ||
271 | printk(" wasn't compiled with CONFIG_ADB_PMU option !\n"); | ||
272 | } | ||
273 | #endif | ||
274 | #ifdef CONFIG_NVRAM | 348 | #ifdef CONFIG_NVRAM |
275 | pmac_nvram_init(); | 349 | pmac_nvram_init(); |
276 | #endif | 350 | #endif |
351 | |||
352 | #ifdef CONFIG_PPC32 | ||
277 | #ifdef CONFIG_BLK_DEV_INITRD | 353 | #ifdef CONFIG_BLK_DEV_INITRD |
278 | if (initrd_start) | 354 | if (initrd_start) |
279 | ROOT_DEV = Root_RAM0; | 355 | ROOT_DEV = Root_RAM0; |
280 | else | 356 | else |
281 | #endif | 357 | #endif |
282 | ROOT_DEV = DEFAULT_ROOT_DEVICE; | 358 | ROOT_DEV = DEFAULT_ROOT_DEVICE; |
359 | #endif | ||
283 | 360 | ||
284 | #ifdef CONFIG_SMP | 361 | #ifdef CONFIG_SMP |
285 | /* Check for Core99 */ | 362 | /* Check for Core99 */ |
286 | if (find_devices("uni-n") || find_devices("u3")) | 363 | if (find_devices("uni-n") || find_devices("u3")) |
287 | smp_ops = &core99_smp_ops; | 364 | smp_ops = &core99_smp_ops; |
365 | #ifdef CONFIG_PPC32 | ||
288 | else | 366 | else |
289 | smp_ops = &psurge_smp_ops; | 367 | smp_ops = &psurge_smp_ops; |
368 | #endif | ||
290 | #endif /* CONFIG_SMP */ | 369 | #endif /* CONFIG_SMP */ |
291 | |||
292 | pci_create_OF_bus_map(); | ||
293 | } | ||
294 | |||
295 | static void __init ohare_init(void) | ||
296 | { | ||
297 | /* | ||
298 | * Turn on the L2 cache. | ||
299 | * We assume that we have a PSX memory controller iff | ||
300 | * we have an ohare I/O controller. | ||
301 | */ | ||
302 | if (find_devices("ohare") != NULL) { | ||
303 | if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) { | ||
304 | if (sysctrl_regs[4] & 0x10) | ||
305 | sysctrl_regs[4] |= 0x04000020; | ||
306 | else | ||
307 | sysctrl_regs[4] |= 0x04000000; | ||
308 | if(has_l2cache) | ||
309 | printk(KERN_INFO "Level 2 cache enabled\n"); | ||
310 | } | ||
311 | } | ||
312 | } | 370 | } |
313 | 371 | ||
314 | char *bootpath; | 372 | char *bootpath; |
@@ -319,8 +377,7 @@ int boot_part; | |||
319 | extern dev_t boot_dev; | 377 | extern dev_t boot_dev; |
320 | 378 | ||
321 | #ifdef CONFIG_SCSI | 379 | #ifdef CONFIG_SCSI |
322 | void __init | 380 | void __init note_scsi_host(struct device_node *node, void *host) |
323 | note_scsi_host(struct device_node *node, void *host) | ||
324 | { | 381 | { |
325 | int l; | 382 | int l; |
326 | char *p; | 383 | char *p; |
@@ -351,8 +408,7 @@ EXPORT_SYMBOL(note_scsi_host); | |||
351 | #endif | 408 | #endif |
352 | 409 | ||
353 | #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) | 410 | #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) |
354 | static dev_t __init | 411 | static dev_t __init find_ide_boot(void) |
355 | find_ide_boot(void) | ||
356 | { | 412 | { |
357 | char *p; | 413 | char *p; |
358 | int n; | 414 | int n; |
@@ -369,15 +425,13 @@ find_ide_boot(void) | |||
369 | } | 425 | } |
370 | #endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */ | 426 | #endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */ |
371 | 427 | ||
372 | static void __init | 428 | static void __init find_boot_device(void) |
373 | find_boot_device(void) | ||
374 | { | 429 | { |
375 | #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) | 430 | #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) |
376 | boot_dev = find_ide_boot(); | 431 | boot_dev = find_ide_boot(); |
377 | #endif | 432 | #endif |
378 | } | 433 | } |
379 | 434 | ||
380 | static int initializing = 1; | ||
381 | /* TODO: Merge the suspend-to-ram with the common code !!! | 435 | /* TODO: Merge the suspend-to-ram with the common code !!! |
382 | * currently, this is a stub implementation for suspend-to-disk | 436 | * currently, this is a stub implementation for suspend-to-disk |
383 | * only | 437 | * only |
@@ -428,6 +482,8 @@ static struct pm_ops pmac_pm_ops = { | |||
428 | 482 | ||
429 | #endif /* CONFIG_SOFTWARE_SUSPEND */ | 483 | #endif /* CONFIG_SOFTWARE_SUSPEND */ |
430 | 484 | ||
485 | static int initializing = 1; | ||
486 | |||
431 | static int pmac_late_init(void) | 487 | static int pmac_late_init(void) |
432 | { | 488 | { |
433 | initializing = 0; | 489 | initializing = 0; |
@@ -440,8 +496,7 @@ static int pmac_late_init(void) | |||
440 | late_initcall(pmac_late_init); | 496 | late_initcall(pmac_late_init); |
441 | 497 | ||
442 | /* can't be __init - can be called whenever a disk is first accessed */ | 498 | /* can't be __init - can be called whenever a disk is first accessed */ |
443 | void | 499 | void note_bootable_part(dev_t dev, int part, int goodness) |
444 | note_bootable_part(dev_t dev, int part, int goodness) | ||
445 | { | 500 | { |
446 | static int found_boot = 0; | 501 | static int found_boot = 0; |
447 | char *p; | 502 | char *p; |
@@ -466,52 +521,68 @@ note_bootable_part(dev_t dev, int part, int goodness) | |||
466 | } | 521 | } |
467 | } | 522 | } |
468 | 523 | ||
469 | static void | ||
470 | pmac_restart(char *cmd) | ||
471 | { | ||
472 | #ifdef CONFIG_ADB_CUDA | 524 | #ifdef CONFIG_ADB_CUDA |
525 | static void cuda_restart(void) | ||
526 | { | ||
473 | struct adb_request req; | 527 | struct adb_request req; |
474 | #endif /* CONFIG_ADB_CUDA */ | ||
475 | 528 | ||
529 | cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM); | ||
530 | for (;;) | ||
531 | cuda_poll(); | ||
532 | } | ||
533 | |||
534 | static void cuda_shutdown(void) | ||
535 | { | ||
536 | struct adb_request req; | ||
537 | |||
538 | cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN); | ||
539 | for (;;) | ||
540 | cuda_poll(); | ||
541 | } | ||
542 | |||
543 | #else | ||
544 | #define cuda_restart() | ||
545 | #define cuda_shutdown() | ||
546 | #endif | ||
547 | |||
548 | #ifndef CONFIG_ADB_PMU | ||
549 | #define pmu_restart() | ||
550 | #define pmu_shutdown() | ||
551 | #endif | ||
552 | |||
553 | #ifndef CONFIG_PMAC_SMU | ||
554 | #define smu_restart() | ||
555 | #define smu_shutdown() | ||
556 | #endif | ||
557 | |||
558 | static void pmac_restart(char *cmd) | ||
559 | { | ||
476 | switch (sys_ctrler) { | 560 | switch (sys_ctrler) { |
477 | #ifdef CONFIG_ADB_CUDA | ||
478 | case SYS_CTRLER_CUDA: | 561 | case SYS_CTRLER_CUDA: |
479 | cuda_request(&req, NULL, 2, CUDA_PACKET, | 562 | cuda_restart(); |
480 | CUDA_RESET_SYSTEM); | ||
481 | for (;;) | ||
482 | cuda_poll(); | ||
483 | break; | 563 | break; |
484 | #endif /* CONFIG_ADB_CUDA */ | ||
485 | #ifdef CONFIG_ADB_PMU | ||
486 | case SYS_CTRLER_PMU: | 564 | case SYS_CTRLER_PMU: |
487 | pmu_restart(); | 565 | pmu_restart(); |
488 | break; | 566 | break; |
489 | #endif /* CONFIG_ADB_PMU */ | 567 | case SYS_CTRLER_SMU: |
568 | smu_restart(); | ||
569 | break; | ||
490 | default: ; | 570 | default: ; |
491 | } | 571 | } |
492 | } | 572 | } |
493 | 573 | ||
494 | static void | 574 | static void pmac_power_off(void) |
495 | pmac_power_off(void) | ||
496 | { | 575 | { |
497 | #ifdef CONFIG_ADB_CUDA | ||
498 | struct adb_request req; | ||
499 | #endif /* CONFIG_ADB_CUDA */ | ||
500 | |||
501 | switch (sys_ctrler) { | 576 | switch (sys_ctrler) { |
502 | #ifdef CONFIG_ADB_CUDA | ||
503 | case SYS_CTRLER_CUDA: | 577 | case SYS_CTRLER_CUDA: |
504 | cuda_request(&req, NULL, 2, CUDA_PACKET, | 578 | cuda_shutdown(); |
505 | CUDA_POWERDOWN); | ||
506 | for (;;) | ||
507 | cuda_poll(); | ||
508 | break; | 579 | break; |
509 | #endif /* CONFIG_ADB_CUDA */ | ||
510 | #ifdef CONFIG_ADB_PMU | ||
511 | case SYS_CTRLER_PMU: | 580 | case SYS_CTRLER_PMU: |
512 | pmu_shutdown(); | 581 | pmu_shutdown(); |
513 | break; | 582 | break; |
514 | #endif /* CONFIG_ADB_PMU */ | 583 | case SYS_CTRLER_SMU: |
584 | smu_shutdown(); | ||
585 | break; | ||
515 | default: ; | 586 | default: ; |
516 | } | 587 | } |
517 | } | 588 | } |
@@ -522,37 +593,17 @@ pmac_halt(void) | |||
522 | pmac_power_off(); | 593 | pmac_power_off(); |
523 | } | 594 | } |
524 | 595 | ||
596 | #ifdef CONFIG_PPC32 | ||
525 | void __init pmac_init(void) | 597 | void __init pmac_init(void) |
526 | { | 598 | { |
527 | /* isa_io_base gets set in pmac_find_bridges */ | 599 | /* isa_io_base gets set in pmac_pci_init */ |
528 | isa_mem_base = PMAC_ISA_MEM_BASE; | 600 | isa_mem_base = PMAC_ISA_MEM_BASE; |
529 | pci_dram_offset = PMAC_PCI_DRAM_OFFSET; | 601 | pci_dram_offset = PMAC_PCI_DRAM_OFFSET; |
530 | ISA_DMA_THRESHOLD = ~0L; | 602 | ISA_DMA_THRESHOLD = ~0L; |
531 | DMA_MODE_READ = 1; | 603 | DMA_MODE_READ = 1; |
532 | DMA_MODE_WRITE = 2; | 604 | DMA_MODE_WRITE = 2; |
533 | 605 | ||
534 | ppc_md.setup_arch = pmac_setup_arch; | 606 | ppc_md = pmac_md; |
535 | ppc_md.show_cpuinfo = pmac_show_cpuinfo; | ||
536 | ppc_md.show_percpuinfo = pmac_show_percpuinfo; | ||
537 | ppc_md.init_IRQ = pmac_pic_init; | ||
538 | ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */ | ||
539 | |||
540 | ppc_md.pcibios_fixup = pmac_pcibios_fixup; | ||
541 | ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook; | ||
542 | ppc_md.pcibios_after_init = pmac_pcibios_after_init; | ||
543 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; | ||
544 | |||
545 | ppc_md.restart = pmac_restart; | ||
546 | ppc_md.power_off = pmac_power_off; | ||
547 | ppc_md.halt = pmac_halt; | ||
548 | |||
549 | ppc_md.time_init = pmac_time_init; | ||
550 | ppc_md.set_rtc_time = pmac_set_rtc_time; | ||
551 | ppc_md.get_rtc_time = pmac_get_rtc_time; | ||
552 | ppc_md.get_boot_time = pmac_get_boot_time; | ||
553 | ppc_md.calibrate_decr = pmac_calibrate_decr; | ||
554 | |||
555 | ppc_md.feature_call = pmac_do_feature_call; | ||
556 | 607 | ||
557 | #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) | 608 | #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) |
558 | #ifdef CONFIG_BLK_DEV_IDE_PMAC | 609 | #ifdef CONFIG_BLK_DEV_IDE_PMAC |
@@ -561,27 +612,62 @@ void __init pmac_init(void) | |||
561 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ | 612 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ |
562 | #endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ | 613 | #endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ |
563 | 614 | ||
564 | #ifdef CONFIG_BOOTX_TEXT | ||
565 | ppc_md.progress = pmac_progress; | ||
566 | #endif /* CONFIG_BOOTX_TEXT */ | ||
567 | |||
568 | if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0); | 615 | if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0); |
569 | 616 | ||
570 | } | 617 | } |
618 | #endif | ||
571 | 619 | ||
572 | #ifdef CONFIG_BOOTX_TEXT | 620 | /* |
573 | static void __init | 621 | * Early initialization. |
574 | pmac_progress(char *s, unsigned short hex) | 622 | */ |
623 | static void __init pmac_init_early(void) | ||
624 | { | ||
625 | #ifdef CONFIG_PPC64 | ||
626 | /* Initialize hash table, from now on, we can take hash faults | ||
627 | * and call ioremap | ||
628 | */ | ||
629 | hpte_init_native(); | ||
630 | |||
631 | /* Init SCC */ | ||
632 | if (strstr(cmd_line, "sccdbg")) { | ||
633 | sccdbg = 1; | ||
634 | udbg_init_scc(NULL); | ||
635 | } | ||
636 | |||
637 | /* Setup interrupt mapping options */ | ||
638 | ppc64_interrupt_controller = IC_OPEN_PIC; | ||
639 | |||
640 | iommu_init_early_u3(); | ||
641 | #endif | ||
642 | } | ||
643 | |||
644 | static void __init pmac_progress(char *s, unsigned short hex) | ||
575 | { | 645 | { |
646 | #ifdef CONFIG_PPC64 | ||
647 | if (sccdbg) { | ||
648 | udbg_puts(s); | ||
649 | udbg_puts("\n"); | ||
650 | return; | ||
651 | } | ||
652 | #endif | ||
653 | #ifdef CONFIG_BOOTX_TEXT | ||
576 | if (boot_text_mapped) { | 654 | if (boot_text_mapped) { |
577 | btext_drawstring(s); | 655 | btext_drawstring(s); |
578 | btext_drawchar('\n'); | 656 | btext_drawchar('\n'); |
579 | } | 657 | } |
580 | } | ||
581 | #endif /* CONFIG_BOOTX_TEXT */ | 658 | #endif /* CONFIG_BOOTX_TEXT */ |
659 | } | ||
582 | 660 | ||
583 | static int __init | 661 | /* |
584 | pmac_declare_of_platform_devices(void) | 662 | * pmac has no legacy IO, anything calling this function has to |
663 | * fail or bad things will happen | ||
664 | */ | ||
665 | static int pmac_check_legacy_ioport(unsigned int baseport) | ||
666 | { | ||
667 | return -ENODEV; | ||
668 | } | ||
669 | |||
670 | static int __init pmac_declare_of_platform_devices(void) | ||
585 | { | 671 | { |
586 | struct device_node *np; | 672 | struct device_node *np; |
587 | 673 | ||
@@ -594,6 +680,13 @@ pmac_declare_of_platform_devices(void) | |||
594 | break; | 680 | break; |
595 | } | 681 | } |
596 | } | 682 | } |
683 | np = find_devices("valkyrie"); | ||
684 | if (np) | ||
685 | of_platform_device_create(np, "valkyrie", NULL); | ||
686 | np = find_devices("platinum"); | ||
687 | if (np) | ||
688 | of_platform_device_create(np, "platinum", NULL); | ||
689 | |||
597 | np = find_devices("u3"); | 690 | np = find_devices("u3"); |
598 | if (np) { | 691 | if (np) { |
599 | for (np = np->child; np != NULL; np = np->sibling) | 692 | for (np = np->child; np != NULL; np = np->sibling) |
@@ -603,15 +696,92 @@ pmac_declare_of_platform_devices(void) | |||
603 | break; | 696 | break; |
604 | } | 697 | } |
605 | } | 698 | } |
606 | 699 | np = of_find_node_by_type(NULL, "smu"); | |
607 | np = find_devices("valkyrie"); | 700 | if (np) { |
608 | if (np) | 701 | of_platform_device_create(np, "smu", NULL); |
609 | of_platform_device_create(np, "valkyrie", NULL); | 702 | of_node_put(np); |
610 | np = find_devices("platinum"); | 703 | } |
611 | if (np) | ||
612 | of_platform_device_create(np, "platinum", NULL); | ||
613 | 704 | ||
614 | return 0; | 705 | return 0; |
615 | } | 706 | } |
616 | 707 | ||
617 | device_initcall(pmac_declare_of_platform_devices); | 708 | device_initcall(pmac_declare_of_platform_devices); |
709 | |||
710 | /* | ||
711 | * Called very early, MMU is off, device-tree isn't unflattened | ||
712 | */ | ||
713 | static int __init pmac_probe(int platform) | ||
714 | { | ||
715 | #ifdef CONFIG_PPC64 | ||
716 | if (platform != PLATFORM_POWERMAC) | ||
717 | return 0; | ||
718 | |||
719 | /* | ||
720 | * On U3, the DART (iommu) must be allocated now since it | ||
721 | * has an impact on htab_initialize (due to the large page it | ||
722 | * occupies having to be broken up so the DART itself is not | ||
723 | * part of the cacheable linar mapping | ||
724 | */ | ||
725 | alloc_u3_dart_table(); | ||
726 | #endif | ||
727 | |||
728 | #ifdef CONFIG_PMAC_SMU | ||
729 | /* | ||
730 | * SMU based G5s need some memory below 2Gb, at least the current | ||
731 | * driver needs that. We have to allocate it now. We allocate 4k | ||
732 | * (1 small page) for now. | ||
733 | */ | ||
734 | smu_cmdbuf_abs = lmb_alloc_base(4096, 4096, 0x80000000UL); | ||
735 | #endif /* CONFIG_PMAC_SMU */ | ||
736 | |||
737 | return 1; | ||
738 | } | ||
739 | |||
740 | #ifdef CONFIG_PPC64 | ||
741 | static int pmac_probe_mode(struct pci_bus *bus) | ||
742 | { | ||
743 | struct device_node *node = bus->sysdata; | ||
744 | |||
745 | /* We need to use normal PCI probing for the AGP bus, | ||
746 | since the device for the AGP bridge isn't in the tree. */ | ||
747 | if (bus->self == NULL && device_is_compatible(node, "u3-agp")) | ||
748 | return PCI_PROBE_NORMAL; | ||
749 | |||
750 | return PCI_PROBE_DEVTREE; | ||
751 | } | ||
752 | #endif | ||
753 | |||
754 | struct machdep_calls __initdata pmac_md = { | ||
755 | #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) | ||
756 | .cpu_die = generic_mach_cpu_die, | ||
757 | #endif | ||
758 | .probe = pmac_probe, | ||
759 | .setup_arch = pmac_setup_arch, | ||
760 | .init_early = pmac_init_early, | ||
761 | .show_cpuinfo = pmac_show_cpuinfo, | ||
762 | .show_percpuinfo = pmac_show_percpuinfo, | ||
763 | .init_IRQ = pmac_pic_init, | ||
764 | .get_irq = mpic_get_irq, /* changed later */ | ||
765 | .pcibios_fixup = pmac_pcibios_fixup, | ||
766 | .restart = pmac_restart, | ||
767 | .power_off = pmac_power_off, | ||
768 | .halt = pmac_halt, | ||
769 | .time_init = pmac_time_init, | ||
770 | .get_boot_time = pmac_get_boot_time, | ||
771 | .set_rtc_time = pmac_set_rtc_time, | ||
772 | .get_rtc_time = pmac_get_rtc_time, | ||
773 | .calibrate_decr = pmac_calibrate_decr, | ||
774 | .feature_call = pmac_do_feature_call, | ||
775 | .check_legacy_ioport = pmac_check_legacy_ioport, | ||
776 | .progress = pmac_progress, | ||
777 | #ifdef CONFIG_PPC64 | ||
778 | .pci_probe_mode = pmac_probe_mode, | ||
779 | .idle_loop = native_idle, | ||
780 | .enable_pmcs = power4_enable_pmcs, | ||
781 | #endif | ||
782 | #ifdef CONFIG_PPC32 | ||
783 | .pcibios_enable_device_hook = pmac_pci_enable_device_hook, | ||
784 | .pcibios_after_init = pmac_pcibios_after_init, | ||
785 | .phys_mem_access_prot = pci_phys_mem_access_prot, | ||
786 | #endif | ||
787 | }; | ||