Merge branch 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus...
[linux-2.6] / arch / ppc / platforms / prep_setup.c
1 /*
2  *  Copyright (C) 1995  Linus Torvalds
3  *  Adapted from 'alpha' version by Gary Thomas
4  *  Modified by Cort Dougan (cort@cs.nmt.edu)
5  *
6  * Support for PReP (Motorola MTX/MVME)
7  * by Troy Benjegerdes (hozer@drgw.net)
8  */
9
10 /*
11  * bootup setup stuff..
12  */
13
14 #include <linux/delay.h>
15 #include <linux/module.h>
16 #include <linux/errno.h>
17 #include <linux/sched.h>
18 #include <linux/kernel.h>
19 #include <linux/mm.h>
20 #include <linux/stddef.h>
21 #include <linux/unistd.h>
22 #include <linux/ptrace.h>
23 #include <linux/slab.h>
24 #include <linux/user.h>
25 #include <linux/a.out.h>
26 #include <linux/screen_info.h>
27 #include <linux/major.h>
28 #include <linux/interrupt.h>
29 #include <linux/reboot.h>
30 #include <linux/init.h>
31 #include <linux/initrd.h>
32 #include <linux/ioport.h>
33 #include <linux/console.h>
34 #include <linux/timex.h>
35 #include <linux/pci.h>
36 #include <linux/ide.h>
37 #include <linux/seq_file.h>
38 #include <linux/root_dev.h>
39
40 #include <asm/sections.h>
41 #include <asm/mmu.h>
42 #include <asm/processor.h>
43 #include <asm/residual.h>
44 #include <asm/io.h>
45 #include <asm/pgtable.h>
46 #include <asm/cache.h>
47 #include <asm/dma.h>
48 #include <asm/machdep.h>
49 #include <asm/mc146818rtc.h>
50 #include <asm/mk48t59.h>
51 #include <asm/prep_nvram.h>
52 #include <asm/raven.h>
53 #include <asm/vga.h>
54 #include <asm/time.h>
55 #include <asm/mpc10x.h>
56 #include <asm/i8259.h>
57 #include <asm/open_pic.h>
58 #include <asm/pci-bridge.h>
59 #include <asm/todc.h>
60
61 /* prep registers for L2 */
62 #define CACHECRBA       0x80000823      /* Cache configuration register address */
63 #define L2CACHE_MASK    0x03    /* Mask for 2 L2 Cache bits */
64 #define L2CACHE_512KB   0x00    /* 512KB */
65 #define L2CACHE_256KB   0x01    /* 256KB */
66 #define L2CACHE_1MB     0x02    /* 1MB */
67 #define L2CACHE_NONE    0x03    /* NONE */
68 #define L2CACHE_PARITY  0x08    /* Mask for L2 Cache Parity Protected bit */
69
70 TODC_ALLOC();
71
72 extern unsigned char prep_nvram_read_val(int addr);
73 extern void prep_nvram_write_val(int addr,
74                                  unsigned char val);
75 extern unsigned char rs_nvram_read_val(int addr);
76 extern void rs_nvram_write_val(int addr,
77                                  unsigned char val);
78 extern void ibm_prep_init(void);
79
80 extern void prep_find_bridges(void);
81
82 int _prep_type;
83
84 extern void prep_residual_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
85 extern void prep_sandalfoot_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
86 extern void prep_thinkpad_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
87 extern void prep_carolina_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
88 extern void prep_tiger1_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);
89
90
91 #define cached_21       (((char *)(ppc_cached_irq_mask))[3])
92 #define cached_A1       (((char *)(ppc_cached_irq_mask))[2])
93
94 extern PTE *Hash, *Hash_end;
95 extern unsigned long Hash_size, Hash_mask;
96 extern int probingmem;
97 extern unsigned long loops_per_jiffy;
98
99 /* useful ISA ports */
100 #define PREP_SYSCTL     0x81c
101 /* present in the IBM reference design; possibly identical in Mot boxes: */
102 #define PREP_IBM_SIMM_ID        0x803   /* SIMM size: 32 or 8 MiB */
103 #define PREP_IBM_SIMM_PRESENCE  0x804
104 #define PREP_IBM_EQUIPMENT      0x80c
105 #define PREP_IBM_L2INFO 0x80d
106 #define PREP_IBM_PM1    0x82a   /* power management register 1 */
107 #define PREP_IBM_PLANAR 0x852   /* planar ID - identifies the motherboard */
108 #define PREP_IBM_DISP   0x8c0   /* 4-digit LED display */
109
110 /* Equipment Present Register masks: */
111 #define PREP_IBM_EQUIPMENT_RESERVED     0x80
112 #define PREP_IBM_EQUIPMENT_SCSIFUSE     0x40
113 #define PREP_IBM_EQUIPMENT_L2_COPYBACK  0x08
114 #define PREP_IBM_EQUIPMENT_L2_256       0x04
115 #define PREP_IBM_EQUIPMENT_CPU  0x02
116 #define PREP_IBM_EQUIPMENT_L2   0x01
117
118 /* planar ID values: */
119 /* Sandalfoot/Sandalbow (6015/7020) */
120 #define PREP_IBM_SANDALFOOT     0xfc
121 /* Woodfield, Thinkpad 850/860 (6042/7249) */
122 #define PREP_IBM_THINKPAD       0xff /* planar ID unimplemented */
123 /* PowerSeries 830/850 (6050/6070) */
124 #define PREP_IBM_CAROLINA_IDE_0 0xf0
125 #define PREP_IBM_CAROLINA_IDE_1 0xf1
126 #define PREP_IBM_CAROLINA_IDE_2 0xf2
127 #define PREP_IBM_CAROLINA_IDE_3 0xf3
128 /* 7248-43P */
129 #define PREP_IBM_CAROLINA_SCSI_0        0xf4
130 #define PREP_IBM_CAROLINA_SCSI_1        0xf5
131 #define PREP_IBM_CAROLINA_SCSI_2        0xf6
132 #define PREP_IBM_CAROLINA_SCSI_3        0xf7 /* missing from Carolina Tech Spec */
133 /* Tiger1 (7043-140) */
134 #define PREP_IBM_TIGER1_133             0xd1
135 #define PREP_IBM_TIGER1_166             0xd2
136 #define PREP_IBM_TIGER1_180             0xd3
137 #define PREP_IBM_TIGER1_xxx             0xd4 /* unknown, but probably exists */
138 #define PREP_IBM_TIGER1_333             0xd5 /* missing from Tiger Tech Spec */
139
140 /* setup_ibm_pci:
141  *      set Motherboard_map_name, Motherboard_map, Motherboard_routes.
142  *      return 8259 edge/level masks.
143  */
144 void (*setup_ibm_pci)(char *irq_lo, char *irq_hi);
145
146 extern char *Motherboard_map_name; /* for use in *_cpuinfo */
147
148 /*
149  * As found in the PReP reference implementation.
150  * Used by Thinkpad, Sandalfoot (6015/7020), and all Motorola PReP.
151  */
152 static void __init
153 prep_gen_enable_l2(void)
154 {
155         outb(inb(PREP_SYSCTL) | 0x3, PREP_SYSCTL);
156 }
157
158 /* Used by Carolina and Tiger1 */
159 static void __init
160 prep_carolina_enable_l2(void)
161 {
162         outb(inb(PREP_SYSCTL) | 0xc0, PREP_SYSCTL);
163 }
164
165 /* cpuinfo code common to all IBM PReP */
166 static void
167 prep_ibm_cpuinfo(struct seq_file *m)
168 {
169         unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
170
171         seq_printf(m, "machine\t\t: PReP %s\n", Motherboard_map_name);
172
173         seq_printf(m, "upgrade cpu\t: ");
174         if (equip_reg & PREP_IBM_EQUIPMENT_CPU) {
175                 seq_printf(m, "not ");
176         }
177         seq_printf(m, "present\n");
178
179         /* print info about the SCSI fuse */
180         seq_printf(m, "scsi fuse\t: ");
181         if (equip_reg & PREP_IBM_EQUIPMENT_SCSIFUSE)
182                 seq_printf(m, "ok");
183         else
184                 seq_printf(m, "bad");
185         seq_printf(m, "\n");
186
187         /* print info about SIMMs */
188         if (have_residual_data) {
189                 int i;
190                 seq_printf(m, "simms\t\t: ");
191                 for (i = 0; (res->ActualNumMemories) && (i < MAX_MEMS); i++) {
192                         if (res->Memories[i].SIMMSize != 0)
193                                 seq_printf(m, "%d:%ldMiB ", i,
194                                         (res->Memories[i].SIMMSize > 1024) ?
195                                         res->Memories[i].SIMMSize>>20 :
196                                         res->Memories[i].SIMMSize);
197                 }
198                 seq_printf(m, "\n");
199         }
200 }
201
202 static int
203 prep_gen_cpuinfo(struct seq_file *m)
204 {
205         prep_ibm_cpuinfo(m);
206         return 0;
207 }
208
209 static int
210 prep_sandalfoot_cpuinfo(struct seq_file *m)
211 {
212         unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
213
214         prep_ibm_cpuinfo(m);
215
216         /* report amount and type of L2 cache present */
217         seq_printf(m, "L2 cache\t: ");
218         if (equip_reg & PREP_IBM_EQUIPMENT_L2) {
219                 seq_printf(m, "not present");
220         } else {
221                 if (equip_reg & PREP_IBM_EQUIPMENT_L2_256)
222                         seq_printf(m, "256KiB");
223                 else
224                         seq_printf(m, "unknown size");
225
226                 if (equip_reg & PREP_IBM_EQUIPMENT_L2_COPYBACK)
227                         seq_printf(m, ", copy-back");
228                 else
229                         seq_printf(m, ", write-through");
230         }
231         seq_printf(m, "\n");
232
233         return 0;
234 }
235
236 static int
237 prep_thinkpad_cpuinfo(struct seq_file *m)
238 {
239         unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
240         char *cpubus_speed, *pci_speed;
241
242         prep_ibm_cpuinfo(m);
243
244         /* report amount and type of L2 cache present */
245         seq_printf(m, "l2 cache\t: ");
246         if ((equip_reg & 0x1) == 0) {
247                 switch ((equip_reg & 0xc) >> 2) {
248                         case 0x0:
249                                 seq_printf(m, "128KiB look-aside 2-way write-through\n");
250                                 break;
251                         case 0x1:
252                                 seq_printf(m, "512KiB look-aside direct-mapped write-back\n");
253                                 break;
254                         case 0x2:
255                                 seq_printf(m, "256KiB look-aside 2-way write-through\n");
256                                 break;
257                         case 0x3:
258                                 seq_printf(m, "256KiB look-aside direct-mapped write-back\n");
259                                 break;
260                 }
261         } else {
262                 seq_printf(m, "not present\n");
263         }
264
265         /* report bus speeds because we can */
266         if ((equip_reg & 0x80) == 0) {
267                 switch ((equip_reg & 0x30) >> 4) {
268                         case 0x1:
269                                 cpubus_speed = "50";
270                                 pci_speed = "25";
271                                 break;
272                         case 0x3:
273                                 cpubus_speed = "66";
274                                 pci_speed = "33";
275                                 break;
276                         default:
277                                 cpubus_speed = "unknown";
278                                 pci_speed = "unknown";
279                                 break;
280                 }
281         } else {
282                 switch ((equip_reg & 0x30) >> 4) {
283                         case 0x1:
284                                 cpubus_speed = "25";
285                                 pci_speed = "25";
286                                 break;
287                         case 0x2:
288                                 cpubus_speed = "60";
289                                 pci_speed = "30";
290                                 break;
291                         case 0x3:
292                                 cpubus_speed = "33";
293                                 pci_speed = "33";
294                                 break;
295                         default:
296                                 cpubus_speed = "unknown";
297                                 pci_speed = "unknown";
298                                 break;
299                 }
300         }
301         seq_printf(m, "60x bus\t\t: %sMHz\n", cpubus_speed);
302         seq_printf(m, "pci bus\t\t: %sMHz\n", pci_speed);
303
304         return 0;
305 }
306
307 static int
308 prep_carolina_cpuinfo(struct seq_file *m)
309 {
310         unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT);
311
312         prep_ibm_cpuinfo(m);
313
314         /* report amount and type of L2 cache present */
315         seq_printf(m, "l2 cache\t: ");
316         if ((equip_reg & 0x1) == 0) {
317                 unsigned int l2_reg = inb(PREP_IBM_L2INFO);
318
319                 /* L2 size */
320                 if ((l2_reg & 0x60) == 0)
321                         seq_printf(m, "256KiB");
322                 else if ((l2_reg & 0x60) == 0x20)
323                         seq_printf(m, "512KiB");
324                 else
325                         seq_printf(m, "unknown size");
326
327                 /* L2 type */
328                 if ((l2_reg & 0x3) == 0)
329                         seq_printf(m, ", async");
330                 else if ((l2_reg & 0x3) == 1)
331                         seq_printf(m, ", sync");
332                 else
333                         seq_printf(m, ", unknown type");
334
335                 seq_printf(m, "\n");
336         } else {
337                 seq_printf(m, "not present\n");
338         }
339
340         return 0;
341 }
342
343 static int
344 prep_tiger1_cpuinfo(struct seq_file *m)
345 {
346         unsigned int l2_reg = inb(PREP_IBM_L2INFO);
347
348         prep_ibm_cpuinfo(m);
349
350         /* report amount and type of L2 cache present */
351         seq_printf(m, "l2 cache\t: ");
352         if ((l2_reg & 0xf) == 0xf) {
353                 seq_printf(m, "not present\n");
354         } else {
355                 if (l2_reg & 0x8)
356                         seq_printf(m, "async, ");
357                 else
358                         seq_printf(m, "sync burst, ");
359         
360                 if (l2_reg & 0x4)
361                         seq_printf(m, "parity, ");
362                 else
363                         seq_printf(m, "no parity, ");
364         
365                 switch (l2_reg & 0x3) {
366                         case 0x0:
367                                 seq_printf(m, "256KiB\n");
368                                 break;
369                         case 0x1:
370                                 seq_printf(m, "512KiB\n");
371                                 break;
372                         case 0x2:
373                                 seq_printf(m, "1MiB\n");
374                                 break;
375                         default:
376                                 seq_printf(m, "unknown size\n");
377                                 break;
378                 }
379         }
380
381         return 0;
382 }
383
384
385 /* Used by all Motorola PReP */
386 static int
387 prep_mot_cpuinfo(struct seq_file *m)
388 {
389         unsigned int cachew = *((unsigned char *)CACHECRBA);
390
391         seq_printf(m, "machine\t\t: PReP %s\n", Motherboard_map_name);
392
393         /* report amount and type of L2 cache present */
394         seq_printf(m, "l2 cache\t: ");
395         switch (cachew & L2CACHE_MASK) {
396                 case L2CACHE_512KB:
397                         seq_printf(m, "512KiB");
398                         break;
399                 case L2CACHE_256KB:
400                         seq_printf(m, "256KiB");
401                         break;
402                 case L2CACHE_1MB:
403                         seq_printf(m, "1MiB");
404                         break;
405                 case L2CACHE_NONE:
406                         seq_printf(m, "none\n");
407                         goto no_l2;
408                         break;
409                 default:
410                         seq_printf(m, "%x\n", cachew);
411         }
412
413         seq_printf(m, ", parity %s",
414                         (cachew & L2CACHE_PARITY)? "enabled" : "disabled");
415
416         seq_printf(m, " SRAM:");
417
418         switch ( ((cachew & 0xf0) >> 4) & ~(0x3) ) {
419                 case 1: seq_printf(m, "synchronous, parity, flow-through\n");
420                                 break;
421                 case 2: seq_printf(m, "asynchronous, no parity\n");
422                                 break;
423                 case 3: seq_printf(m, "asynchronous, parity\n");
424                                 break;
425                 default:seq_printf(m, "synchronous, pipelined, no parity\n");
426                                 break;
427         }
428
429 no_l2:
430         /* print info about SIMMs */
431         if (have_residual_data) {
432                 int i;
433                 seq_printf(m, "simms\t\t: ");
434                 for (i = 0; (res->ActualNumMemories) && (i < MAX_MEMS); i++) {
435                         if (res->Memories[i].SIMMSize != 0)
436                                 seq_printf(m, "%d:%ldM ", i,
437                                         (res->Memories[i].SIMMSize > 1024) ?
438                                         res->Memories[i].SIMMSize>>20 :
439                                         res->Memories[i].SIMMSize);
440                 }
441                 seq_printf(m, "\n");
442         }
443
444         return 0;
445 }
446
447 static void
448 prep_restart(char *cmd)
449 {
450 #define PREP_SP92       0x92    /* Special Port 92 */
451         local_irq_disable(); /* no interrupts */
452
453         /* set exception prefix high - to the prom */
454         _nmask_and_or_msr(0, MSR_IP);
455
456         /* make sure bit 0 (reset) is a 0 */
457         outb( inb(PREP_SP92) & ~1L , PREP_SP92);
458         /* signal a reset to system control port A - soft reset */
459         outb( inb(PREP_SP92) | 1 , PREP_SP92);
460
461         while ( 1 ) ;
462         /* not reached */
463 #undef PREP_SP92
464 }
465
466 static void
467 prep_halt(void)
468 {
469         local_irq_disable(); /* no interrupts */
470
471         /* set exception prefix high - to the prom */
472         _nmask_and_or_msr(0, MSR_IP);
473
474         while ( 1 ) ;
475         /* not reached */
476 }
477
478 /* Carrera is the power manager in the Thinkpads. Unfortunately not much is
479  * known about it, so we can't power down.
480  */
481 static void
482 prep_carrera_poweroff(void)
483 {
484         prep_halt();
485 }
486
487 /*
488  * On most IBM PReP's, power management is handled by a Signetics 87c750
489  * behind the Utah component on the ISA bus. To access the 750 you must write
490  * a series of nibbles to port 0x82a (decoded by the Utah). This is described
491  * somewhat in the IBM Carolina Technical Specification.
492  * -Hollis
493  */
494 static void
495 utah_sig87c750_setbit(unsigned int bytenum, unsigned int bitnum, int value)
496 {
497         /*
498          * byte1: 0 0 0 1 0  d  a5 a4
499          * byte2: 0 0 0 1 a3 a2 a1 a0
500          *
501          * d = the bit's value, enabled or disabled
502          * (a5 a4 a3) = the byte number, minus 20
503          * (a2 a1 a0) = the bit number
504          *
505          * example: set the 5th bit of byte 21 (21.5)
506          *     a5 a4 a3 = 001 (byte 1)
507          *     a2 a1 a0 = 101 (bit 5)
508          *
509          *     byte1 = 0001 0100 (0x14)
510          *     byte2 = 0001 1101 (0x1d)
511          */
512         unsigned char byte1=0x10, byte2=0x10;
513
514         /* the 750's '20.0' is accessed as '0.0' through Utah (which adds 20) */
515         bytenum -= 20;
516
517         byte1 |= (!!value) << 2;                /* set d */
518         byte1 |= (bytenum >> 1) & 0x3;  /* set a5, a4 */
519
520         byte2 |= (bytenum & 0x1) << 3;  /* set a3 */
521         byte2 |= bitnum & 0x7;                  /* set a2, a1, a0 */
522
523         outb(byte1, PREP_IBM_PM1);      /* first nibble */
524         mb();
525         udelay(100);                            /* important: let controller recover */
526
527         outb(byte2, PREP_IBM_PM1);      /* second nibble */
528         mb();
529         udelay(100);                            /* important: let controller recover */
530 }
531
532 static void
533 prep_sig750_poweroff(void)
534 {
535         /* tweak the power manager found in most IBM PRePs (except Thinkpads) */
536
537         local_irq_disable();
538         /* set exception prefix high - to the prom */
539         _nmask_and_or_msr(0, MSR_IP);
540
541         utah_sig87c750_setbit(21, 5, 1); /* set bit 21.5, "PMEXEC_OFF" */
542
543         while (1) ;
544         /* not reached */
545 }
546
547 static int
548 prep_show_percpuinfo(struct seq_file *m, int i)
549 {
550         /* PREP's without residual data will give incorrect values here */
551         seq_printf(m, "clock\t\t: ");
552         if (have_residual_data)
553                 seq_printf(m, "%ldMHz\n",
554                            (res->VitalProductData.ProcessorHz > 1024) ?
555                            res->VitalProductData.ProcessorHz / 1000000 :
556                            res->VitalProductData.ProcessorHz);
557         else
558                 seq_printf(m, "???\n");
559
560         return 0;
561 }
562
563 /*
564  * Fill out screen_info according to the residual data. This allows us to use
565  * at least vesafb.
566  */
567 static void __init
568 prep_init_vesa(void)
569 {
570 #if     (defined(CONFIG_FB_VGA16) || defined(CONFIG_FB_VGA16_MODULE) || \
571          defined(CONFIG_FB_VESA))
572         PPC_DEVICE *vgadev = NULL;
573
574         if (have_residual_data)
575                 vgadev = residual_find_device(~0, NULL, DisplayController,
576                                                         SVGAController, -1, 0);
577
578         if (vgadev != NULL) {
579                 PnP_TAG_PACKET *pkt;
580
581                 pkt = PnP_find_large_vendor_packet(
582                                 (unsigned char *)&res->DevicePnPHeap[vgadev->AllocatedOffset],
583                                 0x04, 0); /* 0x04 = Display Tag */
584                 if (pkt != NULL) {
585                         unsigned char *ptr = (unsigned char *)pkt;
586
587                         if (ptr[4]) {
588                                 /* graphics mode */
589                                 screen_info.orig_video_isVGA = VIDEO_TYPE_VLFB;
590
591                                 screen_info.lfb_depth = ptr[4] * 8;
592
593                                 screen_info.lfb_width = swab16(*(short *)(ptr+6));
594                                 screen_info.lfb_height = swab16(*(short *)(ptr+8));
595                                 screen_info.lfb_linelength = swab16(*(short *)(ptr+10));
596
597                                 screen_info.lfb_base = swab32(*(long *)(ptr+12));
598                                 screen_info.lfb_size = swab32(*(long *)(ptr+20)) / 65536;
599                         }
600                 }
601         }
602 #endif
603 }
604
605 /*
606  * Set DBAT 2 to access 0x80000000 so early progress messages will work
607  */
608 static __inline__ void
609 prep_set_bat(void)
610 {
611         /* wait for all outstanding memory access to complete */
612         mb();
613
614         /* setup DBATs */
615         mtspr(SPRN_DBAT2U, 0x80001ffe);
616         mtspr(SPRN_DBAT2L, 0x8000002a);
617
618         /* wait for updates */
619         mb();
620 }
621
622 /*
623  * IBM 3-digit status LED
624  */
625 static unsigned int ibm_statusled_base;
626
627 static void
628 ibm_statusled_progress(char *s, unsigned short hex);
629
630 static int
631 ibm_statusled_panic(struct notifier_block *dummy1, unsigned long dummy2,
632                     void * dummy3)
633 {
634         ibm_statusled_progress(NULL, 0x505); /* SOS */
635         return NOTIFY_DONE;
636 }
637
638 static struct notifier_block ibm_statusled_block = {
639         ibm_statusled_panic,
640         NULL,
641         INT_MAX /* try to do it first */
642 };
643
644 static void
645 ibm_statusled_progress(char *s, unsigned short hex)
646 {
647         static int notifier_installed;
648         /*
649          * Progress uses 4 digits and we have only 3.  So, we map 0xffff to
650          * 0xfff for display switch off.  Out of range values are mapped to
651          * 0xeff, as I'm told 0xf00 and above are reserved for hardware codes.
652          * Install the panic notifier when the display is first switched off.
653          */
654         if (hex == 0xffff) {
655                 hex = 0xfff;
656                 if (!notifier_installed) {
657                         ++notifier_installed;
658                         atomic_notifier_chain_register(&panic_notifier_list,
659                                                 &ibm_statusled_block);
660                 }
661         }
662         else
663                 if (hex > 0xfff)
664                         hex = 0xeff;
665
666         mb();
667         outw(hex, ibm_statusled_base);
668 }
669
670 static void __init
671 ibm_statusled_init(void)
672 {
673         /*
674          * The IBM 3-digit LED display is specified in the residual data
675          * as an operator panel device, type "System Status LED".  Find
676          * that device and determine its address.  We validate all the
677          * other parameters on the off-chance another, similar device
678          * exists.
679          */
680         if (have_residual_data) {
681                 PPC_DEVICE *led;
682                 PnP_TAG_PACKET *pkt;
683
684                 led = residual_find_device(~0, NULL, SystemPeripheral,
685                                            OperatorPanel, SystemStatusLED, 0);
686                 if (!led)
687                         return;
688
689                 pkt = PnP_find_packet((unsigned char *)
690                        &res->DevicePnPHeap[led->AllocatedOffset], S8_Packet, 0);
691                 if (!pkt)
692                         return;
693
694                 if (pkt->S8_Pack.IOInfo != ISAAddr16bit)
695                         return;
696                 if (*(unsigned short *)pkt->S8_Pack.RangeMin !=
697                     *(unsigned short *)pkt->S8_Pack.RangeMax)
698                         return;
699                 if (pkt->S8_Pack.IOAlign != 2)
700                         return;
701                 if (pkt->S8_Pack.IONum != 2)
702                         return;
703
704                 ibm_statusled_base = ld_le16((unsigned short *)
705                                              (pkt->S8_Pack.RangeMin));
706                 ppc_md.progress = ibm_statusled_progress;
707         }
708 }
709
710 static void __init
711 prep_setup_arch(void)
712 {
713         unsigned char reg;
714         int is_ide=0;
715
716         /* init to some ~sane value until calibrate_delay() runs */
717         loops_per_jiffy = 50000000;
718
719         /* Lookup PCI host bridges */
720         prep_find_bridges();
721
722         /* Set up floppy in PS/2 mode */
723         outb(0x09, SIO_CONFIG_RA);
724         reg = inb(SIO_CONFIG_RD);
725         reg = (reg & 0x3F) | 0x40;
726         outb(reg, SIO_CONFIG_RD);
727         outb(reg, SIO_CONFIG_RD);       /* Have to write twice to change! */
728
729         switch ( _prep_type )
730         {
731         case _PREP_IBM:
732                 reg = inb(PREP_IBM_PLANAR);
733                 printk(KERN_INFO "IBM planar ID: %02x", reg);
734                 switch (reg) {
735                         case PREP_IBM_SANDALFOOT:
736                                 prep_gen_enable_l2();
737                                 setup_ibm_pci = prep_sandalfoot_setup_pci;
738                                 ppc_md.power_off = prep_sig750_poweroff;
739                                 ppc_md.show_cpuinfo = prep_sandalfoot_cpuinfo;
740                                 break;
741                         case PREP_IBM_THINKPAD:
742                                 prep_gen_enable_l2();
743                                 setup_ibm_pci = prep_thinkpad_setup_pci;
744                                 ppc_md.power_off = prep_carrera_poweroff;
745                                 ppc_md.show_cpuinfo = prep_thinkpad_cpuinfo;
746                                 break;
747                         default:
748                                 if (have_residual_data) {
749                                         prep_gen_enable_l2();
750                                         setup_ibm_pci = prep_residual_setup_pci;
751                                         ppc_md.power_off = prep_halt;
752                                         ppc_md.show_cpuinfo = prep_gen_cpuinfo;
753                                         break;
754                                 }
755                                 else
756                                         printk(" - unknown! Assuming Carolina");
757                                         /* fall through */
758                         case PREP_IBM_CAROLINA_IDE_0:
759                         case PREP_IBM_CAROLINA_IDE_1:
760                         case PREP_IBM_CAROLINA_IDE_2:
761                         case PREP_IBM_CAROLINA_IDE_3:
762                                 is_ide = 1;
763                         case PREP_IBM_CAROLINA_SCSI_0:
764                         case PREP_IBM_CAROLINA_SCSI_1:
765                         case PREP_IBM_CAROLINA_SCSI_2:
766                         case PREP_IBM_CAROLINA_SCSI_3:
767                                 prep_carolina_enable_l2();
768                                 setup_ibm_pci = prep_carolina_setup_pci;
769                                 ppc_md.power_off = prep_sig750_poweroff;
770                                 ppc_md.show_cpuinfo = prep_carolina_cpuinfo;
771                                 break;
772                         case PREP_IBM_TIGER1_133:
773                         case PREP_IBM_TIGER1_166:
774                         case PREP_IBM_TIGER1_180:
775                         case PREP_IBM_TIGER1_xxx:
776                         case PREP_IBM_TIGER1_333:
777                                 prep_carolina_enable_l2();
778                                 setup_ibm_pci = prep_tiger1_setup_pci;
779                                 ppc_md.power_off = prep_sig750_poweroff;
780                                 ppc_md.show_cpuinfo = prep_tiger1_cpuinfo;
781                                 break;
782                 }
783                 printk("\n");
784
785                 /* default root device */
786                 if (is_ide)
787                         ROOT_DEV = MKDEV(IDE0_MAJOR, 3);
788                 else
789                         ROOT_DEV = MKDEV(SCSI_DISK0_MAJOR, 3);
790
791                 break;
792         case _PREP_Motorola:
793                 prep_gen_enable_l2();
794                 ppc_md.power_off = prep_halt;
795                 ppc_md.show_cpuinfo = prep_mot_cpuinfo;
796
797 #ifdef CONFIG_BLK_DEV_INITRD
798                 if (initrd_start)
799                         ROOT_DEV = Root_RAM0;
800                 else
801 #endif
802 #ifdef CONFIG_ROOT_NFS
803                         ROOT_DEV = Root_NFS;
804 #else
805                         ROOT_DEV = Root_SDA2;
806 #endif
807                 break;
808         }
809
810         /* Read in NVRAM data */
811         init_prep_nvram();
812
813         /* if no bootargs, look in NVRAM */
814         if ( cmd_line[0] == '\0' ) {
815                 char *bootargs;
816                  bootargs = prep_nvram_get_var("bootargs");
817                  if (bootargs != NULL) {
818                          strcpy(cmd_line, bootargs);
819                          /* again.. */
820                          strcpy(boot_command_line, cmd_line);
821                 }
822         }
823
824         prep_init_vesa();
825
826         switch (_prep_type) {
827         case _PREP_Motorola:
828                 raven_init();
829                 break;
830         case _PREP_IBM:
831                 ibm_prep_init();
832                 break;
833         }
834
835 #ifdef CONFIG_VGA_CONSOLE
836         /* vgacon.c needs to know where we mapped IO memory in io_block_mapping() */
837         vgacon_remap_base = 0xf0000000;
838         conswitchp = &vga_con;
839 #endif
840 }
841
842 /*
843  * First, see if we can get this information from the residual data.
844  * This is important on some IBM PReP systems.  If we cannot, we let the
845  * TODC code handle doing this.
846  */
847 static void __init
848 prep_calibrate_decr(void)
849 {
850         if (have_residual_data) {
851                 unsigned long freq, divisor = 4;
852
853                 if ( res->VitalProductData.ProcessorBusHz ) {
854                         freq = res->VitalProductData.ProcessorBusHz;
855                         printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
856                                         (freq/divisor)/1000000,
857                                         (freq/divisor)%1000000);
858                         tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000);
859                         tb_ticks_per_jiffy = freq / HZ / divisor;
860                 }
861         }
862         else
863                 todc_calibrate_decr();
864 }
865
866 static void __init
867 prep_init_IRQ(void)
868 {
869         unsigned int pci_viddid, pci_did;
870
871         if (OpenPIC_Addr != NULL) {
872                 openpic_init(NUM_8259_INTERRUPTS);
873                 /* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
874                 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
875                                        i8259_irq);
876         }
877
878         if (have_residual_data) {
879                 i8259_init(residual_isapic_addr(), 0);
880                 return;
881         }
882
883         /* If we have a Raven PCI bridge or a Hawk PCI bridge / Memory
884          * controller, we poll (as they have a different int-ack address). */
885         early_read_config_dword(NULL, 0, 0, PCI_VENDOR_ID, &pci_viddid);
886         pci_did = (pci_viddid & 0xffff0000) >> 16;
887         if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA)
888                         && ((pci_did == PCI_DEVICE_ID_MOTOROLA_RAVEN)
889                                 || (pci_did == PCI_DEVICE_ID_MOTOROLA_HAWK)))
890                 i8259_init(0, 0);
891         else
892                 /* PCI interrupt ack address given in section 6.1.8 of the
893                  * PReP specification. */
894                 i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR, 0);
895 }
896
897 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
898 /*
899  * IDE stuff.
900  */
901 static int
902 prep_ide_default_irq(unsigned long base)
903 {
904         switch (base) {
905                 case 0x1f0: return 13;
906                 case 0x170: return 13;
907                 case 0x1e8: return 11;
908                 case 0x168: return 10;
909                 case 0xfff0: return 14;         /* MCP(N)750 ide0 */
910                 case 0xffe0: return 15;         /* MCP(N)750 ide1 */
911                 default: return 0;
912         }
913 }
914
915 static unsigned long
916 prep_ide_default_io_base(int index)
917 {
918         switch (index) {
919                 case 0: return 0x1f0;
920                 case 1: return 0x170;
921                 case 2: return 0x1e8;
922                 case 3: return 0x168;
923                 default:
924                         return 0;
925         }
926 }
927 #endif
928
929 #ifdef CONFIG_SMP
930 /* PReP (MTX) support */
931 static int __init
932 smp_prep_probe(void)
933 {
934         extern int mot_multi;
935
936         if (mot_multi) {
937                 openpic_request_IPIs();
938                 smp_hw_index[1] = 1;
939                 return 2;
940         }
941
942         return 1;
943 }
944
945 static void __init
946 smp_prep_kick_cpu(int nr)
947 {
948         *(unsigned long *)KERNELBASE = nr;
949         asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
950         printk("CPU1 released, waiting\n");
951 }
952
953 static void __init
954 smp_prep_setup_cpu(int cpu_nr)
955 {
956         if (OpenPIC_Addr)
957                 do_openpic_setup_cpu();
958 }
959
960 static struct smp_ops_t prep_smp_ops = {
961         smp_openpic_message_pass,
962         smp_prep_probe,
963         smp_prep_kick_cpu,
964         smp_prep_setup_cpu,
965         .give_timebase = smp_generic_give_timebase,
966         .take_timebase = smp_generic_take_timebase,
967 };
968 #endif /* CONFIG_SMP */
969
970 /*
971  * Setup the bat mappings we're going to load that cover
972  * the io areas.  RAM was mapped by mapin_ram().
973  * -- Cort
974  */
975 static void __init
976 prep_map_io(void)
977 {
978         io_block_mapping(0x80000000, PREP_ISA_IO_BASE, 0x10000000, _PAGE_IO);
979         io_block_mapping(0xf0000000, PREP_ISA_MEM_BASE, 0x08000000, _PAGE_IO);
980 }
981
982 static int __init
983 prep_request_io(void)
984 {
985 #ifdef CONFIG_NVRAM
986         request_region(PREP_NVRAM_AS0, 0x8, "nvram");
987 #endif
988         request_region(0x00,0x20,"dma1");
989         request_region(0x40,0x20,"timer");
990         request_region(0x80,0x10,"dma page reg");
991         request_region(0xc0,0x20,"dma2");
992
993         return 0;
994 }
995
996 device_initcall(prep_request_io);
997
998 void __init
999 prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
1000                 unsigned long r6, unsigned long r7)
1001 {
1002 #ifdef CONFIG_PREP_RESIDUAL
1003         /* make a copy of residual data */
1004         if ( r3 ) {
1005                 memcpy((void *)res,(void *)(r3+KERNELBASE),
1006                          sizeof(RESIDUAL));
1007         }
1008 #endif
1009
1010         isa_io_base = PREP_ISA_IO_BASE;
1011         isa_mem_base = PREP_ISA_MEM_BASE;
1012         pci_dram_offset = PREP_PCI_DRAM_OFFSET;
1013         ISA_DMA_THRESHOLD = 0x00ffffff;
1014         DMA_MODE_READ = 0x44;
1015         DMA_MODE_WRITE = 0x48;
1016         ppc_do_canonicalize_irqs = 1;
1017
1018         /* figure out what kind of prep workstation we are */
1019         if (have_residual_data) {
1020                 if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) )
1021                         _prep_type = _PREP_IBM;
1022                 else
1023                         _prep_type = _PREP_Motorola;
1024         }
1025         else {
1026                 /* assume motorola if no residual (netboot?) */
1027                 _prep_type = _PREP_Motorola;
1028         }
1029
1030 #ifdef CONFIG_PREP_RESIDUAL
1031         /* Switch off all residual data processing if the user requests it */
1032         if (strstr(cmd_line, "noresidual") != NULL)
1033                         res = NULL;
1034 #endif
1035
1036         /* Initialise progress early to get maximum benefit */
1037         prep_set_bat();
1038         ibm_statusled_init();
1039
1040         ppc_md.setup_arch     = prep_setup_arch;
1041         ppc_md.show_percpuinfo = prep_show_percpuinfo;
1042         ppc_md.show_cpuinfo   = NULL; /* set in prep_setup_arch() */
1043         ppc_md.init_IRQ       = prep_init_IRQ;
1044         /* this gets changed later on if we have an OpenPIC -- Cort */
1045         ppc_md.get_irq        = i8259_irq;
1046
1047         ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
1048
1049         ppc_md.restart        = prep_restart;
1050         ppc_md.power_off      = NULL; /* set in prep_setup_arch() */
1051         ppc_md.halt           = prep_halt;
1052
1053         ppc_md.nvram_read_val = prep_nvram_read_val;
1054         ppc_md.nvram_write_val = prep_nvram_write_val;
1055
1056         ppc_md.time_init      = todc_time_init;
1057         if (_prep_type == _PREP_IBM) {
1058                 ppc_md.rtc_read_val = todc_mc146818_read_val;
1059                 ppc_md.rtc_write_val = todc_mc146818_write_val;
1060                 TODC_INIT(TODC_TYPE_MC146818, RTC_PORT(0), NULL, RTC_PORT(1),
1061                                 8);
1062         } else {
1063                 TODC_INIT(TODC_TYPE_MK48T59, PREP_NVRAM_AS0, PREP_NVRAM_AS1,
1064                                 PREP_NVRAM_DATA, 8);
1065         }
1066
1067         ppc_md.calibrate_decr = prep_calibrate_decr;
1068         ppc_md.set_rtc_time   = todc_set_rtc_time;
1069         ppc_md.get_rtc_time   = todc_get_rtc_time;
1070
1071         ppc_md.setup_io_mappings = prep_map_io;
1072
1073 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
1074         ppc_ide_md.default_irq = prep_ide_default_irq;
1075         ppc_ide_md.default_io_base = prep_ide_default_io_base;
1076 #endif
1077
1078 #ifdef CONFIG_SMP
1079         smp_ops                  = &prep_smp_ops;
1080 #endif /* CONFIG_SMP */
1081 }