aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/ddb5xxx/ddb5476
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/ddb5xxx/ddb5476
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/ddb5xxx/ddb5476')
-rw-r--r--arch/mips/ddb5xxx/ddb5476/Makefile9
-rw-r--r--arch/mips/ddb5xxx/ddb5476/dbg_io.c136
-rw-r--r--arch/mips/ddb5xxx/ddb5476/int-handler.S112
-rw-r--r--arch/mips/ddb5xxx/ddb5476/irq.c143
-rw-r--r--arch/mips/ddb5xxx/ddb5476/nile4_pic.c190
-rw-r--r--arch/mips/ddb5xxx/ddb5476/setup.c297
-rw-r--r--arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c112
7 files changed, 999 insertions, 0 deletions
diff --git a/arch/mips/ddb5xxx/ddb5476/Makefile b/arch/mips/ddb5xxx/ddb5476/Makefile
new file mode 100644
index 000000000000..61eec363cb02
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5476/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for the NEC DDB Vrc-5476 specific kernel interface routines
3# under Linux.
4#
5
6obj-y += setup.o irq.o int-handler.o nile4_pic.o vrc5476_irq.o
7obj-$(CONFIG_KGDB) += dbg_io.o
8
9EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/ddb5xxx/ddb5476/dbg_io.c b/arch/mips/ddb5xxx/ddb5476/dbg_io.c
new file mode 100644
index 000000000000..85e9e5013679
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5476/dbg_io.c
@@ -0,0 +1,136 @@
1/*
2 * kgdb io functions for DDB5476. We use the second serial port.
3 *
4 * Copyright (C) 2001 MontaVista Software Inc.
5 * Author: jsun@mvista.com or jsun@junsun.net
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14/* ======================= CONFIG ======================== */
15
16/* [jsun] we use the second serial port for kdb */
17#define BASE 0xa60002f8
18#define MAX_BAUD 115200
19
20/* distance in bytes between two serial registers */
21#define REG_OFFSET 1
22
23/*
24 * 0 - kgdb does serial init
25 * 1 - kgdb skip serial init
26 */
27static int remoteDebugInitialized = 0;
28
29/*
30 * the default baud rate *if* kgdb does serial init
31 */
32#define BAUD_DEFAULT UART16550_BAUD_38400
33
34/* ======================= END OF CONFIG ======================== */
35
36typedef unsigned char uint8;
37typedef unsigned int uint32;
38
39#define UART16550_BAUD_2400 2400
40#define UART16550_BAUD_4800 4800
41#define UART16550_BAUD_9600 9600
42#define UART16550_BAUD_19200 19200
43#define UART16550_BAUD_38400 38400
44#define UART16550_BAUD_57600 57600
45#define UART16550_BAUD_115200 115200
46
47#define UART16550_PARITY_NONE 0
48#define UART16550_PARITY_ODD 0x08
49#define UART16550_PARITY_EVEN 0x18
50#define UART16550_PARITY_MARK 0x28
51#define UART16550_PARITY_SPACE 0x38
52
53#define UART16550_DATA_5BIT 0x0
54#define UART16550_DATA_6BIT 0x1
55#define UART16550_DATA_7BIT 0x2
56#define UART16550_DATA_8BIT 0x3
57
58#define UART16550_STOP_1BIT 0x0
59#define UART16550_STOP_2BIT 0x4
60
61/* register offset */
62#define OFS_RCV_BUFFER 0
63#define OFS_TRANS_HOLD 0
64#define OFS_SEND_BUFFER 0
65#define OFS_INTR_ENABLE (1*REG_OFFSET)
66#define OFS_INTR_ID (2*REG_OFFSET)
67#define OFS_DATA_FORMAT (3*REG_OFFSET)
68#define OFS_LINE_CONTROL (3*REG_OFFSET)
69#define OFS_MODEM_CONTROL (4*REG_OFFSET)
70#define OFS_RS232_OUTPUT (4*REG_OFFSET)
71#define OFS_LINE_STATUS (5*REG_OFFSET)
72#define OFS_MODEM_STATUS (6*REG_OFFSET)
73#define OFS_RS232_INPUT (6*REG_OFFSET)
74#define OFS_SCRATCH_PAD (7*REG_OFFSET)
75
76#define OFS_DIVISOR_LSB (0*REG_OFFSET)
77#define OFS_DIVISOR_MSB (1*REG_OFFSET)
78
79
80/* memory-mapped read/write of the port */
81#define UART16550_READ(y) (*((volatile uint8*)(BASE + y)))
82#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z)
83
84void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
85{
86 /* disable interrupts */
87 UART16550_WRITE(OFS_INTR_ENABLE, 0);
88
89 /* set up buad rate */
90 {
91 uint32 divisor;
92
93 /* set DIAB bit */
94 UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
95
96 /* set divisor */
97 divisor = MAX_BAUD / baud;
98 UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
99 UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
100
101 /* clear DIAB bit */
102 UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
103 }
104
105 /* set data format */
106 UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
107}
108
109
110uint8 getDebugChar(void)
111{
112 if (!remoteDebugInitialized) {
113 remoteDebugInitialized = 1;
114 debugInit(BAUD_DEFAULT,
115 UART16550_DATA_8BIT,
116 UART16550_PARITY_NONE, UART16550_STOP_1BIT);
117 }
118
119 while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
120 return UART16550_READ(OFS_RCV_BUFFER);
121}
122
123
124int putDebugChar(uint8 byte)
125{
126 if (!remoteDebugInitialized) {
127 remoteDebugInitialized = 1;
128 debugInit(BAUD_DEFAULT,
129 UART16550_DATA_8BIT,
130 UART16550_PARITY_NONE, UART16550_STOP_1BIT);
131 }
132
133 while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
134 UART16550_WRITE(OFS_SEND_BUFFER, byte);
135 return 1;
136}
diff --git a/arch/mips/ddb5xxx/ddb5476/int-handler.S b/arch/mips/ddb5xxx/ddb5476/int-handler.S
new file mode 100644
index 000000000000..12c292e189ba
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5476/int-handler.S
@@ -0,0 +1,112 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: jsun@mvista.com or jsun@junsun.net
4 *
5 * First-level interrupt dispatcher for ddb5476
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12#include <asm/asm.h>
13#include <asm/mipsregs.h>
14#include <asm/addrspace.h>
15#include <asm/regdef.h>
16#include <asm/stackframe.h>
17
18#include <asm/ddb5xxx/ddb5476.h>
19
20/*
21 * first level interrupt dispatcher for ocelot board -
22 * We check for the timer first, then check PCI ints A and D.
23 * Then check for serial IRQ and fall through.
24 */
25 .align 5
26 NESTED(ddb5476_handle_int, PT_SIZE, sp)
27 SAVE_ALL
28 CLI
29 .set at
30 .set noreorder
31 mfc0 t0, CP0_CAUSE
32 mfc0 t2, CP0_STATUS
33
34 and t0, t2
35
36 andi t1, t0, STATUSF_IP7 /* cpu timer */
37 bnez t1, ll_cpu_ip7
38 andi t1, t0, STATUSF_IP2 /* vrc5476 & i8259 */
39 bnez t1, ll_cpu_ip2
40 andi t1, t0, STATUSF_IP3
41 bnez t1, ll_cpu_ip3
42 andi t1, t0, STATUSF_IP4
43 bnez t1, ll_cpu_ip4
44 andi t1, t0, STATUSF_IP5
45 bnez t1, ll_cpu_ip5
46 andi t1, t0, STATUSF_IP6
47 bnez t1, ll_cpu_ip6
48 andi t1, t0, STATUSF_IP0 /* software int 0 */
49 bnez t1, ll_cpu_ip0
50 andi t1, t0, STATUSF_IP1 /* software int 1 */
51 bnez t1, ll_cpu_ip1
52 nop
53
54 .set reorder
55
56 /* wrong alarm or masked ... */
57 // j spurious_interrupt
58 move a0, sp
59 jal vrc5476_irq_dispatch
60 j ret_from_irq
61 nop
62
63 .align 5
64
65ll_cpu_ip0:
66 li a0, CPU_IRQ_BASE + 0
67 move a1, sp
68 jal do_IRQ
69 j ret_from_irq
70
71ll_cpu_ip1:
72 li a0, CPU_IRQ_BASE + 1
73 move a1, sp
74 jal do_IRQ
75 j ret_from_irq
76
77ll_cpu_ip2: /* jump to second-level dispatching */
78 move a0, sp
79 jal vrc5476_irq_dispatch
80 j ret_from_irq
81
82ll_cpu_ip3:
83 li a0, CPU_IRQ_BASE + 3
84 move a1, sp
85 jal do_IRQ
86 j ret_from_irq
87
88ll_cpu_ip4:
89 li a0, CPU_IRQ_BASE + 4
90 move a1, sp
91 jal do_IRQ
92 j ret_from_irq
93
94ll_cpu_ip5:
95 li a0, CPU_IRQ_BASE + 5
96 move a1, sp
97 jal do_IRQ
98 j ret_from_irq
99
100ll_cpu_ip6:
101 li a0, CPU_IRQ_BASE + 6
102 move a1, sp
103 jal do_IRQ
104 j ret_from_irq
105
106ll_cpu_ip7:
107 li a0, CPU_IRQ_BASE + 7
108 move a1, sp
109 jal do_IRQ
110 j ret_from_irq
111
112 END(ddb5476_handle_int)
diff --git a/arch/mips/ddb5xxx/ddb5476/irq.c b/arch/mips/ddb5xxx/ddb5476/irq.c
new file mode 100644
index 000000000000..5388b5868c4a
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5476/irq.c
@@ -0,0 +1,143 @@
1/*
2 * arch/mips/ddb5476/irq.c -- NEC DDB Vrc-5476 interrupt routines
3 *
4 * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
5 * Sony Software Development Center Europe (SDCE), Brussels
6 *
7 * Re-write the whole thing to use new irq.c file.
8 * Copyright (C) 2001 MontaVista Software Inc.
9 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
10 *
11 */
12#include <linux/init.h>
13#include <linux/sched.h>
14#include <linux/types.h>
15#include <linux/interrupt.h>
16
17#include <asm/i8259.h>
18#include <asm/io.h>
19#include <asm/ptrace.h>
20
21#include <asm/ddb5xxx/ddb5xxx.h>
22
23#define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */
24#define M1543_PNP_INDEX 0x03f0 /* PnP Index Port */
25#define M1543_PNP_DATA 0x03f1 /* PnP Data Port */
26
27#define M1543_PNP_ALT_CONFIG 0x0370 /* Alternative PnP Config Port */
28#define M1543_PNP_ALT_INDEX 0x0370 /* Alternative PnP Index Port */
29#define M1543_PNP_ALT_DATA 0x0371 /* Alternative PnP Data Port */
30
31#define M1543_INT1_MASTER_CTRL 0x0020 /* INT_1 (master) Control Register */
32#define M1543_INT1_MASTER_MASK 0x0021 /* INT_1 (master) Mask Register */
33
34#define M1543_INT1_SLAVE_CTRL 0x00a0 /* INT_1 (slave) Control Register */
35#define M1543_INT1_SLAVE_MASK 0x00a1 /* INT_1 (slave) Mask Register */
36
37#define M1543_INT1_MASTER_ELCR 0x04d0 /* INT_1 (master) Edge/Level Control */
38#define M1543_INT1_SLAVE_ELCR 0x04d1 /* INT_1 (slave) Edge/Level Control */
39
40static void m1543_irq_setup(void)
41{
42 /*
43 * The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13. Not all
44 * the possible IO sources in the M1543 are in use by us. We will
45 * use the following mapping:
46 *
47 * IRQ1 - keyboard (default set by M1543)
48 * IRQ3 - reserved for UART B (default set by M1543) (note that
49 * the schematics for the DDB Vrc-5476 board seem to
50 * indicate that IRQ3 is connected to the DS1386
51 * watchdog timer interrupt output so we might have
52 * a conflict)
53 * IRQ4 - reserved for UART A (default set by M1543)
54 * IRQ5 - parallel (default set by M1543)
55 * IRQ8 - DS1386 time of day (RTC) interrupt
56 * IRQ9 - USB (hardwired in ddb_setup)
57 * IRQ10 - PMU (hardwired in ddb_setup)
58 * IRQ12 - mouse
59 * IRQ14,15 - IDE controller (need to be confirmed, jsun)
60 */
61
62 /*
63 * Assing mouse interrupt to IRQ12
64 */
65
66 /* Enter configuration mode */
67 outb(0x51, M1543_PNP_CONFIG);
68 outb(0x23, M1543_PNP_CONFIG);
69
70 /* Select logical device 7 (Keyboard) */
71 outb(0x07, M1543_PNP_INDEX);
72 outb(0x07, M1543_PNP_DATA);
73
74 /* Select IRQ12 */
75 outb(0x72, M1543_PNP_INDEX);
76 outb(0x0c, M1543_PNP_DATA);
77
78 /* Leave configration mode */
79 outb(0xbb, M1543_PNP_CONFIG);
80}
81
82static void nile4_irq_setup(void)
83{
84 int i;
85
86 /* Map all interrupts to CPU int #0 (IP2) */
87 nile4_map_irq_all(0);
88
89 /* PCI INTA#-E# must be level triggered */
90 nile4_set_pci_irq_level_or_edge(0, 1);
91 nile4_set_pci_irq_level_or_edge(1, 1);
92 nile4_set_pci_irq_level_or_edge(2, 1);
93 nile4_set_pci_irq_level_or_edge(3, 1);
94
95 /* PCI INTA#, B#, D# must be active low, INTC# must be active high */
96 nile4_set_pci_irq_polarity(0, 0);
97 nile4_set_pci_irq_polarity(1, 0);
98 nile4_set_pci_irq_polarity(2, 1);
99 nile4_set_pci_irq_polarity(3, 0);
100
101 for (i = 0; i < 16; i++)
102 nile4_clear_irq(i);
103
104 /* Enable CPU int #0 */
105 nile4_enable_irq_output(0);
106
107 /* memory resource acquire in ddb_setup */
108}
109
110static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
111static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL };
112
113extern asmlinkage void ddb5476_handle_int(void);
114extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
115extern void mips_cpu_irq_init(u32 irq_base);
116extern void vrc5476_irq_init(u32 irq_base);
117
118void __init arch_init_irq(void)
119{
120 /* hardware initialization */
121 nile4_irq_setup();
122 m1543_irq_setup();
123
124 /* controller setup */
125 init_i8259_irqs();
126 vrc5476_irq_init(VRC5476_IRQ_BASE);
127 mips_cpu_irq_init(CPU_IRQ_BASE);
128
129 /* setup cascade interrupts */
130 setup_irq(VRC5476_IRQ_BASE + VRC5476_I8259_CASCADE, &irq_cascade);
131 setup_irq(CPU_IRQ_BASE + CPU_VRC5476_CASCADE, &irq_cascade);
132
133 /* setup error interrupts for debugging */
134 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_CPCE, &irq_error);
135 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_CNTD, &irq_error);
136 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_MCE, &irq_error);
137 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error);
138 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error);
139 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error);
140
141 /* setup the grandpa intr vector */
142 set_except_vector(0, ddb5476_handle_int);
143}
diff --git a/arch/mips/ddb5xxx/ddb5476/nile4_pic.c b/arch/mips/ddb5xxx/ddb5476/nile4_pic.c
new file mode 100644
index 000000000000..e930cee7944f
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5476/nile4_pic.c
@@ -0,0 +1,190 @@
1/*
2 * arch/mips/ddb5476/nile4.c --
3 * low-level PIC code for NEC Vrc-5476 (Nile 4)
4 *
5 * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
6 * Sony Software Development Center Europe (SDCE), Brussels
7 *
8 * Copyright 2001 MontaVista Software Inc.
9 * Author: jsun@mvista.com or jsun@junsun.net
10 *
11 */
12#include <linux/config.h>
13#include <linux/kernel.h>
14#include <linux/types.h>
15
16#include <asm/addrspace.h>
17
18#include <asm/ddb5xxx/ddb5xxx.h>
19
20
21/*
22 * Interrupt Programming
23 */
24void nile4_map_irq(int nile4_irq, int cpu_irq)
25{
26 u32 offset, t;
27
28 offset = DDB_INTCTRL;
29 if (nile4_irq >= 8) {
30 offset += 4;
31 nile4_irq -= 8;
32 }
33 t = ddb_in32(offset);
34 t &= ~(7 << (nile4_irq * 4));
35 t |= cpu_irq << (nile4_irq * 4);
36 ddb_out32(offset, t);
37}
38
39void nile4_map_irq_all(int cpu_irq)
40{
41 u32 all, t;
42
43 all = cpu_irq;
44 all |= all << 4;
45 all |= all << 8;
46 all |= all << 16;
47 t = ddb_in32(DDB_INTCTRL);
48 t &= 0x88888888;
49 t |= all;
50 ddb_out32(DDB_INTCTRL, t);
51 t = ddb_in32(DDB_INTCTRL + 4);
52 t &= 0x88888888;
53 t |= all;
54 ddb_out32(DDB_INTCTRL + 4, t);
55}
56
57void nile4_enable_irq(int nile4_irq)
58{
59 u32 offset, t;
60
61 offset = DDB_INTCTRL;
62 if (nile4_irq >= 8) {
63 offset += 4;
64 nile4_irq -= 8;
65 }
66 t = ddb_in32(offset);
67 t |= 8 << (nile4_irq * 4);
68 ddb_out32(offset, t);
69}
70
71void nile4_disable_irq(int nile4_irq)
72{
73 u32 offset, t;
74
75 offset = DDB_INTCTRL;
76 if (nile4_irq >= 8) {
77 offset += 4;
78 nile4_irq -= 8;
79 }
80 t = ddb_in32(offset);
81 t &= ~(8 << (nile4_irq * 4));
82 ddb_out32(offset, t);
83}
84
85void nile4_disable_irq_all(void)
86{
87 ddb_out32(DDB_INTCTRL, 0);
88 ddb_out32(DDB_INTCTRL + 4, 0);
89}
90
91u16 nile4_get_irq_stat(int cpu_irq)
92{
93 return ddb_in16(DDB_INTSTAT0 + cpu_irq * 2);
94}
95
96void nile4_enable_irq_output(int cpu_irq)
97{
98 u32 t;
99
100 t = ddb_in32(DDB_INTSTAT1 + 4);
101 t |= 1 << (16 + cpu_irq);
102 ddb_out32(DDB_INTSTAT1, t);
103}
104
105void nile4_disable_irq_output(int cpu_irq)
106{
107 u32 t;
108
109 t = ddb_in32(DDB_INTSTAT1 + 4);
110 t &= ~(1 << (16 + cpu_irq));
111 ddb_out32(DDB_INTSTAT1, t);
112}
113
114void nile4_set_pci_irq_polarity(int pci_irq, int high)
115{
116 u32 t;
117
118 t = ddb_in32(DDB_INTPPES);
119 if (high)
120 t &= ~(1 << (pci_irq * 2));
121 else
122 t |= 1 << (pci_irq * 2);
123 ddb_out32(DDB_INTPPES, t);
124}
125
126void nile4_set_pci_irq_level_or_edge(int pci_irq, int level)
127{
128 u32 t;
129
130 t = ddb_in32(DDB_INTPPES);
131 if (level)
132 t |= 2 << (pci_irq * 2);
133 else
134 t &= ~(2 << (pci_irq * 2));
135 ddb_out32(DDB_INTPPES, t);
136}
137
138void nile4_clear_irq(int nile4_irq)
139{
140 ddb_out32(DDB_INTCLR, 1 << nile4_irq);
141}
142
143void nile4_clear_irq_mask(u32 mask)
144{
145 ddb_out32(DDB_INTCLR, mask);
146}
147
148u8 nile4_i8259_iack(void)
149{
150 u8 irq;
151 u32 reg;
152
153 /* Set window 0 for interrupt acknowledge */
154 reg = ddb_in32(DDB_PCIINIT0);
155
156 ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IACK, 0, DDB_PCI_ACCESS_32);
157 irq = *(volatile u8 *) KSEG1ADDR(DDB_PCI_IACK_BASE);
158 /* restore window 0 for PCI I/O space */
159 // ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32);
160 ddb_out32(DDB_PCIINIT0, reg);
161
162 /* i8269.c set the base vector to be 0x0 */
163 return irq + I8259_IRQ_BASE;
164}
165
166#if defined(CONFIG_RUNTIME_DEBUG)
167void nile4_dump_irq_status(void)
168{
169 printk(KERN_DEBUG "
170 CPUSTAT = %p:%p\n", (void *) ddb_in32(DDB_CPUSTAT + 4),
171 (void *) ddb_in32(DDB_CPUSTAT));
172 printk(KERN_DEBUG "
173 INTCTRL = %p:%p\n", (void *) ddb_in32(DDB_INTCTRL + 4),
174 (void *) ddb_in32(DDB_INTCTRL));
175 printk(KERN_DEBUG
176 "INTSTAT0 = %p:%p\n",
177 (void *) ddb_in32(DDB_INTSTAT0 + 4),
178 (void *) ddb_in32(DDB_INTSTAT0));
179 printk(KERN_DEBUG
180 "INTSTAT1 = %p:%p\n",
181 (void *) ddb_in32(DDB_INTSTAT1 + 4),
182 (void *) ddb_in32(DDB_INTSTAT1));
183 printk(KERN_DEBUG
184 "INTCLR = %p:%p\n", (void *) ddb_in32(DDB_INTCLR + 4),
185 (void *) ddb_in32(DDB_INTCLR));
186 printk(KERN_DEBUG
187 "INTPPES = %p:%p\n", (void *) ddb_in32(DDB_INTPPES + 4),
188 (void *) ddb_in32(DDB_INTPPES));
189}
190#endif
diff --git a/arch/mips/ddb5xxx/ddb5476/setup.c b/arch/mips/ddb5xxx/ddb5476/setup.c
new file mode 100644
index 000000000000..71531f8146ea
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5476/setup.c
@@ -0,0 +1,297 @@
1/*
2 * arch/mips/ddb5476/setup.c -- NEC DDB Vrc-5476 setup routines
3 *
4 * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
5 * Sony Software Development Center Europe (SDCE), Brussels
6 */
7#include <linux/init.h>
8#include <linux/kbd_ll.h>
9#include <linux/kernel.h>
10#include <linux/kdev_t.h>
11#include <linux/types.h>
12#include <linux/sched.h>
13#include <linux/pci.h>
14
15#include <asm/addrspace.h>
16#include <asm/bcache.h>
17#include <asm/irq.h>
18#include <asm/reboot.h>
19#include <asm/gdb-stub.h>
20#include <asm/time.h>
21#include <asm/debug.h>
22#include <asm/traps.h>
23
24#include <asm/ddb5xxx/ddb5xxx.h>
25
26// #define USE_CPU_COUNTER_TIMER /* whether we use cpu counter */
27
28#ifdef USE_CPU_COUNTER_TIMER
29
30#define CPU_COUNTER_FREQUENCY 83000000
31#else
32/* otherwise we use general purpose timer */
33#define TIMER_FREQUENCY 83000000
34#define TIMER_BASE DDB_T2CTRL
35#define TIMER_IRQ (VRC5476_IRQ_BASE + VRC5476_IRQ_GPT)
36#endif
37
38static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000;
39
40static void ddb_machine_restart(char *command)
41{
42 u32 t;
43
44 /* PCI cold reset */
45 t = ddb_in32(DDB_PCICTRL + 4);
46 t |= 0x40000000;
47 ddb_out32(DDB_PCICTRL + 4, t);
48 /* CPU cold reset */
49 t = ddb_in32(DDB_CPUSTAT);
50 t |= 1;
51 ddb_out32(DDB_CPUSTAT, t);
52 /* Call the PROM */
53 back_to_prom();
54}
55
56static void ddb_machine_halt(void)
57{
58 printk(KERN_NOTICE "DDB Vrc-5476 halted.\n");
59 while (1);
60}
61
62static void ddb_machine_power_off(void)
63{
64 printk(KERN_NOTICE "DDB Vrc-5476 halted. Please turn off the power.\n");
65 while (1);
66}
67
68extern void rtc_ds1386_init(unsigned long base);
69
70static void __init ddb_time_init(void)
71{
72#if defined(USE_CPU_COUNTER_TIMER)
73 mips_hpt_frequency = CPU_COUNTER_FREQUENCY;
74#endif
75
76 /* we have ds1396 RTC chip */
77 rtc_ds1386_init(KSEG1ADDR(DDB_PCI_MEM_BASE));
78}
79
80
81extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
82static void __init ddb_timer_setup(struct irqaction *irq)
83{
84#if defined(USE_CPU_COUNTER_TIMER)
85
86 unsigned int count;
87
88 /* we are using the cpu counter for timer interrupts */
89 setup_irq(CPU_IRQ_BASE + 7, irq);
90
91 /* to generate the first timer interrupt */
92 count = read_c0_count();
93 write_c0_compare(count + 1000);
94
95#else
96
97 ddb_out32(TIMER_BASE, TIMER_FREQUENCY/HZ);
98 ddb_out32(TIMER_BASE+4, 0x1); /* enable timer */
99 setup_irq(TIMER_IRQ, irq);
100#endif
101}
102
103static struct {
104 struct resource dma1;
105 struct resource timer;
106 struct resource rtc;
107 struct resource dma_page_reg;
108 struct resource dma2;
109} ddb5476_ioport = {
110 {
111 "dma1", 0x00, 0x1f, IORESOURCE_BUSY}, {
112 "timer", 0x40, 0x5f, IORESOURCE_BUSY}, {
113 "rtc", 0x70, 0x7f, IORESOURCE_BUSY}, {
114 "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY}, {
115 "dma2", 0xc0, 0xdf, IORESOURCE_BUSY}
116};
117
118static struct {
119 struct resource nile4;
120} ddb5476_iomem = {
121 { "Nile 4", DDB_BASE, DDB_BASE + DDB_SIZE - 1, IORESOURCE_BUSY}
122};
123
124
125static void ddb5476_board_init(void);
126
127static void __init ddb5476_setup(void)
128{
129 set_io_port_base(KSEG1ADDR(DDB_PCI_IO_BASE));
130
131 board_time_init = ddb_time_init;
132 board_timer_setup = ddb_timer_setup;
133
134 _machine_restart = ddb_machine_restart;
135 _machine_halt = ddb_machine_halt;
136 _machine_power_off = ddb_machine_power_off;
137
138 /* request io port/mem resources */
139 if (request_resource(&ioport_resource, &ddb5476_ioport.dma1) ||
140 request_resource(&ioport_resource, &ddb5476_ioport.timer) ||
141 request_resource(&ioport_resource, &ddb5476_ioport.rtc) ||
142 request_resource(&ioport_resource,
143 &ddb5476_ioport.dma_page_reg)
144 || request_resource(&ioport_resource, &ddb5476_ioport.dma2)
145 || request_resource(&iomem_resource, &ddb5476_iomem.nile4)) {
146 printk
147 ("ddb_setup - requesting oo port resources failed.\n");
148 for (;;);
149 }
150
151 /* Reboot on panic */
152 panic_timeout = 180;
153
154 /* [jsun] we need to set BAR0 so that SDRAM 0 appears at 0x0 in PCI */
155 /* *(long*)0xbfa00218 = 0x8; */
156
157 /* board initialization stuff */
158 ddb5476_board_init();
159}
160
161early_initcall(ddb5476_setup);
162
163/*
164 * We don't trust bios. We essentially does hardware re-initialization
165 * as complete as possible, as far as we know we can safely do.
166 */
167static void ddb5476_board_init(void)
168{
169 /* ----------- setup PDARs ------------ */
170 /* check SDRAM0, whether we are on MEM bus does not matter */
171 db_assert((ddb_in32(DDB_SDRAM0) & 0xffffffef) ==
172 ddb_calc_pdar(DDB_SDRAM_BASE, DDB_SDRAM_SIZE, 32, 0, 1));
173
174 /* SDRAM1 should be turned off. What is this for anyway ? */
175 db_assert( (ddb_in32(DDB_SDRAM1) & 0xf) == 0);
176
177 /* flash 1&2, DDB status, DDB control */
178 ddb_set_pdar(DDB_DCS2, DDB_DCS2_BASE, DDB_DCS2_SIZE, 16, 0, 0);
179 ddb_set_pdar(DDB_DCS3, DDB_DCS3_BASE, DDB_DCS3_SIZE, 16, 0, 0);
180 ddb_set_pdar(DDB_DCS4, DDB_DCS4_BASE, DDB_DCS4_SIZE, 8, 0, 0);
181 ddb_set_pdar(DDB_DCS5, DDB_DCS5_BASE, DDB_DCS5_SIZE, 8, 0, 0);
182
183 /* shut off other pdar so they don't accidentally get into the way */
184 ddb_set_pdar(DDB_DCS6, 0xffffffff, 0, 32, 0, 0);
185 ddb_set_pdar(DDB_DCS7, 0xffffffff, 0, 32, 0, 0);
186 ddb_set_pdar(DDB_DCS8, 0xffffffff, 0, 32, 0, 0);
187
188 /* verify VRC5477 base addr */
189 /* don't care about some details */
190 db_assert((ddb_in32(DDB_INTCS) & 0xffffff0f) ==
191 ddb_calc_pdar(DDB_INTCS_BASE, DDB_INTCS_SIZE, 8, 0, 0));
192
193 /* verify BOOT ROM addr */
194 /* don't care about some details */
195 db_assert((ddb_in32(DDB_BOOTCS) & 0xffffff0f) ==
196 ddb_calc_pdar(DDB_BOOTCS_BASE, DDB_BOOTCS_SIZE, 8, 0, 0));
197
198 /* setup PCI windows - window1 for MEM/config, window0 for IO */
199 ddb_set_pdar(DDB_PCIW0, DDB_PCI_IO_BASE, DDB_PCI_IO_SIZE, 32, 0, 1);
200 ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32);
201
202 ddb_set_pdar(DDB_PCIW1, DDB_PCI_MEM_BASE, DDB_PCI_MEM_SIZE, 32, 0, 1);
203 ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE, DDB_PCI_ACCESS_32);
204
205 /* ----------- setup PDARs ------------ */
206 /* this is problematic - it will reset Aladin which cause we loose
207 * serial port, and we don't know how to set up Aladin chip again.
208 */
209 // ddb_pci_reset_bus();
210
211 ddb_out32(DDB_BAR0, 0x00000008);
212
213 ddb_out32(DDB_BARC, 0xffffffff);
214 ddb_out32(DDB_BARB, 0xffffffff);
215 ddb_out32(DDB_BAR1, 0xffffffff);
216 ddb_out32(DDB_BAR2, 0xffffffff);
217 ddb_out32(DDB_BAR3, 0xffffffff);
218 ddb_out32(DDB_BAR4, 0xffffffff);
219 ddb_out32(DDB_BAR5, 0xffffffff);
220 ddb_out32(DDB_BAR6, 0xffffffff);
221 ddb_out32(DDB_BAR7, 0xffffffff);
222 ddb_out32(DDB_BAR8, 0xffffffff);
223
224 /* ----------- switch PCI1 to PCI CONFIG space ------------ */
225 ddb_set_pdar(DDB_PCIW1, DDB_PCI_CONFIG_BASE, DDB_PCI_CONFIG_SIZE, 32, 0, 1);
226 ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_CFG, 0x0, DDB_PCI_ACCESS_32);
227
228 /* ----- M1543 PCI setup ------ */
229
230 /* we know M1543 PCI-ISA controller is at addr:18 */
231 /* xxxx1010 makes USB at addr:13 and PMU at addr:14 */
232 *(volatile unsigned char *) 0xa8040072 &= 0xf0;
233 *(volatile unsigned char *) 0xa8040072 |= 0xa;
234
235 /* setup USB interrupt to IRQ 9, (bit 0:3 - 0001)
236 * no IOCHRDY signal, (bit 7 - 1)
237 * M1543C & M7101 VID and Subsys Device ID are read-only (bit 6 - 1)
238 * Make USB Master INTAJ level to edge conversion (bit 4 - 1)
239 */
240 *(unsigned char *) 0xa8040074 = 0xd1;
241
242 /* setup PMU(SCI to IRQ 10 (bit 0:3 - 0011)
243 * SCI routing to IRQ 13 disabled (bit 7 - 1)
244 * SCI interrupt level to edge conversion bypassed (bit 4 - 0)
245 */
246 *(unsigned char *) 0xa8040076 = 0x83;
247
248 /* setup IDE controller
249 * enable IDE controller (bit 6 - 1)
250 * IDE IDSEL to be addr:24 (bit 4:5 - 11)
251 * no IDE ATA Secondary Bus Signal Pad Control (bit 3 - 0)
252 * no IDE ATA Primary Bus Signal Pad Control (bit 2 - 0)
253 * primary IRQ is 14, secondary is 15 (bit 1:0 - 01
254 */
255 // *(unsigned char*)0xa8040058 = 0x71;
256 // *(unsigned char*)0xa8040058 = 0x79;
257 // *(unsigned char*)0xa8040058 = 0x74; // use SIRQ, primary tri-state
258 *(unsigned char *) 0xa8040058 = 0x75; // primary tri-state
259
260#if 0
261 /* this is not necessary if M5229 does not use SIRQ */
262 *(unsigned char *) 0xa8040044 = 0x0d; // primary to IRQ 14
263 *(unsigned char *) 0xa8040075 = 0x0d; // secondary to IRQ 14
264#endif
265
266 /* enable IDE in the M5229 config register 0x50 (bit 0 - 1) */
267 /* M5229 IDSEL is addr:24; see above setting */
268 *(unsigned char *) 0xa9000050 |= 0x1;
269
270 /* enable bus master (bit 2) and IO decoding (bit 0) */
271 *(unsigned char *) 0xa9000004 |= 0x5;
272
273 /* enable native, copied from arch/ppc/k2boot/head.S */
274 /* TODO - need volatile, need to be portable */
275 *(unsigned char *) 0xa9000009 = 0xff;
276
277 /* ----- end of M1543 PCI setup ------ */
278
279 /* ----- reset on-board ether chip ------ */
280 *((volatile u32 *) 0xa8020004) |= 1; /* decode I/O */
281 *((volatile u32 *) 0xa8020010) = 0; /* set BAR address */
282
283 /* send reset command */
284 *((volatile u32 *) 0xa6000000) = 1; /* do a soft reset */
285
286 /* disable ether chip */
287 *((volatile u32 *) 0xa8020004) = 0; /* disable any decoding */
288
289 /* put it into sleep */
290 *((volatile u32 *) 0xa8020040) = 0x80000000;
291
292 /* ----- end of reset on-board ether chip ------ */
293
294 /* ----------- switch PCI1 back to PCI MEM space ------------ */
295 ddb_set_pdar(DDB_PCIW1, DDB_PCI_MEM_BASE, DDB_PCI_MEM_SIZE, 32, 0, 1);
296 ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE, DDB_PCI_ACCESS_32);
297}
diff --git a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
new file mode 100644
index 000000000000..a77682be01ac
--- /dev/null
+++ b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
@@ -0,0 +1,112 @@
1/*
2 * The irq controller for vrc5476.
3 *
4 * Copyright (C) 2001 MontaVista Software Inc.
5 * Author: jsun@mvista.com or jsun@junsun.net
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13#include <linux/init.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/types.h>
17#include <linux/ptrace.h>
18
19#include <asm/system.h>
20
21#include <asm/ddb5xxx/ddb5xxx.h>
22
23static int irq_base;
24
25static void vrc5476_irq_enable(uint irq)
26{
27 nile4_enable_irq(irq - irq_base);
28}
29
30static void vrc5476_irq_disable(uint irq)
31{
32 nile4_disable_irq(irq - irq_base);
33}
34
35static unsigned int vrc5476_irq_startup(uint irq)
36{
37 nile4_enable_irq(irq - irq_base);
38 return 0;
39}
40
41#define vrc5476_irq_shutdown vrc5476_irq_disable
42
43static void vrc5476_irq_ack(uint irq)
44{
45 nile4_clear_irq(irq - irq_base);
46 nile4_disable_irq(irq - irq_base);
47}
48
49static void vrc5476_irq_end(uint irq)
50{
51 if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
52 vrc5476_irq_enable(irq);
53}
54
55static hw_irq_controller vrc5476_irq_controller = {
56 "vrc5476",
57 vrc5476_irq_startup,
58 vrc5476_irq_shutdown,
59 vrc5476_irq_enable,
60 vrc5476_irq_disable,
61 vrc5476_irq_ack,
62 vrc5476_irq_end,
63 NULL /* no affinity stuff for UP */
64};
65
66void __init
67vrc5476_irq_init(u32 base)
68{
69 u32 i;
70
71 irq_base = base;
72 for (i= base; i< base + NUM_VRC5476_IRQ; i++) {
73 irq_desc[i].status = IRQ_DISABLED;
74 irq_desc[i].action = NULL;
75 irq_desc[i].depth = 1;
76 irq_desc[i].handler = &vrc5476_irq_controller;
77 }
78}
79
80
81asmlinkage void
82vrc5476_irq_dispatch(struct pt_regs *regs)
83{
84 extern void spurious_interrupt(void);
85
86 u32 mask;
87 int nile4_irq;
88
89 mask = nile4_get_irq_stat(0);
90
91 /* quick check for possible time interrupt */
92 if (mask & (1 << VRC5476_IRQ_GPT)) {
93 do_IRQ(VRC5476_IRQ_BASE + VRC5476_IRQ_GPT, regs);
94 return;
95 }
96
97 /* check for i8259 interrupts */
98 if (mask & (1 << VRC5476_I8259_CASCADE)) {
99 int i8259_irq = nile4_i8259_iack();
100 do_IRQ(I8259_IRQ_BASE + i8259_irq, regs);
101 return;
102 }
103
104 /* regular nile4 interrupts (we should not really have any */
105 for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1) {
106 if (mask & 1) {
107 do_IRQ(VRC5476_IRQ_BASE + nile4_irq, regs);
108 return;
109 }
110 }
111 spurious_interrupt();
112}