diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/mips/mips-boards |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/mips/mips-boards')
21 files changed, 2363 insertions, 0 deletions
diff --git a/arch/mips/mips-boards/atlas/Makefile b/arch/mips/mips-boards/atlas/Makefile new file mode 100644 index 000000000000..d8dab75906bf --- /dev/null +++ b/arch/mips/mips-boards/atlas/Makefile | |||
@@ -0,0 +1,20 @@ | |||
1 | # | ||
2 | # Carsten Langgaard, carstenl@mips.com | ||
3 | # Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | # | ||
5 | # This program is free software; you can distribute it and/or modify it | ||
6 | # under the terms of the GNU General Public License (Version 2) as | ||
7 | # published by the Free Software Foundation. | ||
8 | # | ||
9 | # This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | # for more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License along | ||
15 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | # | ||
18 | |||
19 | obj-y := atlas_int.o atlas_setup.o | ||
20 | obj-$(CONFIG_KGDB) += atlas_gdb.o | ||
diff --git a/arch/mips/mips-boards/atlas/atlas_gdb.c b/arch/mips/mips-boards/atlas/atlas_gdb.c new file mode 100644 index 000000000000..fb65280f1780 --- /dev/null +++ b/arch/mips/mips-boards/atlas/atlas_gdb.c | |||
@@ -0,0 +1,97 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * This is the interface to the remote debugger stub. | ||
19 | */ | ||
20 | #include <asm/io.h> | ||
21 | #include <asm/mips-boards/atlas.h> | ||
22 | #include <asm/mips-boards/saa9730_uart.h> | ||
23 | |||
24 | #define INB(a) inb((unsigned long)a) | ||
25 | #define OUTB(x,a) outb(x,(unsigned long)a) | ||
26 | |||
27 | /* | ||
28 | * This is the interface to the remote debugger stub | ||
29 | * if the Philips part is used for the debug port, | ||
30 | * called from the platform setup code. | ||
31 | */ | ||
32 | void *saa9730_base = (void *)ATLAS_SAA9730_REG; | ||
33 | |||
34 | static int saa9730_kgdb_active = 0; | ||
35 | |||
36 | #define SAA9730_BAUDCLOCK(baud) (((ATLAS_SAA9730_BAUDCLOCK/(baud))/16)-1) | ||
37 | |||
38 | int saa9730_kgdb_hook(int speed) | ||
39 | { | ||
40 | int baudclock; | ||
41 | t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR); | ||
42 | |||
43 | /* | ||
44 | * Clear all interrupts | ||
45 | */ | ||
46 | (void) INB(&kgdb_uart->Lsr); | ||
47 | (void) INB(&kgdb_uart->Msr); | ||
48 | (void) INB(&kgdb_uart->Thr_Rbr); | ||
49 | (void) INB(&kgdb_uart->Iir_Fcr); | ||
50 | |||
51 | /* | ||
52 | * Now, initialize the UART | ||
53 | */ | ||
54 | /* 8 data bits, one stop bit, no parity */ | ||
55 | OUTB(SAA9730_LCR_DATA8, &kgdb_uart->Lcr); | ||
56 | |||
57 | baudclock = SAA9730_BAUDCLOCK(speed); | ||
58 | |||
59 | OUTB((baudclock >> 16) & 0xff, &kgdb_uart->BaudDivMsb); | ||
60 | OUTB( baudclock & 0xff, &kgdb_uart->BaudDivLsb); | ||
61 | |||
62 | /* Set RTS/DTR active */ | ||
63 | OUTB(SAA9730_MCR_DTR | SAA9730_MCR_RTS, &kgdb_uart->Mcr); | ||
64 | saa9730_kgdb_active = 1; | ||
65 | |||
66 | return speed; | ||
67 | } | ||
68 | |||
69 | int saa9730_putDebugChar(char c) | ||
70 | { | ||
71 | t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR); | ||
72 | |||
73 | if (!saa9730_kgdb_active) { /* need to init device first */ | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_THRE)) | ||
78 | ; | ||
79 | OUTB(c, &kgdb_uart->Thr_Rbr); | ||
80 | |||
81 | return 1; | ||
82 | } | ||
83 | |||
84 | char saa9730_getDebugChar(void) | ||
85 | { | ||
86 | t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR); | ||
87 | char c; | ||
88 | |||
89 | if (!saa9730_kgdb_active) { /* need to init device first */ | ||
90 | return 0; | ||
91 | } | ||
92 | while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_DR)) | ||
93 | ; | ||
94 | |||
95 | c = INB(&kgdb_uart->Thr_Rbr); | ||
96 | return(c); | ||
97 | } | ||
diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c new file mode 100644 index 000000000000..8f1d875217a2 --- /dev/null +++ b/arch/mips/mips-boards/atlas/atlas_int.c | |||
@@ -0,0 +1,142 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * ######################################################################## | ||
6 | * | ||
7 | * This program is free software; you can distribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License (Version 2) as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
19 | * | ||
20 | * ######################################################################## | ||
21 | * | ||
22 | * Routines for generic manipulation of the interrupts found on the MIPS | ||
23 | * Atlas board. | ||
24 | * | ||
25 | */ | ||
26 | #include <linux/compiler.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/sched.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/interrupt.h> | ||
31 | #include <linux/kernel_stat.h> | ||
32 | |||
33 | #include <asm/irq.h> | ||
34 | #include <asm/io.h> | ||
35 | #include <asm/mips-boards/atlas.h> | ||
36 | #include <asm/mips-boards/atlasint.h> | ||
37 | #include <asm/gdb-stub.h> | ||
38 | |||
39 | |||
40 | static struct atlas_ictrl_regs *atlas_hw0_icregs; | ||
41 | |||
42 | extern asmlinkage void mipsIRQ(void); | ||
43 | |||
44 | #if 0 | ||
45 | #define DEBUG_INT(x...) printk(x) | ||
46 | #else | ||
47 | #define DEBUG_INT(x...) | ||
48 | #endif | ||
49 | |||
50 | void disable_atlas_irq(unsigned int irq_nr) | ||
51 | { | ||
52 | atlas_hw0_icregs->intrsten = (1 << (irq_nr-ATLASINT_BASE)); | ||
53 | iob(); | ||
54 | } | ||
55 | |||
56 | void enable_atlas_irq(unsigned int irq_nr) | ||
57 | { | ||
58 | atlas_hw0_icregs->intseten = (1 << (irq_nr-ATLASINT_BASE)); | ||
59 | iob(); | ||
60 | } | ||
61 | |||
62 | static unsigned int startup_atlas_irq(unsigned int irq) | ||
63 | { | ||
64 | enable_atlas_irq(irq); | ||
65 | return 0; /* never anything pending */ | ||
66 | } | ||
67 | |||
68 | #define shutdown_atlas_irq disable_atlas_irq | ||
69 | |||
70 | #define mask_and_ack_atlas_irq disable_atlas_irq | ||
71 | |||
72 | static void end_atlas_irq(unsigned int irq) | ||
73 | { | ||
74 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
75 | enable_atlas_irq(irq); | ||
76 | } | ||
77 | |||
78 | static struct hw_interrupt_type atlas_irq_type = { | ||
79 | "Atlas", | ||
80 | startup_atlas_irq, | ||
81 | shutdown_atlas_irq, | ||
82 | enable_atlas_irq, | ||
83 | disable_atlas_irq, | ||
84 | mask_and_ack_atlas_irq, | ||
85 | end_atlas_irq, | ||
86 | NULL | ||
87 | }; | ||
88 | |||
89 | static inline int ls1bit32(unsigned int x) | ||
90 | { | ||
91 | int b = 31, s; | ||
92 | |||
93 | s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; | ||
94 | s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; | ||
95 | s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; | ||
96 | s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; | ||
97 | s = 1; if (x << 1 == 0) s = 0; b -= s; | ||
98 | |||
99 | return b; | ||
100 | } | ||
101 | |||
102 | void atlas_hw0_irqdispatch(struct pt_regs *regs) | ||
103 | { | ||
104 | unsigned long int_status; | ||
105 | int irq; | ||
106 | |||
107 | int_status = atlas_hw0_icregs->intstatus; | ||
108 | |||
109 | /* if int_status == 0, then the interrupt has already been cleared */ | ||
110 | if (unlikely(int_status == 0)) | ||
111 | return; | ||
112 | |||
113 | irq = ATLASINT_BASE + ls1bit32(int_status); | ||
114 | |||
115 | DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq); | ||
116 | |||
117 | do_IRQ(irq, regs); | ||
118 | } | ||
119 | |||
120 | void __init arch_init_irq(void) | ||
121 | { | ||
122 | int i; | ||
123 | |||
124 | atlas_hw0_icregs = (struct atlas_ictrl_regs *)ioremap (ATLAS_ICTRL_REGS_BASE, sizeof(struct atlas_ictrl_regs *)); | ||
125 | |||
126 | /* | ||
127 | * Mask out all interrupt by writing "1" to all bit position in | ||
128 | * the interrupt reset reg. | ||
129 | */ | ||
130 | atlas_hw0_icregs->intrsten = 0xffffffff; | ||
131 | |||
132 | /* Now safe to set the exception vector. */ | ||
133 | set_except_vector(0, mipsIRQ); | ||
134 | |||
135 | for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) { | ||
136 | irq_desc[i].status = IRQ_DISABLED; | ||
137 | irq_desc[i].action = 0; | ||
138 | irq_desc[i].depth = 1; | ||
139 | irq_desc[i].handler = &atlas_irq_type; | ||
140 | spin_lock_init(&irq_desc[i].lock); | ||
141 | } | ||
142 | } | ||
diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c new file mode 100644 index 000000000000..0a1dd9bbc02e --- /dev/null +++ b/arch/mips/mips-boards/atlas/atlas_setup.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | */ | ||
18 | #include <linux/config.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/ioport.h> | ||
23 | #include <linux/tty.h> | ||
24 | #include <linux/serial.h> | ||
25 | #include <linux/serial_core.h> | ||
26 | |||
27 | #include <asm/cpu.h> | ||
28 | #include <asm/bootinfo.h> | ||
29 | #include <asm/irq.h> | ||
30 | #include <asm/mips-boards/generic.h> | ||
31 | #include <asm/mips-boards/prom.h> | ||
32 | #include <asm/mips-boards/atlas.h> | ||
33 | #include <asm/mips-boards/atlasint.h> | ||
34 | #include <asm/time.h> | ||
35 | #include <asm/traps.h> | ||
36 | |||
37 | extern void mips_reboot_setup(void); | ||
38 | extern void mips_time_init(void); | ||
39 | extern void mips_timer_setup(struct irqaction *irq); | ||
40 | extern unsigned long mips_rtc_get_time(void); | ||
41 | |||
42 | #ifdef CONFIG_KGDB | ||
43 | extern void kgdb_config(void); | ||
44 | #endif | ||
45 | |||
46 | static void __init serial_init(void); | ||
47 | |||
48 | const char *get_system_type(void) | ||
49 | { | ||
50 | return "MIPS Atlas"; | ||
51 | } | ||
52 | |||
53 | static int __init atlas_setup(void) | ||
54 | { | ||
55 | ioport_resource.end = 0x7fffffff; | ||
56 | |||
57 | serial_init (); | ||
58 | |||
59 | #ifdef CONFIG_KGDB | ||
60 | kgdb_config(); | ||
61 | #endif | ||
62 | mips_reboot_setup(); | ||
63 | |||
64 | board_time_init = mips_time_init; | ||
65 | board_timer_setup = mips_timer_setup; | ||
66 | rtc_get_time = mips_rtc_get_time; | ||
67 | |||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | early_initcall(atlas_setup); | ||
72 | |||
73 | static void __init serial_init(void) | ||
74 | { | ||
75 | #ifdef CONFIG_SERIAL_8250 | ||
76 | struct uart_port s; | ||
77 | |||
78 | memset(&s, 0, sizeof(s)); | ||
79 | |||
80 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
81 | s.iobase = ATLAS_UART_REGS_BASE; | ||
82 | #else | ||
83 | s.iobase = ATLAS_UART_REGS_BASE+3; | ||
84 | #endif | ||
85 | s.irq = ATLASINT_UART; | ||
86 | s.uartclk = ATLAS_BASE_BAUD * 16; | ||
87 | s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; | ||
88 | s.iotype = SERIAL_IO_PORT; | ||
89 | s.regshift = 3; | ||
90 | |||
91 | if (early_serial_setup(&s) != 0) { | ||
92 | printk(KERN_ERR "Serial setup failed!\n"); | ||
93 | } | ||
94 | #endif | ||
95 | } | ||
diff --git a/arch/mips/mips-boards/generic/Makefile b/arch/mips/mips-boards/generic/Makefile new file mode 100644 index 000000000000..b21bc6887fa8 --- /dev/null +++ b/arch/mips/mips-boards/generic/Makefile | |||
@@ -0,0 +1,26 @@ | |||
1 | # | ||
2 | # Carsten Langgaard, carstenl@mips.com | ||
3 | # Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | # | ||
5 | # This program is free software; you can distribute it and/or modify it | ||
6 | # under the terms of the GNU General Public License (Version 2) as | ||
7 | # published by the Free Software Foundation. | ||
8 | # | ||
9 | # This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | # for more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License along | ||
15 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | # | ||
18 | # Makefile for the MIPS boards generic routines under Linux. | ||
19 | # | ||
20 | |||
21 | obj-y := mipsIRQ.o reset.o display.o init.o memory.o \ | ||
22 | printf.o cmdline.o time.o | ||
23 | obj-$(CONFIG_PCI) += pci.o | ||
24 | obj-$(CONFIG_KGDB) += gdb_hook.o | ||
25 | |||
26 | EXTRA_AFLAGS := $(CFLAGS) | ||
diff --git a/arch/mips/mips-boards/generic/cmdline.c b/arch/mips/mips-boards/generic/cmdline.c new file mode 100644 index 000000000000..1871c30ed2eb --- /dev/null +++ b/arch/mips/mips-boards/generic/cmdline.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Kernel command line creation using the prom monitor (YAMON) argc/argv. | ||
19 | */ | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/string.h> | ||
22 | |||
23 | #include <asm/bootinfo.h> | ||
24 | |||
25 | extern int prom_argc; | ||
26 | extern int *_prom_argv; | ||
27 | |||
28 | /* | ||
29 | * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. | ||
30 | * This macro take care of sign extension. | ||
31 | */ | ||
32 | #define prom_argv(index) ((char *)(long)_prom_argv[(index)]) | ||
33 | |||
34 | char * __init prom_getcmdline(void) | ||
35 | { | ||
36 | return &(arcs_cmdline[0]); | ||
37 | } | ||
38 | |||
39 | |||
40 | void __init prom_init_cmdline(void) | ||
41 | { | ||
42 | char *cp; | ||
43 | int actr; | ||
44 | |||
45 | actr = 1; /* Always ignore argv[0] */ | ||
46 | |||
47 | cp = &(arcs_cmdline[0]); | ||
48 | while(actr < prom_argc) { | ||
49 | strcpy(cp, prom_argv(actr)); | ||
50 | cp += strlen(prom_argv(actr)); | ||
51 | *cp++ = ' '; | ||
52 | actr++; | ||
53 | } | ||
54 | if (cp != &(arcs_cmdline[0])) { | ||
55 | /* get rid of trailing space */ | ||
56 | --cp; | ||
57 | *cp = '\0'; | ||
58 | } | ||
59 | } | ||
diff --git a/arch/mips/mips-boards/generic/display.c b/arch/mips/mips-boards/generic/display.c new file mode 100644 index 000000000000..f653946afc23 --- /dev/null +++ b/arch/mips/mips-boards/generic/display.c | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Display routines for display messages in MIPS boards ascii display. | ||
19 | */ | ||
20 | |||
21 | #include <linux/compiler.h> | ||
22 | #include <asm/io.h> | ||
23 | #include <asm/mips-boards/generic.h> | ||
24 | |||
25 | void mips_display_message(const char *str) | ||
26 | { | ||
27 | static volatile unsigned int *display = NULL; | ||
28 | int i; | ||
29 | |||
30 | if (unlikely(display == NULL)) | ||
31 | display = (volatile unsigned int *)ioremap(ASCII_DISPLAY_POS_BASE, 16*sizeof(int)); | ||
32 | |||
33 | for (i = 0; i <= 14; i=i+2) { | ||
34 | if (*str) | ||
35 | display[i] = *str++; | ||
36 | else | ||
37 | display[i] = ' '; | ||
38 | } | ||
39 | } | ||
diff --git a/arch/mips/mips-boards/generic/gdb_hook.c b/arch/mips/mips-boards/generic/gdb_hook.c new file mode 100644 index 000000000000..91a2ccbe3730 --- /dev/null +++ b/arch/mips/mips-boards/generic/gdb_hook.c | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * This is the interface to the remote debugger stub. | ||
19 | */ | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/serial.h> | ||
22 | #include <linux/serialP.h> | ||
23 | #include <linux/serial_reg.h> | ||
24 | |||
25 | #include <asm/serial.h> | ||
26 | #include <asm/io.h> | ||
27 | |||
28 | static struct serial_state rs_table[RS_TABLE_SIZE] = { | ||
29 | SERIAL_PORT_DFNS /* Defined in serial.h */ | ||
30 | }; | ||
31 | |||
32 | static struct async_struct kdb_port_info = {0}; | ||
33 | |||
34 | int (*generic_putDebugChar)(char); | ||
35 | char (*generic_getDebugChar)(void); | ||
36 | |||
37 | static __inline__ unsigned int serial_in(struct async_struct *info, int offset) | ||
38 | { | ||
39 | return inb(info->port + offset); | ||
40 | } | ||
41 | |||
42 | static __inline__ void serial_out(struct async_struct *info, int offset, | ||
43 | int value) | ||
44 | { | ||
45 | outb(value, info->port+offset); | ||
46 | } | ||
47 | |||
48 | int rs_kgdb_hook(int tty_no, int speed) { | ||
49 | int t; | ||
50 | struct serial_state *ser = &rs_table[tty_no]; | ||
51 | |||
52 | kdb_port_info.state = ser; | ||
53 | kdb_port_info.magic = SERIAL_MAGIC; | ||
54 | kdb_port_info.port = ser->port; | ||
55 | kdb_port_info.flags = ser->flags; | ||
56 | |||
57 | /* | ||
58 | * Clear all interrupts | ||
59 | */ | ||
60 | serial_in(&kdb_port_info, UART_LSR); | ||
61 | serial_in(&kdb_port_info, UART_RX); | ||
62 | serial_in(&kdb_port_info, UART_IIR); | ||
63 | serial_in(&kdb_port_info, UART_MSR); | ||
64 | |||
65 | /* | ||
66 | * Now, initialize the UART | ||
67 | */ | ||
68 | serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */ | ||
69 | if (kdb_port_info.flags & ASYNC_FOURPORT) { | ||
70 | kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS; | ||
71 | t = UART_MCR_DTR | UART_MCR_OUT1; | ||
72 | } else { | ||
73 | kdb_port_info.MCR | ||
74 | = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; | ||
75 | t = UART_MCR_DTR | UART_MCR_RTS; | ||
76 | } | ||
77 | |||
78 | kdb_port_info.MCR = t; /* no interrupts, please */ | ||
79 | serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR); | ||
80 | |||
81 | /* | ||
82 | * and set the speed of the serial port | ||
83 | */ | ||
84 | if (speed == 0) | ||
85 | speed = 9600; | ||
86 | |||
87 | t = kdb_port_info.state->baud_base / speed; | ||
88 | /* set DLAB */ | ||
89 | serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB); | ||
90 | serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */ | ||
91 | serial_out(&kdb_port_info, UART_DLM, t >> 8); /* MS of divisor */ | ||
92 | /* reset DLAB */ | ||
93 | serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); | ||
94 | |||
95 | return speed; | ||
96 | } | ||
97 | |||
98 | int putDebugChar(char c) | ||
99 | { | ||
100 | return generic_putDebugChar(c); | ||
101 | } | ||
102 | |||
103 | char getDebugChar(void) | ||
104 | { | ||
105 | return generic_getDebugChar(); | ||
106 | } | ||
107 | |||
108 | int rs_putDebugChar(char c) | ||
109 | { | ||
110 | |||
111 | if (!kdb_port_info.state) { /* need to init device first */ | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0) | ||
116 | ; | ||
117 | |||
118 | serial_out(&kdb_port_info, UART_TX, c); | ||
119 | |||
120 | return 1; | ||
121 | } | ||
122 | |||
123 | char rs_getDebugChar(void) | ||
124 | { | ||
125 | if (!kdb_port_info.state) { /* need to init device first */ | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | while (!(serial_in(&kdb_port_info, UART_LSR) & 1)) | ||
130 | ; | ||
131 | |||
132 | return serial_in(&kdb_port_info, UART_RX); | ||
133 | } | ||
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c new file mode 100644 index 000000000000..31caf0603a3f --- /dev/null +++ b/arch/mips/mips-boards/generic/init.c | |||
@@ -0,0 +1,343 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * PROM library initialisation code. | ||
19 | */ | ||
20 | #include <linux/config.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/string.h> | ||
23 | #include <linux/kernel.h> | ||
24 | |||
25 | #include <asm/io.h> | ||
26 | #include <asm/bootinfo.h> | ||
27 | #include <asm/mips-boards/prom.h> | ||
28 | #include <asm/mips-boards/generic.h> | ||
29 | #ifdef CONFIG_MIPS_GT64120 | ||
30 | #include <asm/gt64120.h> | ||
31 | #endif | ||
32 | #include <asm/mips-boards/msc01_pci.h> | ||
33 | #include <asm/mips-boards/bonito64.h> | ||
34 | #ifdef CONFIG_MIPS_MALTA | ||
35 | #include <asm/mips-boards/malta.h> | ||
36 | #endif | ||
37 | |||
38 | #ifdef CONFIG_KGDB | ||
39 | extern int rs_kgdb_hook(int, int); | ||
40 | extern int rs_putDebugChar(char); | ||
41 | extern char rs_getDebugChar(void); | ||
42 | extern int saa9730_kgdb_hook(int); | ||
43 | extern int saa9730_putDebugChar(char); | ||
44 | extern char saa9730_getDebugChar(void); | ||
45 | #endif | ||
46 | |||
47 | int prom_argc; | ||
48 | int *_prom_argv, *_prom_envp; | ||
49 | |||
50 | /* | ||
51 | * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. | ||
52 | * This macro take care of sign extension, if running in 64-bit mode. | ||
53 | */ | ||
54 | #define prom_envp(index) ((char *)(long)_prom_envp[(index)]) | ||
55 | |||
56 | int init_debug = 0; | ||
57 | |||
58 | unsigned int mips_revision_corid; | ||
59 | |||
60 | /* Bonito64 system controller register base. */ | ||
61 | unsigned long _pcictrl_bonito; | ||
62 | unsigned long _pcictrl_bonito_pcicfg; | ||
63 | |||
64 | /* GT64120 system controller register base */ | ||
65 | unsigned long _pcictrl_gt64120; | ||
66 | |||
67 | /* MIPS System controller register base */ | ||
68 | unsigned long _pcictrl_msc; | ||
69 | |||
70 | char *prom_getenv(char *envname) | ||
71 | { | ||
72 | /* | ||
73 | * Return a pointer to the given environment variable. | ||
74 | * In 64-bit mode: we're using 64-bit pointers, but all pointers | ||
75 | * in the PROM structures are only 32-bit, so we need some | ||
76 | * workarounds, if we are running in 64-bit mode. | ||
77 | */ | ||
78 | int i, index=0; | ||
79 | |||
80 | i = strlen(envname); | ||
81 | |||
82 | while (prom_envp(index)) { | ||
83 | if(strncmp(envname, prom_envp(index), i) == 0) { | ||
84 | return(prom_envp(index+1)); | ||
85 | } | ||
86 | index += 2; | ||
87 | } | ||
88 | |||
89 | return NULL; | ||
90 | } | ||
91 | |||
92 | static inline unsigned char str2hexnum(unsigned char c) | ||
93 | { | ||
94 | if (c >= '0' && c <= '9') | ||
95 | return c - '0'; | ||
96 | if (c >= 'a' && c <= 'f') | ||
97 | return c - 'a' + 10; | ||
98 | return 0; /* foo */ | ||
99 | } | ||
100 | |||
101 | static inline void str2eaddr(unsigned char *ea, unsigned char *str) | ||
102 | { | ||
103 | int i; | ||
104 | |||
105 | for (i = 0; i < 6; i++) { | ||
106 | unsigned char num; | ||
107 | |||
108 | if((*str == '.') || (*str == ':')) | ||
109 | str++; | ||
110 | num = str2hexnum(*str++) << 4; | ||
111 | num |= (str2hexnum(*str++)); | ||
112 | ea[i] = num; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | int get_ethernet_addr(char *ethernet_addr) | ||
117 | { | ||
118 | char *ethaddr_str; | ||
119 | |||
120 | ethaddr_str = prom_getenv("ethaddr"); | ||
121 | if (!ethaddr_str) { | ||
122 | printk("ethaddr not set in boot prom\n"); | ||
123 | return -1; | ||
124 | } | ||
125 | str2eaddr(ethernet_addr, ethaddr_str); | ||
126 | |||
127 | if (init_debug > 1) { | ||
128 | int i; | ||
129 | printk("get_ethernet_addr: "); | ||
130 | for (i=0; i<5; i++) | ||
131 | printk("%02x:", (unsigned char)*(ethernet_addr+i)); | ||
132 | printk("%02x\n", *(ethernet_addr+i)); | ||
133 | } | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
139 | static void __init console_config(void) | ||
140 | { | ||
141 | char console_string[40]; | ||
142 | int baud = 0; | ||
143 | char parity = '\0', bits = '\0', flow = '\0'; | ||
144 | char *s; | ||
145 | |||
146 | if ((strstr(prom_getcmdline(), "console=ttyS")) == NULL) { | ||
147 | s = prom_getenv("modetty0"); | ||
148 | if (s) { | ||
149 | while (*s >= '0' && *s <= '9') | ||
150 | baud = baud*10 + *s++ - '0'; | ||
151 | if (*s == ',') s++; | ||
152 | if (*s) parity = *s++; | ||
153 | if (*s == ',') s++; | ||
154 | if (*s) bits = *s++; | ||
155 | if (*s == ',') s++; | ||
156 | if (*s == 'h') flow = 'r'; | ||
157 | } | ||
158 | if (baud == 0) | ||
159 | baud = 38400; | ||
160 | if (parity != 'n' && parity != 'o' && parity != 'e') | ||
161 | parity = 'n'; | ||
162 | if (bits != '7' && bits != '8') | ||
163 | bits = '8'; | ||
164 | if (flow == '\0') | ||
165 | flow = 'r'; | ||
166 | sprintf (console_string, " console=ttyS0,%d%c%c%c", baud, parity, bits, flow); | ||
167 | strcat (prom_getcmdline(), console_string); | ||
168 | prom_printf("Config serial console:%s\n", console_string); | ||
169 | } | ||
170 | } | ||
171 | #endif | ||
172 | |||
173 | #ifdef CONFIG_KGDB | ||
174 | void __init kgdb_config (void) | ||
175 | { | ||
176 | extern int (*generic_putDebugChar)(char); | ||
177 | extern char (*generic_getDebugChar)(void); | ||
178 | char *argptr; | ||
179 | int line, speed; | ||
180 | |||
181 | argptr = prom_getcmdline(); | ||
182 | if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { | ||
183 | argptr += strlen("kgdb=ttyS"); | ||
184 | if (*argptr != '0' && *argptr != '1') | ||
185 | printk("KGDB: Unknown serial line /dev/ttyS%c, " | ||
186 | "falling back to /dev/ttyS1\n", *argptr); | ||
187 | line = *argptr == '0' ? 0 : 1; | ||
188 | printk("KGDB: Using serial line /dev/ttyS%d for session\n", line); | ||
189 | |||
190 | speed = 0; | ||
191 | if (*++argptr == ',') | ||
192 | { | ||
193 | int c; | ||
194 | while ((c = *++argptr) && ('0' <= c && c <= '9')) | ||
195 | speed = speed * 10 + c - '0'; | ||
196 | } | ||
197 | #ifdef CONFIG_MIPS_ATLAS | ||
198 | if (line == 1) { | ||
199 | speed = saa9730_kgdb_hook(speed); | ||
200 | generic_putDebugChar = saa9730_putDebugChar; | ||
201 | generic_getDebugChar = saa9730_getDebugChar; | ||
202 | } | ||
203 | else | ||
204 | #endif | ||
205 | { | ||
206 | speed = rs_kgdb_hook(line, speed); | ||
207 | generic_putDebugChar = rs_putDebugChar; | ||
208 | generic_getDebugChar = rs_getDebugChar; | ||
209 | } | ||
210 | |||
211 | prom_printf("KGDB: Using serial line /dev/ttyS%d at %d for session, " | ||
212 | "please connect your debugger\n", line ? 1 : 0, speed); | ||
213 | |||
214 | { | ||
215 | char *s; | ||
216 | for (s = "Please connect GDB to this port\r\n"; *s; ) | ||
217 | generic_putDebugChar (*s++); | ||
218 | } | ||
219 | |||
220 | kgdb_enabled = 1; | ||
221 | /* Breakpoint is invoked after interrupts are initialised */ | ||
222 | } | ||
223 | } | ||
224 | #endif | ||
225 | |||
226 | void __init prom_init(void) | ||
227 | { | ||
228 | prom_argc = fw_arg0; | ||
229 | _prom_argv = (int *) fw_arg1; | ||
230 | _prom_envp = (int *) fw_arg2; | ||
231 | |||
232 | mips_display_message("LINUX"); | ||
233 | |||
234 | #ifdef CONFIG_MIPS_SEAD | ||
235 | set_io_port_base(KSEG1); | ||
236 | #else | ||
237 | /* | ||
238 | * early setup of _pcictrl_bonito so that we can determine | ||
239 | * the system controller on a CORE_EMUL board | ||
240 | */ | ||
241 | _pcictrl_bonito = (unsigned long)ioremap(BONITO_REG_BASE, BONITO_REG_SIZE); | ||
242 | |||
243 | mips_revision_corid = MIPS_REVISION_CORID; | ||
244 | |||
245 | if (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL) { | ||
246 | if (BONITO_PCIDID == 0x0001df53 || | ||
247 | BONITO_PCIDID == 0x0003df53) | ||
248 | mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_BON; | ||
249 | else | ||
250 | mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC; | ||
251 | } | ||
252 | switch(mips_revision_corid) { | ||
253 | case MIPS_REVISION_CORID_QED_RM5261: | ||
254 | case MIPS_REVISION_CORID_CORE_LV: | ||
255 | case MIPS_REVISION_CORID_CORE_FPGA: | ||
256 | case MIPS_REVISION_CORID_CORE_FPGAR2: | ||
257 | /* | ||
258 | * Setup the North bridge to do Master byte-lane swapping | ||
259 | * when running in bigendian. | ||
260 | */ | ||
261 | _pcictrl_gt64120 = (unsigned long)ioremap(MIPS_GT_BASE, 0x2000); | ||
262 | |||
263 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
264 | GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT | | ||
265 | GT_PCI0_CMD_SBYTESWAP_BIT); | ||
266 | #else | ||
267 | GT_WRITE(GT_PCI0_CMD_OFS, 0); | ||
268 | #endif | ||
269 | |||
270 | #ifdef CONFIG_MIPS_MALTA | ||
271 | set_io_port_base(MALTA_GT_PORT_BASE); | ||
272 | #else | ||
273 | set_io_port_base((unsigned long)ioremap(0, 0x20000000)); | ||
274 | #endif | ||
275 | break; | ||
276 | |||
277 | case MIPS_REVISION_CORID_CORE_EMUL_BON: | ||
278 | case MIPS_REVISION_CORID_BONITO64: | ||
279 | case MIPS_REVISION_CORID_CORE_20K: | ||
280 | _pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE); | ||
281 | |||
282 | /* | ||
283 | * Disable Bonito IOBC. | ||
284 | */ | ||
285 | BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & | ||
286 | ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | | ||
287 | BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); | ||
288 | |||
289 | /* | ||
290 | * Setup the North bridge to do Master byte-lane swapping | ||
291 | * when running in bigendian. | ||
292 | */ | ||
293 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
294 | BONITO_BONGENCFG = BONITO_BONGENCFG & | ||
295 | ~(BONITO_BONGENCFG_MSTRBYTESWAP | | ||
296 | BONITO_BONGENCFG_BYTESWAP); | ||
297 | #else | ||
298 | BONITO_BONGENCFG = BONITO_BONGENCFG | | ||
299 | BONITO_BONGENCFG_MSTRBYTESWAP | | ||
300 | BONITO_BONGENCFG_BYTESWAP; | ||
301 | #endif | ||
302 | |||
303 | #ifdef CONFIG_MIPS_MALTA | ||
304 | set_io_port_base(MALTA_BONITO_PORT_BASE); | ||
305 | #else | ||
306 | set_io_port_base((unsigned long)ioremap(0, 0x20000000)); | ||
307 | #endif | ||
308 | break; | ||
309 | |||
310 | case MIPS_REVISION_CORID_CORE_MSC: | ||
311 | case MIPS_REVISION_CORID_CORE_FPGA2: | ||
312 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: | ||
313 | _pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000); | ||
314 | |||
315 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
316 | MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP); | ||
317 | #else | ||
318 | MSC_WRITE(MSC01_PCI_SWAP, | ||
319 | MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF | | ||
320 | MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF | | ||
321 | MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF); | ||
322 | #endif | ||
323 | |||
324 | #ifdef CONFIG_MIPS_MALTA | ||
325 | set_io_port_base(MALTA_MSC_PORT_BASE); | ||
326 | #else | ||
327 | set_io_port_base((unsigned long)ioremap(0, 0x20000000)); | ||
328 | #endif | ||
329 | break; | ||
330 | |||
331 | default: | ||
332 | /* Unknown Core card */ | ||
333 | mips_display_message("CC Error"); | ||
334 | while(1); /* We die here... */ | ||
335 | } | ||
336 | #endif | ||
337 | prom_printf("\nLINUX started...\n"); | ||
338 | prom_init_cmdline(); | ||
339 | prom_meminit(); | ||
340 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
341 | console_config(); | ||
342 | #endif | ||
343 | } | ||
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c new file mode 100644 index 000000000000..5ae2b43e4c2e --- /dev/null +++ b/arch/mips/mips-boards/generic/memory.c | |||
@@ -0,0 +1,173 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * PROM library functions for acquiring/using memory descriptors given to | ||
19 | * us from the YAMON. | ||
20 | */ | ||
21 | #include <linux/config.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/mm.h> | ||
24 | #include <linux/bootmem.h> | ||
25 | |||
26 | #include <asm/bootinfo.h> | ||
27 | #include <asm/page.h> | ||
28 | |||
29 | #include <asm/mips-boards/prom.h> | ||
30 | |||
31 | /*#define DEBUG*/ | ||
32 | |||
33 | enum yamon_memtypes { | ||
34 | yamon_dontuse, | ||
35 | yamon_prom, | ||
36 | yamon_free, | ||
37 | }; | ||
38 | struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; | ||
39 | |||
40 | #ifdef DEBUG | ||
41 | static char *mtypes[3] = { | ||
42 | "Dont use memory", | ||
43 | "YAMON PROM memory", | ||
44 | "Free memmory", | ||
45 | }; | ||
46 | #endif | ||
47 | |||
48 | /* References to section boundaries */ | ||
49 | extern char _end; | ||
50 | |||
51 | #define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK) | ||
52 | |||
53 | |||
54 | struct prom_pmemblock * __init prom_getmdesc(void) | ||
55 | { | ||
56 | char *memsize_str; | ||
57 | unsigned int memsize; | ||
58 | |||
59 | memsize_str = prom_getenv("memsize"); | ||
60 | if (!memsize_str) { | ||
61 | prom_printf("memsize not set in boot prom, set to default (32Mb)\n"); | ||
62 | memsize = 0x02000000; | ||
63 | } else { | ||
64 | #ifdef DEBUG | ||
65 | prom_printf("prom_memsize = %s\n", memsize_str); | ||
66 | #endif | ||
67 | memsize = simple_strtol(memsize_str, NULL, 0); | ||
68 | } | ||
69 | |||
70 | memset(mdesc, 0, sizeof(mdesc)); | ||
71 | |||
72 | mdesc[0].type = yamon_dontuse; | ||
73 | mdesc[0].base = 0x00000000; | ||
74 | mdesc[0].size = 0x00001000; | ||
75 | |||
76 | mdesc[1].type = yamon_prom; | ||
77 | mdesc[1].base = 0x00001000; | ||
78 | mdesc[1].size = 0x000ef000; | ||
79 | |||
80 | #ifdef CONFIG_MIPS_MALTA | ||
81 | /* | ||
82 | * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the | ||
83 | * south bridge and PCI access always forwarded to the ISA Bus and | ||
84 | * BIOSCS# is always generated. | ||
85 | * This mean that this area can't be used as DMA memory for PCI | ||
86 | * devices. | ||
87 | */ | ||
88 | mdesc[2].type = yamon_dontuse; | ||
89 | mdesc[2].base = 0x000f0000; | ||
90 | mdesc[2].size = 0x00010000; | ||
91 | #else | ||
92 | mdesc[2].type = yamon_prom; | ||
93 | mdesc[2].base = 0x000f0000; | ||
94 | mdesc[2].size = 0x00010000; | ||
95 | #endif | ||
96 | |||
97 | mdesc[3].type = yamon_dontuse; | ||
98 | mdesc[3].base = 0x00100000; | ||
99 | mdesc[3].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[3].base; | ||
100 | |||
101 | mdesc[4].type = yamon_free; | ||
102 | mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end)); | ||
103 | mdesc[4].size = memsize - mdesc[4].base; | ||
104 | |||
105 | return &mdesc[0]; | ||
106 | } | ||
107 | |||
108 | static int __init prom_memtype_classify (unsigned int type) | ||
109 | { | ||
110 | switch (type) { | ||
111 | case yamon_free: | ||
112 | return BOOT_MEM_RAM; | ||
113 | case yamon_prom: | ||
114 | return BOOT_MEM_ROM_DATA; | ||
115 | default: | ||
116 | return BOOT_MEM_RESERVED; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | void __init prom_meminit(void) | ||
121 | { | ||
122 | struct prom_pmemblock *p; | ||
123 | |||
124 | #ifdef DEBUG | ||
125 | prom_printf("YAMON MEMORY DESCRIPTOR dump:\n"); | ||
126 | p = prom_getmdesc(); | ||
127 | while (p->size) { | ||
128 | int i = 0; | ||
129 | prom_printf("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n", | ||
130 | i, p, p->base, p->size, mtypes[p->type]); | ||
131 | p++; | ||
132 | i++; | ||
133 | } | ||
134 | #endif | ||
135 | p = prom_getmdesc(); | ||
136 | |||
137 | while (p->size) { | ||
138 | long type; | ||
139 | unsigned long base, size; | ||
140 | |||
141 | type = prom_memtype_classify (p->type); | ||
142 | base = p->base; | ||
143 | size = p->size; | ||
144 | |||
145 | add_memory_region(base, size, type); | ||
146 | p++; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | unsigned long __init prom_free_prom_memory(void) | ||
151 | { | ||
152 | unsigned long freed = 0; | ||
153 | unsigned long addr; | ||
154 | int i; | ||
155 | |||
156 | for (i = 0; i < boot_mem_map.nr_map; i++) { | ||
157 | if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) | ||
158 | continue; | ||
159 | |||
160 | addr = boot_mem_map.map[i].addr; | ||
161 | while (addr < boot_mem_map.map[i].addr | ||
162 | + boot_mem_map.map[i].size) { | ||
163 | ClearPageReserved(virt_to_page(__va(addr))); | ||
164 | set_page_count(virt_to_page(__va(addr)), 1); | ||
165 | free_page((unsigned long)__va(addr)); | ||
166 | addr += PAGE_SIZE; | ||
167 | freed += PAGE_SIZE; | ||
168 | } | ||
169 | } | ||
170 | printk("Freeing prom memory: %ldkb freed\n", freed >> 10); | ||
171 | |||
172 | return freed; | ||
173 | } | ||
diff --git a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/generic/mipsIRQ.S new file mode 100644 index 000000000000..131f49bccb20 --- /dev/null +++ b/arch/mips/mips-boards/generic/mipsIRQ.S | |||
@@ -0,0 +1,153 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * ######################################################################## | ||
6 | * | ||
7 | * This program is free software; you can distribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License (Version 2) as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
19 | * | ||
20 | * ######################################################################## | ||
21 | * | ||
22 | * Interrupt exception dispatch code. | ||
23 | * | ||
24 | */ | ||
25 | #include <linux/config.h> | ||
26 | |||
27 | #include <asm/asm.h> | ||
28 | #include <asm/mipsregs.h> | ||
29 | #include <asm/regdef.h> | ||
30 | #include <asm/stackframe.h> | ||
31 | |||
32 | /* A lot of complication here is taken away because: | ||
33 | * | ||
34 | * 1) We handle one interrupt and return, sitting in a loop and moving across | ||
35 | * all the pending IRQ bits in the cause register is _NOT_ the answer, the | ||
36 | * common case is one pending IRQ so optimize in that direction. | ||
37 | * | ||
38 | * 2) We need not check against bits in the status register IRQ mask, that | ||
39 | * would make this routine slow as hell. | ||
40 | * | ||
41 | * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in | ||
42 | * between like BSD spl() brain-damage. | ||
43 | * | ||
44 | * Furthermore, the IRQs on the MIPS board look basically (barring software | ||
45 | * IRQs which we don't use at all and all external interrupt sources are | ||
46 | * combined together on hardware interrupt 0 (MIPS IRQ 2)) like: | ||
47 | * | ||
48 | * MIPS IRQ Source | ||
49 | * -------- ------ | ||
50 | * 0 Software (ignored) | ||
51 | * 1 Software (ignored) | ||
52 | * 2 Combined hardware interrupt (hw0) | ||
53 | * 3 Hardware (ignored) | ||
54 | * 4 Hardware (ignored) | ||
55 | * 5 Hardware (ignored) | ||
56 | * 6 Hardware (ignored) | ||
57 | * 7 R4k timer (what we use) | ||
58 | * | ||
59 | * Note: On the SEAD board thing are a little bit different. | ||
60 | * Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired | ||
61 | * wired to UART1. | ||
62 | * | ||
63 | * We handle the IRQ according to _our_ priority which is: | ||
64 | * | ||
65 | * Highest ---- R4k Timer | ||
66 | * Lowest ---- Combined hardware interrupt | ||
67 | * | ||
68 | * then we just return, if multiple IRQs are pending then we will just take | ||
69 | * another exception, big deal. | ||
70 | */ | ||
71 | |||
72 | .text | ||
73 | .set noreorder | ||
74 | .set noat | ||
75 | .align 5 | ||
76 | NESTED(mipsIRQ, PT_SIZE, sp) | ||
77 | SAVE_ALL | ||
78 | CLI | ||
79 | .set at | ||
80 | |||
81 | mfc0 s0, CP0_CAUSE # get irq bits | ||
82 | mfc0 s1, CP0_STATUS # get irq mask | ||
83 | and s0, s1 | ||
84 | |||
85 | /* First we check for r4k counter/timer IRQ. */ | ||
86 | andi a0, s0, CAUSEF_IP7 | ||
87 | beq a0, zero, 1f | ||
88 | andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt | ||
89 | |||
90 | /* Wheee, a timer interrupt. */ | ||
91 | move a0, sp | ||
92 | jal mips_timer_interrupt | ||
93 | nop | ||
94 | |||
95 | j ret_from_irq | ||
96 | nop | ||
97 | |||
98 | 1: | ||
99 | #if defined(CONFIG_MIPS_SEAD) | ||
100 | beq a0, zero, 1f | ||
101 | andi a0, s0, CAUSEF_IP3 # delay slot, check hw1 interrupt | ||
102 | #else | ||
103 | beq a0, zero, 1f # delay slot, check hw3 interrupt | ||
104 | andi a0, s0, CAUSEF_IP5 | ||
105 | #endif | ||
106 | |||
107 | /* Wheee, combined hardware level zero interrupt. */ | ||
108 | #if defined(CONFIG_MIPS_ATLAS) | ||
109 | jal atlas_hw0_irqdispatch | ||
110 | #elif defined(CONFIG_MIPS_MALTA) | ||
111 | jal malta_hw0_irqdispatch | ||
112 | #elif defined(CONFIG_MIPS_SEAD) | ||
113 | jal sead_hw0_irqdispatch | ||
114 | #else | ||
115 | #error "MIPS board not supported\n" | ||
116 | #endif | ||
117 | move a0, sp # delay slot | ||
118 | |||
119 | j ret_from_irq | ||
120 | nop # delay slot | ||
121 | |||
122 | 1: | ||
123 | #if defined(CONFIG_MIPS_SEAD) | ||
124 | beq a0, zero, 1f | ||
125 | andi a0, s0, CAUSEF_IP5 # delay slot, check hw3 interrupt | ||
126 | jal sead_hw1_irqdispatch | ||
127 | move a0, sp # delay slot | ||
128 | j ret_from_irq | ||
129 | nop # delay slot | ||
130 | 1: | ||
131 | #endif | ||
132 | #if defined(CONFIG_MIPS_MALTA) | ||
133 | beq a0, zero, 1f # check hw3 (coreHI) interrupt | ||
134 | nop | ||
135 | jal corehi_irqdispatch | ||
136 | move a0, sp | ||
137 | j ret_from_irq | ||
138 | nop | ||
139 | 1: | ||
140 | #endif | ||
141 | /* | ||
142 | * Here by mistake? This is possible, what can happen is that by the | ||
143 | * time we take the exception the IRQ pin goes low, so just leave if | ||
144 | * this is the case. | ||
145 | */ | ||
146 | move a1,s0 | ||
147 | PRINT("Got interrupt: c0_cause = %08x\n") | ||
148 | mfc0 a1, CP0_EPC | ||
149 | PRINT("c0_epc = %08x\n") | ||
150 | |||
151 | j ret_from_irq | ||
152 | nop | ||
153 | END(mipsIRQ) | ||
diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c new file mode 100644 index 000000000000..92c34bda02ae --- /dev/null +++ b/arch/mips/mips-boards/generic/pci.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) | ||
6 | * | ||
7 | * This program is free software; you can distribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License (Version 2) as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
19 | * | ||
20 | * MIPS boards specific PCI support. | ||
21 | */ | ||
22 | #include <linux/config.h> | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/init.h> | ||
27 | |||
28 | #include <asm/mips-boards/generic.h> | ||
29 | #include <asm/gt64120.h> | ||
30 | #include <asm/mips-boards/bonito64.h> | ||
31 | #include <asm/mips-boards/msc01_pci.h> | ||
32 | #ifdef CONFIG_MIPS_MALTA | ||
33 | #include <asm/mips-boards/malta.h> | ||
34 | #endif | ||
35 | |||
36 | static struct resource bonito64_mem_resource = { | ||
37 | .name = "Bonito PCI MEM", | ||
38 | .start = 0x10000000UL, | ||
39 | .end = 0x1bffffffUL, | ||
40 | .flags = IORESOURCE_MEM, | ||
41 | }; | ||
42 | |||
43 | static struct resource bonito64_io_resource = { | ||
44 | .name = "Bonito IO MEM", | ||
45 | .start = 0x00002000UL, /* avoid conflicts with YAMON allocated I/O addresses */ | ||
46 | .end = 0x000fffffUL, | ||
47 | .flags = IORESOURCE_IO, | ||
48 | }; | ||
49 | |||
50 | static struct resource gt64120_mem_resource = { | ||
51 | .name = "GT64120 PCI MEM", | ||
52 | .start = 0x10000000UL, | ||
53 | .end = 0x1bdfffffUL, | ||
54 | .flags = IORESOURCE_MEM, | ||
55 | }; | ||
56 | |||
57 | static struct resource gt64120_io_resource = { | ||
58 | .name = "GT64120 IO MEM", | ||
59 | #ifdef CONFIG_MIPS_ATLAS | ||
60 | .start = 0x18000000UL, | ||
61 | .end = 0x181fffffUL, | ||
62 | #endif | ||
63 | #ifdef CONFIG_MIPS_MALTA | ||
64 | .start = 0x00002000UL, | ||
65 | .end = 0x001fffffUL, | ||
66 | #endif | ||
67 | .flags = IORESOURCE_IO, | ||
68 | }; | ||
69 | |||
70 | static struct resource msc_mem_resource = { | ||
71 | .name = "MSC PCI MEM", | ||
72 | .start = 0x10000000UL, | ||
73 | .end = 0x1fffffffUL, | ||
74 | .flags = IORESOURCE_MEM, | ||
75 | }; | ||
76 | |||
77 | static struct resource msc_io_resource = { | ||
78 | .name = "MSC IO MEM", | ||
79 | .start = 0x00002000UL, | ||
80 | .end = 0x007fffffUL, | ||
81 | .flags = IORESOURCE_IO, | ||
82 | }; | ||
83 | |||
84 | extern struct pci_ops bonito64_pci_ops; | ||
85 | extern struct pci_ops gt64120_pci_ops; | ||
86 | extern struct pci_ops msc_pci_ops; | ||
87 | |||
88 | static struct pci_controller bonito64_controller = { | ||
89 | .pci_ops = &bonito64_pci_ops, | ||
90 | .io_resource = &bonito64_io_resource, | ||
91 | .mem_resource = &bonito64_mem_resource, | ||
92 | .mem_offset = 0x10000000UL, | ||
93 | .io_offset = 0x00000000UL, | ||
94 | }; | ||
95 | |||
96 | static struct pci_controller gt64120_controller = { | ||
97 | .pci_ops = >64120_pci_ops, | ||
98 | .io_resource = >64120_io_resource, | ||
99 | .mem_resource = >64120_mem_resource, | ||
100 | .mem_offset = 0x00000000UL, | ||
101 | .io_offset = 0x00000000UL, | ||
102 | }; | ||
103 | |||
104 | static struct pci_controller msc_controller = { | ||
105 | .pci_ops = &msc_pci_ops, | ||
106 | .io_resource = &msc_io_resource, | ||
107 | .mem_resource = &msc_mem_resource, | ||
108 | .mem_offset = 0x10000000UL, | ||
109 | .io_offset = 0x00000000UL, | ||
110 | }; | ||
111 | |||
112 | static int __init pcibios_init(void) | ||
113 | { | ||
114 | struct pci_controller *controller; | ||
115 | |||
116 | switch (mips_revision_corid) { | ||
117 | case MIPS_REVISION_CORID_QED_RM5261: | ||
118 | case MIPS_REVISION_CORID_CORE_LV: | ||
119 | case MIPS_REVISION_CORID_CORE_FPGA: | ||
120 | case MIPS_REVISION_CORID_CORE_FPGAR2: | ||
121 | /* | ||
122 | * Due to a bug in the Galileo system controller, we need | ||
123 | * to setup the PCI BAR for the Galileo internal registers. | ||
124 | * This should be done in the bios/bootprom and will be | ||
125 | * fixed in a later revision of YAMON (the MIPS boards | ||
126 | * boot prom). | ||
127 | */ | ||
128 | GT_WRITE(GT_PCI0_CFGADDR_OFS, | ||
129 | (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */ | ||
130 | (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */ | ||
131 | (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/ | ||
132 | ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/ | ||
133 | GT_PCI0_CFGADDR_CONFIGEN_BIT ); | ||
134 | |||
135 | /* Perform the write */ | ||
136 | GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE)); | ||
137 | |||
138 | controller = >64120_controller; | ||
139 | break; | ||
140 | |||
141 | case MIPS_REVISION_CORID_BONITO64: | ||
142 | case MIPS_REVISION_CORID_CORE_20K: | ||
143 | case MIPS_REVISION_CORID_CORE_EMUL_BON: | ||
144 | controller = &bonito64_controller; | ||
145 | break; | ||
146 | |||
147 | case MIPS_REVISION_CORID_CORE_MSC: | ||
148 | case MIPS_REVISION_CORID_CORE_FPGA2: | ||
149 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: | ||
150 | controller = &msc_controller; | ||
151 | break; | ||
152 | default: | ||
153 | return 1; | ||
154 | } | ||
155 | |||
156 | ioport_resource.end = controller->io_resource->end; | ||
157 | |||
158 | register_pci_controller (controller); | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | early_initcall(pcibios_init); | ||
diff --git a/arch/mips/mips-boards/generic/printf.c b/arch/mips/mips-boards/generic/printf.c new file mode 100644 index 000000000000..2c1ab1f19fdc --- /dev/null +++ b/arch/mips/mips-boards/generic/printf.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Putting things on the screen/serial line using YAMONs facilities. | ||
19 | */ | ||
20 | #include <linux/config.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/serial_reg.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <asm/io.h> | ||
26 | |||
27 | #ifdef CONFIG_MIPS_ATLAS | ||
28 | #include <asm/mips-boards/atlas.h> | ||
29 | |||
30 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
31 | #define PORT(offset) (ATLAS_UART_REGS_BASE + ((offset)<<3)) | ||
32 | #else | ||
33 | #define PORT(offset) (ATLAS_UART_REGS_BASE + 3 + ((offset)<<3)) | ||
34 | #endif | ||
35 | |||
36 | #elif defined(CONFIG_MIPS_SEAD) | ||
37 | |||
38 | #include <asm/mips-boards/sead.h> | ||
39 | |||
40 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
41 | #define PORT(offset) (SEAD_UART0_REGS_BASE + ((offset)<<3)) | ||
42 | #else | ||
43 | #define PORT(offset) (SEAD_UART0_REGS_BASE + 3 + ((offset)<<3)) | ||
44 | #endif | ||
45 | |||
46 | #else | ||
47 | |||
48 | #define PORT(offset) (0x3f8 + (offset)) | ||
49 | |||
50 | #endif | ||
51 | |||
52 | static inline unsigned int serial_in(int offset) | ||
53 | { | ||
54 | return inb(PORT(offset)); | ||
55 | } | ||
56 | |||
57 | static inline void serial_out(int offset, int value) | ||
58 | { | ||
59 | outb(value, PORT(offset)); | ||
60 | } | ||
61 | |||
62 | int prom_putchar(char c) | ||
63 | { | ||
64 | while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) | ||
65 | ; | ||
66 | |||
67 | serial_out(UART_TX, c); | ||
68 | |||
69 | return 1; | ||
70 | } | ||
71 | |||
72 | char prom_getchar(void) | ||
73 | { | ||
74 | while (!(serial_in(UART_LSR) & UART_LSR_DR)) | ||
75 | ; | ||
76 | |||
77 | return serial_in(UART_RX); | ||
78 | } | ||
79 | |||
diff --git a/arch/mips/mips-boards/generic/reset.c b/arch/mips/mips-boards/generic/reset.c new file mode 100644 index 000000000000..9fdec743bd95 --- /dev/null +++ b/arch/mips/mips-boards/generic/reset.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * ######################################################################## | ||
6 | * | ||
7 | * This program is free software; you can distribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License (Version 2) as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
19 | * | ||
20 | * ######################################################################## | ||
21 | * | ||
22 | * Reset the MIPS boards. | ||
23 | * | ||
24 | */ | ||
25 | #include <linux/config.h> | ||
26 | |||
27 | #include <asm/io.h> | ||
28 | #include <asm/reboot.h> | ||
29 | #include <asm/mips-boards/generic.h> | ||
30 | #if defined(CONFIG_MIPS_ATLAS) | ||
31 | #include <asm/mips-boards/atlas.h> | ||
32 | #endif | ||
33 | |||
34 | static void mips_machine_restart(char *command); | ||
35 | static void mips_machine_halt(void); | ||
36 | #if defined(CONFIG_MIPS_ATLAS) | ||
37 | static void atlas_machine_power_off(void); | ||
38 | #endif | ||
39 | |||
40 | static void mips_machine_restart(char *command) | ||
41 | { | ||
42 | volatile unsigned int *softres_reg = (unsigned int *)ioremap (SOFTRES_REG, sizeof(unsigned int)); | ||
43 | |||
44 | *softres_reg = GORESET; | ||
45 | } | ||
46 | |||
47 | static void mips_machine_halt(void) | ||
48 | { | ||
49 | volatile unsigned int *softres_reg = (unsigned int *)ioremap (SOFTRES_REG, sizeof(unsigned int)); | ||
50 | |||
51 | *softres_reg = GORESET; | ||
52 | } | ||
53 | |||
54 | #if defined(CONFIG_MIPS_ATLAS) | ||
55 | static void atlas_machine_power_off(void) | ||
56 | { | ||
57 | volatile unsigned int *psustby_reg = (unsigned int *)ioremap(ATLAS_PSUSTBY_REG, sizeof(unsigned int)); | ||
58 | |||
59 | *psustby_reg = ATLAS_GOSTBY; | ||
60 | } | ||
61 | #endif | ||
62 | |||
63 | void mips_reboot_setup(void) | ||
64 | { | ||
65 | _machine_restart = mips_machine_restart; | ||
66 | _machine_halt = mips_machine_halt; | ||
67 | #if defined(CONFIG_MIPS_ATLAS) | ||
68 | _machine_power_off = atlas_machine_power_off; | ||
69 | #endif | ||
70 | #if defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MIPS_SEAD) | ||
71 | _machine_power_off = mips_machine_halt; | ||
72 | #endif | ||
73 | } | ||
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c new file mode 100644 index 000000000000..fe7fc17305a6 --- /dev/null +++ b/arch/mips/mips-boards/generic/time.c | |||
@@ -0,0 +1,167 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Setting up the clock on the MIPS boards. | ||
19 | */ | ||
20 | |||
21 | #include <linux/types.h> | ||
22 | #include <linux/config.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/kernel_stat.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/spinlock.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/time.h> | ||
29 | #include <linux/timex.h> | ||
30 | #include <linux/mc146818rtc.h> | ||
31 | |||
32 | #include <asm/mipsregs.h> | ||
33 | #include <asm/ptrace.h> | ||
34 | #include <asm/div64.h> | ||
35 | #include <asm/cpu.h> | ||
36 | #include <asm/time.h> | ||
37 | #include <asm/mc146818-time.h> | ||
38 | |||
39 | #include <asm/mips-boards/generic.h> | ||
40 | #include <asm/mips-boards/prom.h> | ||
41 | |||
42 | unsigned long cpu_khz; | ||
43 | |||
44 | #if defined(CONFIG_MIPS_SEAD) | ||
45 | #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ5) | ||
46 | #else | ||
47 | #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) | ||
48 | #endif | ||
49 | |||
50 | #if defined(CONFIG_MIPS_ATLAS) | ||
51 | static char display_string[] = " LINUX ON ATLAS "; | ||
52 | #endif | ||
53 | #if defined(CONFIG_MIPS_MALTA) | ||
54 | static char display_string[] = " LINUX ON MALTA "; | ||
55 | #endif | ||
56 | #if defined(CONFIG_MIPS_SEAD) | ||
57 | static char display_string[] = " LINUX ON SEAD "; | ||
58 | #endif | ||
59 | static unsigned int display_count = 0; | ||
60 | #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) | ||
61 | |||
62 | #define MIPS_CPU_TIMER_IRQ (NR_IRQS-1) | ||
63 | |||
64 | static unsigned int timer_tick_count=0; | ||
65 | |||
66 | void mips_timer_interrupt(struct pt_regs *regs) | ||
67 | { | ||
68 | if ((timer_tick_count++ % HZ) == 0) { | ||
69 | mips_display_message(&display_string[display_count++]); | ||
70 | if (display_count == MAX_DISPLAY_COUNT) | ||
71 | display_count = 0; | ||
72 | |||
73 | } | ||
74 | |||
75 | ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs); | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * Estimate CPU frequency. Sets mips_counter_frequency as a side-effect | ||
80 | */ | ||
81 | static unsigned int __init estimate_cpu_frequency(void) | ||
82 | { | ||
83 | unsigned int prid = read_c0_prid() & 0xffff00; | ||
84 | unsigned int count; | ||
85 | |||
86 | #ifdef CONFIG_MIPS_SEAD | ||
87 | /* | ||
88 | * The SEAD board doesn't have a real time clock, so we can't | ||
89 | * really calculate the timer frequency | ||
90 | * For now we hardwire the SEAD board frequency to 12MHz. | ||
91 | */ | ||
92 | |||
93 | if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) || | ||
94 | (prid == (PRID_COMP_MIPS | PRID_IMP_25KF))) | ||
95 | count = 12000000; | ||
96 | else | ||
97 | count = 6000000; | ||
98 | #endif | ||
99 | #if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) | ||
100 | unsigned int flags; | ||
101 | |||
102 | local_irq_save(flags); | ||
103 | |||
104 | /* Start counter exactly on falling edge of update flag */ | ||
105 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | ||
106 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | ||
107 | |||
108 | /* Start r4k counter. */ | ||
109 | write_c0_count(0); | ||
110 | |||
111 | /* Read counter exactly on falling edge of update flag */ | ||
112 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | ||
113 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | ||
114 | |||
115 | count = read_c0_count(); | ||
116 | |||
117 | /* restore interrupts */ | ||
118 | local_irq_restore(flags); | ||
119 | #endif | ||
120 | |||
121 | mips_hpt_frequency = count; | ||
122 | if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && | ||
123 | (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) | ||
124 | count *= 2; | ||
125 | |||
126 | count += 5000; /* round */ | ||
127 | count -= count%10000; | ||
128 | |||
129 | return count; | ||
130 | } | ||
131 | |||
132 | unsigned long __init mips_rtc_get_time(void) | ||
133 | { | ||
134 | return mc146818_get_cmos_time(); | ||
135 | } | ||
136 | |||
137 | void __init mips_time_init(void) | ||
138 | { | ||
139 | unsigned int est_freq, flags; | ||
140 | |||
141 | local_irq_save(flags); | ||
142 | |||
143 | #if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) | ||
144 | /* Set Data mode - binary. */ | ||
145 | CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); | ||
146 | #endif | ||
147 | |||
148 | est_freq = estimate_cpu_frequency (); | ||
149 | |||
150 | printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, | ||
151 | (est_freq%1000000)*100/1000000); | ||
152 | |||
153 | cpu_khz = est_freq / 1000; | ||
154 | |||
155 | local_irq_restore(flags); | ||
156 | } | ||
157 | |||
158 | void __init mips_timer_setup(struct irqaction *irq) | ||
159 | { | ||
160 | /* we are using the cpu counter for timer interrupts */ | ||
161 | irq->handler = no_action; /* we use our own handler */ | ||
162 | setup_irq(MIPS_CPU_TIMER_IRQ, irq); | ||
163 | |||
164 | /* to generate the first timer interrupt */ | ||
165 | write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ); | ||
166 | set_c0_status(ALLINTS); | ||
167 | } | ||
diff --git a/arch/mips/mips-boards/malta/Makefile b/arch/mips/mips-boards/malta/Makefile new file mode 100644 index 000000000000..fd4c143c0e2f --- /dev/null +++ b/arch/mips/mips-boards/malta/Makefile | |||
@@ -0,0 +1,22 @@ | |||
1 | # | ||
2 | # Carsten Langgaard, carstenl@mips.com | ||
3 | # Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | # | ||
5 | # This program is free software; you can distribute it and/or modify it | ||
6 | # under the terms of the GNU General Public License (Version 2) as | ||
7 | # published by the Free Software Foundation. | ||
8 | # | ||
9 | # This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | # for more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License along | ||
15 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | # | ||
18 | # Makefile for the MIPS Malta specific kernel interface routines | ||
19 | # under Linux. | ||
20 | # | ||
21 | |||
22 | obj-y := malta_int.o malta_setup.o | ||
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c new file mode 100644 index 000000000000..dd2db35966bc --- /dev/null +++ b/arch/mips/mips-boards/malta/malta_int.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc. | ||
4 | * Copyright (C) 2001 Ralf Baechle | ||
5 | * | ||
6 | * This program is free software; you can distribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License (Version 2) as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
13 | * for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
18 | * | ||
19 | * Routines for generic manipulation of the interrupts found on the MIPS | ||
20 | * Malta board. | ||
21 | * The interrupt controller is located in the South Bridge a PIIX4 device | ||
22 | * with two internal 82C95 interrupt controllers. | ||
23 | */ | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/irq.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/kernel_stat.h> | ||
30 | #include <linux/random.h> | ||
31 | |||
32 | #include <asm/i8259.h> | ||
33 | #include <asm/io.h> | ||
34 | #include <asm/mips-boards/malta.h> | ||
35 | #include <asm/mips-boards/maltaint.h> | ||
36 | #include <asm/mips-boards/piix4.h> | ||
37 | #include <asm/gt64120.h> | ||
38 | #include <asm/mips-boards/generic.h> | ||
39 | #include <asm/mips-boards/msc01_pci.h> | ||
40 | |||
41 | extern asmlinkage void mipsIRQ(void); | ||
42 | |||
43 | static DEFINE_SPINLOCK(mips_irq_lock); | ||
44 | |||
45 | static inline int mips_pcibios_iack(void) | ||
46 | { | ||
47 | int irq; | ||
48 | u32 dummy; | ||
49 | |||
50 | /* | ||
51 | * Determine highest priority pending interrupt by performing | ||
52 | * a PCI Interrupt Acknowledge cycle. | ||
53 | */ | ||
54 | switch(mips_revision_corid) { | ||
55 | case MIPS_REVISION_CORID_CORE_MSC: | ||
56 | case MIPS_REVISION_CORID_CORE_FPGA2: | ||
57 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: | ||
58 | MSC_READ(MSC01_PCI_IACK, irq); | ||
59 | irq &= 0xff; | ||
60 | break; | ||
61 | case MIPS_REVISION_CORID_QED_RM5261: | ||
62 | case MIPS_REVISION_CORID_CORE_LV: | ||
63 | case MIPS_REVISION_CORID_CORE_FPGA: | ||
64 | case MIPS_REVISION_CORID_CORE_FPGAR2: | ||
65 | irq = GT_READ(GT_PCI0_IACK_OFS); | ||
66 | irq &= 0xff; | ||
67 | break; | ||
68 | case MIPS_REVISION_CORID_BONITO64: | ||
69 | case MIPS_REVISION_CORID_CORE_20K: | ||
70 | case MIPS_REVISION_CORID_CORE_EMUL_BON: | ||
71 | /* The following will generate a PCI IACK cycle on the | ||
72 | * Bonito controller. It's a little bit kludgy, but it | ||
73 | * was the easiest way to implement it in hardware at | ||
74 | * the given time. | ||
75 | */ | ||
76 | BONITO_PCIMAP_CFG = 0x20000; | ||
77 | |||
78 | /* Flush Bonito register block */ | ||
79 | dummy = BONITO_PCIMAP_CFG; | ||
80 | iob(); /* sync */ | ||
81 | |||
82 | irq = *(volatile u32 *)(_pcictrl_bonito_pcicfg); | ||
83 | iob(); /* sync */ | ||
84 | irq &= 0xff; | ||
85 | BONITO_PCIMAP_CFG = 0; | ||
86 | break; | ||
87 | default: | ||
88 | printk("Unknown Core card, don't know the system controller.\n"); | ||
89 | return -1; | ||
90 | } | ||
91 | return irq; | ||
92 | } | ||
93 | |||
94 | static inline int get_int(int *irq) | ||
95 | { | ||
96 | unsigned long flags; | ||
97 | |||
98 | spin_lock_irqsave(&mips_irq_lock, flags); | ||
99 | |||
100 | *irq = mips_pcibios_iack(); | ||
101 | |||
102 | /* | ||
103 | * IRQ7 is used to detect spurious interrupts. | ||
104 | * The interrupt acknowledge cycle returns IRQ7, if no | ||
105 | * interrupts is requested. | ||
106 | * We can differentiate between this situation and a | ||
107 | * "Normal" IRQ7 by reading the ISR. | ||
108 | */ | ||
109 | if (*irq == 7) | ||
110 | { | ||
111 | outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR, | ||
112 | PIIX4_ICTLR1_OCW3); | ||
113 | if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) { | ||
114 | spin_unlock_irqrestore(&mips_irq_lock, flags); | ||
115 | printk("We got a spurious interrupt from PIIX4.\n"); | ||
116 | atomic_inc(&irq_err_count); | ||
117 | return -1; /* Spurious interrupt. */ | ||
118 | } | ||
119 | } | ||
120 | |||
121 | spin_unlock_irqrestore(&mips_irq_lock, flags); | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | void malta_hw0_irqdispatch(struct pt_regs *regs) | ||
127 | { | ||
128 | int irq; | ||
129 | |||
130 | if (get_int(&irq)) | ||
131 | return; /* interrupt has already been cleared */ | ||
132 | |||
133 | do_IRQ(irq, regs); | ||
134 | } | ||
135 | |||
136 | void corehi_irqdispatch(struct pt_regs *regs) | ||
137 | { | ||
138 | unsigned int data,datahi; | ||
139 | |||
140 | /* Mask out corehi interrupt. */ | ||
141 | clear_c0_status(IE_IRQ3); | ||
142 | |||
143 | printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n"); | ||
144 | printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n" | ||
145 | , regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr); | ||
146 | switch(mips_revision_corid) { | ||
147 | case MIPS_REVISION_CORID_CORE_MSC: | ||
148 | case MIPS_REVISION_CORID_CORE_FPGA2: | ||
149 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: | ||
150 | break; | ||
151 | case MIPS_REVISION_CORID_QED_RM5261: | ||
152 | case MIPS_REVISION_CORID_CORE_LV: | ||
153 | case MIPS_REVISION_CORID_CORE_FPGA: | ||
154 | case MIPS_REVISION_CORID_CORE_FPGAR2: | ||
155 | data = GT_READ(GT_INTRCAUSE_OFS); | ||
156 | printk("GT_INTRCAUSE = %08x\n", data); | ||
157 | data = GT_READ(GT_CPUERR_ADDRLO_OFS); | ||
158 | datahi = GT_READ(GT_CPUERR_ADDRHI_OFS); | ||
159 | printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, data); | ||
160 | break; | ||
161 | case MIPS_REVISION_CORID_BONITO64: | ||
162 | case MIPS_REVISION_CORID_CORE_20K: | ||
163 | case MIPS_REVISION_CORID_CORE_EMUL_BON: | ||
164 | data = BONITO_INTISR; | ||
165 | printk("BONITO_INTISR = %08x\n", data); | ||
166 | data = BONITO_INTEN; | ||
167 | printk("BONITO_INTEN = %08x\n", data); | ||
168 | data = BONITO_INTPOL; | ||
169 | printk("BONITO_INTPOL = %08x\n", data); | ||
170 | data = BONITO_INTEDGE; | ||
171 | printk("BONITO_INTEDGE = %08x\n", data); | ||
172 | data = BONITO_INTSTEER; | ||
173 | printk("BONITO_INTSTEER = %08x\n", data); | ||
174 | data = BONITO_PCICMD; | ||
175 | printk("BONITO_PCICMD = %08x\n", data); | ||
176 | break; | ||
177 | } | ||
178 | |||
179 | /* We die here*/ | ||
180 | die("CoreHi interrupt", regs); | ||
181 | } | ||
182 | |||
183 | void __init arch_init_irq(void) | ||
184 | { | ||
185 | set_except_vector(0, mipsIRQ); | ||
186 | init_i8259_irqs(); | ||
187 | } | ||
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c new file mode 100644 index 000000000000..3377e66de9eb --- /dev/null +++ b/arch/mips/mips-boards/malta/malta_setup.c | |||
@@ -0,0 +1,231 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | */ | ||
18 | #include <linux/config.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include <linux/ioport.h> | ||
22 | #include <linux/pci.h> | ||
23 | #include <linux/tty.h> | ||
24 | |||
25 | #ifdef CONFIG_MTD | ||
26 | #include <linux/mtd/partitions.h> | ||
27 | #include <linux/mtd/physmap.h> | ||
28 | #include <linux/mtd/mtd.h> | ||
29 | #include <linux/mtd/map.h> | ||
30 | #endif | ||
31 | |||
32 | #include <asm/cpu.h> | ||
33 | #include <asm/bootinfo.h> | ||
34 | #include <asm/irq.h> | ||
35 | #include <asm/mips-boards/generic.h> | ||
36 | #include <asm/mips-boards/prom.h> | ||
37 | #include <asm/mips-boards/malta.h> | ||
38 | #include <asm/mips-boards/maltaint.h> | ||
39 | #include <asm/dma.h> | ||
40 | #include <asm/time.h> | ||
41 | #include <asm/traps.h> | ||
42 | #ifdef CONFIG_VT | ||
43 | #include <linux/console.h> | ||
44 | #endif | ||
45 | |||
46 | extern void mips_reboot_setup(void); | ||
47 | extern void mips_time_init(void); | ||
48 | extern void mips_timer_setup(struct irqaction *irq); | ||
49 | extern unsigned long mips_rtc_get_time(void); | ||
50 | |||
51 | #ifdef CONFIG_KGDB | ||
52 | extern void kgdb_config(void); | ||
53 | #endif | ||
54 | |||
55 | struct resource standard_io_resources[] = { | ||
56 | { "dma1", 0x00, 0x1f, IORESOURCE_BUSY }, | ||
57 | { "timer", 0x40, 0x5f, IORESOURCE_BUSY }, | ||
58 | { "keyboard", 0x60, 0x6f, IORESOURCE_BUSY }, | ||
59 | { "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY }, | ||
60 | { "dma2", 0xc0, 0xdf, IORESOURCE_BUSY }, | ||
61 | }; | ||
62 | |||
63 | #ifdef CONFIG_MTD | ||
64 | static struct mtd_partition malta_mtd_partitions[] = { | ||
65 | { | ||
66 | .name = "YAMON", | ||
67 | .offset = 0x0, | ||
68 | .size = 0x100000, | ||
69 | .mask_flags = MTD_WRITEABLE | ||
70 | }, | ||
71 | { | ||
72 | .name = "User FS", | ||
73 | .offset = 0x100000, | ||
74 | .size = 0x2e0000 | ||
75 | }, | ||
76 | { | ||
77 | .name = "Board Config", | ||
78 | .offset = 0x3e0000, | ||
79 | .size = 0x020000, | ||
80 | .mask_flags = MTD_WRITEABLE | ||
81 | } | ||
82 | }; | ||
83 | |||
84 | #define number_partitions (sizeof(malta_mtd_partitions)/sizeof(struct mtd_partition)) | ||
85 | #endif | ||
86 | |||
87 | const char *get_system_type(void) | ||
88 | { | ||
89 | return "MIPS Malta"; | ||
90 | } | ||
91 | |||
92 | #ifdef CONFIG_BLK_DEV_FD | ||
93 | void __init fd_activate(void) | ||
94 | { | ||
95 | /* | ||
96 | * Activate Floppy Controller in the SMSC FDC37M817 Super I/O | ||
97 | * Controller. | ||
98 | * Done by YAMON 2.00 onwards | ||
99 | */ | ||
100 | /* Entering config state. */ | ||
101 | SMSC_WRITE(SMSC_CONFIG_ENTER, SMSC_CONFIG_REG); | ||
102 | |||
103 | /* Activate floppy controller. */ | ||
104 | SMSC_WRITE(SMSC_CONFIG_DEVNUM, SMSC_CONFIG_REG); | ||
105 | SMSC_WRITE(SMSC_CONFIG_DEVNUM_FLOPPY, SMSC_DATA_REG); | ||
106 | SMSC_WRITE(SMSC_CONFIG_ACTIVATE, SMSC_CONFIG_REG); | ||
107 | SMSC_WRITE(SMSC_CONFIG_ACTIVATE_ENABLE, SMSC_DATA_REG); | ||
108 | |||
109 | /* Exit config state. */ | ||
110 | SMSC_WRITE(SMSC_CONFIG_EXIT, SMSC_CONFIG_REG); | ||
111 | } | ||
112 | #endif | ||
113 | |||
114 | static int __init malta_setup(void) | ||
115 | { | ||
116 | unsigned int i; | ||
117 | |||
118 | /* Request I/O space for devices used on the Malta board. */ | ||
119 | for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) | ||
120 | request_resource(&ioport_resource, standard_io_resources+i); | ||
121 | |||
122 | /* | ||
123 | * Enable DMA channel 4 (cascade channel) in the PIIX4 south bridge. | ||
124 | */ | ||
125 | enable_dma(4); | ||
126 | |||
127 | #ifdef CONFIG_KGDB | ||
128 | kgdb_config (); | ||
129 | #endif | ||
130 | |||
131 | if ((mips_revision_corid == MIPS_REVISION_CORID_BONITO64) || | ||
132 | (mips_revision_corid == MIPS_REVISION_CORID_CORE_20K) || | ||
133 | (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL_BON)) { | ||
134 | char *argptr; | ||
135 | |||
136 | argptr = prom_getcmdline(); | ||
137 | if (strstr(argptr, "debug")) { | ||
138 | BONITO_BONGENCFG |= BONITO_BONGENCFG_DEBUGMODE; | ||
139 | printk ("Enabled Bonito debug mode\n"); | ||
140 | } | ||
141 | else | ||
142 | BONITO_BONGENCFG &= ~BONITO_BONGENCFG_DEBUGMODE; | ||
143 | |||
144 | #ifdef CONFIG_DMA_COHERENT | ||
145 | if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) { | ||
146 | BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN; | ||
147 | printk("Enabled Bonito CPU coherency\n"); | ||
148 | |||
149 | argptr = prom_getcmdline(); | ||
150 | if (strstr(argptr, "iobcuncached")) { | ||
151 | BONITO_PCICACHECTRL &= ~BONITO_PCICACHECTRL_IOBCCOH_EN; | ||
152 | BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & | ||
153 | ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | | ||
154 | BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); | ||
155 | printk("Disabled Bonito IOBC coherency\n"); | ||
156 | } | ||
157 | else { | ||
158 | BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_IOBCCOH_EN; | ||
159 | BONITO_PCIMEMBASECFG |= | ||
160 | (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | | ||
161 | BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); | ||
162 | printk("Disabled Bonito IOBC coherency\n"); | ||
163 | } | ||
164 | } | ||
165 | else | ||
166 | panic("Hardware DMA cache coherency not supported"); | ||
167 | |||
168 | #endif | ||
169 | } | ||
170 | #ifdef CONFIG_DMA_COHERENT | ||
171 | else { | ||
172 | panic("Hardware DMA cache coherency not supported"); | ||
173 | } | ||
174 | #endif | ||
175 | |||
176 | #ifdef CONFIG_BLK_DEV_IDE | ||
177 | /* Check PCI clock */ | ||
178 | { | ||
179 | int jmpr = (*((volatile unsigned int *)ioremap(MALTA_JMPRS_REG, sizeof(unsigned int))) >> 2) & 0x07; | ||
180 | static const int pciclocks[] __initdata = { | ||
181 | 33, 20, 25, 30, 12, 16, 37, 10 | ||
182 | }; | ||
183 | int pciclock = pciclocks[jmpr]; | ||
184 | char *argptr = prom_getcmdline(); | ||
185 | |||
186 | if (pciclock != 33 && !strstr (argptr, "idebus=")) { | ||
187 | printk("WARNING: PCI clock is %dMHz, setting idebus\n", pciclock); | ||
188 | argptr += strlen(argptr); | ||
189 | sprintf (argptr, " idebus=%d", pciclock); | ||
190 | if (pciclock < 20 || pciclock > 66) | ||
191 | printk ("WARNING: IDE timing calculations will be incorrect\n"); | ||
192 | } | ||
193 | } | ||
194 | #endif | ||
195 | #ifdef CONFIG_BLK_DEV_FD | ||
196 | fd_activate (); | ||
197 | #endif | ||
198 | #ifdef CONFIG_VT | ||
199 | #if defined(CONFIG_VGA_CONSOLE) | ||
200 | screen_info = (struct screen_info) { | ||
201 | 0, 25, /* orig-x, orig-y */ | ||
202 | 0, /* unused */ | ||
203 | 0, /* orig-video-page */ | ||
204 | 0, /* orig-video-mode */ | ||
205 | 80, /* orig-video-cols */ | ||
206 | 0,0,0, /* ega_ax, ega_bx, ega_cx */ | ||
207 | 25, /* orig-video-lines */ | ||
208 | VIDEO_TYPE_VGAC, /* orig-video-isVGA */ | ||
209 | 16 /* orig-video-points */ | ||
210 | }; | ||
211 | #endif | ||
212 | #endif | ||
213 | |||
214 | #ifdef CONFIG_MTD | ||
215 | /* | ||
216 | * Support for MTD on Malta. Use the generic physmap driver | ||
217 | */ | ||
218 | physmap_configure(0x1e000000, 0x400000, 4, NULL); | ||
219 | physmap_set_partitions(malta_mtd_partitions, number_partitions); | ||
220 | #endif | ||
221 | |||
222 | mips_reboot_setup(); | ||
223 | |||
224 | board_time_init = mips_time_init; | ||
225 | board_timer_setup = mips_timer_setup; | ||
226 | rtc_get_time = mips_rtc_get_time; | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | early_initcall(malta_setup); | ||
diff --git a/arch/mips/mips-boards/sead/Makefile b/arch/mips/mips-boards/sead/Makefile new file mode 100644 index 000000000000..224bb848f16b --- /dev/null +++ b/arch/mips/mips-boards/sead/Makefile | |||
@@ -0,0 +1,26 @@ | |||
1 | # | ||
2 | # Carsten Langgaard, carstenl@mips.com | ||
3 | # Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. | ||
4 | # | ||
5 | # ######################################################################## | ||
6 | # | ||
7 | # This program is free software; you can distribute it and/or modify it | ||
8 | # under the terms of the GNU General Public License (Version 2) as | ||
9 | # published by the Free Software Foundation. | ||
10 | # | ||
11 | # This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | # for more details. | ||
15 | # | ||
16 | # You should have received a copy of the GNU General Public License along | ||
17 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
19 | # | ||
20 | # ####################################################################### | ||
21 | # | ||
22 | # Makefile for the MIPS SEAD specific kernel interface routines | ||
23 | # under Linux. | ||
24 | # | ||
25 | |||
26 | obj-y := sead_int.o sead_setup.o | ||
diff --git a/arch/mips/mips-boards/sead/sead_int.c b/arch/mips/mips-boards/sead/sead_int.c new file mode 100644 index 000000000000..e5109657ed5a --- /dev/null +++ b/arch/mips/mips-boards/sead/sead_int.c | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. | ||
4 | * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org) | ||
5 | * | ||
6 | * This program is free software; you can distribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License (Version 2) as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
13 | * for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
18 | * | ||
19 | * Routines for generic manipulation of the interrupts found on the MIPS | ||
20 | * Sead board. | ||
21 | */ | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/irq.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | |||
26 | #include <asm/mips-boards/seadint.h> | ||
27 | |||
28 | extern asmlinkage void mipsIRQ(void); | ||
29 | |||
30 | asmlinkage void sead_hw0_irqdispatch(struct pt_regs *regs) | ||
31 | { | ||
32 | do_IRQ(SEADINT_UART0, regs); | ||
33 | } | ||
34 | |||
35 | asmlinkage void sead_hw1_irqdispatch(struct pt_regs *regs) | ||
36 | { | ||
37 | do_IRQ(SEADINT_UART1, regs); | ||
38 | } | ||
39 | |||
40 | void __init arch_init_irq(void) | ||
41 | { | ||
42 | /* | ||
43 | * Mask out all interrupt | ||
44 | */ | ||
45 | clear_c0_status(0x0000ff00); | ||
46 | |||
47 | /* Now safe to set the exception vector. */ | ||
48 | set_except_vector(0, mipsIRQ); | ||
49 | |||
50 | mips_cpu_irq_init(0); | ||
51 | } | ||
diff --git a/arch/mips/mips-boards/sead/sead_setup.c b/arch/mips/mips-boards/sead/sead_setup.c new file mode 100644 index 000000000000..29892b88a4fc --- /dev/null +++ b/arch/mips/mips-boards/sead/sead_setup.c | |||
@@ -0,0 +1,84 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * SEAD specific setup. | ||
19 | */ | ||
20 | #include <linux/config.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/ioport.h> | ||
24 | #include <linux/tty.h> | ||
25 | #include <linux/serial.h> | ||
26 | #include <linux/serial_core.h> | ||
27 | |||
28 | #include <asm/cpu.h> | ||
29 | #include <asm/bootinfo.h> | ||
30 | #include <asm/irq.h> | ||
31 | #include <asm/mips-boards/generic.h> | ||
32 | #include <asm/mips-boards/prom.h> | ||
33 | #include <asm/mips-boards/sead.h> | ||
34 | #include <asm/mips-boards/seadint.h> | ||
35 | #include <asm/time.h> | ||
36 | |||
37 | extern void mips_reboot_setup(void); | ||
38 | extern void mips_time_init(void); | ||
39 | extern void mips_timer_setup(struct irqaction *irq); | ||
40 | |||
41 | static void __init serial_init(void); | ||
42 | |||
43 | const char *get_system_type(void) | ||
44 | { | ||
45 | return "MIPS SEAD"; | ||
46 | } | ||
47 | |||
48 | static void __init sead_setup(void) | ||
49 | { | ||
50 | ioport_resource.end = 0x7fffffff; | ||
51 | |||
52 | serial_init (); | ||
53 | |||
54 | board_time_init = mips_time_init; | ||
55 | board_timer_setup = mips_timer_setup; | ||
56 | |||
57 | mips_reboot_setup(); | ||
58 | } | ||
59 | |||
60 | early_initcall(sead_setup); | ||
61 | |||
62 | static void __init serial_init(void) | ||
63 | { | ||
64 | #ifdef CONFIG_SERIAL_8250 | ||
65 | struct uart_port s; | ||
66 | |||
67 | memset(&s, 0, sizeof(s)); | ||
68 | |||
69 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
70 | s.iobase = SEAD_UART0_REGS_BASE; | ||
71 | #else | ||
72 | s.iobase = SEAD_UART0_REGS_BASE+3; | ||
73 | #endif | ||
74 | s.irq = SEADINT_UART0; | ||
75 | s.uartclk = SEAD_BASE_BAUD * 16; | ||
76 | s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; | ||
77 | s.iotype = 0; | ||
78 | s.regshift = 3; | ||
79 | |||
80 | if (early_serial_setup(&s) != 0) { | ||
81 | printk(KERN_ERR "Serial setup failed!\n"); | ||
82 | } | ||
83 | #endif | ||
84 | } | ||