aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/momentum/ocelot_g
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/momentum/ocelot_g
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/momentum/ocelot_g')
-rw-r--r--arch/mips/momentum/ocelot_g/Makefile8
-rw-r--r--arch/mips/momentum/ocelot_g/dbg_io.c126
-rw-r--r--arch/mips/momentum/ocelot_g/gt-irq.c214
-rw-r--r--arch/mips/momentum/ocelot_g/int-handler.S131
-rw-r--r--arch/mips/momentum/ocelot_g/irq.c69
-rw-r--r--arch/mips/momentum/ocelot_g/ocelot_pld.h30
-rw-r--r--arch/mips/momentum/ocelot_g/prom.c86
-rw-r--r--arch/mips/momentum/ocelot_g/reset.c47
-rw-r--r--arch/mips/momentum/ocelot_g/setup.c266
9 files changed, 977 insertions, 0 deletions
diff --git a/arch/mips/momentum/ocelot_g/Makefile b/arch/mips/momentum/ocelot_g/Makefile
new file mode 100644
index 000000000000..e5f1cb086973
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for Momentum Computer's Ocelot-G board.
3#
4
5obj-y += int-handler.o irq.o gt-irq.o prom.o reset.o setup.o
6obj-$(CONFIG_KGDB) += dbg_io.o
7
8EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/momentum/ocelot_g/dbg_io.c b/arch/mips/momentum/ocelot_g/dbg_io.c
new file mode 100644
index 000000000000..8720bccfdea2
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/dbg_io.c
@@ -0,0 +1,126 @@
1#include <linux/config.h>
2
3#ifdef CONFIG_KGDB
4
5#include <asm/serial.h> /* For the serial port location and base baud */
6
7/* --- CONFIG --- */
8
9typedef unsigned char uint8;
10typedef unsigned int uint32;
11
12/* --- END OF CONFIG --- */
13
14#define UART16550_BAUD_2400 2400
15#define UART16550_BAUD_4800 4800
16#define UART16550_BAUD_9600 9600
17#define UART16550_BAUD_19200 19200
18#define UART16550_BAUD_38400 38400
19#define UART16550_BAUD_57600 57600
20#define UART16550_BAUD_115200 115200
21
22#define UART16550_PARITY_NONE 0
23#define UART16550_PARITY_ODD 0x08
24#define UART16550_PARITY_EVEN 0x18
25#define UART16550_PARITY_MARK 0x28
26#define UART16550_PARITY_SPACE 0x38
27
28#define UART16550_DATA_5BIT 0x0
29#define UART16550_DATA_6BIT 0x1
30#define UART16550_DATA_7BIT 0x2
31#define UART16550_DATA_8BIT 0x3
32
33#define UART16550_STOP_1BIT 0x0
34#define UART16550_STOP_2BIT 0x4
35
36/* ----------------------------------------------------- */
37
38/* === CONFIG === */
39
40/* [jsun] we use the second serial port for kdb */
41#define BASE OCELOT_SERIAL1_BASE
42#define MAX_BAUD OCELOT_BASE_BAUD
43
44/* === END OF CONFIG === */
45
46#define REG_OFFSET 4
47
48/* register offset */
49#define OFS_RCV_BUFFER 0
50#define OFS_TRANS_HOLD 0
51#define OFS_SEND_BUFFER 0
52#define OFS_INTR_ENABLE (1*REG_OFFSET)
53#define OFS_INTR_ID (2*REG_OFFSET)
54#define OFS_DATA_FORMAT (3*REG_OFFSET)
55#define OFS_LINE_CONTROL (3*REG_OFFSET)
56#define OFS_MODEM_CONTROL (4*REG_OFFSET)
57#define OFS_RS232_OUTPUT (4*REG_OFFSET)
58#define OFS_LINE_STATUS (5*REG_OFFSET)
59#define OFS_MODEM_STATUS (6*REG_OFFSET)
60#define OFS_RS232_INPUT (6*REG_OFFSET)
61#define OFS_SCRATCH_PAD (7*REG_OFFSET)
62
63#define OFS_DIVISOR_LSB (0*REG_OFFSET)
64#define OFS_DIVISOR_MSB (1*REG_OFFSET)
65
66
67/* memory-mapped read/write of the port */
68#define UART16550_READ(y) (*((volatile uint8*)(BASE + y)))
69#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z)
70
71void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
72{
73 /* disable interrupts */
74 UART16550_WRITE(OFS_INTR_ENABLE, 0);
75
76 /* set up buad rate */
77 {
78 uint32 divisor;
79
80 /* set DIAB bit */
81 UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
82
83 /* set divisor */
84 divisor = MAX_BAUD / baud;
85 UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
86 UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
87
88 /* clear DIAB bit */
89 UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
90 }
91
92 /* set data format */
93 UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
94}
95
96static int remoteDebugInitialized = 0;
97
98uint8 getDebugChar(void)
99{
100 if (!remoteDebugInitialized) {
101 remoteDebugInitialized = 1;
102 debugInit(UART16550_BAUD_38400,
103 UART16550_DATA_8BIT,
104 UART16550_PARITY_NONE, UART16550_STOP_1BIT);
105 }
106
107 while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
108 return UART16550_READ(OFS_RCV_BUFFER);
109}
110
111
112int putDebugChar(uint8 byte)
113{
114 if (!remoteDebugInitialized) {
115 remoteDebugInitialized = 1;
116 debugInit(UART16550_BAUD_38400,
117 UART16550_DATA_8BIT,
118 UART16550_PARITY_NONE, UART16550_STOP_1BIT);
119 }
120
121 while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
122 UART16550_WRITE(OFS_SEND_BUFFER, byte);
123 return 1;
124}
125
126#endif
diff --git a/arch/mips/momentum/ocelot_g/gt-irq.c b/arch/mips/momentum/ocelot_g/gt-irq.c
new file mode 100644
index 000000000000..d0b5c9dd0ea4
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/gt-irq.c
@@ -0,0 +1,214 @@
1/*
2 *
3 * Copyright 2002 Momentum Computer
4 * Author: mdharm@momenco.com
5 *
6 * arch/mips/momentum/ocelot_g/gt_irq.c
7 * Interrupt routines for gt64240. Currently it only handles timer irq.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14#include <linux/config.h>
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/kernel.h>
18#include <asm/ptrace.h>
19#include <linux/sched.h>
20#include <linux/kernel_stat.h>
21#include <asm/gt64240.h>
22#include <asm/io.h>
23
24unsigned long bus_clock;
25
26/*
27 * These are interrupt handlers for the GT on-chip interrupts. They
28 * all come in to the MIPS on a single interrupt line, and have to
29 * be handled and ack'ed differently than other MIPS interrupts.
30 */
31
32#if CURRENTLY_UNUSED
33
34struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH];
35void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr);
36
37/*
38 * Hooks IRQ handler to the system. When the system is interrupted
39 * the interrupt service routine is called.
40 *
41 * Inputs :
42 * int_cause - The interrupt cause number. In EVB64120 two parameters
43 * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
44 * bit_num - Indicates which bit number in the cause register
45 * isr_ptr - Pointer to the interrupt service routine
46 */
47void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr)
48{
49 irq_handlers[int_cause][bit_num].routine = isr_ptr;
50}
51
52
53/*
54 * Enables the IRQ on Galileo Chip
55 *
56 * Inputs :
57 * int_cause - The interrupt cause number. In EVB64120 two parameters
58 * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
59 * bit_num - Indicates which bit number in the cause register
60 *
61 * Outputs :
62 * 1 if succesful, 0 if failure
63 */
64int enable_galileo_irq(int int_cause, int bit_num)
65{
66 if (int_cause == INT_CAUSE_MAIN)
67 SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num));
68 else if (int_cause == INT_CAUSE_HIGH)
69 SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
70 (1 << bit_num));
71 else
72 return 0;
73
74 return 1;
75}
76
77/*
78 * Disables the IRQ on Galileo Chip
79 *
80 * Inputs :
81 * int_cause - The interrupt cause number. In EVB64120 two parameters
82 * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
83 * bit_num - Indicates which bit number in the cause register
84 *
85 * Outputs :
86 * 1 if succesful, 0 if failure
87 */
88int disable_galileo_irq(int int_cause, int bit_num)
89{
90 if (int_cause == INT_CAUSE_MAIN)
91 RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER,
92 (1 << bit_num));
93 else if (int_cause == INT_CAUSE_HIGH)
94 RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
95 (1 << bit_num));
96 else
97 return 0;
98 return 1;
99}
100#endif /* UNUSED */
101
102/*
103 * Interrupt handler for interrupts coming from the Galileo chip via P0_INT#.
104 *
105 * We route the timer interrupt to P0_INT# (IRQ 6), and that's all this
106 * routine can handle, for now.
107 *
108 * In the future, we'll route more interrupts to this pin, and that's why
109 * we keep this particular structure in the function.
110 */
111
112static irqreturn_t gt64240_p0int_irq(int irq, void *dev, struct pt_regs *regs)
113{
114 uint32_t irq_src, irq_src_mask;
115 int handled;
116
117 /* get the low interrupt cause register */
118 irq_src = MV_READ(LOW_INTERRUPT_CAUSE_REGISTER);
119
120 /* get the mask register for this pin */
121 irq_src_mask = MV_READ(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW);
122
123 /* mask off only the interrupts we're interested in */
124 irq_src = irq_src & irq_src_mask;
125
126 handled = IRQ_NONE;
127
128 /* Check for timer interrupt */
129 if (irq_src & 0x00000100) {
130 handled = IRQ_HANDLED;
131 irq_src &= ~0x00000100;
132
133 /* Clear any pending cause bits */
134 MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);
135
136 /* handle the timer call */
137 do_timer(regs);
138#ifndef CONFIG_SMP
139 update_process_times(user_mode(regs));
140#endif
141 }
142
143 if (irq_src) {
144 printk(KERN_INFO
145 "UNKNOWN P0_INT# interrupt received, irq_src=0x%x\n",
146 irq_src);
147 }
148
149 return handled;
150}
151
152/*
153 * Initializes timer using galileo's built in timer.
154 */
155
156/*
157 * This will ignore the standard MIPS timer interrupt handler
158 * that is passed in as *irq (=irq0 in ../kernel/time.c).
159 * We will do our own timer interrupt handling.
160 */
161void gt64240_time_init(void)
162{
163 static struct irqaction timer;
164
165 /* Stop the timer -- we'll use timer #0 */
166 MV_WRITE(TIMER_COUNTER_0_3_CONTROL, 0x0);
167
168 /* Load timer value for 100 Hz */
169 MV_WRITE(TIMER_COUNTER0, bus_clock / 100);
170
171 /*
172 * Create the IRQ structure entry for the timer. Since we're too early
173 * in the boot process to use the "request_irq()" call, we'll hard-code
174 * the values to the correct interrupt line.
175 */
176 timer.handler = &gt64240_p0int_irq;
177 timer.flags = SA_SHIRQ | SA_INTERRUPT;
178 timer.name = "timer";
179 timer.dev_id = NULL;
180 timer.next = NULL;
181 timer.mask = 0;
182 irq_desc[6].action = &timer;
183
184 enable_irq(6);
185
186 /* Clear any pending cause bits */
187 MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);
188
189 /* Enable the interrupt for timer 0 */
190 MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_MASK, 0x1);
191
192 /* Enable the timer interrupt for GT-64240 pin P0_INT# */
193 MV_WRITE (PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0x100);
194
195 /* Configure and start the timer */
196 MV_WRITE(TIMER_COUNTER_0_3_CONTROL, 0x3);
197}
198
199void gt64240_irq_init(void)
200{
201#if CURRENTLY_UNUSED
202 int i, j;
203
204 /* Reset irq handlers pointers to NULL */
205 for (i = 0; i < MAX_CAUSE_REGS; i++) {
206 for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) {
207 irq_handlers[i][j].next = NULL;
208 irq_handlers[i][j].sync = 0;
209 irq_handlers[i][j].routine = NULL;
210 irq_handlers[i][j].data = NULL;
211 }
212 }
213#endif
214}
diff --git a/arch/mips/momentum/ocelot_g/int-handler.S b/arch/mips/momentum/ocelot_g/int-handler.S
new file mode 100644
index 000000000000..772e8f713176
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/int-handler.S
@@ -0,0 +1,131 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: jsun@mvista.com or jsun@junsun.net
4 *
5 * First-level interrupt dispatcher for ocelot board.
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/*
19 * first level interrupt dispatcher for ocelot board -
20 * We check for the timer first, then check PCI ints A and D.
21 * Then check for serial IRQ and fall through.
22 */
23 .align 5
24 NESTED(ocelot_handle_int, PT_SIZE, sp)
25 SAVE_ALL
26 CLI
27 .set at
28 mfc0 t0, CP0_CAUSE
29 mfc0 t2, CP0_STATUS
30
31 and t0, t2
32
33 andi t1, t0, STATUSF_IP2 /* int0 hardware line */
34 bnez t1, ll_pri_enet_irq
35 andi t1, t0, STATUSF_IP3 /* int1 hardware line */
36 bnez t1, ll_sec_enet_irq
37 andi t1, t0, STATUSF_IP4 /* int2 hardware line */
38 bnez t1, ll_uart_irq
39 andi t1, t0, STATUSF_IP5 /* int3 hardware line */
40 bnez t1, ll_cpci_irq
41 andi t1, t0, STATUSF_IP6 /* int4 hardware line */
42 bnez t1, ll_galileo_p0_irq
43 andi t1, t0, STATUSF_IP7 /* cpu timer */
44 bnez t1, ll_cputimer_irq
45
46 /* now look at the extended interrupts */
47 mfc0 t0, CP0_CAUSE
48 cfc0 t1, CP0_S1_INTCONTROL
49
50 /* shift the mask 8 bits left to line up the bits */
51 sll t2, t1, 8
52
53 and t0, t2
54 srl t0, t0, 16
55
56 andi t1, t0, STATUSF_IP8 /* int6 hardware line */
57 bnez t1, ll_galileo_p1_irq
58 andi t1, t0, STATUSF_IP9 /* int7 hardware line */
59 bnez t1, ll_pmc_irq
60 andi t1, t0, STATUSF_IP10 /* int8 hardware line */
61 bnez t1, ll_cpci_abcd_irq
62 andi t1, t0, STATUSF_IP11 /* int9 hardware line */
63 bnez t1, ll_testpoint_irq
64
65 .set reorder
66
67 /* wrong alarm or masked ... */
68 j spurious_interrupt
69 nop
70 END(ocelot_handle_int)
71
72 .align 5
73ll_pri_enet_irq:
74 li a0, 2
75 move a1, sp
76 jal do_IRQ
77 j ret_from_irq
78
79ll_sec_enet_irq:
80 li a0, 3
81 move a1, sp
82 jal do_IRQ
83 j ret_from_irq
84
85ll_uart_irq:
86 li a0, 4
87 move a1, sp
88 jal do_IRQ
89 j ret_from_irq
90
91ll_cpci_irq:
92 li a0, 5
93 move a1, sp
94 jal do_IRQ
95 j ret_from_irq
96
97ll_galileo_p0_irq:
98 li a0, 6
99 move a1, sp
100 jal do_IRQ
101 j ret_from_irq
102
103ll_cputimer_irq:
104 li a0, 7
105 move a1, sp
106 jal do_IRQ
107 j ret_from_irq
108
109ll_galileo_p1_irq:
110 li a0, 8
111 move a1, sp
112 jal do_IRQ
113 j ret_from_irq
114
115ll_pmc_irq:
116 li a0, 9
117 move a1, sp
118 jal do_IRQ
119 j ret_from_irq
120
121ll_cpci_abcd_irq:
122 li a0, 10
123 move a1, sp
124 jal do_IRQ
125 j ret_from_irq
126
127ll_testpoint_irq:
128 li a0, 11
129 move a1, sp
130 jal do_IRQ
131 j ret_from_irq
diff --git a/arch/mips/momentum/ocelot_g/irq.c b/arch/mips/momentum/ocelot_g/irq.c
new file mode 100644
index 000000000000..5eb85b164205
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/irq.c
@@ -0,0 +1,69 @@
1/*
2 * Copyright (C) 2000 RidgeRun, Inc.
3 * Author: RidgeRun, Inc.
4 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
5 *
6 * Copyright 2001 MontaVista Software Inc.
7 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
8 * Copyright (C) 2000, 01, 05 Ralf Baechle (ralf@linux-mips.org)
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
18 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
21 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 */
31#include <linux/errno.h>
32#include <linux/init.h>
33#include <linux/kernel_stat.h>
34#include <linux/module.h>
35#include <linux/signal.h>
36#include <linux/sched.h>
37#include <linux/types.h>
38#include <linux/interrupt.h>
39#include <linux/ioport.h>
40#include <linux/timex.h>
41#include <linux/slab.h>
42#include <linux/random.h>
43#include <linux/bitops.h>
44#include <asm/bootinfo.h>
45#include <asm/io.h>
46#include <asm/irq.h>
47#include <asm/irq_cpu.h>
48#include <asm/mipsregs.h>
49#include <asm/system.h>
50
51extern asmlinkage void ocelot_handle_int(void);
52extern void gt64240_irq_init(void);
53
54void __init arch_init_irq(void)
55{
56 /*
57 * Clear all of the interrupts while we change the able around a bit.
58 * int-handler is not on bootstrap
59 */
60 clear_c0_status(ST0_IM);
61 local_irq_disable();
62
63 /* Sets the first-level interrupt dispatcher. */
64 set_except_vector(0, ocelot_handle_int);
65 mips_cpu_irq_init(0);
66 rm7k_cpu_irq_init(8);
67
68 gt64240_irq_init();
69}
diff --git a/arch/mips/momentum/ocelot_g/ocelot_pld.h b/arch/mips/momentum/ocelot_g/ocelot_pld.h
new file mode 100644
index 000000000000..fcb8275e219d
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/ocelot_pld.h
@@ -0,0 +1,30 @@
1/*
2 * Ocelot Board Register Definitions
3 *
4 * (C) 2001 Red Hat, Inc.
5 *
6 * GPL'd
7 */
8#ifndef __MOMENCO_OCELOT_PLD_H__
9#define __MOMENCO_OCELOT_PLD_H__
10
11#define OCELOT_CS0_ADDR (0xfc000000)
12
13#define OCELOT_REG_BOARDREV (0)
14#define OCELOT_REG_PLD1_ID (1)
15#define OCELOT_REG_PLD2_ID (2)
16#define OCELOT_REG_RESET_STATUS (3)
17#define OCELOT_REG_BOARD_STATUS (4)
18#define OCELOT_REG_CPCI_ID (5)
19#define OCELOT_REG_I2C_CTRL (8)
20#define OCELOT_REG_EEPROM_MODE (9)
21#define OCELOT_REG_INTMASK (10)
22#define OCELOT_REG_INTSTATUS (11)
23#define OCELOT_REG_INTSET (12)
24#define OCELOT_REG_INTCLR (13)
25
26#define OCELOT_PLD_WRITE(x, y) writeb(x, OCELOT_CS0_ADDR + OCELOT_REG_##y)
27#define OCELOT_PLD_READ(x) readb(OCELOT_CS0_ADDR + OCELOT_REG_##x)
28
29
30#endif /* __MOMENCO_OCELOT_PLD_H__ */
diff --git a/arch/mips/momentum/ocelot_g/prom.c b/arch/mips/momentum/ocelot_g/prom.c
new file mode 100644
index 000000000000..6b4f577c2757
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/prom.c
@@ -0,0 +1,86 @@
1/*
2 * Copyright 2002 Momentum Computer Inc.
3 * Author: Matthew Dharm <mdharm@momenco.com>
4 *
5 * Based on Ocelot Linux port, which is
6 * Copyright 2001 MontaVista Software Inc.
7 * Author: jsun@mvista.com or jsun@junsun.net
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14#include <linux/config.h>
15#include <linux/init.h>
16#include <linux/mm.h>
17#include <linux/sched.h>
18#include <linux/bootmem.h>
19
20#include <asm/addrspace.h>
21#include <asm/bootinfo.h>
22#include <asm/pmon.h>
23#include <asm/gt64240.h>
24
25#include "ocelot_pld.h"
26
27struct callvectors* debug_vectors;
28
29extern unsigned long marvell_base;
30extern unsigned long bus_clock;
31
32#ifdef CONFIG_GALILLEO_GT64240_ETH
33extern unsigned char prom_mac_addr_base[6];
34#endif
35
36const char *get_system_type(void)
37{
38 return "Momentum Ocelot";
39}
40
41void __init prom_init(void)
42{
43 int argc = fw_arg0;
44 char **arg = (char **) fw_arg1;
45 char **env = (char **) fw_arg2;
46 struct callvectors *cv = (struct callvectors *) fw_arg3;
47 int i;
48
49 /* save the PROM vectors for debugging use */
50 debug_vectors = cv;
51
52 /* arg[0] is "g", the rest is boot parameters */
53 arcs_cmdline[0] = '\0';
54 for (i = 1; i < argc; i++) {
55 if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
56 >= sizeof(arcs_cmdline))
57 break;
58 strcat(arcs_cmdline, arg[i]);
59 strcat(arcs_cmdline, " ");
60 }
61
62 mips_machgroup = MACH_GROUP_MOMENCO;
63 mips_machtype = MACH_MOMENCO_OCELOT_G;
64
65#ifdef CONFIG_GALILLEO_GT64240_ETH
66 /* get the base MAC address for on-board ethernet ports */
67 memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6);
68#endif
69
70 while (*env) {
71 if (strncmp("gtbase", *env, strlen("gtbase")) == 0) {
72 marvell_base = simple_strtol(*env + strlen("gtbase="),
73 NULL, 16);
74 }
75 if (strncmp("busclock", *env, strlen("busclock")) == 0) {
76 bus_clock = simple_strtol(*env + strlen("busclock="),
77 NULL, 10);
78 }
79 env++;
80 }
81}
82
83unsigned long __init prom_free_prom_memory(void)
84{
85 return 0;
86}
diff --git a/arch/mips/momentum/ocelot_g/reset.c b/arch/mips/momentum/ocelot_g/reset.c
new file mode 100644
index 000000000000..3fd499adf4cf
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/reset.c
@@ -0,0 +1,47 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the License, or (at your
5 * option) any later version.
6 *
7 * Copyright (C) 1997, 2001 Ralf Baechle
8 * Copyright 2001 MontaVista Software Inc.
9 * Author: jsun@mvista.com or jsun@junsun.net
10 */
11#include <linux/sched.h>
12#include <linux/mm.h>
13#include <asm/io.h>
14#include <asm/pgtable.h>
15#include <asm/processor.h>
16#include <asm/reboot.h>
17#include <asm/system.h>
18#include <linux/delay.h>
19
20void momenco_ocelot_restart(char *command)
21{
22 void *nvram = ioremap_nocache(0x2c807000, 0x1000);
23
24 if (!nvram) {
25 printk(KERN_NOTICE "ioremap of reset register failed\n");
26 return;
27 }
28 writeb(0x84, nvram + 0xff7); /* Ask the NVRAM/RTC/watchdog chip to
29 assert reset in 1/16 second */
30 mdelay(10+(1000/16));
31 iounmap(nvram);
32 printk(KERN_NOTICE "Watchdog reset failed\n");
33}
34
35void momenco_ocelot_halt(void)
36{
37 printk(KERN_NOTICE "\n** You can safely turn off the power\n");
38 while (1)
39 __asm__(".set\tmips3\n\t"
40 "wait\n\t"
41 ".set\tmips0");
42}
43
44void momenco_ocelot_power_off(void)
45{
46 momenco_ocelot_halt();
47}
diff --git a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c
new file mode 100644
index 000000000000..38a78ab8c830
--- /dev/null
+++ b/arch/mips/momentum/ocelot_g/setup.c
@@ -0,0 +1,266 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Momentum Computer Ocelot-G (CP7000G) - board dependent boot routines
4 *
5 * Copyright (C) 1996, 1997, 2001 Ralf Baechle
6 * Copyright (C) 2000 RidgeRun, Inc.
7 * Copyright (C) 2001 Red Hat, Inc.
8 * Copyright (C) 2002 Momentum Computer
9 *
10 * Author: Matthew Dharm, Momentum Computer
11 * mdharm@momenco.com
12 *
13 * Author: RidgeRun, Inc.
14 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
15 *
16 * Copyright 2001 MontaVista Software Inc.
17 * Author: jsun@mvista.com or jsun@junsun.net
18 *
19 * This program is free software; you can redistribute it and/or modify it
20 * under the terms of the GNU General Public License as published by the
21 * Free Software Foundation; either version 2 of the License, or (at your
22 * option) any later version.
23 *
24 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
27 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 * You should have received a copy of the GNU General Public License along
36 * with this program; if not, write to the Free Software Foundation, Inc.,
37 * 675 Mass Ave, Cambridge, MA 02139, USA.
38 *
39 */
40#include <linux/config.h>
41#include <linux/init.h>
42#include <linux/kernel.h>
43#include <linux/types.h>
44#include <linux/mm.h>
45#include <linux/swap.h>
46#include <linux/ioport.h>
47#include <linux/sched.h>
48#include <linux/interrupt.h>
49#include <linux/pci.h>
50#include <linux/timex.h>
51#include <linux/vmalloc.h>
52#include <asm/time.h>
53#include <asm/bootinfo.h>
54#include <asm/page.h>
55#include <asm/io.h>
56#include <asm/gt64240.h>
57#include <asm/irq.h>
58#include <asm/pci.h>
59#include <asm/processor.h>
60#include <asm/ptrace.h>
61#include <asm/reboot.h>
62#include <linux/bootmem.h>
63
64#include "ocelot_pld.h"
65
66#ifdef CONFIG_GALILLEO_GT64240_ETH
67extern unsigned char prom_mac_addr_base[6];
68#endif
69
70unsigned long marvell_base;
71
72/* These functions are used for rebooting or halting the machine*/
73extern void momenco_ocelot_restart(char *command);
74extern void momenco_ocelot_halt(void);
75extern void momenco_ocelot_power_off(void);
76
77extern void gt64240_time_init(void);
78extern void momenco_ocelot_irq_setup(void);
79
80static char reset_reason;
81
82static unsigned long ENTRYLO(unsigned long paddr)
83{
84 return ((paddr & PAGE_MASK) |
85 (_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL |
86 _CACHE_UNCACHED)) >> 6;
87}
88
89/* setup code for a handoff from a version 2 PMON 2000 PROM */
90void PMON_v2_setup(void)
91{
92 /* A wired TLB entry for the GT64240 and the serial port. The
93 GT64240 is going to be hit on every IRQ anyway - there's
94 absolutely no point in letting it be a random TLB entry, as
95 it'll just cause needless churning of the TLB. And we use
96 the other half for the serial port, which is just a PITA
97 otherwise :)
98
99 Device Physical Virtual
100 GT64240 Internal Regs 0xf4000000 0xe0000000
101 UARTs (CS2) 0xfd000000 0xe0001000
102 */
103 add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000),
104 0xf4000000, PM_64K);
105 add_wired_entry(ENTRYLO(0xfd000000), ENTRYLO(0xfd001000),
106 0xfd000000, PM_4K);
107
108 /* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM
109 in the CS[012] region. We can't use ioremap() yet. The NVRAM
110 is a ST M48T37Y, which includes NVRAM, RTC, and Watchdog functions.
111
112 Ocelot PLD (CS0) 0xfc000000 0xe0020000
113 NVRAM (CS1) 0xfc800000 0xe0030000
114 */
115 add_temporary_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfc010000),
116 0xfc000000, PM_64K);
117 add_temporary_entry(ENTRYLO(0xfc800000), ENTRYLO(0xfc810000),
118 0xfc800000, PM_64K);
119
120 marvell_base = 0xf4000000;
121}
122
123extern int rm7k_tcache_enabled;
124
125/*
126 * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache()
127 */
128#define Page_Invalidate_T 0x16
129static void __init setup_l3cache(unsigned long size)
130{
131 int register i;
132
133 printk("Enabling L3 cache...");
134
135 /* Enable the L3 cache in the GT64120A's CPU Configuration register */
136 MV_WRITE(0, MV_READ(0) | (1<<14));
137
138 /* Enable the L3 cache in the CPU */
139 set_c0_config(1<<12 /* CONF_TE */);
140
141 /* Clear the cache */
142 write_c0_taglo(0);
143 write_c0_taghi(0);
144
145 for (i=0; i < size; i+= 4096) {
146 __asm__ __volatile__ (
147 ".set noreorder\n\t"
148 ".set mips3\n\t"
149 "cache %1, (%0)\n\t"
150 ".set mips0\n\t"
151 ".set reorder"
152 :
153 : "r" (KSEG0ADDR(i)),
154 "i" (Page_Invalidate_T));
155 }
156
157 /* Let the RM7000 MM code know that the tertiary cache is enabled */
158 rm7k_tcache_enabled = 1;
159
160 printk("Done\n");
161}
162
163static int __init momenco_ocelot_g_setup(void)
164{
165 void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache);
166 unsigned int tmpword;
167
168 board_time_init = gt64240_time_init;
169
170 _machine_restart = momenco_ocelot_restart;
171 _machine_halt = momenco_ocelot_halt;
172 _machine_power_off = momenco_ocelot_power_off;
173
174 /*
175 * initrd_start = (ulong)ocelot_initrd_start;
176 * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size;
177 * initrd_below_start_ok = 1;
178 */
179
180 /* do handoff reconfiguration */
181 PMON_v2_setup();
182
183#ifdef CONFIG_GALILLEO_GT64240_ETH
184 /* get the mac addr */
185 memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6);
186#endif
187
188 /* Turn off the Bit-Error LED */
189 OCELOT_PLD_WRITE(0x80, INTCLR);
190
191 tmpword = OCELOT_PLD_READ(BOARDREV);
192 if (tmpword < 26)
193 printk("Momenco Ocelot-G: Board Assembly Rev. %c\n", 'A'+tmpword);
194 else
195 printk("Momenco Ocelot-G: Board Assembly Revision #0x%x\n", tmpword);
196
197 tmpword = OCELOT_PLD_READ(PLD1_ID);
198 printk("PLD 1 ID: %d.%d\n", tmpword>>4, tmpword&15);
199 tmpword = OCELOT_PLD_READ(PLD2_ID);
200 printk("PLD 2 ID: %d.%d\n", tmpword>>4, tmpword&15);
201 tmpword = OCELOT_PLD_READ(RESET_STATUS);
202 printk("Reset reason: 0x%x\n", tmpword);
203 reset_reason = tmpword;
204 OCELOT_PLD_WRITE(0xff, RESET_STATUS);
205
206 tmpword = OCELOT_PLD_READ(BOARD_STATUS);
207 printk("Board Status register: 0x%02x\n", tmpword);
208 printk(" - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
209 printk(" - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
210 printk(" - Tulip PHY %s connected\n", (tmpword&0x10)?"is":"not");
211 printk(" - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1);
212 printk(" - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3)));
213
214 if (tmpword&12)
215 l3func((1<<(((tmpword&12) >> 2)+20)));
216
217 switch(tmpword &3) {
218 case 3:
219 /* 512MiB -- two banks of 256MiB */
220 add_memory_region( 0x0<<20, 0x100<<20, BOOT_MEM_RAM);
221/*
222 add_memory_region(0x100<<20, 0x100<<20, BOOT_MEM_RAM);
223*/
224 break;
225 case 2:
226 /* 256MiB -- two banks of 128MiB */
227 add_memory_region( 0x0<<20, 0x80<<20, BOOT_MEM_RAM);
228 add_memory_region(0x80<<20, 0x80<<20, BOOT_MEM_RAM);
229 break;
230 case 1:
231 /* 128MiB -- 64MiB per bank */
232 add_memory_region( 0x0<<20, 0x40<<20, BOOT_MEM_RAM);
233 add_memory_region(0x40<<20, 0x40<<20, BOOT_MEM_RAM);
234 break;
235 case 0:
236 /* 64MiB */
237 add_memory_region( 0x0<<20, 0x40<<20, BOOT_MEM_RAM);
238 break;
239 }
240
241 /* FIXME: Fix up the DiskOnChip mapping */
242 MV_WRITE(0x468, 0xfef73);
243
244 return 0;
245}
246
247early_initcall(momenco_ocelot_g_setup);
248
249/* This needs to be one of the first initcalls, because no I/O port access
250 can work before this */
251
252static int io_base_ioremap(void)
253{
254 /* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */
255 unsigned long io_remap_range;
256
257 io_remap_range = (unsigned long) ioremap(0xc0000000, 0x30000000);
258 if (!io_remap_range)
259 panic("Could not ioremap I/O port range");
260
261 set_io_port_base(io_remap_range - 0xc0000000);
262
263 return 0;
264}
265
266module_init(io_base_ioremap);