pre-2.3.4..
[davej-history.git] / arch / ppc / kernel / mbx_setup.c
blob40f016fb5afb3defefeed5b7dbf63441c58ece86
1 /*
2 * $Id: mbx_setup.c,v 1.10 1999/05/14 07:24:19 davem Exp $
4 * linux/arch/ppc/kernel/setup.c
6 * Copyright (C) 1995 Linus Torvalds
7 * Adapted from 'alpha' version by Gary Thomas
8 * Modified by Cort Dougan (cort@cs.nmt.edu)
9 * Modified for MBX using prep/chrp/pmac functions by Dan (dmalek@jlc.net)
13 * bootup setup stuff..
16 #include <linux/config.h>
17 #include <linux/errno.h>
18 #include <linux/sched.h>
19 #include <linux/kernel.h>
20 #include <linux/mm.h>
21 #include <linux/stddef.h>
22 #include <linux/unistd.h>
23 #include <linux/ptrace.h>
24 #include <linux/malloc.h>
25 #include <linux/user.h>
26 #include <linux/a.out.h>
27 #include <linux/tty.h>
28 #include <linux/major.h>
29 #include <linux/interrupt.h>
30 #include <linux/reboot.h>
31 #include <linux/init.h>
32 #include <linux/blk.h>
33 #include <linux/ioport.h>
35 #include <asm/mmu.h>
36 #include <asm/processor.h>
37 #include <asm/residual.h>
38 #include <asm/io.h>
39 #include <asm/pgtable.h>
40 #include <asm/ide.h>
41 #include <asm/mbx.h>
42 #include <asm/machdep.h>
44 #include "time.h"
45 #include "local_irq.h"
47 static int mbx_set_rtc_time(unsigned long time);
48 unsigned long mbx_get_rtc_time(void);
49 void mbx_calibrate_decr(void);
51 extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
52 extern int mackbd_getkeycode(unsigned int scancode);
53 extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
54 char raw_mode);
55 extern char mackbd_unexpected_up(unsigned char keycode);
56 extern void mackbd_leds(unsigned char leds);
57 extern void mackbd_init_hw(void);
59 extern unsigned long loops_per_sec;
61 unsigned long empty_zero_page[1024];
63 #ifdef CONFIG_BLK_DEV_RAM
64 extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
65 extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
66 extern int rd_image_start; /* starting block # of image */
67 #endif
69 extern char saved_command_line[256];
71 extern unsigned long find_available_memory(void);
72 extern void m8xx_cpm_reset(uint);
74 void __init adbdev_init(void)
78 __initfunc(void
79 mbx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p))
81 int cpm_page;
82 extern char cmd_line[];
84 cpm_page = *memory_start_p;
85 *memory_start_p += PAGE_SIZE;
87 sprintf(cmd_line,
88 "%s root=/dev/nfs nfsroot=/sys/mbxroot",
89 cmd_line);
90 printk("Boot arguments: %s\n", cmd_line);
92 /* Reset the Communication Processor Module.
94 m8xx_cpm_reset(cpm_page);
96 #ifdef notdef
97 ROOT_DEV = to_kdev_t(0x0301); /* hda1 */
98 #endif
100 #ifdef CONFIG_BLK_DEV_INITRD
101 #if 0
102 ROOT_DEV = to_kdev_t(0x0200); /* floppy */
103 rd_prompt = 1;
104 rd_doload = 1;
105 rd_image_start = 0;
106 #endif
107 /* initrd_start and size are setup by boot/head.S and kernel/head.S */
108 if ( initrd_start )
110 if (initrd_end > *memory_end_p)
112 printk("initrd extends beyond end of memory "
113 "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
114 initrd_end,*memory_end_p);
115 initrd_start = 0;
118 #endif
120 #ifdef notdef
121 request_region(0x20,0x20,"pic1");
122 request_region(0xa0,0x20,"pic2");
123 request_region(0x00,0x20,"dma1");
124 request_region(0x40,0x20,"timer");
125 request_region(0x80,0x10,"dma page reg");
126 request_region(0xc0,0x20,"dma2");
127 #endif
130 void
131 abort(void)
133 #ifdef CONFIG_XMON
134 extern void xmon(void *);
135 xmon(0);
136 #endif
137 machine_restart(NULL);
140 /* The decrementer counts at the system (internal) clock frequency divided by
141 * sixteen, or external oscillator divided by four. Currently, we only
142 * support the MBX, which is system clock divided by sixteen.
144 __initfunc(void mbx_calibrate_decr(void))
146 bd_t *binfo = (bd_t *)&res;
147 int freq, fp, divisor;
149 if ((((immap_t *)MBX_IMAP_ADDR)->im_clkrst.car_sccr & 0x02000000) == 0)
150 printk("WARNING: Wrong decrementer source clock.\n");
152 /* The manual says the frequency is in Hz, but it is really
153 * as MHz. The value 'fp' is the number of decrementer ticks
154 * per second.
156 fp = (binfo->bi_intfreq * 1000000) / 16;
157 freq = fp*60; /* try to make freq/1e6 an integer */
158 divisor = 60;
159 printk("time_init: decrementer frequency = %d/%d\n", freq, divisor);
160 decrementer_count = freq / HZ / divisor;
161 count_period_num = divisor;
162 count_period_den = freq / 1000000;
165 /* A place holder for time base interrupts, if they are ever enabled.
167 void timebase_interrupt(int irq, void * dev, struct pt_regs * regs)
169 printk("timebase_interrupt()\n");
172 /* The RTC on the MPC8xx is an internal register.
173 * We want to protect this during power down, so we need to unlock,
174 * modify, and re-lock.
176 static int
177 mbx_set_rtc_time(unsigned long time)
179 ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY;
180 ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_rtc = time;
181 ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY;
182 return(0);
185 initfunc(unsigned long
186 mbx_get_rtc_time(void)
188 /* First, unlock all of the registers we are going to modify.
189 * To protect them from corruption during power down, registers
190 * that are maintained by keep alive power are "locked". To
191 * modify these registers we have to write the key value to
192 * the key location associated with the register.
194 ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_tbscrk = KAPWR_KEY;
195 ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_rtcsck = KAPWR_KEY;
198 /* Disable the RTC one second and alarm interrupts.
200 ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_rtcsc &=
201 ~(RTCSC_SIE | RTCSC_ALE);
203 /* Enabling the decrementer also enables the timebase interrupts
204 * (or from the other point of view, to get decrementer interrupts
205 * we have to enable the timebase). The decrementer interrupt
206 * is wired into the vector table, nothing to do here for that.
208 ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_tbscr =
209 ((mk_int_int_mask(DEC_INTERRUPT) << 8) |
210 (TBSCR_TBF | TBSCR_TBE));
211 if (request_irq(DEC_INTERRUPT, timebase_interrupt, 0, "tbint", NULL) != 0)
212 panic("Could not allocate timer IRQ!");
214 /* Get time from the RTC.
216 return ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_rtc;
219 void
220 mbx_restart(char *cmd)
222 extern void MBX_gorom(void);
224 MBX_gorom();
227 void
228 mbx_power_off(void)
230 mbx_restart(NULL);
233 void
234 mbx_halt(void)
236 mbx_restart(NULL)
240 int mbx_setup_residual(char *buffer)
242 int len = 0;
243 bd_t *bp;
244 extern RESIDUAL *res;
246 bp = (bd_t *)res;
248 len += sprintf(len+buffer,"clock\t\t: %dMHz\n"
249 "bus clock\t: %dMHz\n",
250 bp->bi_intfreq /*/ 1000000*/,
251 bp->bi_busfreq /*/ 1000000*/);
253 return len;
256 void
257 mbx_do_IRQ(struct pt_regs *regs,
258 int cpu,
259 int isfake)
261 int irq;
262 unsigned long bits = 0;
264 /* For MPC8xx, read the SIVEC register and shift the bits down
265 * to get the irq number. */
266 bits = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec;
267 irq = bits >> 26;
268 irq += ppc8xx_pic.irq_offset;
269 bits = 1UL << irq;
271 if (irq < 0) {
272 printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
273 irq, regs->nip);
274 spurious_interrupts++;
276 else {
277 ppc_irq_dispatch_handler( regs, irq );
282 static void mbx_i8259_action(int cpl, void *dev_id, struct pt_regs *regs)
284 int bits, irq;
286 /* A bug in the QSpan chip causes it to give us 0xff always
287 * when doing a character read. So read 32 bits and shift.
288 * This doesn't seem to return useful values anyway, but
289 * read it to make sure things are acked.
290 * -- Cort
292 irq = (inl(0x508) >> 24)&0xff;
293 if ( irq != 0xff ) printk("iack %d\n", irq);
295 outb(0x0C, 0x20);
296 irq = inb(0x20) & 7;
297 if (irq == 2)
299 outb(0x0C, 0xA0);
300 irq = inb(0xA0);
301 irq = (irq&7) + 8;
303 bits = 1UL << irq;
304 irq += i8259_pic.irq_offset;
305 ppc_irq_dispatch_handler( regs, irq );
309 /* On MBX8xx, the interrupt control (SIEL) was set by EPPC-bug. External
310 * interrupts can be either edge or level triggered, but there is no
311 * reason for us to change the EPPC-bug values (it would not work if we did).
313 __initfunc(void
314 mbx_init_IRQ(void))
316 int i;
318 ppc8xx_pic.irq_offset = 16;
319 for ( i = 16 ; i < 32 ; i++ )
320 irq_desc[i].ctl = &ppc8xx_pic;
321 unmask_irq(CPM_INTERRUPT);
323 for ( i = 0 ; i < 16 ; i++ )
324 irq_desc[i].ctl = &i8259_pic;
325 i8259_init();
326 request_irq(ISA_BRIDGE_INT, mbx_i8259_action, 0, "8259 cascade", NULL);
327 enable_irq(ISA_BRIDGE_INT);
330 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
332 * IDE stuff.
334 void
335 mbx_ide_insw(ide_ioreg_t port, void *buf, int ns)
337 ide_insw(port+_IO_BASE), buf, ns);
340 void
341 mbx_ide_outsw(ide_ioreg_t port, void *buf, int ns)
343 ide_outsw(port+_IO_BASE, buf, ns);
347 mbx_ide_default_irq(ide_ioreg_t base)
349 return 14;
352 ide_ioreg_t
353 mbx_ide_default_io_base(int index)
355 return index;
359 mbx_ide_check_region(ide_ioreg_t from, unsigned int extent)
361 return 0
364 void
365 mbx_ide_request_region(ide_ioreg_t from,
366 unsigned int extent,
367 const char *name)
371 void
372 mbx_ide_release_region(ide_ioreg_t from,
373 unsigned int extent)
377 void
378 mbx_ide_fix_driveid(struct hd_driveid *id)
380 ppc_generic_ide_fix_driveid(id);
383 void
384 mbx_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
386 ide_ioreg_t reg = data_port;
387 int i;
389 *irq = 0;
391 if (data_port != 0) /* Only map the first ATA flash drive */
392 return;
394 #ifdef ATA_FLASH
396 reg = (ide_ioreg_t) ioremap(PCMCIA_MEM_ADDR, 0x200);
398 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
399 hw->io_ports[i] = reg;
400 reg += 1;
403 /* Does not matter */
405 if (ctrl_port) {
406 hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
407 } else {
408 hw->io_ports[IDE_CONTROL_OFFSET] = reg;
410 if (irq)
411 hw->irq = 13;
412 #endif
414 #endif
416 __initfunc(void
417 mbx_init(unsigned long r3, unsigned long r4, unsigned long r5,
418 unsigned long r6, unsigned long r7))
421 if ( r3 )
422 memcpy( (void *)&res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
424 #ifdef CONFIG_PCI
425 mbx_setup_pci_ptrs();
426 #endif
428 #ifdef CONFIG_BLK_DEV_INITRD
429 /* take care of initrd if we have one */
430 if ( r4 )
432 initrd_start = r4 + KERNELBASE;
433 initrd_end = r5 + KERNELBASE;
435 #endif /* CONFIG_BLK_DEV_INITRD */
436 /* take care of cmd line */
437 if ( r6 )
440 *(char *)(r7+KERNELBASE) = 0;
441 strcpy(cmd_line, (char *)(r6+KERNELBASE));
444 ppc_md.setup_arch = mbx_setup_arch;
445 ppc_md.setup_residual = mbx_setup_residual;
446 ppc_md.get_cpuinfo = NULL;
447 ppc_md.irq_cannonicalize = NULL;
448 ppc_md.init_IRQ = mbx_init_IRQ;
449 ppc_md.do_IRQ = mbx_do_IRQ;
450 ppc_md.init = NULL;
452 ppc_md.restart = mbx_restart;
453 ppc_md.power_off = mbx_power_off;
454 ppc_md.halt = mbx_halt;
456 ppc_md.time_init = NULL;
457 ppc_md.set_rtc_time = mbx_set_rtc_time;
458 ppc_md.get_rtc_time = mbx_get_rtc_time;
459 ppc_md.calibrate_decr = mbx_calibrate_decr;
461 ppc_md.kbd_setkeycode = pckbd_setkeycode;
462 ppc_md.kbd_getkeycode = pckbd_getkeycode;
463 ppc_md.kbd_translate = pckbd_translate;
464 ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
465 ppc_md.kbd_leds = pckbd_leds;
466 ppc_md.kbd_init_hw = pckbd_init_hw;
467 #ifdef CONFIG_MAGIC_SYSRQ
468 ppc_md.kbd_sysrq_xlate = pckbd_sysrq_xlate;
469 #endif
471 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
472 ppc_ide_md.insw = mbx_ide_insw;
473 ppc_ide_md.outsw = mbx_ide_outsw;
474 ppc_ide_md.default_irq = mbx_ide_default_irq;
475 ppc_ide_md.default_io_base = mbx_ide_default_io_base;
476 ppc_ide_md.check_region = mbx_ide_check_region;
477 ppc_ide_md.request_region = mbx_ide_request_region;
478 ppc_ide_md.release_region = mbx_ide_release_region;
479 ppc_ide_md.fix_driveid = mbx_ide_fix_driveid;
480 ppc_ide_md.ide_init_hwif = mbx_ide_init_hwif_ports;
482 ppc_ide_md.io_base = _IO_BASE;
483 #endif