pre-2.3.4..
[davej-history.git] / arch / ppc / kernel / chrp_setup.c
blobd3dbcca414261f0e295e8940f8e7a3f64702936a
1 /*
2 * linux/arch/ppc/kernel/setup.c
4 * Copyright (C) 1995 Linus Torvalds
5 * Adapted from 'alpha' version by Gary Thomas
6 * Modified by Cort Dougan (cort@cs.nmt.edu)
7 */
9 /*
10 * bootup setup stuff..
13 #include <linux/config.h>
14 #include <linux/module.h>
15 #include <linux/errno.h>
16 #include <linux/sched.h>
17 #include <linux/kernel.h>
18 #include <linux/mm.h>
19 #include <linux/stddef.h>
20 #include <linux/unistd.h>
21 #include <linux/ptrace.h>
22 #include <linux/malloc.h>
23 #include <linux/user.h>
24 #include <linux/a.out.h>
25 #include <linux/tty.h>
26 #include <linux/major.h>
27 #include <linux/interrupt.h>
28 #include <linux/reboot.h>
29 #include <linux/init.h>
30 #include <linux/blk.h>
31 #include <linux/ioport.h>
32 #include <linux/console.h>
33 #include <linux/pci.h>
34 #include <linux/openpic.h>
36 #include <asm/mmu.h>
37 #include <asm/processor.h>
38 #include <asm/io.h>
39 #include <asm/pgtable.h>
40 #include <linux/ide.h>
41 #include <asm/ide.h>
42 #include <asm/prom.h>
43 #include <asm/gg2.h>
44 #include <asm/pci-bridge.h>
45 #include <asm/dma.h>
46 #include <asm/machdep.h>
47 #include <asm/irq.h>
48 #include <asm/adb.h>
49 #include <asm/hydra.h>
51 #include "time.h"
52 #include "local_irq.h"
53 #include "i8259.h"
54 #include "open_pic.h"
56 /* Fixme - need to move these into their own .c and .h file */
57 extern void i8259_mask_and_ack_irq(unsigned int irq_nr);
58 extern void i8259_set_irq_mask(unsigned int irq_nr);
59 extern void i8259_mask_irq(unsigned int irq_nr);
60 extern void i8259_unmask_irq(unsigned int irq_nr);
61 extern void i8259_init(void);
63 /* Fixme - remove this when it is fixed. - Corey */
64 extern volatile unsigned char *chrp_int_ack_special;
66 unsigned long chrp_get_rtc_time(void);
67 int chrp_set_rtc_time(unsigned long nowtime);
68 void chrp_calibrate_decr(void);
69 void chrp_time_init(void);
71 void chrp_setup_pci_ptrs(void);
73 extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
74 extern int pckbd_getkeycode(unsigned int scancode);
75 extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
76 char raw_mode);
77 extern char pckbd_unexpected_up(unsigned char keycode);
78 extern void pckbd_leds(unsigned char leds);
79 extern void pckbd_init_hw(void);
80 extern unsigned char pckbd_sysrq_xlate[128];
81 extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
82 extern int mackbd_getkeycode(unsigned int scancode);
83 extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
84 char raw_mode);
85 extern char mackbd_unexpected_up(unsigned char keycode);
86 extern void mackbd_leds(unsigned char leds);
87 extern void mackbd_init_hw(void);
88 extern unsigned char mackbd_sysrq_xlate[128];
90 /* for the mac fs */
91 kdev_t boot_dev;
93 extern PTE *Hash, *Hash_end;
94 extern unsigned long Hash_size, Hash_mask;
95 extern int probingmem;
96 extern unsigned long loops_per_sec;
98 unsigned long empty_zero_page[1024];
100 #ifdef CONFIG_BLK_DEV_RAM
101 extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
102 extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
103 extern int rd_image_start; /* starting block # of image */
104 #endif
106 static const char *gg2_memtypes[4] = {
107 "FPM", "SDRAM", "EDO", "BEDO"
109 static const char *gg2_cachesizes[4] = {
110 "256 KB", "512 KB", "1 MB", "Reserved"
112 static const char *gg2_cachetypes[4] = {
113 "Asynchronous", "Reserved", "Flow-Through Synchronous",
114 "Pipelined Synchronous"
116 static const char *gg2_cachemodes[4] = {
117 "Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
121 chrp_get_cpuinfo(char *buffer)
123 int i, len, sdramen;
124 unsigned int t;
125 struct device_node *root;
126 const char *model = "";
128 root = find_path_device("/");
129 if (root)
130 model = get_property(root, "model", NULL);
131 len = sprintf(buffer,"machine\t\t: CHRP %s\n", model);
133 /* longtrail (goldengate) stuff */
134 if ( !strncmp( model, "IBM,LongTrail", 9 ) )
136 /* VLSI VAS96011/12 `Golden Gate 2' */
137 /* Memory banks */
138 sdramen = (in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+
139 GG2_PCI_DRAM_CTRL))
140 >>31) & 1;
141 for (i = 0; i < (sdramen ? 4 : 6); i++) {
142 t = in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+
143 GG2_PCI_DRAM_BANK0+
144 i*4));
145 if (!(t & 1))
146 continue;
147 switch ((t>>8) & 0x1f) {
148 case 0x1f:
149 model = "4 MB";
150 break;
151 case 0x1e:
152 model = "8 MB";
153 break;
154 case 0x1c:
155 model = "16 MB";
156 break;
157 case 0x18:
158 model = "32 MB";
159 break;
160 case 0x10:
161 model = "64 MB";
162 break;
163 case 0x00:
164 model = "128 MB";
165 break;
166 default:
167 model = "Reserved";
168 break;
170 len += sprintf(buffer+len, "memory bank %d\t: %s %s\n", i, model,
171 gg2_memtypes[sdramen ? 1 : ((t>>1) & 3)]);
173 /* L2 cache */
174 t = in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+GG2_PCI_CC_CTRL));
175 len += sprintf(buffer+len, "board l2\t: %s %s (%s)\n",
176 gg2_cachesizes[(t>>7) & 3],
177 gg2_cachetypes[(t>>2) & 3],
178 gg2_cachemodes[t & 3]);
180 return len;
184 * Fixes for the National Semiconductor PC78308VUL SuperI/O
186 * Some versions of Open Firmware incorrectly initialize the IRQ settings
187 * for keyboard and mouse
190 __initfunc(static inline void sio_write(u8 val, u8 index))
192 outb(index, 0x15c);
193 outb(val, 0x15d);
196 __initfunc(static inline u8 sio_read(u8 index))
198 outb(index, 0x15c);
199 return inb(0x15d);
202 __initfunc(static void sio_fixup_irq(const char *name, u8 device, u8 level,
203 u8 type))
205 u8 level0, type0, active;
207 /* select logical device */
208 sio_write(device, 0x07);
209 active = sio_read(0x30);
210 level0 = sio_read(0x70);
211 type0 = sio_read(0x71);
212 printk("sio: %s irq level %d, type %d, %sactive: ", name, level0, type0,
213 !active ? "in" : "");
214 if (level0 == level && type0 == type && active)
215 printk("OK\n");
216 else {
217 printk("remapping to level %d, type %d, active\n", level, type);
218 sio_write(0x01, 0x30);
219 sio_write(level, 0x70);
220 sio_write(type, 0x71);
225 __initfunc(static void sio_init(void))
227 /* logical device 0 (KBC/Keyboard) */
228 sio_fixup_irq("keyboard", 0, 1, 2);
229 /* select logical device 1 (KBC/Mouse) */
230 sio_fixup_irq("mouse", 1, 12, 2);
234 __initfunc(void
235 chrp_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p))
237 extern char cmd_line[];
239 /* init to some ~sane value until calibrate_delay() runs */
240 loops_per_sec = 50000000;
242 #ifdef CONFIG_BLK_DEV_INITRD
243 /* this is fine for chrp */
244 initrd_below_start_ok = 1;
246 if (initrd_start)
247 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
248 else
249 #endif
250 ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */
252 printk("Boot arguments: %s\n", cmd_line);
254 request_region(0x20,0x20,"pic1");
255 request_region(0xa0,0x20,"pic2");
256 request_region(0x00,0x20,"dma1");
257 request_region(0x40,0x20,"timer");
258 request_region(0x80,0x10,"dma page reg");
259 request_region(0xc0,0x20,"dma2");
261 /* PCI bridge config space access area -
262 * appears to be not in devtree on longtrail. */
263 ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
265 * Temporary fixes for PCI devices.
266 * -- Geert
268 hydra_init(); /* Mac I/O */
270 /* Some IBM machines don't have the hydra -- Cort */
271 if ( !OpenPIC )
273 OpenPIC = (struct OpenPIC *)*(unsigned long *)get_property(
274 find_path_device("/"), "platform-open-pic", NULL);
275 OpenPIC = ioremap((unsigned long)OpenPIC, sizeof(struct OpenPIC));
279 * Fix the Super I/O configuration
281 sio_init();
282 #ifdef CONFIG_DUMMY_CONSOLE
283 conswitchp = &dummy_con;
284 #endif
285 /* my starmax 6000 needs this but the longtrail shouldn't do it -- Cort */
286 if ( !strncmp("MOT", get_property(find_path_device("/"),
287 "model", NULL),3) )
288 *memory_start_p = pmac_find_bridges(*memory_start_p, *memory_end_p);
291 void
292 chrp_restart(char *cmd)
294 #if 0
295 extern unsigned int rtas_entry, rtas_data, rtas_size;
296 printk("RTAS system-reboot returned %d\n",
297 call_rtas("system-reboot", 0, 1, NULL));
298 printk("rtas_entry: %08lx rtas_data: %08lx rtas_size: %08lx\n",
299 rtas_entry,rtas_data,rtas_size);
300 for (;;);
301 #else
302 printk("System Halted\n");
303 while(1);
304 #endif
307 void
308 chrp_power_off(void)
310 /* RTAS doesn't seem to work on Longtrail.
311 For now, do it the same way as the PReP. */
312 #if 0
313 extern unsigned int rtas_entry, rtas_data, rtas_size;
314 printk("RTAS power-off returned %d\n",
315 call_rtas("power-off", 2, 1, NULL, 0, 0));
316 printk("rtas_entry: %08lx rtas_data: %08lx rtas_size: %08lx\n",
317 rtas_entry,rtas_data,rtas_size);
318 for (;;);
319 #else
320 chrp_restart(NULL);
321 #endif
324 void
325 chrp_halt(void)
327 chrp_restart(NULL);
330 u_int
331 chrp_irq_cannonicalize(u_int irq)
333 if (irq == 2)
335 return 9;
337 else
339 return irq;
343 void
344 chrp_do_IRQ(struct pt_regs *regs,
345 int cpu,
346 int isfake)
348 int irq;
349 unsigned long bits = 0;
350 int openpic_eoi_done = 0;
352 #ifdef __SMP__
354 unsigned int loops = 1000000;
355 while (test_bit(0, &global_irq_lock)) {
356 if (smp_processor_id() == global_irq_holder) {
357 printk("uh oh, interrupt while we hold global irq lock!\n");
358 #ifdef CONFIG_XMON
359 xmon(0);
360 #endif
361 break;
363 if (loops-- == 0) {
364 printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder);
365 #ifdef CONFIG_XMON
366 xmon(0);
367 #endif
371 #endif /* __SMP__ */
373 irq = openpic_irq(0);
374 if (irq == IRQ_8259_CASCADE)
377 * This magic address generates a PCI IACK cycle.
379 * This should go in the above mask/ack code soon. -- Cort
381 if ( chrp_int_ack_special )
382 irq = *chrp_int_ack_special;
383 else
384 irq = i8259_irq(0);
386 * Acknowledge as soon as possible to allow i8259
387 * interrupt nesting */
388 openpic_eoi(0);
389 openpic_eoi_done = 1;
391 if (irq == OPENPIC_VEC_SPURIOUS)
394 * Spurious interrupts should never be
395 * acknowledged
397 ppc_spurious_interrupts++;
398 openpic_eoi_done = 1;
399 goto out;
401 bits = 1UL << irq;
403 if (irq < 0)
405 printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
406 irq, regs->nip);
407 ppc_spurious_interrupts++;
409 else
411 ppc_irq_dispatch_handler( regs, irq );
413 out:
414 if (!openpic_eoi_done)
415 openpic_eoi(0);
418 __initfunc(void
419 chrp_init_IRQ(void))
421 struct device_node *np;
422 int i;
424 if ( !(np = find_devices("pci") ) )
425 printk("Cannot find pci to get ack address\n");
426 else
428 chrp_int_ack_special = (volatile unsigned char *)
429 (*(unsigned long *)get_property(np,
430 "8259-interrupt-acknowledge", NULL));
432 for ( i = 16 ; i < NR_IRQS ; i++ )
433 irq_desc[i].ctl = &open_pic;
434 /* openpic knows that it's at irq 16 offset
435 * so we don't need to set it in the pic structure
436 * -- Cort
438 openpic_init(1);
439 for ( i = 0 ; i < 16 ; i++ )
440 irq_desc[i].ctl = &i8259_pic;
441 i8259_init();
442 #ifdef CONFIG_XMON
443 request_irq(openpic_to_irq(HYDRA_INT_ADB_NMI),
444 xmon_irq, 0, "NMI", 0);
445 #endif /* CONFIG_XMON */
446 #ifdef __SMP__
447 request_irq(openpic_to_irq(OPENPIC_VEC_IPI),
448 openpic_ipi_action, 0, "IPI0", 0);
449 #endif /* __SMP__ */
452 __initfunc(void
453 chrp_init2(void))
455 adb_init();
457 /* Should this be here? - Corey */
458 pmac_nvram_init();
461 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
463 * IDE stuff.
465 unsigned int chrp_ide_irq = 0;
466 int chrp_ide_ports_known = 0;
467 ide_ioreg_t chrp_ide_regbase[MAX_HWIFS];
468 ide_ioreg_t chrp_idedma_regbase;
470 void chrp_ide_probe(void) {
472 struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, NULL);
474 chrp_ide_ports_known = 1;
476 if(pdev) {
477 chrp_ide_regbase[0]=pdev->base_address[0] &
478 PCI_BASE_ADDRESS_IO_MASK;
479 chrp_ide_regbase[1]=pdev->base_address[2] &
480 PCI_BASE_ADDRESS_IO_MASK;
481 chrp_idedma_regbase=pdev->base_address[4] &
482 PCI_BASE_ADDRESS_IO_MASK;
483 chrp_ide_irq=pdev->irq;
487 void
488 chrp_ide_insw(ide_ioreg_t port, void *buf, int ns)
490 ide_insw(port+_IO_BASE, buf, ns);
493 void
494 chrp_ide_outsw(ide_ioreg_t port, void *buf, int ns)
496 ide_outsw(port+_IO_BASE, buf, ns);
500 chrp_ide_default_irq(ide_ioreg_t base)
502 if (chrp_ide_ports_known == 0)
503 chrp_ide_probe();
504 return chrp_ide_irq;
507 ide_ioreg_t
508 chrp_ide_default_io_base(int index)
510 if (chrp_ide_ports_known == 0)
511 chrp_ide_probe();
512 return chrp_ide_regbase[index];
516 chrp_ide_check_region(ide_ioreg_t from, unsigned int extent)
518 return check_region(from, extent);
521 void
522 chrp_ide_request_region(ide_ioreg_t from,
523 unsigned int extent,
524 const char *name)
526 request_region(from, extent, name);
529 void
530 chrp_ide_release_region(ide_ioreg_t from,
531 unsigned int extent)
533 release_region(from, extent);
536 void
537 chrp_ide_fix_driveid(struct hd_driveid *id)
539 ppc_generic_ide_fix_driveid(id);
542 void
543 chrp_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
545 ide_ioreg_t reg = data_port;
546 int i;
548 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
549 hw->io_ports[i] = reg;
550 reg += 1;
552 if (ctrl_port) {
553 hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
554 } else {
555 hw->io_ports[IDE_CONTROL_OFFSET] = 0;
557 if (irq != NULL)
558 hw->irq = chrp_ide_irq;
561 EXPORT_SYMBOL(chrp_ide_irq);
562 EXPORT_SYMBOL(chrp_ide_ports_known);
563 EXPORT_SYMBOL(chrp_ide_regbase);
564 EXPORT_SYMBOL(chrp_ide_probe);
566 #endif
568 __initfunc(void
569 chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
570 unsigned long r6, unsigned long r7))
572 chrp_setup_pci_ptrs();
573 #ifdef CONFIG_BLK_DEV_INITRD
574 /* take care of initrd if we have one */
575 if ( r3 )
577 initrd_start = r3 + KERNELBASE;
578 initrd_end = r3 + r4 + KERNELBASE;
580 #endif /* CONFIG_BLK_DEV_INITRD */
582 /* pci_dram_offset/isa_io_base/isa_mem_base set by setup_pci_ptrs() */
583 ISA_DMA_THRESHOLD = ~0L;
584 DMA_MODE_READ = 0x44;
585 DMA_MODE_WRITE = 0x48;
587 ppc_md.setup_arch = chrp_setup_arch;
588 ppc_md.setup_residual = NULL;
589 ppc_md.get_cpuinfo = chrp_get_cpuinfo;
590 ppc_md.irq_cannonicalize = chrp_irq_cannonicalize;
591 ppc_md.init_IRQ = chrp_init_IRQ;
592 ppc_md.do_IRQ = chrp_do_IRQ;
594 ppc_md.init = chrp_init2;
596 ppc_md.restart = chrp_restart;
597 ppc_md.power_off = chrp_power_off;
598 ppc_md.halt = chrp_halt;
600 ppc_md.time_init = chrp_time_init;
601 ppc_md.set_rtc_time = chrp_set_rtc_time;
602 ppc_md.get_rtc_time = chrp_get_rtc_time;
603 ppc_md.calibrate_decr = chrp_calibrate_decr;
605 #ifdef CONFIG_VT
606 #ifdef CONFIG_MAC_KEYBOAD
607 if ( adb_hardware == ADB_NONE )
609 ppc_md.kbd_setkeycode = pckbd_setkeycode;
610 ppc_md.kbd_getkeycode = pckbd_getkeycode;
611 ppc_md.kbd_translate = pckbd_translate;
612 ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
613 ppc_md.kbd_leds = pckbd_leds;
614 ppc_md.kbd_init_hw = pckbd_init_hw;
615 #ifdef CONFIG_MAGIC_SYSRQ
616 ppc_md.kbd_sysrq_xlate = pckbd_sysrq_xlate;
617 #endif
619 else
621 ppc_md.kbd_setkeycode = mackbd_setkeycode;
622 ppc_md.kbd_getkeycode = mackbd_getkeycode;
623 ppc_md.kbd_translate = mackbd_translate;
624 ppc_md.kbd_unexpected_up = mackbd_unexpected_up;
625 ppc_md.kbd_leds = mackbd_leds;
626 ppc_md.kbd_init_hw = mackbd_init_hw;
627 #ifdef CONFIG_MAGIC_SYSRQ
628 ppc_md.kbd_sysrq_xlate = mackbd_sysrq_xlate;
629 #endif
631 #else
632 ppc_md.kbd_setkeycode = pckbd_setkeycode;
633 ppc_md.kbd_getkeycode = pckbd_getkeycode;
634 ppc_md.kbd_translate = pckbd_translate;
635 ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
636 ppc_md.kbd_leds = pckbd_leds;
637 ppc_md.kbd_init_hw = pckbd_init_hw;
638 #ifdef CONFIG_MAGIC_SYSRQ
639 ppc_md.kbd_sysrq_xlate = pckbd_sysrq_xlate;
640 #endif
641 #endif
642 #endif
644 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
645 ppc_ide_md.insw = chrp_ide_insw;
646 ppc_ide_md.outsw = chrp_ide_outsw;
647 ppc_ide_md.default_irq = chrp_ide_default_irq;
648 ppc_ide_md.default_io_base = chrp_ide_default_io_base;
649 ppc_ide_md.check_region = chrp_ide_check_region;
650 ppc_ide_md.request_region = chrp_ide_request_region;
651 ppc_ide_md.release_region = chrp_ide_release_region;
652 ppc_ide_md.fix_driveid = chrp_ide_fix_driveid;
653 ppc_ide_md.ide_init_hwif = chrp_ide_init_hwif_ports;
655 ppc_ide_md.io_base = _IO_BASE;
656 #endif