aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/sni
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/sni')
-rw-r--r--arch/mips/sni/Makefile2
-rw-r--r--arch/mips/sni/a20r.c13
-rw-r--r--arch/mips/sni/eisa.c50
-rw-r--r--arch/mips/sni/irq.c4
-rw-r--r--arch/mips/sni/rm200.c326
-rw-r--r--arch/mips/sni/setup.c143
-rw-r--r--arch/mips/sni/sniprom.c251
-rw-r--r--arch/mips/sni/time.c1
8 files changed, 520 insertions, 270 deletions
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile
index 3a99cd62c0bd..a7dbeebe7fe6 100644
--- a/arch/mips/sni/Makefile
+++ b/arch/mips/sni/Makefile
@@ -3,6 +3,6 @@
3# 3#
4 4
5obj-y += irq.o reset.o setup.o a20r.o rm200.o pcimt.o pcit.o time.o 5obj-y += irq.o reset.o setup.o a20r.o rm200.o pcimt.o pcit.o time.o
6obj-$(CONFIG_CPU_BIG_ENDIAN) += sniprom.o 6obj-$(CONFIG_EISA) += eisa.o
7 7
8EXTRA_CFLAGS += -Werror 8EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
index b74607599971..3f8cf5eb2f06 100644
--- a/arch/mips/sni/a20r.c
+++ b/arch/mips/sni/a20r.c
@@ -117,10 +117,19 @@ static struct resource sc26xx_rsrc[] = {
117 } 117 }
118}; 118};
119 119
120static unsigned int sc26xx_data[2] = {
121 /* DTR | RTS | DSR | CTS | DCD | RI */
122 (8 << 0) | (4 << 4) | (6 << 8) | (0 << 12) | (6 << 16) | (0 << 20),
123 (3 << 0) | (2 << 4) | (1 << 8) | (2 << 12) | (3 << 16) | (4 << 20)
124};
125
120static struct platform_device sc26xx_pdev = { 126static struct platform_device sc26xx_pdev = {
121 .name = "SC26xx", 127 .name = "SC26xx",
122 .num_resources = ARRAY_SIZE(sc26xx_rsrc), 128 .num_resources = ARRAY_SIZE(sc26xx_rsrc),
123 .resource = sc26xx_rsrc 129 .resource = sc26xx_rsrc,
130 .dev = {
131 .platform_data = sc26xx_data,
132 }
124}; 133};
125 134
126static u32 a20r_ack_hwint(void) 135static u32 a20r_ack_hwint(void)
@@ -231,9 +240,9 @@ static int __init snirm_a20r_setup_devinit(void)
231 platform_device_register(&sc26xx_pdev); 240 platform_device_register(&sc26xx_pdev);
232 platform_device_register(&a20r_serial8250_device); 241 platform_device_register(&a20r_serial8250_device);
233 platform_device_register(&a20r_ds1216_device); 242 platform_device_register(&a20r_ds1216_device);
243 sni_eisa_root_init();
234 break; 244 break;
235 } 245 }
236
237 return 0; 246 return 0;
238} 247}
239 248
diff --git a/arch/mips/sni/eisa.c b/arch/mips/sni/eisa.c
new file mode 100644
index 000000000000..7396cd719900
--- /dev/null
+++ b/arch/mips/sni/eisa.c
@@ -0,0 +1,50 @@
1/*
2 * Virtual EISA root driver.
3 * Acts as a placeholder if we don't have a proper EISA bridge.
4 *
5 * (C) 2003 Marc Zyngier <maz@wild-wind.fr.eu.org>
6 * modified for SNI usage by Thomas Bogendoerfer
7 *
8 * This code is released under the GPL version 2.
9 */
10
11#include <linux/kernel.h>
12#include <linux/platform_device.h>
13#include <linux/eisa.h>
14#include <linux/init.h>
15
16/* The default EISA device parent (virtual root device).
17 * Now use a platform device, since that's the obvious choice. */
18
19static struct platform_device eisa_root_dev = {
20 .name = "eisa",
21 .id = 0,
22};
23
24static struct eisa_root_device eisa_bus_root = {
25 .dev = &eisa_root_dev.dev,
26 .bus_base_addr = 0,
27 .res = &ioport_resource,
28 .slots = EISA_MAX_SLOTS,
29 .dma_mask = 0xffffffff,
30 .force_probe = 1,
31};
32
33int __init sni_eisa_root_init(void)
34{
35 int r;
36
37 r = platform_device_register(&eisa_root_dev);
38 if (!r)
39 return r;
40
41 eisa_root_dev.dev.driver_data = &eisa_bus_root;
42
43 if (eisa_root_register(&eisa_bus_root)) {
44 /* A real bridge may have been registered before
45 * us. So quietly unregister. */
46 platform_device_unregister(&eisa_root_dev);
47 return -1;
48 }
49 return 0;
50}
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c
index 9ccffdfb8289..e8e72bb3a9af 100644
--- a/arch/mips/sni/irq.c
+++ b/arch/mips/sni/irq.c
@@ -35,14 +35,14 @@ static irqreturn_t sni_isa_irq_handler(int dummy, void *p)
35 if (unlikely(irq < 0)) 35 if (unlikely(irq < 0))
36 return IRQ_NONE; 36 return IRQ_NONE;
37 37
38 do_IRQ(irq); 38 generic_handle_irq(irq);
39 return IRQ_HANDLED; 39 return IRQ_HANDLED;
40} 40}
41 41
42struct irqaction sni_isa_irq = { 42struct irqaction sni_isa_irq = {
43 .handler = sni_isa_irq_handler, 43 .handler = sni_isa_irq_handler,
44 .name = "ISA", 44 .name = "ISA",
45 .flags = IRQF_SHARED 45 .flags = IRQF_SHARED | IRQF_DISABLED
46}; 46};
47 47
48/* 48/*
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
index 67b061eef6cd..5310aa75afa4 100644
--- a/arch/mips/sni/rm200.c
+++ b/arch/mips/sni/rm200.c
@@ -5,30 +5,36 @@
5 * License. See the file "COPYING" in the main directory of this archive 5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details. 6 * for more details.
7 * 7 *
8 * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de) 8 * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
9 *
10 * i8259 parts ripped out of arch/mips/kernel/i8259.c
9 */ 11 */
10 12
13#include <linux/delay.h>
11#include <linux/init.h> 14#include <linux/init.h>
12#include <linux/interrupt.h> 15#include <linux/interrupt.h>
13#include <linux/platform_device.h> 16#include <linux/platform_device.h>
14#include <linux/serial_8250.h> 17#include <linux/serial_8250.h>
18#include <linux/io.h>
15 19
16#include <asm/sni.h> 20#include <asm/sni.h>
17#include <asm/time.h> 21#include <asm/time.h>
18#include <asm/irq_cpu.h> 22#include <asm/irq_cpu.h>
19 23
20#define PORT(_base,_irq) \ 24#define RM200_I8259A_IRQ_BASE 32
25
26#define MEMPORT(_base,_irq) \
21 { \ 27 { \
22 .iobase = _base, \ 28 .mapbase = _base, \
23 .irq = _irq, \ 29 .irq = _irq, \
24 .uartclk = 1843200, \ 30 .uartclk = 1843200, \
25 .iotype = UPIO_PORT, \ 31 .iotype = UPIO_MEM, \
26 .flags = UPF_BOOT_AUTOCONF, \ 32 .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP, \
27 } 33 }
28 34
29static struct plat_serial8250_port rm200_data[] = { 35static struct plat_serial8250_port rm200_data[] = {
30 PORT(0x3f8, 4), 36 MEMPORT(0x160003f8, RM200_I8259A_IRQ_BASE + 4),
31 PORT(0x2f8, 3), 37 MEMPORT(0x160002f8, RM200_I8259A_IRQ_BASE + 3),
32 { }, 38 { },
33}; 39};
34 40
@@ -112,15 +118,311 @@ static int __init snirm_setup_devinit(void)
112 platform_device_register(&rm200_ds1216_device); 118 platform_device_register(&rm200_ds1216_device);
113 platform_device_register(&snirm_82596_rm200_pdev); 119 platform_device_register(&snirm_82596_rm200_pdev);
114 platform_device_register(&snirm_53c710_rm200_pdev); 120 platform_device_register(&snirm_53c710_rm200_pdev);
121 sni_eisa_root_init();
115 } 122 }
116 return 0; 123 return 0;
117} 124}
118 125
119device_initcall(snirm_setup_devinit); 126device_initcall(snirm_setup_devinit);
120 127
128/*
129 * RM200 has an ISA and an EISA bus. The iSA bus is only used
130 * for onboard devices and also has twi i8259 PICs. Since these
131 * PICs are no accessible via inb/outb the following code uses
132 * readb/writeb to access them
133 */
134
135DEFINE_SPINLOCK(sni_rm200_i8259A_lock);
136#define PIC_CMD 0x00
137#define PIC_IMR 0x01
138#define PIC_ISR PIC_CMD
139#define PIC_POLL PIC_ISR
140#define PIC_OCW3 PIC_ISR
141
142/* i8259A PIC related value */
143#define PIC_CASCADE_IR 2
144#define MASTER_ICW4_DEFAULT 0x01
145#define SLAVE_ICW4_DEFAULT 0x01
146
147/*
148 * This contains the irq mask for both 8259A irq controllers,
149 */
150static unsigned int rm200_cached_irq_mask = 0xffff;
151static __iomem u8 *rm200_pic_master;
152static __iomem u8 *rm200_pic_slave;
153
154#define cached_master_mask (rm200_cached_irq_mask)
155#define cached_slave_mask (rm200_cached_irq_mask >> 8)
156
157static void sni_rm200_disable_8259A_irq(unsigned int irq)
158{
159 unsigned int mask;
160 unsigned long flags;
161
162 irq -= RM200_I8259A_IRQ_BASE;
163 mask = 1 << irq;
164 spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
165 rm200_cached_irq_mask |= mask;
166 if (irq & 8)
167 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
168 else
169 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
170 spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
171}
172
173static void sni_rm200_enable_8259A_irq(unsigned int irq)
174{
175 unsigned int mask;
176 unsigned long flags;
177
178 irq -= RM200_I8259A_IRQ_BASE;
179 mask = ~(1 << irq);
180 spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
181 rm200_cached_irq_mask &= mask;
182 if (irq & 8)
183 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
184 else
185 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
186 spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
187}
188
189static inline int sni_rm200_i8259A_irq_real(unsigned int irq)
190{
191 int value;
192 int irqmask = 1 << irq;
193
194 if (irq < 8) {
195 writeb(0x0B, rm200_pic_master + PIC_CMD);
196 value = readb(rm200_pic_master + PIC_CMD) & irqmask;
197 writeb(0x0A, rm200_pic_master + PIC_CMD);
198 return value;
199 }
200 writeb(0x0B, rm200_pic_slave + PIC_CMD); /* ISR register */
201 value = readb(rm200_pic_slave + PIC_CMD) & (irqmask >> 8);
202 writeb(0x0A, rm200_pic_slave + PIC_CMD);
203 return value;
204}
205
206/*
207 * Careful! The 8259A is a fragile beast, it pretty
208 * much _has_ to be done exactly like this (mask it
209 * first, _then_ send the EOI, and the order of EOI
210 * to the two 8259s is important!
211 */
212void sni_rm200_mask_and_ack_8259A(unsigned int irq)
213{
214 unsigned int irqmask;
215 unsigned long flags;
216
217 irq -= RM200_I8259A_IRQ_BASE;
218 irqmask = 1 << irq;
219 spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
220 /*
221 * Lightweight spurious IRQ detection. We do not want
222 * to overdo spurious IRQ handling - it's usually a sign
223 * of hardware problems, so we only do the checks we can
224 * do without slowing down good hardware unnecessarily.
225 *
226 * Note that IRQ7 and IRQ15 (the two spurious IRQs
227 * usually resulting from the 8259A-1|2 PICs) occur
228 * even if the IRQ is masked in the 8259A. Thus we
229 * can check spurious 8259A IRQs without doing the
230 * quite slow i8259A_irq_real() call for every IRQ.
231 * This does not cover 100% of spurious interrupts,
232 * but should be enough to warn the user that there
233 * is something bad going on ...
234 */
235 if (rm200_cached_irq_mask & irqmask)
236 goto spurious_8259A_irq;
237 rm200_cached_irq_mask |= irqmask;
238
239handle_real_irq:
240 if (irq & 8) {
241 readb(rm200_pic_slave + PIC_IMR);
242 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
243 writeb(0x60+(irq & 7), rm200_pic_slave + PIC_CMD);
244 writeb(0x60+PIC_CASCADE_IR, rm200_pic_master + PIC_CMD);
245 } else {
246 readb(rm200_pic_master + PIC_IMR);
247 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
248 writeb(0x60+irq, rm200_pic_master + PIC_CMD);
249 }
250 spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
251 return;
252
253spurious_8259A_irq:
254 /*
255 * this is the slow path - should happen rarely.
256 */
257 if (sni_rm200_i8259A_irq_real(irq))
258 /*
259 * oops, the IRQ _is_ in service according to the
260 * 8259A - not spurious, go handle it.
261 */
262 goto handle_real_irq;
263
264 {
265 static int spurious_irq_mask;
266 /*
267 * At this point we can be sure the IRQ is spurious,
268 * lets ACK and report it. [once per IRQ]
269 */
270 if (!(spurious_irq_mask & irqmask)) {
271 printk(KERN_DEBUG
272 "spurious RM200 8259A interrupt: IRQ%d.\n", irq);
273 spurious_irq_mask |= irqmask;
274 }
275 atomic_inc(&irq_err_count);
276 /*
277 * Theoretically we do not have to handle this IRQ,
278 * but in Linux this does not cause problems and is
279 * simpler for us.
280 */
281 goto handle_real_irq;
282 }
283}
284
285static struct irq_chip sni_rm200_i8259A_chip = {
286 .name = "RM200-XT-PIC",
287 .mask = sni_rm200_disable_8259A_irq,
288 .unmask = sni_rm200_enable_8259A_irq,
289 .mask_ack = sni_rm200_mask_and_ack_8259A,
290};
291
292/*
293 * Do the traditional i8259 interrupt polling thing. This is for the few
294 * cases where no better interrupt acknowledge method is available and we
295 * absolutely must touch the i8259.
296 */
297static inline int sni_rm200_i8259_irq(void)
298{
299 int irq;
300
301 spin_lock(&sni_rm200_i8259A_lock);
302
303 /* Perform an interrupt acknowledge cycle on controller 1. */
304 writeb(0x0C, rm200_pic_master + PIC_CMD); /* prepare for poll */
305 irq = readb(rm200_pic_master + PIC_CMD) & 7;
306 if (irq == PIC_CASCADE_IR) {
307 /*
308 * Interrupt is cascaded so perform interrupt
309 * acknowledge on controller 2.
310 */
311 writeb(0x0C, rm200_pic_slave + PIC_CMD); /* prepare for poll */
312 irq = (readb(rm200_pic_slave + PIC_CMD) & 7) + 8;
313 }
314
315 if (unlikely(irq == 7)) {
316 /*
317 * This may be a spurious interrupt.
318 *
319 * Read the interrupt status register (ISR). If the most
320 * significant bit is not set then there is no valid
321 * interrupt.
322 */
323 writeb(0x0B, rm200_pic_master + PIC_ISR); /* ISR register */
324 if (~readb(rm200_pic_master + PIC_ISR) & 0x80)
325 irq = -1;
326 }
327
328 spin_unlock(&sni_rm200_i8259A_lock);
329
330 return likely(irq >= 0) ? irq + RM200_I8259A_IRQ_BASE : irq;
331}
332
333void sni_rm200_init_8259A(void)
334{
335 unsigned long flags;
336
337 spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
338
339 writeb(0xff, rm200_pic_master + PIC_IMR);
340 writeb(0xff, rm200_pic_slave + PIC_IMR);
341
342 writeb(0x11, rm200_pic_master + PIC_CMD);
343 writeb(0, rm200_pic_master + PIC_IMR);
344 writeb(1U << PIC_CASCADE_IR, rm200_pic_master + PIC_IMR);
345 writeb(MASTER_ICW4_DEFAULT, rm200_pic_master + PIC_IMR);
346 writeb(0x11, rm200_pic_slave + PIC_CMD);
347 writeb(8, rm200_pic_slave + PIC_IMR);
348 writeb(PIC_CASCADE_IR, rm200_pic_slave + PIC_IMR);
349 writeb(SLAVE_ICW4_DEFAULT, rm200_pic_slave + PIC_IMR);
350 udelay(100); /* wait for 8259A to initialize */
351
352 writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
353 writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
354
355 spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
356}
357
358/*
359 * IRQ2 is cascade interrupt to second interrupt controller
360 */
361static struct irqaction sni_rm200_irq2 = {
362 no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL
363};
364
365static struct resource sni_rm200_pic1_resource = {
366 .name = "onboard ISA pic1",
367 .start = 0x16000020,
368 .end = 0x16000023,
369 .flags = IORESOURCE_BUSY
370};
371
372static struct resource sni_rm200_pic2_resource = {
373 .name = "onboard ISA pic2",
374 .start = 0x160000a0,
375 .end = 0x160000a3,
376 .flags = IORESOURCE_BUSY
377};
378
379/* ISA irq handler */
380static irqreturn_t sni_rm200_i8259A_irq_handler(int dummy, void *p)
381{
382 int irq;
383
384 irq = sni_rm200_i8259_irq();
385 if (unlikely(irq < 0))
386 return IRQ_NONE;
387
388 do_IRQ(irq);
389 return IRQ_HANDLED;
390}
391
392struct irqaction sni_rm200_i8259A_irq = {
393 .handler = sni_rm200_i8259A_irq_handler,
394 .name = "onboard ISA",
395 .flags = IRQF_SHARED
396};
397
398void __init sni_rm200_i8259_irqs(void)
399{
400 int i;
401
402 rm200_pic_master = ioremap_nocache(0x16000020, 4);
403 if (!rm200_pic_master)
404 return;
405 rm200_pic_slave = ioremap_nocache(0x160000a0, 4);
406 if (!rm200_pic_master) {
407 iounmap(rm200_pic_master);
408 return;
409 }
410
411 insert_resource(&iomem_resource, &sni_rm200_pic1_resource);
412 insert_resource(&iomem_resource, &sni_rm200_pic2_resource);
413
414 sni_rm200_init_8259A();
415
416 for (i = RM200_I8259A_IRQ_BASE; i < RM200_I8259A_IRQ_BASE + 16; i++)
417 set_irq_chip_and_handler(i, &sni_rm200_i8259A_chip,
418 handle_level_irq);
419
420 setup_irq(RM200_I8259A_IRQ_BASE + PIC_CASCADE_IR, &sni_rm200_irq2);
421}
422
121 423
122#define SNI_RM200_INT_STAT_REG 0xbc000000 424#define SNI_RM200_INT_STAT_REG CKSEG1ADDR(0xbc000000)
123#define SNI_RM200_INT_ENA_REG 0xbc080000 425#define SNI_RM200_INT_ENA_REG CKSEG1ADDR(0xbc080000)
124 426
125#define SNI_RM200_INT_START 24 427#define SNI_RM200_INT_START 24
126#define SNI_RM200_INT_END 28 428#define SNI_RM200_INT_END 28
@@ -181,17 +483,17 @@ void __init sni_rm200_irq_init(void)
181 483
182 * (volatile u8 *)SNI_RM200_INT_ENA_REG = 0x1f; 484 * (volatile u8 *)SNI_RM200_INT_ENA_REG = 0x1f;
183 485
486 sni_rm200_i8259_irqs();
184 mips_cpu_irq_init(); 487 mips_cpu_irq_init();
185 /* Actually we've got more interrupts to handle ... */ 488 /* Actually we've got more interrupts to handle ... */
186 for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++) 489 for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++)
187 set_irq_chip(i, &rm200_irq_type); 490 set_irq_chip(i, &rm200_irq_type);
188 sni_hwint = sni_rm200_hwint; 491 sni_hwint = sni_rm200_hwint;
189 change_c0_status(ST0_IM, IE_IRQ0); 492 change_c0_status(ST0_IM, IE_IRQ0);
190 setup_irq(SNI_RM200_INT_START + 0, &sni_isa_irq); 493 setup_irq(SNI_RM200_INT_START + 0, &sni_rm200_i8259A_irq);
494 setup_irq(SNI_RM200_INT_START + 1, &sni_isa_irq);
191} 495}
192 496
193void __init sni_rm200_init(void) 497void __init sni_rm200_init(void)
194{ 498{
195 set_io_port_base(SNI_PORT_BASE + 0x02000000);
196 ioport_resource.end += 0x02000000;
197} 499}
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
index e8b26bdee24c..5484e1c62054 100644
--- a/arch/mips/sni/setup.c
+++ b/arch/mips/sni/setup.c
@@ -19,11 +19,17 @@
19#include <asm/sgialib.h> 19#include <asm/sgialib.h>
20#endif 20#endif
21 21
22#ifdef CONFIG_SNIPROM
23#include <asm/mipsprom.h>
24#endif
25
26#include <asm/bootinfo.h>
22#include <asm/io.h> 27#include <asm/io.h>
23#include <asm/reboot.h> 28#include <asm/reboot.h>
24#include <asm/sni.h> 29#include <asm/sni.h>
25 30
26unsigned int sni_brd_type; 31unsigned int sni_brd_type;
32EXPORT_SYMBOL(sni_brd_type);
27 33
28extern void sni_machine_restart(char *command); 34extern void sni_machine_restart(char *command);
29extern void sni_machine_power_off(void); 35extern void sni_machine_power_off(void);
@@ -47,20 +53,152 @@ static void __init sni_display_setup(void)
47#endif 53#endif
48} 54}
49 55
56static void __init sni_console_setup(void)
57{
58#ifndef CONFIG_ARC
59 char *ctype;
60 char *cdev;
61 char *baud;
62 int port;
63 static char options[8];
64
65 cdev = prom_getenv("console_dev");
66 if (strncmp(cdev, "tty", 3) == 0) {
67 ctype = prom_getenv("console");
68 switch (*ctype) {
69 default:
70 case 'l':
71 port = 0;
72 baud = prom_getenv("lbaud");
73 break;
74 case 'r':
75 port = 1;
76 baud = prom_getenv("rbaud");
77 break;
78 }
79 if (baud)
80 strcpy(options, baud);
81 if (strncmp(cdev, "tty552", 6) == 0)
82 add_preferred_console("ttyS", port,
83 baud ? options : NULL);
84 else
85 add_preferred_console("ttySC", port,
86 baud ? options : NULL);
87 }
88#endif
89}
90
91#ifdef DEBUG
92static void __init sni_idprom_dump(void)
93{
94 int i;
95
96 pr_debug("SNI IDProm dump:\n");
97 for (i = 0; i < 256; i++) {
98 if (i%16 == 0)
99 pr_debug("%04x ", i);
100
101 printk("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i));
102
103 if (i % 16 == 15)
104 printk("\n");
105 }
106}
107#endif
50 108
51void __init plat_mem_setup(void) 109void __init plat_mem_setup(void)
52{ 110{
111 int cputype;
112
53 set_io_port_base(SNI_PORT_BASE); 113 set_io_port_base(SNI_PORT_BASE);
54// ioport_resource.end = sni_io_resource.end; 114// ioport_resource.end = sni_io_resource.end;
55 115
56 /* 116 /*
57 * Setup (E)ISA I/O memory access stuff 117 * Setup (E)ISA I/O memory access stuff
58 */ 118 */
59 isa_slot_offset = 0xb0000000; 119 isa_slot_offset = CKSEG1ADDR(0xb0000000);
60#ifdef CONFIG_EISA 120#ifdef CONFIG_EISA
61 EISA_bus = 1; 121 EISA_bus = 1;
62#endif 122#endif
63 123
124 sni_brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
125 cputype = *(unsigned char *)SNI_IDPROM_CPUTYPE;
126 switch (sni_brd_type) {
127 case SNI_BRD_TOWER_OASIC:
128 switch (cputype) {
129 case SNI_CPU_M8030:
130 system_type = "RM400-330";
131 break;
132 case SNI_CPU_M8031:
133 system_type = "RM400-430";
134 break;
135 case SNI_CPU_M8037:
136 system_type = "RM400-530";
137 break;
138 case SNI_CPU_M8034:
139 system_type = "RM400-730";
140 break;
141 default:
142 system_type = "RM400-xxx";
143 break;
144 }
145 break;
146 case SNI_BRD_MINITOWER:
147 switch (cputype) {
148 case SNI_CPU_M8021:
149 case SNI_CPU_M8043:
150 system_type = "RM400-120";
151 break;
152 case SNI_CPU_M8040:
153 system_type = "RM400-220";
154 break;
155 case SNI_CPU_M8053:
156 system_type = "RM400-225";
157 break;
158 case SNI_CPU_M8050:
159 system_type = "RM400-420";
160 break;
161 default:
162 system_type = "RM400-xxx";
163 break;
164 }
165 break;
166 case SNI_BRD_PCI_TOWER:
167 system_type = "RM400-Cxx";
168 break;
169 case SNI_BRD_RM200:
170 system_type = "RM200-xxx";
171 break;
172 case SNI_BRD_PCI_MTOWER:
173 system_type = "RM300-Cxx";
174 break;
175 case SNI_BRD_PCI_DESKTOP:
176 switch (read_c0_prid() & 0xff00) {
177 case PRID_IMP_R4600:
178 case PRID_IMP_R4700:
179 system_type = "RM200-C20";
180 break;
181 case PRID_IMP_R5000:
182 system_type = "RM200-C40";
183 break;
184 default:
185 system_type = "RM200-Cxx";
186 break;
187 }
188 break;
189 case SNI_BRD_PCI_TOWER_CPLUS:
190 system_type = "RM400-Exx";
191 break;
192 case SNI_BRD_PCI_MTOWER_CPLUS:
193 system_type = "RM300-Exx";
194 break;
195 }
196 pr_debug("Found SNI brdtype %02x name %s\n", sni_brd_type, system_type);
197
198#ifdef DEBUG
199 sni_idprom_dump();
200#endif
201
64 switch (sni_brd_type) { 202 switch (sni_brd_type) {
65 case SNI_BRD_10: 203 case SNI_BRD_10:
66 case SNI_BRD_10NEW: 204 case SNI_BRD_10NEW:
@@ -89,9 +227,10 @@ void __init plat_mem_setup(void)
89 pm_power_off = sni_machine_power_off; 227 pm_power_off = sni_machine_power_off;
90 228
91 sni_display_setup(); 229 sni_display_setup();
230 sni_console_setup();
92} 231}
93 232
94#if CONFIG_PCI 233#ifdef CONFIG_PCI
95 234
96#include <linux/pci.h> 235#include <linux/pci.h>
97#include <video/vga.h> 236#include <video/vga.h>
diff --git a/arch/mips/sni/sniprom.c b/arch/mips/sni/sniprom.c
deleted file mode 100644
index eff4b89d7b75..000000000000
--- a/arch/mips/sni/sniprom.c
+++ /dev/null
@@ -1,251 +0,0 @@
1/*
2 * Big Endian PROM code for SNI RM machines
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) 2005-2006 Florian Lohoff (flo@rfc822.org)
9 * Copyright (C) 2005-2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
10 */
11
12#define DEBUG
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/string.h>
17#include <linux/console.h>
18
19#include <asm/addrspace.h>
20#include <asm/sni.h>
21#include <asm/mipsprom.h>
22#include <asm/mipsregs.h>
23#include <asm/bootinfo.h>
24
25/* special SNI prom calls */
26/*
27 * This does not exist in all proms - SINIX compares
28 * the prom env variable "version" against "2.0008"
29 * or greater. If lesser it tries to probe interesting
30 * registers
31 */
32#define PROM_GET_MEMCONF 58
33
34#define PROM_VEC (u64 *)CKSEG1ADDR(0x1fc00000)
35#define PROM_ENTRY(x) (PROM_VEC + (x))
36
37
38static int *(*__prom_putchar)(int) = (int *(*)(int))PROM_ENTRY(PROM_PUTCHAR);
39
40void prom_putchar(char c)
41{
42 __prom_putchar(c);
43}
44
45static char *(*__prom_getenv)(char *) = (char *(*)(char *))PROM_ENTRY(PROM_GETENV);
46static void (*__prom_get_memconf)(void *) = (void (*)(void *))PROM_ENTRY(PROM_GET_MEMCONF);
47
48char *prom_getenv(char *s)
49{
50 return __prom_getenv(s);
51}
52
53void __init prom_free_prom_memory(void)
54{
55}
56
57/*
58 * /proc/cpuinfo system type
59 *
60 */
61static const char *systype = "Unknown";
62const char *get_system_type(void)
63{
64 return systype;
65}
66
67#define SNI_IDPROM_BASE 0xbff00000
68#define SNI_IDPROM_MEMSIZE (SNI_IDPROM_BASE+0x28) /* Memsize in 16MB quantities */
69#define SNI_IDPROM_BRDTYPE (SNI_IDPROM_BASE+0x29) /* Board Type */
70#define SNI_IDPROM_CPUTYPE (SNI_IDPROM_BASE+0x30) /* CPU Type */
71
72#define SNI_IDPROM_SIZE 0x1000
73
74#ifdef DEBUG
75static void __init sni_idprom_dump(void)
76{
77 int i;
78
79 pr_debug("SNI IDProm dump:\n");
80 for (i = 0; i < 256; i++) {
81 if (i%16 == 0)
82 pr_debug("%04x ", i);
83
84 printk("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i));
85
86 if (i % 16 == 15)
87 printk("\n");
88 }
89}
90#endif
91
92static void __init sni_mem_init(void )
93{
94 int i, memsize;
95 struct membank {
96 u32 size;
97 u32 base;
98 u32 size2;
99 u32 pad1;
100 u32 pad2;
101 } memconf[8];
102
103 /* MemSIZE from prom in 16MByte chunks */
104 memsize = *((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
105
106 pr_debug("IDProm memsize: %lu MByte\n", memsize);
107
108 /* get memory bank layout from prom */
109 __prom_get_memconf(&memconf);
110
111 pr_debug("prom_get_mem_conf memory configuration:\n");
112 for (i = 0;i < 8 && memconf[i].size; i++) {
113 if (sni_brd_type == SNI_BRD_PCI_TOWER ||
114 sni_brd_type == SNI_BRD_PCI_TOWER_CPLUS) {
115 if (memconf[i].base >= 0x20000000 &&
116 memconf[i].base < 0x30000000) {
117 memconf[i].base -= 0x20000000;
118 }
119 }
120 pr_debug("Bank%d: %08x @ %08x\n", i,
121 memconf[i].size, memconf[i].base);
122 add_memory_region(memconf[i].base, memconf[i].size, BOOT_MEM_RAM);
123 }
124}
125
126static void __init sni_console_setup(void)
127{
128 char *ctype;
129 char *cdev;
130 char *baud;
131 int port;
132 static char options[8];
133
134 cdev = prom_getenv("console_dev");
135 if (strncmp (cdev, "tty", 3) == 0) {
136 ctype = prom_getenv("console");
137 switch (*ctype) {
138 default:
139 case 'l':
140 port = 0;
141 baud = prom_getenv("lbaud");
142 break;
143 case 'r':
144 port = 1;
145 baud = prom_getenv("rbaud");
146 break;
147 }
148 if (baud)
149 strcpy(options, baud);
150 if (strncmp (cdev, "tty552", 6) == 0)
151 add_preferred_console("ttyS", port, baud ? options : NULL);
152 else
153 add_preferred_console("ttySC", port, baud ? options : NULL);
154 }
155}
156
157void __init prom_init(void)
158{
159 int argc = fw_arg0;
160 char **argv = (void *)fw_arg1;
161 int i;
162 int cputype;
163
164 sni_brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
165 cputype = *(unsigned char *)SNI_IDPROM_CPUTYPE;
166 switch (sni_brd_type) {
167 case SNI_BRD_TOWER_OASIC:
168 switch (cputype) {
169 case SNI_CPU_M8030:
170 systype = "RM400-330";
171 break;
172 case SNI_CPU_M8031:
173 systype = "RM400-430";
174 break;
175 case SNI_CPU_M8037:
176 systype = "RM400-530";
177 break;
178 case SNI_CPU_M8034:
179 systype = "RM400-730";
180 break;
181 default:
182 systype = "RM400-xxx";
183 break;
184 }
185 break;
186 case SNI_BRD_MINITOWER:
187 switch (cputype) {
188 case SNI_CPU_M8021:
189 case SNI_CPU_M8043:
190 systype = "RM400-120";
191 break;
192 case SNI_CPU_M8040:
193 systype = "RM400-220";
194 break;
195 case SNI_CPU_M8053:
196 systype = "RM400-225";
197 break;
198 case SNI_CPU_M8050:
199 systype = "RM400-420";
200 break;
201 default:
202 systype = "RM400-xxx";
203 break;
204 }
205 break;
206 case SNI_BRD_PCI_TOWER:
207 systype = "RM400-Cxx";
208 break;
209 case SNI_BRD_RM200:
210 systype = "RM200-xxx";
211 break;
212 case SNI_BRD_PCI_MTOWER:
213 systype = "RM300-Cxx";
214 break;
215 case SNI_BRD_PCI_DESKTOP:
216 switch (read_c0_prid() & 0xff00) {
217 case PRID_IMP_R4600:
218 case PRID_IMP_R4700:
219 systype = "RM200-C20";
220 break;
221 case PRID_IMP_R5000:
222 systype = "RM200-C40";
223 break;
224 default:
225 systype = "RM200-Cxx";
226 break;
227 }
228 break;
229 case SNI_BRD_PCI_TOWER_CPLUS:
230 systype = "RM400-Exx";
231 break;
232 case SNI_BRD_PCI_MTOWER_CPLUS:
233 systype = "RM300-Exx";
234 break;
235 }
236 pr_debug("Found SNI brdtype %02x name %s\n", sni_brd_type, systype);
237
238#ifdef DEBUG
239 sni_idprom_dump();
240#endif
241 sni_mem_init();
242 sni_console_setup();
243
244 /* copy prom cmdline parameters to kernel cmdline */
245 for (i = 1; i < argc; i++) {
246 strcat(arcs_cmdline, argv[i]);
247 if (i < (argc - 1))
248 strcat(arcs_cmdline, " ");
249 }
250}
251
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c
index 6f339af08d22..796e3ce28720 100644
--- a/arch/mips/sni/time.c
+++ b/arch/mips/sni/time.c
@@ -178,6 +178,7 @@ void __init plat_time_init(void)
178 sni_a20r_timer_setup(); 178 sni_a20r_timer_setup();
179 break; 179 break;
180 } 180 }
181 setup_pit_timer();
181} 182}
182 183
183unsigned long read_persistent_clock(void) 184unsigned long read_persistent_clock(void)