2 * Copyright (C) 2004, 2005 by Basler Vision Technologies AG
3 * Author: Thomas Koeller <thomas.koeller@baslerweb.com>
4 * Based on the PMC-Sierra Yosemite board support by Ralf Baechle and
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <linux/types.h>
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/string.h>
26 #include <linux/tty.h>
27 #include <linux/serial_core.h>
28 #include <linux/serial.h>
29 #include <linux/serial_8250.h>
30 #include <linux/ioport.h>
31 #include <linux/spinlock.h>
32 #include <asm/bootinfo.h>
33 #include <asm/mipsregs.h>
34 #include <asm/pgtable-32.h>
37 #include <asm/rm9k-ocd.h>
41 #define TITAN_UART_CLK 25000000
44 /* normal serial port assignment */
45 #define REGBASE_SER0 0x0208
46 #define REGBASE_SER1 0x0238
50 /* serial ports swapped */
51 #define REGBASE_SER0 0x0238
52 #define REGBASE_SER1 0x0208
57 unsigned long memsize
;
59 unsigned int titan_irq
= TITAN_IRQ
;
60 static void __iomem
* ctl_regs
;
63 volatile void __iomem
* const ocd_base
= (void *) (EXCITE_ADDR_OCD
);
64 volatile void __iomem
* const titan_base
= (void *) (EXCITE_ADDR_TITAN
);
66 /* Protect access to shared GPI registers */
67 DEFINE_SPINLOCK(titan_lock
);
72 * The eXcite platform uses the alternate timer interrupt
74 * Fixme: At the time of this writing cevt-r4k.c doesn't yet know about how
75 * to handle the alternate timer interrupt of the RM9000.
77 void __init
plat_time_init(void)
79 const u32 modebit5
= ocd_readl(0x00e4);
80 unsigned int mult
= ((modebit5
>> 11) & 0x1f) + 2;
81 unsigned int div
= ((modebit5
>> 16) & 0x1f) + 2;
85 mips_hpt_frequency
= EXCITE_CPU_EXT_CLOCK
* mult
/ div
/ 2;
88 static int __init
excite_init_console(void)
90 #if defined(CONFIG_SERIAL_8250)
91 static __initdata
char serr
[] =
92 KERN_ERR
"Serial port #%u setup failed\n";
95 /* Take the DUART out of reset */
96 titan_writel(0x00ff1cff, CPRR
);
98 #if (CONFIG_SERIAL_8250_NR_UARTS > 1)
99 /* Enable both ports */
100 titan_writel(MASK_SER0
| MASK_SER1
, UACFG
);
102 /* Enable port #0 only */
103 titan_writel(MASK_SER0
, UACFG
);
107 * Set up serial port #0. Do not use autodetection; the result is
110 memset(&up
, 0, sizeof(up
));
111 up
.membase
= (char *) titan_addr(REGBASE_SER0
);
113 up
.uartclk
= TITAN_UART_CLK
;
115 up
.iotype
= UPIO_RM9000
;
116 up
.type
= PORT_RM9000
;
117 up
.flags
= UPF_SHARE_IRQ
;
119 if (early_serial_setup(&up
))
120 printk(serr
, up
.line
);
122 #if CONFIG_SERIAL_8250_NR_UARTS > 1
123 /* And now for port #1. */
124 up
.membase
= (char *) titan_addr(REGBASE_SER1
);
126 if (early_serial_setup(&up
))
127 printk(serr
, up
.line
);
128 #endif /* CONFIG_SERIAL_8250_NR_UARTS > 1 */
130 /* Leave the DUART in reset */
131 titan_writel(0x00ff3cff, CPRR
);
132 #endif /* defined(CONFIG_SERIAL_8250) */
137 static int __init
excite_platform_init(void)
140 unsigned char buf
[3];
144 /* BIU buffer allocations */
145 ocd_writel(8, CPURSLMT
); /* CPU */
146 titan_writel(4, CPGRWL
); /* GPI / Ethernet */
148 /* Map control registers located in FPGA */
149 ctl_regs
= ioremap_nocache(EXCITE_PHYS_FPGA
+ EXCITE_FPGA_SYSCTL
, 16);
151 panic("eXcite: failed to map platform control registers\n");
152 memcpy_fromio(buf
, ctl_regs
+ 2, ARRAY_SIZE(buf
));
153 unit_id
= buf
[0] | (buf
[1] << 8) | (buf
[2] << 16);
155 /* Clear the reboot flag */
156 dpr
= ioremap_nocache(EXCITE_PHYS_FPGA
+ EXCITE_FPGA_DPR
, 1);
157 reg
= __raw_readb(dpr
);
158 __raw_writeb(reg
& 0x7f, dpr
);
161 /* Interrupt controller setup */
162 for (i
= INTP0Status0
; i
< INTP0Status0
+ 0x80; i
+= 0x10) {
163 ocd_writel(0x00000000, i
+ 0x04);
164 ocd_writel(0xffffffff, i
+ 0x0c);
166 ocd_writel(0x2, NMICONFIG
);
168 ocd_writel(0x1 << (TITAN_MSGINT
% 0x20),
169 INTP0Mask0
+ (0x10 * (TITAN_MSGINT
/ 0x20)));
170 ocd_writel((0x1 << (FPGA0_MSGINT
% 0x20))
171 | ocd_readl(INTP0Mask0
+ (0x10 * (FPGA0_MSGINT
/ 0x20))),
172 INTP0Mask0
+ (0x10 * (FPGA0_MSGINT
/ 0x20)));
173 ocd_writel((0x1 << (FPGA1_MSGINT
% 0x20))
174 | ocd_readl(INTP0Mask0
+ (0x10 * (FPGA1_MSGINT
/ 0x20))),
175 INTP0Mask0
+ (0x10 * (FPGA1_MSGINT
/ 0x20)));
176 ocd_writel((0x1 << (PHY_MSGINT
% 0x20))
177 | ocd_readl(INTP0Mask0
+ (0x10 * (PHY_MSGINT
/ 0x20))),
178 INTP0Mask0
+ (0x10 * (PHY_MSGINT
/ 0x20)));
180 ocd_writel((0x1 << (USB_MSGINT
% 0x20))
181 | ocd_readl(INTP0Mask0
+ (0x10 * (USB_MSGINT
/ 0x20))),
182 INTP0Mask0
+ (0x10 * (USB_MSGINT
/ 0x20)));
184 /* Enable the packet FIFO, XDMA and XDMA arbiter */
185 titan_writel(0x00ff18ff, CPRR
);
188 * Set up the PADMUX. Power down all ethernet slices,
189 * they will be powered up and configured at device startup.
191 titan_writel(0x00878206, CPTC1R
);
192 titan_writel(0x00001100, CPTC0R
); /* latch PADMUX, enable WCIMODE */
194 /* Reset and enable the FIFO block */
195 titan_writel(0x00000001, SDRXFCIE
);
196 titan_writel(0x00000001, SDTXFCIE
);
197 titan_writel(0x00000100, SDRXFCIE
);
198 titan_writel(0x00000000, SDTXFCIE
);
201 * Initialize the common interrupt shared by all components of
202 * the GPI/Ethernet subsystem.
204 titan_writel((EXCITE_PHYS_OCD
>> 12), CPCFG0
);
205 titan_writel(TITAN_MSGINT
, CPCFG1
);
208 * XDMA configuration.
209 * In order for the XDMA to be sharable among multiple drivers,
210 * the setup must be done here in the platform. The reason is that
211 * this setup can only be done while the XDMA is in reset. If this
212 * were done in a driver, it would interrupt all other drivers
215 titan_writel(0x80021dff, GXCFG
); /* XDMA reset */
216 titan_writel(0x00000000, CPXCISRA
);
217 titan_writel(0x00000000, CPXCISRB
); /* clear pending interrupts */
218 #if defined(CONFIG_HIGHMEM)
219 # error change for HIGHMEM support!
221 titan_writel(0x00000000, GXDMADRPFX
); /* buffer address prefix */
223 titan_writel(0, GXDMA_DESCADR
);
225 for (i
= 0x5040; i
<= 0x5300; i
+= 0x0040)
226 titan_writel(0x80080000, i
); /* reset channel */
228 titan_writel((0x1 << 29) /* no sparse tx descr. */
229 | (0x1 << 28) /* no sparse rx descr. */
230 | (0x1 << 23) | (0x1 << 24) /* descriptor coherency */
231 | (0x1 << 21) | (0x1 << 22) /* data coherency */
236 #if defined(CONFIG_SMP)
237 # error No SMP support
239 /* All interrupts go to core #0 only. */
240 titan_writel(0x1f007fff, CPDST0A
);
241 titan_writel(0x00000000, CPDST0B
);
242 titan_writel(0x0000ff3f, CPDST1A
);
243 titan_writel(0x00000000, CPDST1B
);
244 titan_writel(0x00ffffff, CPXDSTA
);
245 titan_writel(0x00000000, CPXDSTB
);
248 /* Enable DUART interrupts, disable everything else. */
249 titan_writel(0x04000000, CPGIG0ER
);
250 titan_writel(0x000000c0, CPGIG1ER
);
252 excite_procfs_init();
256 void __init
plat_mem_setup(void)
258 volatile u32
* const boot_ocd_base
= (u32
*) 0xbf7fc000;
260 /* Announce RAM to system */
261 add_memory_region(0x00000000, memsize
, BOOT_MEM_RAM
);
263 /* Set up the peripheral address map */
264 *(boot_ocd_base
+ (LKB9
/ sizeof(u32
))) = 0;
265 *(boot_ocd_base
+ (LKB10
/ sizeof(u32
))) = 0;
266 *(boot_ocd_base
+ (LKB11
/ sizeof(u32
))) = 0;
267 *(boot_ocd_base
+ (LKB12
/ sizeof(u32
))) = 0;
269 *(boot_ocd_base
+ (LKB0
/ sizeof(u32
))) = EXCITE_PHYS_OCD
>> 4;
272 ocd_writel((EXCITE_PHYS_TITAN
>> 4) | 0x1UL
, LKB5
);
273 ocd_writel(((EXCITE_SIZE_TITAN
>> 4) & 0x7fffff00) - 0x100, LKM5
);
274 ocd_writel((EXCITE_PHYS_SCRAM
>> 4) | 0x1UL
, LKB13
);
275 ocd_writel(((EXCITE_SIZE_SCRAM
>> 4) & 0xffffff00) - 0x100, LKM13
);
277 /* Local bus slot #0 */
278 ocd_writel(0x00040510, LDP0
);
279 ocd_writel((EXCITE_PHYS_BOOTROM
>> 4) | 0x1UL
, LKB9
);
280 ocd_writel(((EXCITE_SIZE_BOOTROM
>> 4) & 0x03ffff00) - 0x100, LKM9
);
282 /* Local bus slot #2 */
283 ocd_writel(0x00000330, LDP2
);
284 ocd_writel((EXCITE_PHYS_FPGA
>> 4) | 0x1, LKB11
);
285 ocd_writel(((EXCITE_SIZE_FPGA
>> 4) - 0x100) & 0x03ffff00, LKM11
);
287 /* Local bus slot #3 */
288 ocd_writel(0x00123413, LDP3
);
289 ocd_writel((EXCITE_PHYS_NAND
>> 4) | 0x1, LKB12
);
290 ocd_writel(((EXCITE_SIZE_NAND
>> 4) - 0x100) & 0x03ffff00, LKM12
);
295 console_initcall(excite_init_console
);
296 arch_initcall(excite_platform_init
);
298 EXPORT_SYMBOL(titan_lock
);
299 EXPORT_SYMBOL(titan_irqflags
);
300 EXPORT_SYMBOL(titan_irq
);
301 EXPORT_SYMBOL(ocd_base
);
302 EXPORT_SYMBOL(titan_base
);