diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2005-02-21 11:18:36 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2005-10-29 14:30:42 -0400 |
commit | c4ed38a0c6e2e5c4906296758f816ee71373792f (patch) | |
tree | 65ebab9ca61ea6d03109c53acd2989b626dce52a /arch | |
parent | 049b13c358f0187cf3c5003d5fb9848dbcb28bc3 (diff) |
Resurrect Cobalt support for 2.6.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/Makefile | 1 | ||||
-rw-r--r-- | arch/mips/cobalt/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/cobalt/int-handler.S | 4 | ||||
-rw-r--r-- | arch/mips/cobalt/irq.c | 111 | ||||
-rw-r--r-- | arch/mips/cobalt/promcon.c | 87 | ||||
-rw-r--r-- | arch/mips/cobalt/reset.c | 59 | ||||
-rw-r--r-- | arch/mips/cobalt/setup.c | 100 | ||||
-rw-r--r-- | arch/mips/pci/fixup-cobalt.c | 55 | ||||
-rw-r--r-- | arch/mips/pci/ops-gt64111.c | 10 |
9 files changed, 233 insertions, 196 deletions
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index dbd79bef34a0..5f2dfcddb9f2 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -323,6 +323,7 @@ load-$(CONFIG_MIPS_XXS1500) += 0xffffffff80100000 | |||
323 | # Cobalt Server | 323 | # Cobalt Server |
324 | # | 324 | # |
325 | core-$(CONFIG_MIPS_COBALT) += arch/mips/cobalt/ | 325 | core-$(CONFIG_MIPS_COBALT) += arch/mips/cobalt/ |
326 | cflags-$(CONFIG_MIPS_COBALT) += -Iinclude/asm-mips/cobalt | ||
326 | load-$(CONFIG_MIPS_COBALT) += 0xffffffff80080000 | 327 | load-$(CONFIG_MIPS_COBALT) += 0xffffffff80080000 |
327 | 328 | ||
328 | # | 329 | # |
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile index a5e6554b2326..3b6b7579d1de 100644 --- a/arch/mips/cobalt/Makefile +++ b/arch/mips/cobalt/Makefile | |||
@@ -2,6 +2,6 @@ | |||
2 | # Makefile for the Cobalt micro systems family specific parts of the kernel | 2 | # Makefile for the Cobalt micro systems family specific parts of the kernel |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := irq.o int-handler.o reset.o setup.o promcon.o | 5 | obj-y := irq.o int-handler.o reset.o setup.o |
6 | 6 | ||
7 | EXTRA_AFLAGS := $(CFLAGS) | 7 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/cobalt/int-handler.S b/arch/mips/cobalt/int-handler.S index 1a21dec1b3ca..f92608e8d84f 100644 --- a/arch/mips/cobalt/int-handler.S +++ b/arch/mips/cobalt/int-handler.S | |||
@@ -18,8 +18,8 @@ | |||
18 | SAVE_ALL | 18 | SAVE_ALL |
19 | CLI | 19 | CLI |
20 | 20 | ||
21 | la ra, ret_from_irq | 21 | PTR_LA ra, ret_from_irq |
22 | move a1, sp | 22 | move a0, sp |
23 | j cobalt_irq | 23 | j cobalt_irq |
24 | 24 | ||
25 | END(cobalt_handle_int) | 25 | END(cobalt_handle_int) |
diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c index 6d2a81581397..0d90851f925e 100644 --- a/arch/mips/cobalt/irq.c +++ b/arch/mips/cobalt/irq.c | |||
@@ -10,6 +10,8 @@ | |||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/irq.h> | 12 | #include <linux/irq.h> |
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/pci.h> | ||
13 | 15 | ||
14 | #include <asm/i8259.h> | 16 | #include <asm/i8259.h> |
15 | #include <asm/irq_cpu.h> | 17 | #include <asm/irq_cpu.h> |
@@ -25,8 +27,8 @@ extern void cobalt_handle_int(void); | |||
25 | * the CPU interrupt lines, and ones that come in on the via chip. The CPU | 27 | * the CPU interrupt lines, and ones that come in on the via chip. The CPU |
26 | * mappings are: | 28 | * mappings are: |
27 | * | 29 | * |
28 | * 16, - Software interrupt 0 (unused) IE_SW0 | 30 | * 16 - Software interrupt 0 (unused) IE_SW0 |
29 | * 17 - Software interrupt 1 (unused) IE_SW0 | 31 | * 17 - Software interrupt 1 (unused) IE_SW1 |
30 | * 18 - Galileo chip (timer) IE_IRQ0 | 32 | * 18 - Galileo chip (timer) IE_IRQ0 |
31 | * 19 - Tulip 0 + NCR SCSI IE_IRQ1 | 33 | * 19 - Tulip 0 + NCR SCSI IE_IRQ1 |
32 | * 20 - Tulip 1 IE_IRQ2 | 34 | * 20 - Tulip 1 IE_IRQ2 |
@@ -42,61 +44,94 @@ extern void cobalt_handle_int(void); | |||
42 | * 15 - IDE1 | 44 | * 15 - IDE1 |
43 | */ | 45 | */ |
44 | 46 | ||
45 | asmlinkage void cobalt_irq(struct pt_regs *regs) | 47 | static inline void galileo_irq(struct pt_regs *regs) |
46 | { | 48 | { |
47 | unsigned int pending = read_c0_status() & read_c0_cause(); | 49 | unsigned int mask, pending, devfn; |
48 | |||
49 | if (pending & CAUSEF_IP2) { /* int 18 */ | ||
50 | unsigned long irq_src = GALILEO_INL(GT_INTRCAUSE_OFS); | ||
51 | |||
52 | /* Check for timer irq ... */ | ||
53 | if (irq_src & GALILEO_T0EXP) { | ||
54 | /* Clear the int line */ | ||
55 | GALILEO_OUTL(0, GT_INTRCAUSE_OFS); | ||
56 | do_IRQ(COBALT_TIMER_IRQ, regs); | ||
57 | } | ||
58 | return; | ||
59 | } | ||
60 | 50 | ||
61 | if (pending & CAUSEF_IP6) { /* int 22 */ | 51 | mask = GALILEO_INL(GT_INTRMASK_OFS); |
62 | int irq = i8259_irq(); | 52 | pending = GALILEO_INL(GT_INTRCAUSE_OFS) & mask; |
63 | 53 | ||
64 | if (irq >= 0) | 54 | if (pending & GALILEO_INTR_T0EXP) { |
65 | do_IRQ(irq, regs); | ||
66 | return; | ||
67 | } | ||
68 | 55 | ||
69 | if (pending & CAUSEF_IP3) { /* int 19 */ | 56 | GALILEO_OUTL(~GALILEO_INTR_T0EXP, GT_INTRCAUSE_OFS); |
70 | do_IRQ(COBALT_ETH0_IRQ, regs); | 57 | do_IRQ(COBALT_GALILEO_IRQ, regs); |
71 | return; | ||
72 | } | ||
73 | 58 | ||
74 | if (pending & CAUSEF_IP4) { /* int 20 */ | 59 | } else if (pending & GALILEO_INTR_RETRY_CTR) { |
75 | do_IRQ(COBALT_ETH1_IRQ, regs); | ||
76 | return; | ||
77 | } | ||
78 | 60 | ||
79 | if (pending & CAUSEF_IP5) { /* int 21 */ | 61 | devfn = GALILEO_INL(GT_PCI0_CFGADDR_OFS) >> 8; |
80 | do_IRQ(COBALT_SERIAL_IRQ, regs); | 62 | GALILEO_OUTL(~GALILEO_INTR_RETRY_CTR, GT_INTRCAUSE_OFS); |
81 | return; | 63 | printk(KERN_WARNING "Galileo: PCI retry count exceeded (%02x.%u)\n", |
82 | } | 64 | PCI_SLOT(devfn), PCI_FUNC(devfn)); |
65 | |||
66 | } else { | ||
83 | 67 | ||
84 | if (pending & CAUSEF_IP7) { /* int 23 */ | 68 | GALILEO_OUTL(mask & ~pending, GT_INTRMASK_OFS); |
85 | do_IRQ(COBALT_QUBE_SLOT_IRQ, regs); | 69 | printk(KERN_WARNING "Galileo: masking unexpected interrupt %08x\n", pending); |
86 | return; | ||
87 | } | 70 | } |
88 | } | 71 | } |
89 | 72 | ||
73 | static inline void via_pic_irq(struct pt_regs *regs) | ||
74 | { | ||
75 | int irq; | ||
76 | |||
77 | irq = i8259_irq(); | ||
78 | if (irq >= 0) | ||
79 | do_IRQ(irq, regs); | ||
80 | } | ||
81 | |||
82 | asmlinkage void cobalt_irq(struct pt_regs *regs) | ||
83 | { | ||
84 | unsigned pending; | ||
85 | |||
86 | pending = read_c0_status() & read_c0_cause(); | ||
87 | |||
88 | if (pending & CAUSEF_IP2) /* COBALT_GALILEO_IRQ (18) */ | ||
89 | |||
90 | galileo_irq(regs); | ||
91 | |||
92 | else if (pending & CAUSEF_IP6) /* COBALT_VIA_IRQ (22) */ | ||
93 | |||
94 | via_pic_irq(regs); | ||
95 | |||
96 | else if (pending & CAUSEF_IP3) /* COBALT_ETH0_IRQ (19) */ | ||
97 | |||
98 | do_IRQ(COBALT_CPU_IRQ + 3, regs); | ||
99 | |||
100 | else if (pending & CAUSEF_IP4) /* COBALT_ETH1_IRQ (20) */ | ||
101 | |||
102 | do_IRQ(COBALT_CPU_IRQ + 4, regs); | ||
103 | |||
104 | else if (pending & CAUSEF_IP5) /* COBALT_SERIAL_IRQ (21) */ | ||
105 | |||
106 | do_IRQ(COBALT_CPU_IRQ + 5, regs); | ||
107 | |||
108 | else if (pending & CAUSEF_IP7) /* IRQ 23 */ | ||
109 | |||
110 | do_IRQ(COBALT_CPU_IRQ + 7, regs); | ||
111 | } | ||
112 | |||
113 | static struct irqaction irq_via = { | ||
114 | no_action, 0, { { 0, } }, "cascade", NULL, NULL | ||
115 | }; | ||
116 | |||
90 | void __init arch_init_irq(void) | 117 | void __init arch_init_irq(void) |
91 | { | 118 | { |
119 | /* | ||
120 | * Mask all Galileo interrupts. The Galileo | ||
121 | * handler is set in cobalt_timer_setup() | ||
122 | */ | ||
123 | GALILEO_OUTL(0, GT_INTRMASK_OFS); | ||
124 | |||
92 | set_except_vector(0, cobalt_handle_int); | 125 | set_except_vector(0, cobalt_handle_int); |
93 | 126 | ||
94 | init_i8259_irqs(); /* 0 ... 15 */ | 127 | init_i8259_irqs(); /* 0 ... 15 */ |
95 | mips_cpu_irq_init(16); /* 16 ... 23 */ | 128 | mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */ |
96 | 129 | ||
97 | /* | 130 | /* |
98 | * Mask all cpu interrupts | 131 | * Mask all cpu interrupts |
99 | * (except IE4, we already masked those at VIA level) | 132 | * (except IE4, we already masked those at VIA level) |
100 | */ | 133 | */ |
101 | change_c0_status(ST0_IM, IE_IRQ4); | 134 | change_c0_status(ST0_IM, IE_IRQ4); |
135 | |||
136 | setup_irq(COBALT_VIA_IRQ, &irq_via); | ||
102 | } | 137 | } |
diff --git a/arch/mips/cobalt/promcon.c b/arch/mips/cobalt/promcon.c deleted file mode 100644 index f03df761e9f1..000000000000 --- a/arch/mips/cobalt/promcon.c +++ /dev/null | |||
@@ -1,87 +0,0 @@ | |||
1 | /* | ||
2 | * PROM console for Cobalt Raq2 | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 1995, 1996, 1997 by Ralf Baechle | ||
9 | * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv) | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/init.h> | ||
14 | #include <linux/console.h> | ||
15 | #include <linux/kdev_t.h> | ||
16 | #include <linux/serial_reg.h> | ||
17 | |||
18 | #include <asm/delay.h> | ||
19 | #include <asm/serial.h> | ||
20 | #include <asm/io.h> | ||
21 | |||
22 | static unsigned long port = 0xc800000; | ||
23 | |||
24 | static __inline__ void ns16550_cons_put_char(char ch, unsigned long ioaddr) | ||
25 | { | ||
26 | char lsr; | ||
27 | |||
28 | do { | ||
29 | lsr = inb(ioaddr + UART_LSR); | ||
30 | } while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE)); | ||
31 | outb(ch, ioaddr + UART_TX); | ||
32 | } | ||
33 | |||
34 | static __inline__ char ns16550_cons_get_char(unsigned long ioaddr) | ||
35 | { | ||
36 | while ((inb(ioaddr + UART_LSR) & UART_LSR_DR) == 0) | ||
37 | udelay(1); | ||
38 | return inb(ioaddr + UART_RX); | ||
39 | } | ||
40 | |||
41 | void ns16550_console_write(struct console *co, const char *s, unsigned count) | ||
42 | { | ||
43 | char lsr, ier; | ||
44 | unsigned i; | ||
45 | |||
46 | ier = inb(port + UART_IER); | ||
47 | outb(0x00, port + UART_IER); | ||
48 | for (i=0; i < count; i++, s++) { | ||
49 | |||
50 | if(*s == '\n') | ||
51 | ns16550_cons_put_char('\r', port); | ||
52 | ns16550_cons_put_char(*s, port); | ||
53 | } | ||
54 | |||
55 | do { | ||
56 | lsr = inb(port + UART_LSR); | ||
57 | } while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE)); | ||
58 | |||
59 | outb(ier, port + UART_IER); | ||
60 | } | ||
61 | |||
62 | char getDebugChar(void) | ||
63 | { | ||
64 | return ns16550_cons_get_char(port); | ||
65 | } | ||
66 | |||
67 | void putDebugChar(char kgdb_char) | ||
68 | { | ||
69 | ns16550_cons_put_char(kgdb_char, port); | ||
70 | } | ||
71 | |||
72 | static struct console ns16550_console = { | ||
73 | .name = "prom", | ||
74 | .setup = NULL, | ||
75 | .write = ns16550_console_write, | ||
76 | .flags = CON_PRINTBUFFER, | ||
77 | .index = -1, | ||
78 | }; | ||
79 | |||
80 | static int __init ns16550_setup_console(void) | ||
81 | { | ||
82 | register_console(&ns16550_console); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | console_initcall(ns16550_setup_console); | ||
diff --git a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c index 084c8e59f42c..805a0e88507b 100644 --- a/arch/mips/cobalt/reset.c +++ b/arch/mips/cobalt/reset.c | |||
@@ -16,48 +16,45 @@ | |||
16 | #include <asm/reboot.h> | 16 | #include <asm/reboot.h> |
17 | #include <asm/system.h> | 17 | #include <asm/system.h> |
18 | #include <asm/mipsregs.h> | 18 | #include <asm/mipsregs.h> |
19 | #include <asm/cobalt/cobalt.h> | ||
19 | 20 | ||
20 | void cobalt_machine_restart(char *command) | 21 | void cobalt_machine_halt(void) |
21 | { | 22 | { |
22 | *(volatile char *)0xbc000000 = 0x0f; | 23 | int state, last, diff; |
24 | unsigned long mark; | ||
23 | 25 | ||
24 | /* | 26 | /* |
25 | * Ouch, we're still alive ... This time we take the silver bullet ... | 27 | * turn off bar on Qube, flash power off LED on RaQ (0.5Hz) |
26 | * ... and find that we leave the hardware in a state in which the | 28 | * |
27 | * kernel in the flush locks up somewhen during of after the PCI | 29 | * restart if ENTER and SELECT are pressed |
28 | * detection stuff. | ||
29 | */ | 30 | */ |
30 | set_c0_status(ST0_BEV | ST0_ERL); | ||
31 | change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); | ||
32 | flush_cache_all(); | ||
33 | write_c0_wired(0); | ||
34 | __asm__ __volatile__( | ||
35 | "jr\t%0" | ||
36 | : | ||
37 | : "r" (0xbfc00000)); | ||
38 | } | ||
39 | 31 | ||
40 | extern int led_state; | 32 | last = COBALT_KEY_PORT; |
41 | #define kLED 0xBC000000 | ||
42 | #define LEDSet(x) (*(volatile unsigned char *) kLED) = (( unsigned char)x) | ||
43 | 33 | ||
44 | void cobalt_machine_halt(void) | 34 | for (state = 0;;) { |
45 | { | 35 | |
46 | int mark; | 36 | state ^= COBALT_LED_POWER_OFF; |
37 | COBALT_LED_PORT = state; | ||
38 | |||
39 | diff = COBALT_KEY_PORT ^ last; | ||
40 | last ^= diff; | ||
47 | 41 | ||
48 | /* Blink our cute? little LED (number 3)... */ | 42 | if((diff & (COBALT_KEY_ENTER | COBALT_KEY_SELECT)) && !(~last & (COBALT_KEY_ENTER | COBALT_KEY_SELECT))) |
49 | while (1) { | 43 | COBALT_LED_PORT = COBALT_LED_RESET; |
50 | led_state = led_state | ( 1 << 3 ); | 44 | |
51 | LEDSet(led_state); | 45 | for (mark = jiffies; jiffies - mark < HZ;) |
52 | mark = jiffies; | 46 | ; |
53 | while (jiffies<(mark+HZ)); | ||
54 | led_state = led_state & ~( 1 << 3 ); | ||
55 | LEDSet(led_state); | ||
56 | mark = jiffies; | ||
57 | while (jiffies<(mark+HZ)); | ||
58 | } | 47 | } |
59 | } | 48 | } |
60 | 49 | ||
50 | void cobalt_machine_restart(char *command) | ||
51 | { | ||
52 | COBALT_LED_PORT = COBALT_LED_RESET; | ||
53 | |||
54 | /* we should never get here */ | ||
55 | cobalt_machine_halt(); | ||
56 | } | ||
57 | |||
61 | /* | 58 | /* |
62 | * This triggers the luser mode device driver for the power switch ;-) | 59 | * This triggers the luser mode device driver for the power switch ;-) |
63 | */ | 60 | */ |
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c index f8138c15a535..d358a118fa31 100644 --- a/arch/mips/cobalt/setup.c +++ b/arch/mips/cobalt/setup.c | |||
@@ -13,6 +13,8 @@ | |||
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/serial.h> | ||
17 | #include <linux/serial_core.h> | ||
16 | 18 | ||
17 | #include <asm/bootinfo.h> | 19 | #include <asm/bootinfo.h> |
18 | #include <asm/time.h> | 20 | #include <asm/time.h> |
@@ -21,6 +23,7 @@ | |||
21 | #include <asm/processor.h> | 23 | #include <asm/processor.h> |
22 | #include <asm/reboot.h> | 24 | #include <asm/reboot.h> |
23 | #include <asm/gt64120.h> | 25 | #include <asm/gt64120.h> |
26 | #include <asm/serial.h> | ||
24 | 27 | ||
25 | #include <asm/cobalt/cobalt.h> | 28 | #include <asm/cobalt/cobalt.h> |
26 | 29 | ||
@@ -30,45 +33,44 @@ extern void cobalt_machine_power_off(void); | |||
30 | 33 | ||
31 | int cobalt_board_id; | 34 | int cobalt_board_id; |
32 | 35 | ||
33 | static char my_cmdline[CL_SIZE] = { | ||
34 | "console=ttyS0,115200 " | ||
35 | #ifdef CONFIG_IP_PNP | ||
36 | "ip=on " | ||
37 | #endif | ||
38 | #ifdef CONFIG_ROOT_NFS | ||
39 | "root=/dev/nfs " | ||
40 | #else | ||
41 | "root=/dev/hda1 " | ||
42 | #endif | ||
43 | }; | ||
44 | |||
45 | const char *get_system_type(void) | 36 | const char *get_system_type(void) |
46 | { | 37 | { |
38 | switch (cobalt_board_id) { | ||
39 | case COBALT_BRD_ID_QUBE1: | ||
40 | return "Cobalt Qube"; | ||
41 | case COBALT_BRD_ID_RAQ1: | ||
42 | return "Cobalt RaQ"; | ||
43 | case COBALT_BRD_ID_QUBE2: | ||
44 | return "Cobalt Qube2"; | ||
45 | case COBALT_BRD_ID_RAQ2: | ||
46 | return "Cobalt RaQ2"; | ||
47 | } | ||
47 | return "MIPS Cobalt"; | 48 | return "MIPS Cobalt"; |
48 | } | 49 | } |
49 | 50 | ||
50 | static void __init cobalt_timer_setup(struct irqaction *irq) | 51 | static void __init cobalt_timer_setup(struct irqaction *irq) |
51 | { | 52 | { |
52 | /* Load timer value for 150 Hz */ | 53 | /* Load timer value for 1KHz (TCLK is 50MHz) */ |
53 | GALILEO_OUTL(500000, GT_TC0_OFS); | 54 | GALILEO_OUTL(50*1000*1000 / 1000, GT_TC0_OFS); |
54 | 55 | ||
55 | /* Register our timer interrupt */ | 56 | /* Enable timer */ |
56 | setup_irq(COBALT_TIMER_IRQ, irq); | 57 | GALILEO_OUTL(GALILEO_ENTC0 | GALILEO_SELTC0, GT_TC_CONTROL_OFS); |
57 | 58 | ||
58 | /* Enable timer ints */ | 59 | /* Register interrupt */ |
59 | GALILEO_OUTL((GALILEO_ENTC0 | GALILEO_SELTC0), GT_TC_CONTROL_OFS); | 60 | setup_irq(COBALT_GALILEO_IRQ, irq); |
60 | /* Unmask timer int */ | 61 | |
61 | GALILEO_OUTL(0x100, GT_INTRMASK_OFS); | 62 | /* Enable interrupt */ |
63 | GALILEO_OUTL(GALILEO_INTR_T0EXP | GALILEO_INL(GT_INTRMASK_OFS), GT_INTRMASK_OFS); | ||
62 | } | 64 | } |
63 | 65 | ||
64 | extern struct pci_ops gt64111_pci_ops; | 66 | extern struct pci_ops gt64111_pci_ops; |
65 | 67 | ||
66 | static struct resource cobalt_mem_resource = { | 68 | static struct resource cobalt_mem_resource = { |
67 | "GT64111 PCI MEM", GT64111_IO_BASE, 0xffffffffUL, IORESOURCE_MEM | 69 | "PCI memory", GT64111_MEM_BASE, GT64111_MEM_END, IORESOURCE_MEM |
68 | }; | 70 | }; |
69 | 71 | ||
70 | static struct resource cobalt_io_resource = { | 72 | static struct resource cobalt_io_resource = { |
71 | "GT64111 IO MEM", 0x00001000UL, 0x0fffffffUL, IORESOURCE_IO | 73 | "PCI I/O", 0x1000, 0xffff, IORESOURCE_IO |
72 | }; | 74 | }; |
73 | 75 | ||
74 | static struct resource cobalt_io_resources[] = { | 76 | static struct resource cobalt_io_resources[] = { |
@@ -86,11 +88,12 @@ static struct pci_controller cobalt_pci_controller = { | |||
86 | .mem_resource = &cobalt_mem_resource, | 88 | .mem_resource = &cobalt_mem_resource, |
87 | .mem_offset = 0, | 89 | .mem_offset = 0, |
88 | .io_resource = &cobalt_io_resource, | 90 | .io_resource = &cobalt_io_resource, |
89 | .io_offset = 0x00001000UL - GT64111_IO_BASE | 91 | .io_offset = 0 - GT64111_IO_BASE |
90 | }; | 92 | }; |
91 | 93 | ||
92 | void __init plat_setup(void) | 94 | void __init plat_setup(void) |
93 | { | 95 | { |
96 | static struct uart_port uart; | ||
94 | unsigned int devfn = PCI_DEVFN(COBALT_PCICONF_VIA, 0); | 97 | unsigned int devfn = PCI_DEVFN(COBALT_PCICONF_VIA, 0); |
95 | int i; | 98 | int i; |
96 | 99 | ||
@@ -100,7 +103,10 @@ void __init plat_setup(void) | |||
100 | 103 | ||
101 | board_timer_setup = cobalt_timer_setup; | 104 | board_timer_setup = cobalt_timer_setup; |
102 | 105 | ||
103 | set_io_port_base(KSEG1ADDR(GT64111_IO_BASE)); | 106 | set_io_port_base(CKSEG1ADDR(GT64111_IO_BASE)); |
107 | |||
108 | /* I/O port resource must include UART and LCD/buttons */ | ||
109 | ioport_resource.end = 0x0fffffff; | ||
104 | 110 | ||
105 | /* | 111 | /* |
106 | * This is a prom style console. We just poke at the | 112 | * This is a prom style console. We just poke at the |
@@ -120,25 +126,61 @@ void __init plat_setup(void) | |||
120 | cobalt_board_id >>= ((VIA_COBALT_BRD_ID_REG & 3) * 8); | 126 | cobalt_board_id >>= ((VIA_COBALT_BRD_ID_REG & 3) * 8); |
121 | cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id); | 127 | cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id); |
122 | 128 | ||
129 | printk("Cobalt board ID: %d\n", cobalt_board_id); | ||
130 | |||
123 | #ifdef CONFIG_PCI | 131 | #ifdef CONFIG_PCI |
124 | register_pci_controller(&cobalt_pci_controller); | 132 | register_pci_controller(&cobalt_pci_controller); |
125 | #endif | 133 | #endif |
134 | |||
135 | #ifdef CONFIG_SERIAL_8250 | ||
136 | if (cobalt_board_id > COBALT_BRD_ID_RAQ1) { | ||
137 | |||
138 | uart.line = 0; | ||
139 | uart.type = PORT_UNKNOWN; | ||
140 | uart.uartclk = 18432000; | ||
141 | uart.irq = COBALT_SERIAL_IRQ; | ||
142 | uart.flags = STD_COM_FLAGS; | ||
143 | uart.iobase = 0xc800000; | ||
144 | uart.iotype = UPIO_PORT; | ||
145 | |||
146 | early_serial_setup(&uart); | ||
147 | } | ||
148 | #endif | ||
126 | } | 149 | } |
127 | 150 | ||
128 | /* | 151 | /* |
129 | * Prom init. We read our one and only communication with the firmware. | 152 | * Prom init. We read our one and only communication with the firmware. |
130 | * Grab the amount of installed memory | 153 | * Grab the amount of installed memory. |
154 | * Better boot loaders (CoLo) pass a command line too :-) | ||
131 | */ | 155 | */ |
132 | 156 | ||
133 | void __init prom_init(void) | 157 | void __init prom_init(void) |
134 | { | 158 | { |
135 | int argc = fw_arg0; | 159 | int narg, indx, posn, nchr; |
136 | 160 | unsigned long memsz; | |
137 | strcpy(arcs_cmdline, my_cmdline); | 161 | char **argv; |
138 | 162 | ||
139 | mips_machgroup = MACH_GROUP_COBALT; | 163 | mips_machgroup = MACH_GROUP_COBALT; |
140 | 164 | ||
141 | add_memory_region(0x0, argc & 0x7fffffff, BOOT_MEM_RAM); | 165 | memsz = fw_arg0 & 0x7fff0000; |
166 | narg = fw_arg0 & 0x0000ffff; | ||
167 | |||
168 | if (narg) { | ||
169 | arcs_cmdline[0] = '\0'; | ||
170 | argv = (char **) fw_arg1; | ||
171 | posn = 0; | ||
172 | for (indx = 1; indx < narg; ++indx) { | ||
173 | nchr = strlen(argv[indx]); | ||
174 | if (posn + 1 + nchr + 1 > sizeof(arcs_cmdline)) | ||
175 | break; | ||
176 | if (posn) | ||
177 | arcs_cmdline[posn++] = ' '; | ||
178 | strcpy(arcs_cmdline + posn, argv[indx]); | ||
179 | posn += nchr; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | add_memory_region(0x0, memsz, BOOT_MEM_RAM); | ||
142 | } | 184 | } |
143 | 185 | ||
144 | unsigned long __init prom_free_prom_memory(void) | 186 | unsigned long __init prom_free_prom_memory(void) |
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c index 57e1ca2116bb..909292f50d06 100644 --- a/arch/mips/pci/fixup-cobalt.c +++ b/arch/mips/pci/fixup-cobalt.c | |||
@@ -21,6 +21,20 @@ | |||
21 | 21 | ||
22 | extern int cobalt_board_id; | 22 | extern int cobalt_board_id; |
23 | 23 | ||
24 | static void qube_raq_galileo_early_fixup(struct pci_dev *dev) | ||
25 | { | ||
26 | if (dev->devfn == PCI_DEVFN(0, 0) && | ||
27 | (dev->class >> 8) == PCI_CLASS_MEMORY_OTHER) { | ||
28 | |||
29 | dev->class = (PCI_CLASS_BRIDGE_HOST << 8) | (dev->class & 0xff); | ||
30 | |||
31 | printk(KERN_INFO "Galileo: fixed bridge class\n"); | ||
32 | } | ||
33 | } | ||
34 | |||
35 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111, | ||
36 | qube_raq_galileo_early_fixup); | ||
37 | |||
24 | static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev) | 38 | static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev) |
25 | { | 39 | { |
26 | unsigned short cfgword; | 40 | unsigned short cfgword; |
@@ -48,6 +62,9 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev) | |||
48 | { | 62 | { |
49 | unsigned short galileo_id; | 63 | unsigned short galileo_id; |
50 | 64 | ||
65 | if (dev->devfn != PCI_DEVFN(0, 0)) | ||
66 | return; | ||
67 | |||
51 | /* Fix PCI latency-timer and cache-line-size values in Galileo | 68 | /* Fix PCI latency-timer and cache-line-size values in Galileo |
52 | * host bridge. | 69 | * host bridge. |
53 | */ | 70 | */ |
@@ -55,6 +72,13 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev) | |||
55 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7); | 72 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7); |
56 | 73 | ||
57 | /* | 74 | /* |
75 | * The code described by the comment below has been removed | ||
76 | * as it causes bus mastering by the Ethernet controllers | ||
77 | * to break under any kind of network load. We always set | ||
78 | * the retry timeouts to their maximum. | ||
79 | * | ||
80 | * --x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x-- | ||
81 | * | ||
58 | * On all machines prior to Q2, we had the STOP line disconnected | 82 | * On all machines prior to Q2, we had the STOP line disconnected |
59 | * from Galileo to VIA on PCI. The new Galileo does not function | 83 | * from Galileo to VIA on PCI. The new Galileo does not function |
60 | * correctly unless we have it connected. | 84 | * correctly unless we have it connected. |
@@ -64,21 +88,43 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev) | |||
64 | */ | 88 | */ |
65 | pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id); | 89 | pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id); |
66 | galileo_id &= 0xff; /* mask off class info */ | 90 | galileo_id &= 0xff; /* mask off class info */ |
91 | |||
92 | printk(KERN_INFO "Galileo: revision %u\n", galileo_id); | ||
93 | |||
94 | #if 0 | ||
67 | if (galileo_id >= 0x10) { | 95 | if (galileo_id >= 0x10) { |
68 | /* New Galileo, assumes PCI stop line to VIA is connected. */ | 96 | /* New Galileo, assumes PCI stop line to VIA is connected. */ |
69 | GALILEO_OUTL(0x4020, GT_PCI0_TOR_OFS); | 97 | GALILEO_OUTL(0x4020, GT_PCI0_TOR_OFS); |
70 | } else if (galileo_id == 0x1 || galileo_id == 0x2) { | 98 | } else if (galileo_id == 0x1 || galileo_id == 0x2) |
99 | #endif | ||
100 | { | ||
71 | signed int timeo; | 101 | signed int timeo; |
72 | /* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */ | 102 | /* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */ |
73 | timeo = GALILEO_INL(GT_PCI0_TOR_OFS); | 103 | timeo = GALILEO_INL(GT_PCI0_TOR_OFS); |
74 | /* Old Galileo, assumes PCI STOP line to VIA is disconnected. */ | 104 | /* Old Galileo, assumes PCI STOP line to VIA is disconnected. */ |
75 | GALILEO_OUTL(0xffff, GT_PCI0_TOR_OFS); | 105 | GALILEO_OUTL( |
106 | (0xff << 16) | /* retry count */ | ||
107 | (0xff << 8) | /* timeout 1 */ | ||
108 | 0xff, /* timeout 0 */ | ||
109 | GT_PCI0_TOR_OFS); | ||
110 | |||
111 | /* enable PCI retry exceeded interrupt */ | ||
112 | GALILEO_OUTL(GALILEO_INTR_RETRY_CTR | GALILEO_INL(GT_INTRMASK_OFS), GT_INTRMASK_OFS); | ||
76 | } | 113 | } |
77 | } | 114 | } |
78 | 115 | ||
79 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_GALILEO, PCI_ANY_ID, | 116 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111, |
80 | qube_raq_galileo_fixup); | 117 | qube_raq_galileo_fixup); |
81 | 118 | ||
119 | static char irq_tab_qube1[] __initdata = { | ||
120 | [COBALT_PCICONF_CPU] = 0, | ||
121 | [COBALT_PCICONF_ETH0] = COBALT_QUBE1_ETH0_IRQ, | ||
122 | [COBALT_PCICONF_RAQSCSI] = COBALT_SCSI_IRQ, | ||
123 | [COBALT_PCICONF_VIA] = 0, | ||
124 | [COBALT_PCICONF_PCISLOT] = COBALT_QUBE_SLOT_IRQ, | ||
125 | [COBALT_PCICONF_ETH1] = 0 | ||
126 | }; | ||
127 | |||
82 | static char irq_tab_cobalt[] __initdata = { | 128 | static char irq_tab_cobalt[] __initdata = { |
83 | [COBALT_PCICONF_CPU] = 0, | 129 | [COBALT_PCICONF_CPU] = 0, |
84 | [COBALT_PCICONF_ETH0] = COBALT_ETH0_IRQ, | 130 | [COBALT_PCICONF_ETH0] = COBALT_ETH0_IRQ, |
@@ -99,6 +145,9 @@ static char irq_tab_raq2[] __initdata = { | |||
99 | 145 | ||
100 | int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | 146 | int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) |
101 | { | 147 | { |
148 | if (cobalt_board_id < COBALT_BRD_ID_QUBE2) | ||
149 | return irq_tab_qube1[slot]; | ||
150 | |||
102 | if (cobalt_board_id == COBALT_BRD_ID_RAQ2) | 151 | if (cobalt_board_id == COBALT_BRD_ID_RAQ2) |
103 | return irq_tab_raq2[slot]; | 152 | return irq_tab_raq2[slot]; |
104 | 153 | ||
diff --git a/arch/mips/pci/ops-gt64111.c b/arch/mips/pci/ops-gt64111.c index c5b0fc184c2a..c1807934768d 100644 --- a/arch/mips/pci/ops-gt64111.c +++ b/arch/mips/pci/ops-gt64111.c | |||
@@ -18,15 +18,15 @@ | |||
18 | #include <asm/cobalt/cobalt.h> | 18 | #include <asm/cobalt/cobalt.h> |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * Accessing device 31 hangs the GT64120. Not sure if this will also hang | 21 | * Device 31 on the GT64111 is used to generate PCI special |
22 | * the GT64111, let's be paranoid for now. | 22 | * cycles, so we shouldn't expected to find a device there ... |
23 | */ | 23 | */ |
24 | static inline int pci_range_ck(struct pci_bus *bus, unsigned int devfn) | 24 | static inline int pci_range_ck(struct pci_bus *bus, unsigned int devfn) |
25 | { | 25 | { |
26 | if (bus->number == 0 && devfn == PCI_DEVFN(31, 0)) | 26 | if (bus->number == 0 && PCI_SLOT(devfn) < 31) |
27 | return -1; | 27 | return 0; |
28 | 28 | ||
29 | return 0; | 29 | return -1; |
30 | } | 30 | } |
31 | 31 | ||
32 | static int gt64111_pci_read_config(struct pci_bus *bus, unsigned int devfn, | 32 | static int gt64111_pci_read_config(struct pci_bus *bus, unsigned int devfn, |