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