1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/kernel.h>
17#include <linux/interrupt.h>
18#include <linux/init.h>
19#include <linux/ioport.h>
20#include <linux/console.h>
21#include <linux/pci.h>
22#include <linux/ide.h>
23#include <linux/seq_file.h>
24#include <linux/root_dev.h>
25
26#include <asm/system.h>
27#include <asm/io.h>
28#include <asm/pgtable.h>
29#include <asm/dma.h>
30#include <asm/machdep.h>
31#include <asm/prep_nvram.h>
32#include <asm/vga.h>
33#include <asm/i8259.h>
34#include <asm/open_pic.h>
35#include <asm/hawk.h>
36#include <asm/todc.h>
37#include <asm/bootinfo.h>
38#include <asm/kgdb.h>
39#include <asm/reg.h>
40
41#include "pplus.h"
42
43#undef DUMP_DBATS
44
45TODC_ALLOC();
46
47extern void pplus_setup_hose(void);
48extern void pplus_set_VIA_IDE_native(void);
49
50extern unsigned long loops_per_jiffy;
51unsigned char *Motherboard_map_name;
52
53
54
55
56static inline int
57mesquite_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
58{
59 static char pci_irq_table[][4] =
60
61
62
63
64
65
66 {
67 {18, 0, 0, 0},
68 { 0, 0, 0, 0},
69 {19, 19, 19, 19},
70 { 0, 0, 0, 0},
71 { 0, 0, 0, 0},
72 { 0, 0, 0, 0},
73 {24, 25, 26, 27},
74 { 0, 0, 0, 0},
75 {28, 29, 30, 31}
76 };
77
78 const long min_idsel = 14, max_idsel = 22, irqs_per_slot = 4;
79 return PCI_IRQ_TABLE_LOOKUP;
80}
81
82
83static inline int
84sitka_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
85{
86 static char pci_irq_table[][4] =
87
88
89
90
91
92
93 {
94 {18, 0, 0, 0},
95 { 0, 0, 0, 0},
96 {25, 26, 27, 28},
97 {28, 25, 26, 27},
98 { 0, 0, 0, 0},
99 { 0, 0, 0, 0},
100 {20, 0, 0, 0}
101 };
102
103 const long min_idsel = 14, max_idsel = 20, irqs_per_slot = 4;
104 return PCI_IRQ_TABLE_LOOKUP;
105}
106
107
108static inline int
109MTX_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
110{
111 static char pci_irq_table[][4] =
112
113
114
115
116
117
118 {
119 {19, 0, 0, 0},
120 { 0, 0, 0, 0},
121 {18, 0, 0, 0},
122 { 0, 0, 0, 0},
123 {25, 26, 27, 28},
124 {26, 27, 28, 25},
125 {27, 28, 25, 26}
126 };
127
128 const long min_idsel = 12, max_idsel = 18, irqs_per_slot = 4;
129 return PCI_IRQ_TABLE_LOOKUP;
130}
131
132
133
134static inline int
135MTXplus_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
136{
137 static char pci_irq_table[][4] =
138
139
140
141
142
143
144 {
145 {19, 0, 0, 0},
146 { 0, 0, 0, 0},
147 {18, 0, 0, 0},
148 { 0, 0, 0, 0},
149 {25, 26, 27, 28},
150 {26, 27, 28, 25},
151 {27, 28, 25, 26},
152 {26, 0, 0, 0},
153 { 0, 0, 0, 0}
154 };
155
156 const long min_idsel = 12, max_idsel = 20, irqs_per_slot = 4;
157 return PCI_IRQ_TABLE_LOOKUP;
158}
159
160static inline int
161Genesis2_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
162{
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196 static char pci_irq_table[][4] =
197
198
199
200
201
202
203 {
204 {19, 0, 0, 0},
205 { 0, 0, 0, 0},
206 {18, 0, 0, 0},
207 { 0, 0, 0, 0},
208 {25, 26, 27, 28},
209 {28, 25, 26, 27},
210 {27, 28, 25, 26},
211 {26, 0, 0, 0},
212 {25, 26, 27, 28}
213 };
214
215 const long min_idsel = 12, max_idsel = 20, irqs_per_slot = 4;
216 return PCI_IRQ_TABLE_LOOKUP;
217}
218
219#define MOTOROLA_CPUTYPE_REG 0x800
220#define MOTOROLA_BASETYPE_REG 0x803
221#define MPIC_RAVEN_ID 0x48010000
222#define MPIC_HAWK_ID 0x48030000
223#define MOT_PROC2_BIT 0x800
224
225static u_char pplus_openpic_initsenses[] __initdata = {
226 (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),
227 (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE),
228 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
229 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
230 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
231 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
232 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
233 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
234 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
235 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
236 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
237 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
238 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
239 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
240 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
241 (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
242};
243
244int mot_entry = -1;
245int prep_keybd_present = 1;
246int mot_multi = 0;
247
248struct brd_info {
249
250
251 int cpu_type;
252
253 int base_type;
254
255 int max_cpu;
256 const char *name;
257 int (*map_irq) (struct pci_dev *, unsigned char, unsigned char);
258};
259struct brd_info mot_info[] = {
260 {0x300, 0x00, 0x00, "MVME 2400", Genesis2_map_irq},
261 {0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)", mesquite_map_irq},
262 {0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)", sitka_map_irq},
263 {0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC", mesquite_map_irq},
264 {0x1E0, 0xF6, 0x80, "MTX Plus", MTXplus_map_irq},
265 {0x1E0, 0xF6, 0x81, "Dual MTX Plus", MTXplus_map_irq},
266 {0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port", MTX_map_irq},
267 {0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port", MTX_map_irq},
268 {0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port", MTX_map_irq},
269 {0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port", MTX_map_irq},
270 {0x1E0, 0xF9, 0x00, "MVME 2300", Genesis2_map_irq},
271 {0x1E0, 0xFA, 0x00, "MVME 2300SC/2600", Genesis2_map_irq},
272 {0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M", Genesis2_map_irq},
273 {0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761", Genesis2_map_irq},
274 {0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M", Genesis2_map_irq},
275 {0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M", Genesis2_map_irq},
276 {0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761", Genesis2_map_irq},
277 {0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761", Genesis2_map_irq},
278 {0x000, 0x00, 0x00, "", NULL}
279};
280
281void __init pplus_set_board_type(void)
282{
283 unsigned char cpu_type;
284 unsigned char base_mod;
285 int entry;
286 unsigned short devid;
287 unsigned long *ProcInfo = NULL;
288
289 cpu_type = inb(MOTOROLA_CPUTYPE_REG) & 0xF0;
290 base_mod = inb(MOTOROLA_BASETYPE_REG);
291 early_read_config_word(0, 0, 0, PCI_VENDOR_ID, &devid);
292
293 for (entry = 0; mot_info[entry].cpu_type != 0; entry++) {
294
295 if (mot_info[entry].cpu_type & 0x200) {
296 if (devid != PCI_DEVICE_ID_MOTOROLA_HAWK)
297 continue;
298 } else {
299
300 ProcInfo =
301 (unsigned long *)ioremap(PPLUS_SYS_CONFIG_REG, 4);
302
303
304 if ((mot_info[entry].cpu_type & 0xff) != cpu_type)
305 continue;
306
307 if (mot_info[entry].base_type == 0) {
308 mot_entry = entry;
309 break;
310 }
311
312 if (mot_info[entry].base_type != base_mod)
313 continue;
314 }
315
316 if (!(mot_info[entry].max_cpu & 0x80)) {
317 mot_entry = entry;
318 break;
319 }
320
321
322 if ((*ProcInfo & MOT_PROC2_BIT)
323 && !(mot_info[entry].max_cpu & 0x7f)) {
324 mot_entry = entry;
325 break;
326 }
327
328
329 if (!(*ProcInfo & MOT_PROC2_BIT)
330 && (mot_info[entry].max_cpu & 0x7f)) {
331 mot_entry = entry;
332 break;
333 }
334
335
336 if (!(*ProcInfo & MOT_PROC2_BIT))
337 mot_multi = 1;
338 }
339
340 if (mot_entry == -1)
341
342 mot_entry = 1;
343
344 Motherboard_map_name = (unsigned char *)mot_info[mot_entry].name;
345 ppc_md.pci_map_irq = mot_info[mot_entry].map_irq;
346}
347void __init pplus_pib_init(void)
348{
349 unsigned char reg;
350 unsigned short short_reg;
351
352 struct pci_dev *dev = NULL;
353
354
355
356
357
358 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
359 PCI_DEVICE_ID_VIA_82C586_1, dev))) {
360
361
362
363
364 pci_read_config_byte(dev, 0x40, ®);
365
366 reg |= 0x03;
367 pci_write_config_byte(dev, 0x40, reg);
368 }
369
370 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
371 PCI_DEVICE_ID_VIA_82C586_2,
372 dev)) && (dev->devfn = 0x5a)) {
373
374 dev->irq = 11;
375 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
376 }
377
378 if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
379 PCI_DEVICE_ID_WINBOND_83C553, dev))) {
380
381 short_reg = 0x0000;
382 pci_write_config_word(dev, 0x44, short_reg);
383
384 reg = 0xEE;
385 pci_write_config_byte(dev, 0x43, reg);
386 }
387
388 if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
389 PCI_DEVICE_ID_WINBOND_82C105, dev))) {
390
391
392
393
394 pci_write_config_dword(dev, 0x40, 0x10ff0033);
395
396
397 dev->irq = 14;
398 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
399 }
400 pci_dev_put(dev);
401}
402
403void __init pplus_set_VIA_IDE_legacy(void)
404{
405 unsigned short vend, dev;
406
407 early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_VENDOR_ID, &vend);
408 early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_DEVICE_ID, &dev);
409
410 if ((vend == PCI_VENDOR_ID_VIA) &&
411 (dev == PCI_DEVICE_ID_VIA_82C586_1)) {
412 unsigned char temp;
413
414
415 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
416 PCI_BASE_ADDRESS_0, 0x1f1);
417 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
418 PCI_BASE_ADDRESS_1, 0x3f5);
419 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
420 PCI_BASE_ADDRESS_2, 0x171);
421 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
422 PCI_BASE_ADDRESS_3, 0x375);
423 early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
424 PCI_BASE_ADDRESS_4, 0xcc01);
425
426
427 early_read_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
428 &temp);
429 temp &= ~0x05;
430 early_write_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
431 temp);
432 }
433}
434
435void pplus_set_VIA_IDE_native(void)
436{
437 unsigned short vend, dev;
438
439 early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_VENDOR_ID, &vend);
440 early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_DEVICE_ID, &dev);
441
442 if ((vend == PCI_VENDOR_ID_VIA) &&
443 (dev == PCI_DEVICE_ID_VIA_82C586_1)) {
444 unsigned char temp;
445
446
447 early_read_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
448 &temp);
449 temp |= 0x05;
450 early_write_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
451 temp);
452 }
453}
454
455void __init pplus_pcibios_fixup(void)
456{
457
458 unsigned char reg;
459 unsigned short devid;
460 unsigned char base_mod;
461
462 printk(KERN_INFO "Setting PCI interrupts for a \"%s\"\n",
463 Motherboard_map_name);
464
465
466 pplus_pib_init();
467
468
469 outb(0x09, SIO_CONFIG_RA);
470 reg = inb(SIO_CONFIG_RD);
471 reg = (reg & 0x3F) | 0x40;
472 outb(reg, SIO_CONFIG_RD);
473 outb(reg, SIO_CONFIG_RD);
474
475
476
477
478
479 early_read_config_word(0, 0, 0, PCI_VENDOR_ID, &devid);
480 base_mod = inb(MOTOROLA_BASETYPE_REG);
481 if ((devid == PCI_DEVICE_ID_MOTOROLA_HAWK) ||
482 (base_mod == 0xF9) || (base_mod == 0xFA) || (base_mod == 0xE1))
483 prep_keybd_present = 0;
484}
485
486void __init pplus_find_bridges(void)
487{
488 struct pci_controller *hose;
489
490 hose = pcibios_alloc_controller();
491 if (!hose)
492 return;
493
494 hose->first_busno = 0;
495 hose->last_busno = 0xff;
496
497 hose->pci_mem_offset = PREP_ISA_MEM_BASE;
498 hose->io_base_virt = (void *)PREP_ISA_IO_BASE;
499
500 pci_init_resource(&hose->io_resource, PPLUS_PCI_IO_START,
501 PPLUS_PCI_IO_END, IORESOURCE_IO, "PCI host bridge");
502 pci_init_resource(&hose->mem_resources[0], PPLUS_PROC_PCI_MEM_START,
503 PPLUS_PROC_PCI_MEM_END, IORESOURCE_MEM,
504 "PCI host bridge");
505
506 hose->io_space.start = PPLUS_PCI_IO_START;
507 hose->io_space.end = PPLUS_PCI_IO_END;
508 hose->mem_space.start = PPLUS_PCI_MEM_START;
509 hose->mem_space.end = PPLUS_PCI_MEM_END - HAWK_MPIC_SIZE;
510
511 if (hawk_init(hose, PPLUS_HAWK_PPC_REG_BASE, PPLUS_PROC_PCI_MEM_START,
512 PPLUS_PROC_PCI_MEM_END - HAWK_MPIC_SIZE,
513 PPLUS_PROC_PCI_IO_START, PPLUS_PROC_PCI_IO_END,
514 PPLUS_PROC_PCI_MEM_END - HAWK_MPIC_SIZE + 1)
515 != 0) {
516 printk(KERN_CRIT "Could not initialize host bridge\n");
517
518 }
519
520 pplus_set_VIA_IDE_legacy();
521
522 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
523
524 ppc_md.pcibios_fixup = pplus_pcibios_fixup;
525 ppc_md.pci_swizzle = common_swizzle;
526}
527
528static int pplus_show_cpuinfo(struct seq_file *m)
529{
530 seq_printf(m, "vendor\t\t: Motorola MCG\n");
531 seq_printf(m, "machine\t\t: %s\n", Motherboard_map_name);
532
533 return 0;
534}
535
536static void __init pplus_setup_arch(void)
537{
538 struct pci_controller *hose;
539
540 if (ppc_md.progress)
541 ppc_md.progress("pplus_setup_arch: enter", 0);
542
543
544 loops_per_jiffy = 50000000;
545
546 if (ppc_md.progress)
547 ppc_md.progress("pplus_setup_arch: find_bridges", 0);
548
549
550 pplus_find_bridges();
551
552 hose = pci_bus_to_hose(0);
553 isa_io_base = (ulong) hose->io_base_virt;
554
555 if (ppc_md.progress)
556 ppc_md.progress("pplus_setup_arch: set_board_type", 0);
557
558 pplus_set_board_type();
559
560
561 *(unsigned char *)(PPLUS_L2_CONTROL_REG) |= 3;
562
563#ifdef CONFIG_BLK_DEV_INITRD
564 if (initrd_start)
565 ROOT_DEV = Root_RAM0;
566 else
567#endif
568#ifdef CONFIG_ROOT_NFS
569 ROOT_DEV = Root_NFS;
570#else
571 ROOT_DEV = Root_SDA2;
572#endif
573
574 printk(KERN_INFO "Motorola PowerPlus Platform\n");
575 printk(KERN_INFO
576 "Port by MontaVista Software, Inc. (source@mvista.com)\n");
577
578#ifdef CONFIG_VGA_CONSOLE
579
580 vgacon_remap_base = (unsigned long)ioremap(PPLUS_ISA_MEM_BASE,
581 0x08000000);
582 conswitchp = &vga_con;
583#endif
584#ifdef CONFIG_PPCBUG_NVRAM
585
586 init_prep_nvram();
587
588
589 if (cmd_line[0] == '\0') {
590 char *bootargs;
591 bootargs = prep_nvram_get_var("bootargs");
592 if (bootargs != NULL) {
593 strcpy(cmd_line, bootargs);
594
595 strcpy(boot_command_line, cmd_line);
596 }
597 }
598#endif
599 if (ppc_md.progress)
600 ppc_md.progress("pplus_setup_arch: exit", 0);
601}
602
603static void pplus_restart(char *cmd)
604{
605 unsigned long i = 10000;
606
607 local_irq_disable();
608
609
610 pplus_set_VIA_IDE_native();
611
612
613 _nmask_and_or_msr(0, MSR_IP);
614
615
616 outb(inb(0x92) & ~1L, 0x92);
617
618 outb(inb(0x92) | 1, 0x92);
619
620 while (i != 0)
621 i++;
622 panic("restart failed\n");
623}
624
625static void pplus_halt(void)
626{
627
628 _nmask_and_or_msr(MSR_EE, MSR_IP);
629
630
631 outb(inb(0x92) & ~1L, 0x92);
632
633 outb(inb(0x92) | 1, 0x92);
634
635 while (1) ;
636
637
638
639}
640
641static void pplus_power_off(void)
642{
643 pplus_halt();
644}
645
646static void __init pplus_init_IRQ(void)
647{
648 int i;
649
650 if (ppc_md.progress)
651 ppc_md.progress("init_irq: enter", 0);
652
653 OpenPIC_InitSenses = pplus_openpic_initsenses;
654 OpenPIC_NumInitSenses = sizeof(pplus_openpic_initsenses);
655
656 if (OpenPIC_Addr != NULL) {
657
658 openpic_set_sources(0, 16, OpenPIC_Addr + 0x10000);
659 openpic_init(NUM_8259_INTERRUPTS);
660 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
661 i8259_irq);
662 ppc_md.get_irq = openpic_get_irq;
663 }
664
665 i8259_init(0, 0);
666
667 if (ppc_md.progress)
668 ppc_md.progress("init_irq: exit", 0);
669}
670
671#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
672
673
674
675static int pplus_ide_default_irq(unsigned long base)
676{
677 switch (base) {
678 case 0x1f0:
679 return 14;
680 case 0x170:
681 return 15;
682 default:
683 return 0;
684 }
685}
686
687static unsigned long pplus_ide_default_io_base(int index)
688{
689 switch (index) {
690 case 0:
691 return 0x1f0;
692 case 1:
693 return 0x170;
694 default:
695 return 0;
696 }
697}
698
699static void __init
700pplus_ide_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
701 unsigned long ctrl_port, int *irq)
702{
703 unsigned long reg = data_port;
704 int i;
705
706 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
707 hw->io_ports[i] = reg;
708 reg += 1;
709 }
710
711 if (ctrl_port)
712 hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
713 else
714 hw->io_ports[IDE_CONTROL_OFFSET] =
715 hw->io_ports[IDE_DATA_OFFSET] + 0x206;
716
717 if (irq != NULL)
718 *irq = pplus_ide_default_irq(data_port);
719}
720#endif
721
722#ifdef CONFIG_SMP
723
724static int __init smp_pplus_probe(void)
725{
726 extern int mot_multi;
727
728 if (mot_multi) {
729 openpic_request_IPIs();
730 smp_hw_index[1] = 1;
731 return 2;
732 }
733
734 return 1;
735}
736
737static void __init smp_pplus_kick_cpu(int nr)
738{
739 *(unsigned long *)KERNELBASE = nr;
740 asm volatile ("dcbf 0,%0"::"r" (KERNELBASE):"memory");
741 printk(KERN_INFO "CPU1 reset, waiting\n");
742}
743
744static void __init smp_pplus_setup_cpu(int cpu_nr)
745{
746 if (OpenPIC_Addr)
747 do_openpic_setup_cpu();
748}
749
750static struct smp_ops_t pplus_smp_ops = {
751 smp_openpic_message_pass,
752 smp_pplus_probe,
753 smp_pplus_kick_cpu,
754 smp_pplus_setup_cpu,
755 .give_timebase = smp_generic_give_timebase,
756 .take_timebase = smp_generic_take_timebase,
757};
758#endif
759
760#ifdef DUMP_DBATS
761static void print_dbat(int idx, u32 bat)
762{
763
764 char str[64];
765
766 sprintf(str, "DBAT%c%c = 0x%08x\n",
767 (char)((idx - DBAT0U) / 2) + '0', (idx & 1) ? 'L' : 'U', bat);
768 ppc_md.progress(str, 0);
769}
770
771#define DUMP_DBAT(x) \
772 do { \
773 u32 __temp = mfspr(x);\
774 print_dbat(x, __temp); \
775 } while (0)
776
777static void dump_dbats(void)
778{
779 if (ppc_md.progress) {
780 DUMP_DBAT(DBAT0U);
781 DUMP_DBAT(DBAT0L);
782 DUMP_DBAT(DBAT1U);
783 DUMP_DBAT(DBAT1L);
784 DUMP_DBAT(DBAT2U);
785 DUMP_DBAT(DBAT2L);
786 DUMP_DBAT(DBAT3U);
787 DUMP_DBAT(DBAT3L);
788 }
789}
790#endif
791
792static unsigned long __init pplus_find_end_of_memory(void)
793{
794 unsigned long total;
795
796 if (ppc_md.progress)
797 ppc_md.progress("pplus_find_end_of_memory", 0);
798
799#ifdef DUMP_DBATS
800 dump_dbats();
801#endif
802
803 total = hawk_get_mem_size(PPLUS_HAWK_SMC_BASE);
804 return (total);
805}
806
807static void __init pplus_map_io(void)
808{
809 io_block_mapping(PPLUS_ISA_IO_BASE, PPLUS_ISA_IO_BASE, 0x10000000,
810 _PAGE_IO);
811 io_block_mapping(0xfef80000, 0xfef80000, 0x00080000, _PAGE_IO);
812}
813
814static void __init pplus_init2(void)
815{
816#ifdef CONFIG_NVRAM
817 request_region(PREP_NVRAM_AS0, 0x8, "nvram");
818#endif
819 request_region(0x20, 0x20, "pic1");
820 request_region(0xa0, 0x20, "pic2");
821 request_region(0x00, 0x20, "dma1");
822 request_region(0x40, 0x20, "timer");
823 request_region(0x80, 0x10, "dma page reg");
824 request_region(0xc0, 0x20, "dma2");
825}
826
827
828
829
830
831static __inline__ void pplus_set_bat(void)
832{
833
834 mb();
835
836
837 mtspr(SPRN_DBAT2U, 0x80001ffe);
838 mtspr(SPRN_DBAT2L, 0x8000002a);
839 mtspr(SPRN_DBAT3U, 0xf0001ffe);
840 mtspr(SPRN_DBAT3L, 0xf000002a);
841
842
843 mb();
844}
845
846void __init
847platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
848 unsigned long r6, unsigned long r7)
849{
850 parse_bootinfo(find_bootinfo());
851
852
853 pplus_set_bat();
854
855 isa_io_base = PREP_ISA_IO_BASE;
856 isa_mem_base = PREP_ISA_MEM_BASE;
857 pci_dram_offset = PREP_PCI_DRAM_OFFSET;
858 ISA_DMA_THRESHOLD = 0x00ffffff;
859 DMA_MODE_READ = 0x44;
860 DMA_MODE_WRITE = 0x48;
861 ppc_do_canonicalize_irqs = 1;
862
863 ppc_md.setup_arch = pplus_setup_arch;
864 ppc_md.show_cpuinfo = pplus_show_cpuinfo;
865 ppc_md.init_IRQ = pplus_init_IRQ;
866
867 ppc_md.get_irq = i8259_irq;
868 ppc_md.init = pplus_init2;
869
870 ppc_md.restart = pplus_restart;
871 ppc_md.power_off = pplus_power_off;
872 ppc_md.halt = pplus_halt;
873
874 TODC_INIT(TODC_TYPE_MK48T59, PREP_NVRAM_AS0, PREP_NVRAM_AS1,
875 PREP_NVRAM_DATA, 8);
876
877 ppc_md.time_init = todc_time_init;
878 ppc_md.set_rtc_time = todc_set_rtc_time;
879 ppc_md.get_rtc_time = todc_get_rtc_time;
880 ppc_md.calibrate_decr = todc_calibrate_decr;
881 ppc_md.nvram_read_val = todc_m48txx_read_val;
882 ppc_md.nvram_write_val = todc_m48txx_write_val;
883
884 ppc_md.find_end_of_memory = pplus_find_end_of_memory;
885 ppc_md.setup_io_mappings = pplus_map_io;
886
887#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
888 ppc_ide_md.default_irq = pplus_ide_default_irq;
889 ppc_ide_md.default_io_base = pplus_ide_default_io_base;
890 ppc_ide_md.ide_init_hwif = pplus_ide_init_hwif_ports;
891#endif
892
893#ifdef CONFIG_SERIAL_TEXT_DEBUG
894 ppc_md.progress = gen550_progress;
895#endif
896#ifdef CONFIG_KGDB
897 ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
898#endif
899#ifdef CONFIG_SMP
900 smp_ops = &pplus_smp_ops;
901#endif
902}
903