diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-05-12 21:05:59 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-05-12 21:05:59 +0000 |
commit | ba2dacab305c598cd4c34a604f8e276bf5bab5ff (patch) | |
tree | 78670a0139bf4d5ace617b29b7eba82bbc74d602 /arch/ppc/kernel/gemini_setup.c | |
parent | b77bf69998121e689c5e86cc5630d39a0a9ee6ca (diff) |
Merge with Linux 2.3.99-pre7 and various other bits.
Diffstat (limited to 'arch/ppc/kernel/gemini_setup.c')
-rw-r--r-- | arch/ppc/kernel/gemini_setup.c | 223 |
1 files changed, 97 insertions, 126 deletions
diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c index ae9a0bd5c..e069baf5b 100644 --- a/arch/ppc/kernel/gemini_setup.c +++ b/arch/ppc/kernel/gemini_setup.c @@ -35,15 +35,14 @@ #include "open_pic.h" void gemini_setup_pci_ptrs(void); +static int gemini_get_clock_speed(void); +extern void gemini_pcibios_fixup(void); -static unsigned char gemini_switch_map = 0; static char *gemini_board_families[] = { - "VGM", "VSS", "KGM", "VGR", "KSS" -}; - -static char *gemini_memtypes[] = { - "EDO DRAM, 60nS", "SDRAM, 15nS, CL=2", "SDRAM, 15nS, CL=2 with ECC" + "VGM", "VSS", "KGM", "VGR", "VCM", "VCS", "KCM", "VCR" }; +static int gemini_board_count = sizeof(gemini_board_families) / + sizeof(gemini_board_families[0]); static unsigned int cpu_7xx[16] = { 0, 15, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0 @@ -66,14 +65,14 @@ static inline unsigned long _get_HID1(void) int gemini_get_cpuinfo(char *buffer) { - int i, len; + int len; unsigned char reg, rev; char *family; unsigned int type; reg = readb(GEMINI_FEAT); family = gemini_board_families[((reg>>4) & 0xf)]; - if (((reg>>4) & 0xf) > 2) + if (((reg>>4) & 0xf) > gemini_board_count) printk(KERN_ERR "cpuinfo(): unable to determine board family\n"); reg = readb(GEMINI_BREV); @@ -85,18 +84,17 @@ gemini_get_cpuinfo(char *buffer) len = sprintf( buffer, "machine\t\t: Gemini %s%d, rev %c, eco %d\n", family, type, (rev + 'A'), (reg & 0xf)); - len += sprintf( buffer+len, "vendor\t\t: %s\n", - (_get_PVR() & (1<<15)) ? "IBM" : "Motorola"); + len = sprintf(buffer, "board\t\t: Gemini %s", family); + if (type > 9) + len += sprintf(buffer+len, "%c", (type - 10) + 'A'); + else + len += sprintf(buffer+len, "%d", type); - reg = readb(GEMINI_MEMCFG); - len += sprintf( buffer+len, "memory type\t: %s\n", - gemini_memtypes[(reg & 0xc0)>>6]); - len += sprintf( buffer+len, "switches on\t: "); - for( i=0; i < 8; i++ ) { - if ( gemini_switch_map & (1<<i)) - len += sprintf(buffer+len, "%d ", i); - } - len += sprintf(buffer+len, "\n"); + len += sprintf(buffer+len, ", rev %c, eco %d\n", + (rev + 'A'), (reg & 0xf)); + + len += sprintf(buffer+len, "clock\t\t: %dMhz\n", + gemini_get_clock_speed()); return len; } @@ -116,11 +114,16 @@ static u_char gemini_openpic_initsenses[] = { void __init gemini_openpic_init(void) { + + OpenPIC = (volatile struct OpenPIC *) + grackle_read(0x80005800 + 0x10); +#if 0 grackle_write(GEMINI_MPIC_PCI_CFG + PCI_BASE_ADDRESS_0, GEMINI_MPIC_ADDR); grackle_write(GEMINI_MPIC_PCI_CFG + PCI_COMMAND, PCI_COMMAND_MEMORY); OpenPIC = (volatile struct OpenPIC *) GEMINI_MPIC_ADDR; +#endif OpenPIC_InitSenses = gemini_openpic_initsenses; OpenPIC_NumInitSenses = sizeof( gemini_openpic_initsenses ); @@ -148,7 +151,6 @@ gemini_heartbeat(void) void __init gemini_setup_arch(void) { - unsigned int cpu; extern char cmd_line[]; @@ -165,29 +167,8 @@ void __init gemini_setup_arch(void) /* nothing but serial consoles... */ sprintf(cmd_line, "%s console=ttyS0", cmd_line); - - /* The user switches on the front panel can be used as follows: - - Switch 0 - adds "debug" to the command line for verbose boot info, - Switch 7 - boots in single-user mode - - */ - - gemini_switch_map = readb( GEMINI_USWITCH ); - - if ( gemini_switch_map & (1<<GEMINI_SWITCH_VERBOSE)) - sprintf(cmd_line, "%s debug", cmd_line); - - if ( gemini_switch_map & (1<<GEMINI_SWITCH_SINGLE_USER)) - sprintf(cmd_line, "%s single", cmd_line); - printk("Boot arguments: %s\n", cmd_line); - /* mutter some kind words about who made the CPU */ - cpu = _get_PVR(); - printk("CPU manufacturer: %s [rev=%04x]\n", (cpu & (1<<15)) ? "IBM" : - "Motorola", (cpu & 0xffff)); - ppc_md.heartbeat = gemini_heartbeat; ppc_md.heartbeat_reset = HZ/8; ppc_md.heartbeat_count = 1; @@ -202,19 +183,17 @@ void __init gemini_setup_arch(void) int gemini_get_clock_speed(void) { - unsigned long hid1; + unsigned long hid1, pvr = _get_PVR(); int clock; - unsigned char reg; - - hid1 = _get_HID1(); - if ((_get_PVR()>>16) == 8) + + hid1 = (_get_HID1() >> 28) & 0xf; + if (PVR_VER(pvr) == 8 || + PVR_VER(pvr) == 12) hid1 = cpu_7xx[hid1]; else hid1 = cpu_6xx[hid1]; - reg = readb(GEMINI_BSTAT) & 0xc0; - - switch( reg >> 2 ) { + switch((readb(GEMINI_BSTAT) & 0xc) >> 2) { case 0: default: @@ -226,7 +205,7 @@ gemini_get_clock_speed(void) break; case 2: - clock = (hid1*50)/3; + clock = (hid1*50); break; } @@ -242,83 +221,72 @@ gemini_get_clock_speed(void) void __init gemini_init_l2(void) { - unsigned char reg; - unsigned long cache; - int speed; - - reg = readb(GEMINI_L2CFG); - - /* 750's L2 initializes differently from a 604's. Also note that a Grackle - bug will hang a dual-604 board, so make sure that doesn't happen by not - turning on the L2 */ - if ( _get_PVR() >> 16 != 8 ) { - - /* check for dual cpus and cry sadly about the loss of an L2... */ - if ((( readb(GEMINI_CPUSTAT) & 0x0c ) >> 2) != 1) - printk("Sorry. Your dual-604 does not allow the L2 to be enabled due " - "to a Grackle bug.\n"); - else if ( reg & GEMINI_L2_SIZE_MASK ) { - printk("Enabling 604 L2 cache: %dKb\n", - (128<<((reg & GEMINI_L2_SIZE_MASK)>>6))); - writeb( 1, GEMINI_L2CFG ); - } - } + unsigned char reg, brev, fam, creg; + unsigned long cache; + unsigned long pvr = _get_PVR(); + + reg = readb(GEMINI_L2CFG); + brev = readb(GEMINI_BREV); + fam = readb(GEMINI_FEAT); + + switch(PVR_VER(pvr)) { + + case 8: + if (reg & 0xc0) + cache = (((reg >> 6) & 0x3) << 28); + else + cache = 0x3 << 28; - /* do a 750 */ - else { - /* Synergy's first round of 750 boards had the L2 size stuff into the - board register above. If it's there, it's used; if not, the - standard default is 1Mb. The L2 type, I'm told, is "most likely - probably always going to be late-write". --Dan */ - - if (reg & 0xc0) { - printk("Enabling 750 L2 cache: %dKb\n", - (128 << ((reg & 0xc0)>>6))); - /* take the size given */ - cache = (((reg>>6) & 0x3)<<28); - } - else - { - printk("Enabling 750 L2 cache: 1M\n"); - /* default of 1Mb */ - cache = 0x3<<28; - } - - reg &= 0x3; - - /* a cache ratio of 1:1 and CPU clock speeds in excess of 300Mhz are bad - things. If found, tune it down to 1:1.5. -- Dan */ - if (!reg) { - -printk("3\n"); - speed = gemini_get_clock_speed(); - - if (speed >= 300) { - printk("Warning: L2 ratio is 1:1 on a %dMhz processor. Dropping to 1:1.5.\n", - speed ); - printk("Contact Synergy Microsystems for an ECO to fix this problem\n"); - reg = 0x1; - } - } - - /* standard stuff */ - cache |= ((1<<reg)<<25); #ifdef CONFIG_SMP - /* A couple errata for the 750's (both IBM and Motorola silicon) - note that you can get missed cache lines on MP implementations. - The workaround - if you call it that - is to make the L2 - write-through. This is fixed in IBM's 3.1 rev (I'm told), but - for now, always make 2.x versions use L2 write-through. --Dan */ - if (((_get_PVR()>>8) & 0xf) <= 2) - { - cache |= L2CR_L2WT; - printk("L2 cache: Enabling Write-Through due to 750 Errata.\n"); - } -#endif - cache |= L2CR_PIPE_LATEWR|L2CR_L2CTL|L2CR_INST_DISABLE; - _set_L2CR(0); - _set_L2CR(cache|L2CR_L2I|L2CR_L2E); + /* Pre-3.0 processor revs had snooping errata. Leave + their L2's disabled with SMP. -- Dan */ + if (PVR_CFG(pvr) < 3) { + printk("Pre-3.0 750; L2 left disabled!\n"); + return; + } +#endif /* CONFIG_SMP */ + + /* Special case: VGM5-B's came before L2 ratios were set on + the board. Processor speed shouldn't be too high, so + set L2 ratio to 1:1.5. */ + if ((brev == 0x51) && ((fam & 0xa0) >> 4) == 0) + reg |= 1; + + /* determine best cache ratio based upon what the board + tells us (which sometimes _may_ not be true) and + the processor speed. */ + else { + if (gemini_get_clock_speed() > 250) + reg = 2; + } + break; + case 12: + { + static unsigned long l2_size_val = 0; + + if (!l2_size_val) + l2_size_val = _get_L2CR(); + cache = l2_size_val; + break; } + case 4: + case 9: + creg = readb(GEMINI_CPUSTAT); + if (((creg & 0xc) >> 2) != 1) + printk("Dual-604 boards don't support the use of L2\n"); + else + writeb(1, GEMINI_L2CFG); + return; + default: + printk("Unknown processor; L2 left disabled\n"); + return; + } + + cache |= ((1<<reg) << 25); + cache |= (L2CR_PIPE_LATEWR|L2CR_L2CTL|L2CR_INST_DISABLE); + _set_L2CR(0); + _set_L2CR(cache | L2CR_L2I | L2CR_L2E); + } void @@ -540,8 +508,11 @@ void gemini_post_irq(struct pt_regs* regs, int irq) void __init gemini_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { + int i; int chrp_get_irq( struct pt_regs * ); - void layout_bus( struct pci_bus * ); + + for(i = 0; i < GEMINI_LEDS; i++) + gemini_led_off(i); gemini_setup_pci_ptrs(); @@ -585,5 +556,5 @@ void __init gemini_init(unsigned long r3, unsigned long r4, unsigned long r5, #ifdef CONFIG_MAGIC_SYSRQ ppc_md.ppc_kbd_sysrq_xlate = NULL; #endif - ppc_md.pcibios_fixup_bus = layout_bus; + ppc_md.pcibios_fixup_bus = gemini_pcibios_fixup; } |