This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / arch / ppc / platforms / dmv182.c
1 /*
2  * arch/ppc/platforms/dmv182p.c
3  * Setup code for the Dy-4 SVME/DMV-182
4  *
5  * Copyright (C) 2004 TimeSys Corporation
6  * Copyright (C) 2004 Red Hat, Inc.
7  *
8  * Original 2.4 port by Scott Wood <scott.wood@timesys.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  */
14
15 #include <linux/config.h>
16 #include <linux/init.h>
17 #include <linux/pci.h>
18 #include <linux/irq.h>
19 #include <linux/interrupt.h>
20 #include <linux/initrd.h>
21 #include <linux/root_dev.h>
22 #include <linux/delay.h>
23
24 #include <asm/serial.h>
25 #include <asm/bootinfo.h>
26 #include <asm/machdep.h>
27 #include <asm/io.h>
28 #include <asm/pgtable.h>
29 #include <asm/mv64x60.h>
30 #include <asm/processor.h>
31 #include <asm/time.h>
32 #include <asm/atomic.h>
33 #include <asm/bitops.h>
34 #include <asm/todc.h>
35 #include <linux/tty.h>  /* for linux/serial_core.h */
36 #include <linux/serial.h>
37 #include <linux/serial_core.h>
38
39 #include "dmv182.h"
40
41 extern int mv64360_get_irq(struct pt_regs *regs);
42 extern void mv64360_init_irq(void);
43
44 extern void gen550_progress(char *s, unsigned short hex);
45 extern void gen550_init(int, struct uart_port *);
46
47 static void __init dmv182_setup_peripherals(void);
48 static void __init dmv182_setup_bridge(void);
49
50 static struct mv64x60_handle bh;
51
52 TODC_ALLOC();
53
54 static void __init dmv182_map_io(void)
55 {
56         io_block_mapping((unsigned long)dmv182_board_io_virt,
57                          dmv182_board_io_phys, 0x10000000, _PAGE_IO);
58 }
59
60 // This sets up BAT3 to cover the serial port and Discovery chip.
61
62 static void __init dmv182_setup_bats(void)
63 {
64         int tmp1, tmp2;
65
66         asm volatile("lis %0, 0xe000;"
67                      "ori %0, %0, 0x002a;"
68                      "lis %1, 0xf000;"
69                      "ori %1, %1, 0x1ffe;"
70                      "mtspr %2, %0;"
71                      "mtspr %3, %1"
72                    : "=r" (tmp1), "=r" (tmp2)
73                    : "i" (DBAT3L), "i" (DBAT3U)
74                    : "memory");
75 }
76
77 static u8 *const irqstat = dmv182_fpga_io + 0x80;
78 static u8 *const irqmask = dmv182_fpga_io + 0x81;
79
80 // These two functions transform an IRQ number into
81 // byte and bit indices into the above arrays.
82
83 static inline int irqreg(unsigned int irq)
84 {
85         return ((irq - 96) >> 3) * 3;
86 }
87
88 static inline int irqbit(unsigned int irq)
89 {
90         return (irq - 96) & 7;
91 }
92
93 // FIXME: CPU1 and affinity support
94 // The Marvell code doesn't appear to support anything
95 // other than doorbells on CPU1 at the moment.
96
97 static void dmv182_mask_irq(unsigned int irq)
98 {
99         irqmask[irqreg(irq)] &= ~(1 << irqbit(irq));
100 }
101
102 static void dmv182_unmask_irq(unsigned int irq)
103 {
104         irqmask[irqreg(irq)] |= 1 << irqbit(irq);
105 }
106
107 static unsigned int dmv182_startup_irq(unsigned int irq)
108 {
109         dmv182_unmask_irq(irq);
110         return 0;
111 }
112
113 struct hw_interrupt_type dmv182_pic = {
114         .typename     = " DMV182_PIC ",
115         .startup      = dmv182_startup_irq,
116         .shutdown     = dmv182_mask_irq,
117         .enable       = dmv182_unmask_irq,
118         .disable      = dmv182_mask_irq,
119         .ack          = dmv182_mask_irq,
120         .end          = dmv182_unmask_irq,
121         .set_affinity = NULL
122 };
123
124 atomic_t spurious_interrupts;
125
126 static irqreturn_t dmv182_cascade(int irq, void *dev_id, struct pt_regs *regs)
127 {
128         int i, j;
129         int cpu = smp_processor_id();
130         int irqs;
131
132         for (i = 0, j = 96; i < 24; i += 3, j += 8) {
133                 irqs = irqstat[i] & irqmask[i + cpu];
134                 
135                 if (irqs)
136                         break;
137         }
138         
139         if (i < 24) {
140                 ppc_irq_dispatch_handler(regs, j + ffs(irqs) - 1);
141                 return IRQ_HANDLED;
142         }
143
144         atomic_inc(&spurious_interrupts);
145         return IRQ_NONE;
146 }
147
148 #ifdef CONFIG_SMP
149 static irqreturn_t dmv182_doorbell(int irq, void *dev_id, struct pt_regs *regs);
150 #endif
151
152 static void __init dmv182_init_irq(void)
153 {
154         int i;
155
156         if (ppc_md.progress)
157                 ppc_md.progress("dmv182_init_irq", 0x1821);
158         
159         for (i = 96; i < 160; i++) {
160                 dmv182_mask_irq(i);
161                 irqmask[irqreg(i) + 1] &= ~(1 << irqbit(i));
162                 irq_desc[i].handler = &dmv182_pic;
163                 irq_desc[i].status = IRQ_LEVEL | IRQ_DISABLED;
164         }
165         
166         mv64360_init_irq();
167         
168         if (request_irq(94, dmv182_cascade, SA_INTERRUPT,
169                         "DMV182 CPU0 cascade", NULL) < 0)
170         {
171                 panic("Could not request CPU0 cascade IRQ\n");
172         }
173
174 #ifdef CONFIG_SMP
175 #if 0
176         if (request_irq(95, dmv182_cascade, SA_INTERRUPT,
177                         "DMV182 CPU1 cascade", NULL) < 0)
178         {
179                 panic("Could not request CPU1 cascade IRQ\n");
180         }
181 #endif
182
183         if (request_irq(60, dmv182_doorbell, SA_INTERRUPT,
184                         "CPU0 doorbell", NULL) < 0)
185         {
186                 panic("Could not request CPU1 doorbell IRQ\n");
187         }
188
189         if (request_irq(28, dmv182_doorbell, SA_INTERRUPT,
190                         "CPU1 doorbell", NULL) < 0)
191         {
192                 panic("Could not request CPU1 doorbell IRQ\n");
193         }
194         
195         // Clear and unmask all doorbell interrupts.
196         
197         mv64x60_write(&bh, MV64360_CPU0_DOORBELL_CLR, 0xff);
198         mv64x60_write(&bh, MV64360_CPU1_DOORBELL_CLR, 0xff);
199         mv64x60_write(&bh, MV64360_CPU0_DOORBELL_MASK, 0xff);
200         mv64x60_write(&bh, MV64360_CPU1_DOORBELL_MASK, 0xff);
201 #endif
202 }
203
204 // It's really device numbers, not idsels, but we have
205 // to call it that so the PCI_IRQ_TABLE_LOOKUP will work.
206
207 static int __init dmv182_map_irq(struct pci_dev *dev,
208                                   unsigned char idsel,
209                                   unsigned char pin)
210 {
211         struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
212
213 #if 0
214         printk("map irq: hose %d, bus %d, slot %d, first %d\n", hose->index,
215                dev->bus->number, idsel, hose->first_busno);
216 #endif
217
218         if (hose->index != 0 && hose->index != 1) {
219                 printk(KERN_ERR "map_irq: unknown hose %d\n", hose->index);
220                 return 0;
221         }
222         
223         // Some of this is guesswork...
224         // In particular, I don't know if the ABCD mappings are right,
225         // and I don't know which IPM goes with which slot (the manual
226         // merely says "IPM" for both).
227
228         if (hose->index == 0) {
229                 static u8 pci_irq_table[][4] = 
230                 /*
231                  * PCI IDSEL/INTPIN->INTLINE
232                  *  A   B   C   D
233                  */
234                 {
235                         { DMV182_IRQ_PMC1A, DMV182_IRQ_PMC1B,
236                           DMV182_IRQ_PMC1C, DMV182_IRQ_PMC1D }, // PMC Slot 1 A
237                         { DMV182_IRQ_PMC1A, DMV182_IRQ_PMC1B,
238                           DMV182_IRQ_PMC1C, DMV182_IRQ_PMC1D }, // PMC Slot 1 B
239                 };
240                 
241                 const int min_idsel = 4, max_idsel = 5, irqs_per_slot = 4;
242                 return PCI_IRQ_TABLE_LOOKUP;
243         } else if (dev->bus->parent && dev->bus->primary == hose->first_busno &&
244                    dev->bus->self->devfn == 0x10) {
245                 static u8 pci_irq_table[][4] = 
246                 /*
247                  * PCI IDSEL/INTPIN->INTLINE
248                  *  A   B   C   D
249                  */
250                 {
251                         { DMV182_IRQ_IPM0, DMV182_IRQ_IPM0,
252                           DMV182_IRQ_IPM0, DMV182_IRQ_IPM0 }, // IPM... 0?
253                         { DMV182_IRQ_IPM1, DMV182_IRQ_IPM1,
254                           DMV182_IRQ_IPM1, DMV182_IRQ_IPM1 }, // IPM... 1?
255                         { DMV182_IRQ_USB_A, DMV182_IRQ_USB_B,
256                           DMV182_IRQ_USB_C, DMV182_IRQ_USB_SMI }, // USB
257                         { DMV182_IRQ_VME_CPU0, DMV182_IRQ_VME_CPU1, 0, 0 }, // VME
258                 };
259                 
260                 const int min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
261                 return PCI_IRQ_TABLE_LOOKUP;
262         } else {
263                 static u8 pci_irq_table[][4] = 
264                 /*
265                  * PCI IDSEL/INTPIN->INTLINE
266                  *  A   B   C   D
267                  */
268                 {
269                         { DMV182_IRQ_PMC2A, DMV182_IRQ_PMC2B,
270                           DMV182_IRQ_PMC2C, DMV182_IRQ_PMC2D }, // PMC Slot 2 A
271                         { DMV182_IRQ_PMC2A, DMV182_IRQ_PMC2B,
272                           DMV182_IRQ_PMC2C, DMV182_IRQ_PMC2D }, // PMC Slot 2 B
273                 };
274                 
275                 const int min_idsel = 4, max_idsel = 5, irqs_per_slot = 4;
276                 return PCI_IRQ_TABLE_LOOKUP;
277         }
278 }
279
280 static unsigned char dmv182_pci_swizzle(struct pci_dev *dev,
281                                          unsigned char *pinp)
282 {
283         struct pci_controller *hose = dev->sysdata;
284
285         // The devices under this particular bridge have their IRQs
286         // directly routed to the PIC, rather than through the parent
287         // bus.  Thus, don't swizzle them.  The bus is determined by
288         // the devfn of the parent, rather than its own bus number,
289         // in case a PMC card is added that has its own bridge(s),
290         // causing the numbering to change.
291         
292         if (hose->index == 1 && dev->bus->parent &&
293             dev->bus->primary == hose->first_busno &&
294             dev->bus->self->devfn == 0x10)
295                 return PCI_SLOT(dev->devfn);
296         
297         return common_swizzle(dev, pinp);
298 }
299
300 static unsigned long __init
301 dmv182_pci_bridge_reserve_space(struct pci_controller *hose,
302                                  unsigned char bus, unsigned char devfn)
303 {
304         // Reserve 768 MiB for the bus containing VME.  This
305         // will allow one to map the entire RAM of a 512 MiB
306         // card over VME, while still allowing space for other
307         // stuff on the bridge.
308         if (hose->first_busno == bus && devfn == 0x10)
309                 return 0x30000000;
310         
311         return 0;
312 }
313
314 static void __init dmv182_setup_caches(void)
315 {
316 #if 0 // This actually causes the TimeSys 2.4 port to blow up too, for me 
317
318         // Why can't L2CR be set by generic 745x code?
319         // And what's with the underscore?
320         _set_L2CR(0xc0000000);
321
322         _set_L3CR(0x9e8a0180);
323 #endif
324 }
325
326 #ifdef CONFIG_SERIAL_8250
327 static void __init dmv182_early_serial_map(void)
328 {
329         struct uart_port uart_req;
330         void *membase = ioremap(0xe0010000, PAGE_SIZE);
331
332         /* Setup serial port access */
333         memset(&uart_req, 0, sizeof (uart_req));
334         uart_req.irq = DMV182_IRQ_SERIAL_CH1;
335         uart_req.flags = 0;
336         uart_req.type = PORT_16550;
337         uart_req.uartclk = BASE_BAUD * 16;
338         uart_req.iotype = SERIAL_IO_MEM;
339         uart_req.mapbase = (unsigned long)dmv182_fpga_io + 0x18;
340         uart_req.membase = membase + 0x18;
341
342 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
343         gen550_init(0, &uart_req);
344 #endif
345
346         if (early_serial_setup(&uart_req) != 0)
347                 printk("Early serial init of port 0 failed\n");
348
349         /* Assume early_serial_setup() doesn't modify uart_req */
350         uart_req.line = 1;
351         uart_req.mapbase = (unsigned long)dmv182_fpga_io + 0x20;
352         uart_req.membase = membase + 0x20;
353         uart_req.irq = DMV182_IRQ_SERIAL_CH2;
354
355 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
356         gen550_init(1, &uart_req);
357 #endif
358
359         if (early_serial_setup(&uart_req) != 0)
360                 printk("Early serial init of port 1 failed\n");
361 }
362 #endif
363
364 static void __init dmv182_setup_arch(void)
365 {
366         if (ppc_md.progress)
367                 ppc_md.progress("dmv182_setup_arch", 0x1820);
368
369         ppc_md.pci_swizzle = dmv182_pci_swizzle;
370
371         dmv182_setup_caches();
372
373         // Enable snooping.
374 //      MV_SET_REG_BITS(MV64360_CPU_MASTER_CONTROL, (1 << 12) | (1 << 13));
375
376         // Set up the RTC.
377         dmv182_setup_bridge();
378         dmv182_setup_peripherals();
379
380 #ifdef CONFIG_SERIAL_8250
381         dmv182_early_serial_map();
382 #endif
383         if (ppc_md.progress)
384                 ppc_md.progress("dmv182_setup_arch end", 0x182f);
385 }
386
387 static void __init dmv182_calibrate_decr(void)
388 {
389         if (ppc_md.progress)
390                 ppc_md.progress("dmv182_calibrate_decr", 0x1822);
391         
392         tb_ticks_per_jiffy = 25000000 / HZ;
393         tb_to_us = mulhwu_scale_factor(25000000, 1000000);
394 }
395
396 static void dmv182_halt(void)
397 {
398         local_irq_disable();
399         for(;;);
400 }
401
402 static void dmv182_restart(char *cmd)
403 {
404         unsigned long reg;
405         volatile unsigned long *ptr = NULL;
406         struct pci_dev *dev;
407
408         local_irq_disable();
409
410         /* 
411          * The best way to reset the board is through the Universe VME. 
412          * Since the VME driver may or may not be loaded, we can't rely
413          * on that, so the best way I can think of in resetting the board
414          * is to search all the PCI devices looking for the Universe chip 
415          * and write to its command register to reset the board.
416          */
417         dev = pci_find_device(PCI_VENDOR_ID_TUNDRA, 0, NULL);
418         if (dev) {
419                 printk("Found VME device %s\n",dev->slot_name);
420
421                 for (reg = 0; reg < 6; reg++) {
422                         struct resource *res = dev->resource + reg;
423                         if ((res->flags & PCI_BASE_ADDRESS_SPACE) ==
424                             PCI_BASE_ADDRESS_SPACE_MEMORY) {
425                                 ptr = ioremap(res->start + 0x404, sizeof(ptr)); /* CTRL_REG */
426                                 break;
427                         }
428                 }
429         }
430
431         if (!ptr) {
432                 printk("No VME device found to reset board\n");
433                 return;
434         }
435
436         printk("**** resetting board through VME ****\n");
437         mdelay(10);
438
439         reg = *ptr;
440         reg |= 0x8000; /* reset only the board and not the entire chassis. */
441         *ptr = reg;
442
443         for(;;);
444 }
445
446 void board_get_mac(int port, u8 *addr)
447 {
448         if (port < 1 || port > 2) {
449                 printk(KERN_ERR "Unknown port %d in board_get_mac()...\n", port);
450                 return;
451         }
452         
453         memcpy(addr, (u8 *)dmv182_nvram + 8 + (2 - port) * 6, 6);
454         printk(KERN_NOTICE "Ethernet port %d MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
455                port, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
456 }
457
458 #ifdef CONFIG_SMP
459
460 static int dmv182_smp_probe(void)
461 {
462         return 2;
463 }
464
465 void __secondary_start(void);
466
467 static void dmv182_kick_cpu(int cpu)
468 {
469         BUG_ON(cpu != 1);
470
471         *(u32 *)(PAGE_OFFSET + 4) = (u32)__secondary_start - PAGE_OFFSET;
472         wmb();
473         *(u32 *)(PAGE_OFFSET + 0) = 0x38a3fd19;
474         wmb();
475
476         /* Set MaskBR1 to allow CPU1 to get access to the bus. */
477         mv64x60_modify(&bh, MV64x60_CPU_MASTER_CNTL, 0, 1<<9);
478 }
479
480 static void dmv182_setup_cpu(int cpu)
481 {
482         int whoami = mv64x60_read(&bh, MV64360_WHO_AM_I);
483         
484         if (cpu != whoami) {
485                 printk("CPU %d whoami %d\n", cpu, whoami);
486                 BUG();
487         }
488
489         // Enable broadcasting of synchronization and cache/tlb
490         // flushing/invalidation instructions
491         
492         mtspr(SPRN_HID1, mfspr(SPRN_HID1) | HID1_ABE | HID1_SYNCBE);
493         asm volatile("sync; isync" : : : "memory");
494
495         if (cpu == 1)
496                 dmv182_setup_caches();
497 }
498
499 static void dmv182_message_pass(int target, int msg, ulong data, int wait)
500 {
501         int i;
502         int reg;
503         
504         if (unlikely(msg < 0 || msg > 7)) {
505                 printk(KERN_ERR "dmv182_message_pass: bad message %x\n", msg);
506                 return;
507         }
508         
509         for_each_online_cpu(i) {
510                 reg = MV64360_CPUx_DOORBELL(i);
511
512                 if (target == MSG_ALL ||
513                     (target == MSG_ALL_BUT_SELF && i != smp_processor_id()) ||
514                     target == i)
515                         mv64x60_modify(&bh, reg, 1 << msg, 1 << msg);
516         }
517 }
518
519 static irqreturn_t dmv182_doorbell(int irq, void *dev_id, struct pt_regs *regs)
520 {
521         u32 bits = mv64x60_read(&bh, MV64360_CPUx_DOORBELL(smp_processor_id()));
522
523         bits &= 0xff;
524
525         mv64x60_write(&bh, MV64360_CPU0_DOORBELL_CLR +
526                       smp_processor_id() * 0x10, bits);
527
528         while (bits) {
529                 int msg = __ilog2(bits);;
530                 smp_message_recv(msg, regs);
531                 bits &= ~(1 << msg);
532         }
533         return IRQ_HANDLED;
534 }
535
536 static struct smp_ops_t dmv182_smp_ops = {
537         .probe        = dmv182_smp_probe,
538         .kick_cpu     = dmv182_kick_cpu,
539         .setup_cpu    = dmv182_setup_cpu,
540         .message_pass = dmv182_message_pass,
541         .give_timebase = smp_generic_give_timebase,
542         .take_timebase = smp_generic_take_timebase,
543 };
544
545 #endif
546
547 static void __init dmv182_setup_bridge(void)
548 {
549         mv64x60_setup_info_t si;
550
551         memset(&si, 0, sizeof(si));
552
553         si.phys_reg_base = CONFIG_MV64X60_NEW_BASE;
554         si.map_irq = dmv182_map_irq;
555
556         si.pci_0.enable_bus = 1;
557         si.pci_0.enumerate_bus = 1;
558         si.pci_0.pci_io.cpu_base = 0xa0000000;
559         si.pci_0.pci_io.pci_base_hi = 0;
560         si.pci_0.pci_io.pci_base_lo = 0;
561         si.pci_0.pci_io.size = 0x01000000;
562         si.pci_0.pci_io.swap = 0x01000000; /* XXXX No swapping */
563         si.pci_0.pci_mem[0].cpu_base = 0x80000000;
564         si.pci_0.pci_mem[0].pci_base_hi = 0;
565         si.pci_0.pci_mem[0].pci_base_lo = 0x80000000;
566         si.pci_0.pci_mem[0].size = 0x10000000;
567         si.pci_0.pci_mem[0].swap = 0x01000000; /* XXXX No swapping */
568         si.pci_0.pci_mem[1].cpu_base = 0;
569         si.pci_0.pci_mem[1].pci_base_hi = 0;
570         si.pci_0.pci_mem[1].pci_base_lo = 0;
571         si.pci_0.pci_mem[1].size = 0;   /* Don't use this window */
572         si.pci_0.pci_mem[1].swap = 0;
573         si.pci_0.pci_mem[2].cpu_base = 0;
574         si.pci_0.pci_mem[2].pci_base_hi = 0;
575         si.pci_0.pci_mem[2].pci_base_lo = 0;
576         si.pci_0.pci_mem[2].size = 0;   /* Don't use this window */
577         si.pci_0.pci_mem[1].swap = 0;
578         si.pci_0.pci_cmd_bits = 0;
579         si.pci_0.latency_timer = 0x8;
580
581         si.pci_1.enable_bus = 1;
582         si.pci_1.enumerate_bus = 1;
583         si.pci_1.pci_io.cpu_base = 0xa1000000;
584         si.pci_1.pci_io.pci_base_hi = 0;
585         si.pci_1.pci_io.pci_base_lo = 0x01000000;
586         si.pci_1.pci_io.size = 0x01000000;
587         si.pci_1.pci_io.swap = 0x01000000; /* XXXX No swapping */
588         si.pci_1.pci_mem[0].cpu_base = 0x90000000;
589         si.pci_1.pci_mem[0].pci_base_hi = 0;
590         si.pci_1.pci_mem[0].pci_base_lo = 0x90000000;
591         si.pci_1.pci_mem[0].size = 0x10000000;
592         si.pci_1.pci_mem[0].swap = 0x01000000; /* XXXX No swapping */
593         si.pci_1.pci_mem[1].cpu_base = 0;
594         si.pci_1.pci_mem[1].pci_base_hi = 0;
595         si.pci_1.pci_mem[1].pci_base_lo = 0;
596         si.pci_1.pci_mem[1].size = 0;   /* Don't use this window */
597         si.pci_1.pci_mem[1].swap = 0;
598         si.pci_1.pci_mem[2].cpu_base = 0;
599         si.pci_1.pci_mem[2].pci_base_hi = 0;
600         si.pci_1.pci_mem[2].pci_base_lo = 0;
601         si.pci_1.pci_mem[2].size = 0;   /* Don't use this window */
602         si.pci_1.pci_mem[1].swap = 0;
603         si.pci_1.pci_cmd_bits = 0;
604         si.pci_1.latency_timer = 0x8;
605         si.pci_1.pci_cmd_bits = 0;
606         si.pci_1.latency_timer = 0x8;
607
608         si.window_preserve_mask_32 = 0x1f0;
609 #if 0
610         for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
611                 si.cpu_prot_options[i] = 0;
612 //              si.cpu_snoop_options[i] = GT64260_CPU_SNOOP_WB;
613                 si.pci_0.acc_cntl_options[i] =
614                         /* Breaks PCI (especially slot 4)
615                         GT64260_PCI_ACC_CNTL_PREFETCHEN |
616                         */
617                         GT64260_PCI_ACC_CNTL_DREADEN |
618                         GT64260_PCI_ACC_CNTL_RDPREFETCH |
619                         GT64260_PCI_ACC_CNTL_RDLINEPREFETCH |
620                         GT64260_PCI_ACC_CNTL_RDMULPREFETCH |
621                         GT64260_PCI_ACC_CNTL_SWAP_NONE |
622                         GT64260_PCI_ACC_CNTL_MBURST_32_BTYES;
623                 si.pci_0.snoop_options[i] = GT64260_PCI_SNOOP_WB;
624                 si.pci_1.acc_cntl_options[i] =
625                         /* Breaks PCI (especially slot 4)
626                         GT64260_PCI_ACC_CNTL_PREFETCHEN |
627                         */
628                         GT64260_PCI_ACC_CNTL_DREADEN |
629                         GT64260_PCI_ACC_CNTL_RDPREFETCH |
630                         GT64260_PCI_ACC_CNTL_RDLINEPREFETCH |
631                         GT64260_PCI_ACC_CNTL_RDMULPREFETCH |
632                         GT64260_PCI_ACC_CNTL_SWAP_NONE |
633                         GT64260_PCI_ACC_CNTL_MBURST_32_BTYES;
634 //              si.pci_1.snoop_options[i] = GT64260_PCI_SNOOP_WB;
635         }
636 #endif
637
638         mv64x60_pci_exclude_bridge = 0;
639
640         /* Lookup PCI host bridges */
641         if (mv64x60_init(&bh, &si)) {
642                 printk("Bridge initialization failed.\n");
643         }
644
645         return;
646 }
647
648 static void __init dmv182_setup_peripherals(void)
649 {
650         mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN,
651                                  0xf0000000, 0x08000000, 0); // FLASH
652         mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_0_WIN,
653                                  0xe0010000, 0x10000, 0); // I/O FPGA
654         mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_1_WIN,
655                                  0xe0000000, 0x10000, 0); // EPLD
656         mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_2_WIN,
657                                  0xe0020000, 0x10000, 0); // RTC
658         mv64x60_set_32bit_window(&bh, MV64x60_CPU2DEV_3_WIN,
659                                  0xe0030000, 0x10000, 0); // NVRAM
660
661         TODC_INIT(TODC_TYPE_DS1501, 0, 0, dmv182_rtc, 8);
662 }
663
664 unsigned long __init dmv182_find_end_of_memory(void)
665 {
666 #if 0
667         return mv64x60_get_mem_size(0xfff00000 /*CONFIG_MV64X60_NEW_BASE*/,
668                                                   MV64x60_TYPE_MV64360);
669 #endif
670         /* But it dies if we enable more than 512MiB. Debug later... */
671         return 0x20000000;
672 }
673
674 void __init platform_init(unsigned long r3, unsigned long r4,
675                           unsigned long r5, unsigned long r6,
676                           unsigned long r7)
677 {
678         parse_bootinfo(find_bootinfo());
679         
680         dmv182_setup_bats();
681
682 #if defined(CONFIG_SERIAL_TEXT_DEBUG)
683         ppc_md.progress = gen550_progress;
684 #endif
685         ppc_md.setup_io_mappings = dmv182_map_io;
686         ppc_md.find_end_of_memory = dmv182_find_end_of_memory;
687         ppc_md.setup_arch = dmv182_setup_arch;
688         ppc_md.init_IRQ = dmv182_init_irq;
689         ppc_md.get_irq = mv64360_get_irq;
690         ppc_md.calibrate_decr = dmv182_calibrate_decr;
691 //      ppc_md.pci_bridge_reserve_space = dmv182_pci_bridge_reserve_space;
692         
693         ppc_md.halt = dmv182_halt;
694         ppc_md.power_off = dmv182_halt;
695         ppc_md.restart = dmv182_restart;
696 #ifdef CONFIG_SMP
697         ppc_md.smp_ops = &dmv182_smp_ops;
698 #endif
699 #ifdef CONFIG_GEN_RTC
700         ppc_md.time_init = todc_time_init;
701         ppc_md.set_rtc_time = todc_set_rtc_time;
702         ppc_md.get_rtc_time = todc_get_rtc_time;
703
704         ppc_md.nvram_read_val = todc_direct_read_val;
705         ppc_md.nvram_write_val = todc_direct_write_val;
706 #endif
707 }