aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mips-boards
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /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')
-rw-r--r--arch/mips/mips-boards/atlas/Makefile20
-rw-r--r--arch/mips/mips-boards/atlas/atlas_gdb.c97
-rw-r--r--arch/mips/mips-boards/atlas/atlas_int.c142
-rw-r--r--arch/mips/mips-boards/atlas/atlas_setup.c95
-rw-r--r--arch/mips/mips-boards/generic/Makefile26
-rw-r--r--arch/mips/mips-boards/generic/cmdline.c59
-rw-r--r--arch/mips/mips-boards/generic/display.c39
-rw-r--r--arch/mips/mips-boards/generic/gdb_hook.c133
-rw-r--r--arch/mips/mips-boards/generic/init.c343
-rw-r--r--arch/mips/mips-boards/generic/memory.c173
-rw-r--r--arch/mips/mips-boards/generic/mipsIRQ.S153
-rw-r--r--arch/mips/mips-boards/generic/pci.c163
-rw-r--r--arch/mips/mips-boards/generic/printf.c79
-rw-r--r--arch/mips/mips-boards/generic/reset.c73
-rw-r--r--arch/mips/mips-boards/generic/time.c167
-rw-r--r--arch/mips/mips-boards/malta/Makefile22
-rw-r--r--arch/mips/mips-boards/malta/malta_int.c187
-rw-r--r--arch/mips/mips-boards/malta/malta_setup.c231
-rw-r--r--arch/mips/mips-boards/sead/Makefile26
-rw-r--r--arch/mips/mips-boards/sead/sead_int.c51
-rw-r--r--arch/mips/mips-boards/sead/sead_setup.c84
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
19obj-y := atlas_int.o atlas_setup.o
20obj-$(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 */
32void *saa9730_base = (void *)ATLAS_SAA9730_REG;
33
34static int saa9730_kgdb_active = 0;
35
36#define SAA9730_BAUDCLOCK(baud) (((ATLAS_SAA9730_BAUDCLOCK/(baud))/16)-1)
37
38int 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
69int 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
84char 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
40static struct atlas_ictrl_regs *atlas_hw0_icregs;
41
42extern 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
50void disable_atlas_irq(unsigned int irq_nr)
51{
52 atlas_hw0_icregs->intrsten = (1 << (irq_nr-ATLASINT_BASE));
53 iob();
54}
55
56void enable_atlas_irq(unsigned int irq_nr)
57{
58 atlas_hw0_icregs->intseten = (1 << (irq_nr-ATLASINT_BASE));
59 iob();
60}
61
62static 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
72static 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
78static 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
89static 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
102void 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
120void __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
37extern void mips_reboot_setup(void);
38extern void mips_time_init(void);
39extern void mips_timer_setup(struct irqaction *irq);
40extern unsigned long mips_rtc_get_time(void);
41
42#ifdef CONFIG_KGDB
43extern void kgdb_config(void);
44#endif
45
46static void __init serial_init(void);
47
48const char *get_system_type(void)
49{
50 return "MIPS Atlas";
51}
52
53static 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
71early_initcall(atlas_setup);
72
73static 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
21obj-y := mipsIRQ.o reset.o display.o init.o memory.o \
22 printf.o cmdline.o time.o
23obj-$(CONFIG_PCI) += pci.o
24obj-$(CONFIG_KGDB) += gdb_hook.o
25
26EXTRA_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
25extern int prom_argc;
26extern 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
34char * __init prom_getcmdline(void)
35{
36 return &(arcs_cmdline[0]);
37}
38
39
40void __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
25void 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
28static struct serial_state rs_table[RS_TABLE_SIZE] = {
29 SERIAL_PORT_DFNS /* Defined in serial.h */
30};
31
32static struct async_struct kdb_port_info = {0};
33
34int (*generic_putDebugChar)(char);
35char (*generic_getDebugChar)(void);
36
37static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
38{
39 return inb(info->port + offset);
40}
41
42static __inline__ void serial_out(struct async_struct *info, int offset,
43 int value)
44{
45 outb(value, info->port+offset);
46}
47
48int 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
98int putDebugChar(char c)
99{
100 return generic_putDebugChar(c);
101}
102
103char getDebugChar(void)
104{
105 return generic_getDebugChar();
106}
107
108int 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
123char 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
39extern int rs_kgdb_hook(int, int);
40extern int rs_putDebugChar(char);
41extern char rs_getDebugChar(void);
42extern int saa9730_kgdb_hook(int);
43extern int saa9730_putDebugChar(char);
44extern char saa9730_getDebugChar(void);
45#endif
46
47int prom_argc;
48int *_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
56int init_debug = 0;
57
58unsigned int mips_revision_corid;
59
60/* Bonito64 system controller register base. */
61unsigned long _pcictrl_bonito;
62unsigned long _pcictrl_bonito_pcicfg;
63
64/* GT64120 system controller register base */
65unsigned long _pcictrl_gt64120;
66
67/* MIPS System controller register base */
68unsigned long _pcictrl_msc;
69
70char *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
92static 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
101static 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
116int 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
139static 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
174void __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
226void __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
33enum yamon_memtypes {
34 yamon_dontuse,
35 yamon_prom,
36 yamon_free,
37};
38struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
39
40#ifdef DEBUG
41static char *mtypes[3] = {
42 "Dont use memory",
43 "YAMON PROM memory",
44 "Free memmory",
45};
46#endif
47
48/* References to section boundaries */
49extern char _end;
50
51#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
52
53
54struct 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
108static 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
120void __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
150unsigned 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
981:
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
1221:
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
1301:
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
1391:
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
36static struct resource bonito64_mem_resource = {
37 .name = "Bonito PCI MEM",
38 .start = 0x10000000UL,
39 .end = 0x1bffffffUL,
40 .flags = IORESOURCE_MEM,
41};
42
43static 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
50static struct resource gt64120_mem_resource = {
51 .name = "GT64120 PCI MEM",
52 .start = 0x10000000UL,
53 .end = 0x1bdfffffUL,
54 .flags = IORESOURCE_MEM,
55};
56
57static 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
70static struct resource msc_mem_resource = {
71 .name = "MSC PCI MEM",
72 .start = 0x10000000UL,
73 .end = 0x1fffffffUL,
74 .flags = IORESOURCE_MEM,
75};
76
77static struct resource msc_io_resource = {
78 .name = "MSC IO MEM",
79 .start = 0x00002000UL,
80 .end = 0x007fffffUL,
81 .flags = IORESOURCE_IO,
82};
83
84extern struct pci_ops bonito64_pci_ops;
85extern struct pci_ops gt64120_pci_ops;
86extern struct pci_ops msc_pci_ops;
87
88static 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
96static struct pci_controller gt64120_controller = {
97 .pci_ops = &gt64120_pci_ops,
98 .io_resource = &gt64120_io_resource,
99 .mem_resource = &gt64120_mem_resource,
100 .mem_offset = 0x00000000UL,
101 .io_offset = 0x00000000UL,
102};
103
104static 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
112static 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 = &gt64120_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
163early_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
52static inline unsigned int serial_in(int offset)
53{
54 return inb(PORT(offset));
55}
56
57static inline void serial_out(int offset, int value)
58{
59 outb(value, PORT(offset));
60}
61
62int 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
72char 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
34static void mips_machine_restart(char *command);
35static void mips_machine_halt(void);
36#if defined(CONFIG_MIPS_ATLAS)
37static void atlas_machine_power_off(void);
38#endif
39
40static 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
47static 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)
55static 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
63void 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
42unsigned 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)
51static char display_string[] = " LINUX ON ATLAS ";
52#endif
53#if defined(CONFIG_MIPS_MALTA)
54static char display_string[] = " LINUX ON MALTA ";
55#endif
56#if defined(CONFIG_MIPS_SEAD)
57static char display_string[] = " LINUX ON SEAD ";
58#endif
59static 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
64static unsigned int timer_tick_count=0;
65
66void 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 */
81static 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
132unsigned long __init mips_rtc_get_time(void)
133{
134 return mc146818_get_cmos_time();
135}
136
137void __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
158void __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
22obj-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
41extern asmlinkage void mipsIRQ(void);
42
43static DEFINE_SPINLOCK(mips_irq_lock);
44
45static 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
94static 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
126void 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
136void 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
183void __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
46extern void mips_reboot_setup(void);
47extern void mips_time_init(void);
48extern void mips_timer_setup(struct irqaction *irq);
49extern unsigned long mips_rtc_get_time(void);
50
51#ifdef CONFIG_KGDB
52extern void kgdb_config(void);
53#endif
54
55struct 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
64static 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
87const char *get_system_type(void)
88{
89 return "MIPS Malta";
90}
91
92#ifdef CONFIG_BLK_DEV_FD
93void __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
114static 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
231early_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
26obj-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
28extern asmlinkage void mipsIRQ(void);
29
30asmlinkage void sead_hw0_irqdispatch(struct pt_regs *regs)
31{
32 do_IRQ(SEADINT_UART0, regs);
33}
34
35asmlinkage void sead_hw1_irqdispatch(struct pt_regs *regs)
36{
37 do_IRQ(SEADINT_UART1, regs);
38}
39
40void __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
37extern void mips_reboot_setup(void);
38extern void mips_time_init(void);
39extern void mips_timer_setup(struct irqaction *irq);
40
41static void __init serial_init(void);
42
43const char *get_system_type(void)
44{
45 return "MIPS SEAD";
46}
47
48static 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
60early_initcall(sead_setup);
61
62static 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}