From: Ralf Baechle SMP support for the PMC-Sierra Yosemite evaluation board. Signed-off-by: Andrew Morton --- 25-akpm/arch/mips/Kconfig | 1 25-akpm/arch/mips/configs/yosemite_defconfig | 49 ++++ 25-akpm/arch/mips/pci/ops-titan.c | 46 +--- 25-akpm/arch/mips/pci/pci-yosemite.c | 6 25-akpm/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h | 2 25-akpm/arch/mips/pmc-sierra/yosemite/dbg_io.c | 4 25-akpm/arch/mips/pmc-sierra/yosemite/irq-handler.S | 31 -- 25-akpm/arch/mips/pmc-sierra/yosemite/irq.c | 26 +- 25-akpm/arch/mips/pmc-sierra/yosemite/prom.c | 10 25-akpm/arch/mips/pmc-sierra/yosemite/py-console.c | 41 +-- 25-akpm/arch/mips/pmc-sierra/yosemite/setup.c | 108 ++++++---- 25-akpm/arch/mips/pmc-sierra/yosemite/setup.h | 9 25-akpm/arch/mips/pmc-sierra/yosemite/smp.c | 46 +++- 25-akpm/include/asm-mips/mach-yosemite/cpu-feature-overrides.h | 1 14 files changed, 218 insertions(+), 162 deletions(-) diff -puN arch/mips/configs/yosemite_defconfig~mips-pmc-sierra-updates arch/mips/configs/yosemite_defconfig --- 25/arch/mips/configs/yosemite_defconfig~mips-pmc-sierra-updates 2005-01-29 11:26:14.120601264 -0800 +++ 25-akpm/arch/mips/configs/yosemite_defconfig 2005-01-29 11:26:14.143597768 -0800 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-rc2 -# Fri Nov 26 00:00:39 2004 +# Linux kernel version: 2.6.11-rc2 +# Wed Jan 26 02:49:13 2005 # CONFIG_MIPS=y # CONFIG_MIPS64 is not set @@ -80,14 +80,15 @@ CONFIG_PMC_YOSEMITE=y # CONFIG_SNI_RM200_PCI is not set # CONFIG_TOSHIBA_RBTX4927 is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_HAVE_DEC_LOCK=y CONFIG_DMA_COHERENT=y # CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_IRQ_CPU=y CONFIG_IRQ_CPU_RM7K=y +CONFIG_IRQ_CPU_RM9K=y CONFIG_SWAP_IO_SPACE=y CONFIG_MIPS_L1_CACHE_SHIFT=5 -# CONFIG_FB is not set # # CPU selection @@ -134,6 +135,19 @@ CONFIG_PCI_NAMES=y CONFIG_MMU=y # +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PC-card bridges +# + +# +# PCI Hotplug Support +# + +# # Executable file formats # CONFIG_BINFMT_ELF=y @@ -149,6 +163,7 @@ CONFIG_TRAD_SIGNALS=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set # @@ -172,10 +187,12 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_INITRAMFS_SOURCE="" # CONFIG_LBD is not set CONFIG_CDROM_PKTCDVD=m @@ -189,6 +206,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y +CONFIG_ATA_OVER_ETH=m # # ATA/ATAPI/MFM/RLL support @@ -401,7 +419,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # # CONFIG_WATCHDOG is not set # CONFIG_RTC is not set -# CONFIG_GEN_RTC is not set +CONFIG_GEN_RTC=y +CONFIG_GEN_RTC_X=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -409,7 +428,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # # Ftape, the floppy tape device driver # -# CONFIG_AGP is not set # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set @@ -440,6 +458,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # # Graphics support # +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -454,11 +474,25 @@ CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y # +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# + +# # USB Gadget Support # # CONFIG_USB_GADGET is not set # +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# # File systems # # CONFIG_EXT2_FS is not set @@ -548,6 +582,7 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_HIGHMEM is not set # CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set CONFIG_CROSSCOMPILE=y CONFIG_CMDLINE="" # CONFIG_DEBUG_STACK_USAGE is not set @@ -567,6 +602,10 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y # CONFIG_CRYPTO is not set # +# Hardware crypto devices +# + +# # Library routines # # CONFIG_CRC_CCITT is not set diff -puN arch/mips/Kconfig~mips-pmc-sierra-updates arch/mips/Kconfig --- 25/arch/mips/Kconfig~mips-pmc-sierra-updates 2005-01-29 11:26:14.121601112 -0800 +++ 25-akpm/arch/mips/Kconfig 2005-01-29 11:26:14.144597616 -0800 @@ -388,6 +388,7 @@ config PMC_YOSEMITE select HW_HAS_PCI select IRQ_CPU select IRQ_CPU_RM7K + select IRQ_CPU_RM9K select SWAP_IO_SPACE help Yosemite is an evaluation board for the RM9000x2 processor diff -puN arch/mips/pci/ops-titan.c~mips-pmc-sierra-updates arch/mips/pci/ops-titan.c --- 25/arch/mips/pci/ops-titan.c~mips-pmc-sierra-updates 2005-01-29 11:26:14.122600960 -0800 +++ 25-akpm/arch/mips/pci/ops-titan.c 2005-01-29 11:26:14.141598072 -0800 @@ -22,91 +22,69 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include #include -#include -#include -#include -#include #include -/* - * Titan PCI Config Read Byte - */ static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg, int size, u32 * val) { + uint32_t address, tmp; int dev, busno, func; - uint32_t address_reg, data_reg; - uint32_t address; busno = bus->number; dev = PCI_SLOT(devfn); func = PCI_FUNC(devfn); - address_reg = TITAN_PCI_0_CONFIG_ADDRESS; - data_reg = TITAN_PCI_0_CONFIG_DATA; - address = (busno << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 0x80000000; + /* start the configuration cycle */ - TITAN_WRITE(address_reg, address); + TITAN_WRITE(TITAN_PCI_0_CONFIG_ADDRESS, address); + tmp = TITAN_READ(TITAN_PCI_0_CONFIG_DATA) >> ((reg & 3) << 3); switch (size) { case 1: - *val = TITAN_READ_8(data_reg + (~reg & 0x3)); - break; - + tmp &= 0xff; case 2: - *val = TITAN_READ_16(data_reg + (~reg & 0x2)); - break; - - case 4: - *val = TITAN_READ(data_reg); - break; + tmp &= 0xffff; } + *val = tmp; return PCIBIOS_SUCCESSFUL; } -/* - * Titan PCI Config Byte Write - */ static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg, int size, u32 val) { - uint32_t address_reg, data_reg, address; + uint32_t address; int dev, busno, func; busno = bus->number; dev = PCI_SLOT(devfn); func = PCI_FUNC(devfn); - address_reg = TITAN_PCI_0_CONFIG_ADDRESS; - data_reg = TITAN_PCI_0_CONFIG_DATA; - address = (busno << 16) | (dev << 11) | (func << 8) | (reg & 0xfc) | 0x80000000; /* start the configuration cycle */ - TITAN_WRITE(address_reg, address); + TITAN_WRITE(TITAN_PCI_0_CONFIG_ADDRESS, address); /* write the data */ switch (size) { case 1: - TITAN_WRITE_8(data_reg + (~reg & 0x3), val); + TITAN_WRITE_8(TITAN_PCI_0_CONFIG_DATA + (~reg & 0x3), val); break; case 2: - TITAN_WRITE_16(data_reg + (~reg & 0x2), val); + TITAN_WRITE_16(TITAN_PCI_0_CONFIG_DATA + (~reg & 0x2), val); break; case 4: - TITAN_WRITE(data_reg, val); + TITAN_WRITE(TITAN_PCI_0_CONFIG_DATA, val); break; } diff -puN arch/mips/pci/pci-yosemite.c~mips-pmc-sierra-updates arch/mips/pci/pci-yosemite.c --- 25/arch/mips/pci/pci-yosemite.c~mips-pmc-sierra-updates 2005-01-29 11:26:14.124600656 -0800 +++ 25-akpm/arch/mips/pci/pci-yosemite.c 2005-01-29 11:26:14.142597920 -0800 @@ -9,7 +9,7 @@ #include #include #include -#include +#include extern struct pci_ops titan_pci_ops; @@ -23,6 +23,7 @@ static struct resource py_mem_resource = * anyway. So we just claim 64kB here. */ #define TITAN_IO_SIZE 0x0000ffffUL +#define TITAN_IO_BASE 0xe8000000UL static struct resource py_io_resource = { "Titan IO MEM", 0x00001000UL, TITAN_IO_SIZE - 1, IORESOURCE_IO, @@ -42,11 +43,12 @@ static int __init pmc_yosemite_setup(voi { unsigned long io_v_base; - io_v_base = (unsigned long) ioremap(0xe0000000UL,TITAN_IO_SIZE); + io_v_base = (unsigned long) ioremap(TITAN_IO_BASE, TITAN_IO_SIZE); if (!io_v_base) panic(ioremap_failed); set_io_port_base(io_v_base); + TITAN_WRITE(RM9000x2_OCD_LKM7, TITAN_READ(RM9000x2_OCD_LKM7) | 1); ioport_resource.end = TITAN_IO_SIZE - 1; diff -puN arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h --- 25/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h~mips-pmc-sierra-updates 2005-01-29 11:26:14.125600504 -0800 +++ 25-akpm/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h 2005-01-29 11:26:14.148597008 -0800 @@ -3,6 +3,7 @@ * * Copyright (C) 2003 PMC-Sierra Inc. * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -29,7 +30,6 @@ * Header file for atmel_read_eeprom.c */ -#include #include #include #include diff -puN arch/mips/pmc-sierra/yosemite/dbg_io.c~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/dbg_io.c --- 25/arch/mips/pmc-sierra/yosemite/dbg_io.c~mips-pmc-sierra-updates 2005-01-29 11:26:14.126600352 -0800 +++ 25-akpm/arch/mips/pmc-sierra/yosemite/dbg_io.c 2005-01-29 11:26:14.145597464 -0800 @@ -31,9 +31,6 @@ * the interrupt came from channel A or B. */ -#include - -#ifdef CONFIG_KGDB #include /* @@ -181,4 +178,3 @@ int putDebugChar(unsigned char byte) return 1; } -#endif diff -puN arch/mips/pmc-sierra/yosemite/irq.c~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/irq.c --- 25/arch/mips/pmc-sierra/yosemite/irq.c~mips-pmc-sierra-updates 2005-01-29 11:26:14.128600048 -0800 +++ 25-akpm/arch/mips/pmc-sierra/yosemite/irq.c 2005-01-29 11:26:14.150596704 -0800 @@ -24,7 +24,7 @@ * * Second level Interrupt handlers for the PMC-Sierra Titan/Yosemite board */ - +#include #include #include #include @@ -58,7 +58,7 @@ extern asmlinkage void titan_handle_int(void); extern void jaguar_mailbox_irq(struct pt_regs *); -/* +/* * Handle hypertransport & SMP interrupts. The interrupt lines are scarce. * For interprocessor interrupts, the best thing to do is to use the INTMSG * register. We use the same external interrupt line, i.e. INTB3 and monitor @@ -66,15 +66,15 @@ extern void jaguar_mailbox_irq(struct pt */ asmlinkage void ll_ht_smp_irq_handler(int irq, struct pt_regs *regs) { - u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4); + u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4); /* Ack all the bits that correspond to the interrupt sources */ if (status != 0) - OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS); + OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS); status = OCD_READ(RM9000x2_OCD_INTP1STATUS4); if (status != 0) - OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS); + OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS); #ifdef CONFIG_HT_LEVEL_TRIGGER /* @@ -110,6 +110,21 @@ asmlinkage void ll_ht_smp_irq_handler(in do_IRQ(irq, regs); } +asmlinkage void do_extended_irq(struct pt_regs *regs) +{ + unsigned int intcontrol = read_c0_intcontrol(); + unsigned int cause = read_c0_cause(); + unsigned int status = read_c0_status(); + unsigned int pending_sr, pending_ic; + + pending_sr = status & cause & 0xff00; + pending_ic = (cause >> 8) & intcontrol & 0xff00; + + if (pending_ic & (1 << 13)) + do_IRQ(13, regs); + +} + #ifdef CONFIG_KGDB extern void init_second_port(void); #endif @@ -124,6 +139,7 @@ void __init arch_init_irq(void) set_except_vector(0, titan_handle_int); mips_cpu_irq_init(0); rm7k_cpu_irq_init(8); + rm9k_cpu_irq_init(12); #ifdef CONFIG_KGDB /* At this point, initialize the second serial port */ diff -puN arch/mips/pmc-sierra/yosemite/irq-handler.S~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/irq-handler.S --- 25/arch/mips/pmc-sierra/yosemite/irq-handler.S~mips-pmc-sierra-updates 2005-01-29 11:26:14.129599896 -0800 +++ 25-akpm/arch/mips/pmc-sierra/yosemite/irq-handler.S 2005-01-29 11:26:14.149596856 -0800 @@ -34,37 +34,24 @@ and t0, t2 + andi t2, t0, STATUSF_IP7 /* INTB5 hardware line */ + bnez t2, ll_timer_irq /* Timer */ andi t1, t0, STATUSF_IP2 /* INTB0 hardware line */ bnez t1, ll_pcia_irq /* 64-bit PCI */ - andi t1, t0, STATUSF_IP3 /* INTB1 hardware line */ - bnez t1, ll_pcib_irq /* second 64-bit PCI slot */ + andi t2, t0, STATUSF_IP3 /* INTB1 hardware line */ + bnez t2, ll_pcib_irq /* second 64-bit PCI slot */ andi t1, t0, STATUSF_IP4 /* INTB2 hardware line */ bnez t1, ll_duart_irq /* UART */ - andi t1, t0, STATUSF_IP5 /* SMP inter-core interrupts */ - bnez t1, ll_smp_irq + andi t2, t0, STATUSF_IP5 /* SMP inter-core interrupts */ + bnez t2, ll_smp_irq andi t1, t0, STATUSF_IP6 bnez t1, ll_ht_irq /* Hypertransport */ - andi t1, t0, STATUSF_IP7 /* INTB5 hardware line */ - bnez t1, ll_timer_irq /* Timer */ - nop - nop - - /* Extended interrupts */ - mfc0 t0, CP0_CAUSE - cfc0 t1, CP0_S1_INTCONTROL - - sll t2, t1, 8 - - and t0, t2 - srl t0, t0, 16 - - .set reorder - - j spurious_interrupt - nop + move a0, sp + j do_extended_irq END(titan_handle_int) + .set reorder .align 5 ll_pcia_irq: diff -puN arch/mips/pmc-sierra/yosemite/prom.c~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/prom.c --- 25/arch/mips/pmc-sierra/yosemite/prom.c~mips-pmc-sierra-updates 2005-01-29 11:26:14.130599744 -0800 +++ 25-akpm/arch/mips/pmc-sierra/yosemite/prom.c 2005-01-29 11:26:14.148597008 -0800 @@ -43,7 +43,7 @@ const char *get_system_type(void) static void prom_cpu0_exit(void *arg) { - void *nvram = (void *) YOSEMITE_NVRAM_BASE_ADDR; + void *nvram = (void *) YOSEMITE_RTC_BASE; /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */ writeb(0x84, nvram + 0xff7); @@ -94,8 +94,6 @@ void __init prom_init(void) _machine_halt = prom_halt; _machine_power_off = prom_halt; -#ifdef CONFIG_MIPS32 - debug_vectors = cv; arcs_cmdline[0] = '\0'; @@ -109,6 +107,11 @@ void __init prom_init(void) strcat(arcs_cmdline, " "); } +#ifdef CONFIG_SERIAL_8250_CONSOLE + if ((strstr(arcs_cmdline, "console=ttyS")) == NULL) + strcat(arcs_cmdline, "console=ttyS0,115200"); +#endif + while (*env) { if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0) yosemite_base = @@ -122,7 +125,6 @@ void __init prom_init(void) env++; } -#endif /* CONFIG_MIPS32 */ mips_machgroup = MACH_GROUP_TITAN; mips_machtype = MACH_TITAN_YOSEMITE; diff -puN arch/mips/pmc-sierra/yosemite/py-console.c~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/py-console.c --- 25/arch/mips/pmc-sierra/yosemite/py-console.c~mips-pmc-sierra-updates 2005-01-29 11:26:14.132599440 -0800 +++ 25-akpm/arch/mips/pmc-sierra/yosemite/py-console.c 2005-01-29 11:26:14.149596856 -0800 @@ -48,9 +48,12 @@ struct yo_uartregs { #define iu_iir u3.iir #define iu_fcr u3.fcr +#define ssnop() __asm__ __volatile__("sll $0, $0, 1\n"); +#define ssnop_4() do { ssnop(); ssnop(); ssnop(); ssnop(); } while (0) + #define IO_BASE_64 0x9000000000000000ULL -static unsigned char readb_outer_space(unsigned long phys) +static unsigned char readb_outer_space(unsigned long long phys) { unsigned long long vaddr = IO_BASE_64 | phys; unsigned char res; @@ -58,29 +61,23 @@ static unsigned char readb_outer_space(u sr = read_c0_status(); write_c0_status((sr | ST0_KX) & ~ ST0_IE); - __asm__("sll $0, $0, 2\n"); - __asm__("sll $0, $0, 2\n"); - __asm__("sll $0, $0, 2\n"); - __asm__("sll $0, $0, 2\n"); + ssnop_4(); __asm__ __volatile__ ( " .set mips3 \n" - " ld %0, (%0) \n" + " ld %0, %1 \n" " lbu %0, (%0) \n" " .set mips0 \n" : "=r" (res) - : "0" (&vaddr)); + : "m" (vaddr)); write_c0_status(sr); - __asm__("sll $0, $0, 2\n"); - __asm__("sll $0, $0, 2\n"); - __asm__("sll $0, $0, 2\n"); - __asm__("sll $0, $0, 2\n"); + ssnop_4(); return res; } -static void writeb_outer_space(unsigned long phys, unsigned char c) +static void writeb_outer_space(unsigned long long phys, unsigned char c) { unsigned long long vaddr = IO_BASE_64 | phys; unsigned long tmp; @@ -88,30 +85,24 @@ static void writeb_outer_space(unsigned sr = read_c0_status(); write_c0_status((sr | ST0_KX) & ~ ST0_IE); - __asm__("sll $0, $0, 2\n"); - __asm__("sll $0, $0, 2\n"); - __asm__("sll $0, $0, 2\n"); - __asm__("sll $0, $0, 2\n"); + ssnop_4(); __asm__ __volatile__ ( " .set mips3 \n" - " ld %0, (%1) \n" + " ld %0, %1 \n" " sb %2, (%0) \n" " .set mips0 \n" - : "=r" (tmp) - : "r" (&vaddr), "r" (c)); + : "=&r" (tmp) + : "m" (vaddr), "r" (c)); write_c0_status(sr); - __asm__("sll $0, $0, 2\n"); - __asm__("sll $0, $0, 2\n"); - __asm__("sll $0, $0, 2\n"); - __asm__("sll $0, $0, 2\n"); + ssnop_4(); } void prom_putchar(char c) { - unsigned long lsr = 0xfd000008UL + offsetof(struct yo_uartregs, iu_lsr); - unsigned long thr = 0xfd000008UL + offsetof(struct yo_uartregs, iu_thr); + unsigned long lsr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_lsr); + unsigned long thr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_thr); while ((readb_outer_space(lsr) & 0x20) == 0); writeb_outer_space(thr, c); diff -puN arch/mips/pmc-sierra/yosemite/setup.c~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/setup.c --- 25/arch/mips/pmc-sierra/yosemite/setup.c~mips-pmc-sierra-updates 2005-01-29 11:26:14.133599288 -0800 +++ 25-akpm/arch/mips/pmc-sierra/yosemite/setup.c 2005-01-29 11:26:14.147597160 -0800 @@ -35,6 +35,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -45,84 +49,80 @@ #include #include #include -#include -#include -#include -#include #include +#include #include "setup.h" unsigned char titan_ge_mac_addr_base[6] = { - 0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00 + // 0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00 + 0x00, 0xe0, 0x04, 0x00, 0x00, 0x21 }; unsigned long cpu_clock; unsigned long yosemite_base; +static struct m48t37_rtc *m48t37_base; + void __init bus_error_init(void) { /* Do nothing */ } + unsigned long m48t37y_get_time(void) { - //unsigned char *rtc_base = (unsigned char *) YOSEMITE_RTC_BASE; - unsigned char *rtc_base = (unsigned char *) 0xfc000000UL; unsigned int year, month, day, hour, min, sec; -return; /* Stop the update to the time */ - rtc_base[0x7ff8] = 0x40; + m48t37_base->control = 0x40; - year = BCD2BIN(rtc_base[0x7fff]); - year += BCD2BIN(rtc_base[0x7fff1]) * 100; + year = BCD2BIN(m48t37_base->year); + year += BCD2BIN(m48t37_base->century) * 100; - month = BCD2BIN(rtc_base[0x7ffe]); - day = BCD2BIN(rtc_base[0x7ffd]); - hour = BCD2BIN(rtc_base[0x7ffb]); - min = BCD2BIN(rtc_base[0x7ffa]); - sec = BCD2BIN(rtc_base[0x7ff9]); + month = BCD2BIN(m48t37_base->month); + day = BCD2BIN(m48t37_base->date); + hour = BCD2BIN(m48t37_base->hour); + min = BCD2BIN(m48t37_base->min); + sec = BCD2BIN(m48t37_base->sec); /* Start the update to the time again */ - rtc_base[0x7ff8] = 0x00; + m48t37_base->control = 0x00; return mktime(year, month, day, hour, min, sec); } int m48t37y_set_time(unsigned long sec) { - unsigned char *rtc_base = (unsigned char *) YOSEMITE_RTC_BASE; struct rtc_time tm; -return; /* convert to a more useful format -- note months count from 0 */ to_tm(sec, &tm); tm.tm_mon += 1; /* enable writing */ - rtc_base[0x7ff8] = 0x80; + m48t37_base->control = 0x80; /* year */ - rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100); - rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100); + m48t37_base->year = BIN2BCD(tm.tm_year % 100); + m48t37_base->century = BIN2BCD(tm.tm_year / 100); /* month */ - rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon); + m48t37_base->month = BIN2BCD(tm.tm_mon); /* day */ - rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday); + m48t37_base->date = BIN2BCD(tm.tm_mday); /* hour/min/sec */ - rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour); - rtc_base[0x7ffa] = BIN2BCD(tm.tm_min); - rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec); + m48t37_base->hour = BIN2BCD(tm.tm_hour); + m48t37_base->min = BIN2BCD(tm.tm_min); + m48t37_base->sec = BIN2BCD(tm.tm_sec); /* day of week -- not really used, but let's keep it up-to-date */ - rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1); + m48t37_base->day = BIN2BCD(tm.tm_wday + 1); /* disable writing */ - rtc_base[0x7ff8] = 0x00; + m48t37_base->control = 0x00; return 0; } @@ -136,13 +136,9 @@ void yosemite_time_init(void) { board_timer_setup = yosemite_timer_setup; mips_hpt_frequency = cpu_clock / 2; - - rtc_get_time = m48t37y_get_time; - rtc_set_time = m48t37y_set_time; +mips_hpt_frequency = 33000000 * 3 * 5; } -unsigned long uart_base = 0xfd000000L; - /* No other usable initialization hook than this ... */ extern void (*late_time_init)(void); @@ -161,16 +157,18 @@ EXPORT_SYMBOL(ocd_base); static void __init py_map_ocd(void) { - struct uart_port up; - - /* - * Not specifically interrupt stuff but in case of SMP core_send_ipi - * needs this first so I'm mapping it here ... - */ ocd_base = (unsigned long) ioremap(OCD_BASE, OCD_SIZE); if (!ocd_base) panic("Mapping OCD failed - game over. Your score is 0."); + /* Kludge for PMON bug ... */ + OCD_WRITE(0x0710, 0x0ffff029); +} + +static void __init py_uart_setup(void) +{ + struct uart_port up; + /* * Register to interrupt zero because we share the interrupt with * the serial driver which we don't properly support yet. @@ -188,12 +186,36 @@ static void __init py_map_ocd(void) printk(KERN_ERR "Early serial init of port 0 failed\n"); } -static int __init pmc_yosemite_setup(void) +static void __init py_rtc_setup(void) +{ + m48t37_base = ioremap(YOSEMITE_RTC_BASE, YOSEMITE_RTC_SIZE); + if (!m48t37_base) + printk(KERN_ERR "Mapping the RTC failed\n"); + + rtc_get_time = m48t37y_get_time; + rtc_set_time = m48t37y_set_time; + + write_seqlock(&xtime_lock); + xtime.tv_sec = m48t37y_get_time(); + xtime.tv_nsec = 0; + + set_normalized_timespec(&wall_to_monotonic, + -xtime.tv_sec, -xtime.tv_nsec); + write_sequnlock(&xtime_lock); +} + +/* Not only time init but that's what the hook it's called through is named */ +static void __init py_late_time_init(void) { - extern void pmon_smp_bootstrap(void); + py_map_ocd(); + py_uart_setup(); + py_rtc_setup(); +} +static int __init pmc_yosemite_setup(void) +{ board_time_init = yosemite_time_init; - late_time_init = py_map_ocd; + late_time_init = py_late_time_init; /* Add memory regions */ add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM); diff -puN arch/mips/pmc-sierra/yosemite/setup.h~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/setup.h --- 25/arch/mips/pmc-sierra/yosemite/setup.h~mips-pmc-sierra-updates 2005-01-29 11:26:14.135598984 -0800 +++ 25-akpm/arch/mips/pmc-sierra/yosemite/setup.h 2005-01-29 11:26:14.146597312 -0800 @@ -1,6 +1,7 @@ /* - * Copyright 2003 PMC-Sierra + * Copyright 2003, 04 PMC-Sierra * Author: Manish Lachwani (lachwani@pmc-sierra.com) + * Copyright 2004 Ralf Baechle * * Board specific definititions for the PMC-Sierra Yosemite * @@ -12,9 +13,9 @@ #ifndef __SETUP_H__ #define __SETUP_H__ -/* NVRAM Base */ -#define YOSEMITE_NVRAM_BASE_ADDR 0xbb000678 /* XXX Need change */ -#define YOSEMITE_RTC_BASE 0xbb000679 /* XXX Need change */ +/* M48T37 RTC + NVRAM */ +#define YOSEMITE_RTC_BASE 0xfc800000 +#define YOSEMITE_RTC_SIZE 0x00800000 #define HYPERTRANSPORT_BAR0_ADDR 0x00000006 #define HYPERTRANSPORT_SIZE0 0x0fffffff diff -puN arch/mips/pmc-sierra/yosemite/smp.c~mips-pmc-sierra-updates arch/mips/pmc-sierra/yosemite/smp.c --- 25/arch/mips/pmc-sierra/yosemite/smp.c~mips-pmc-sierra-updates 2005-01-29 11:26:14.136598832 -0800 +++ 25-akpm/arch/mips/pmc-sierra/yosemite/smp.c 2005-01-29 11:26:14.145597464 -0800 @@ -4,6 +4,9 @@ #include #include +extern unsigned int (*mips_hpt_read)(void); +extern void (*mips_hpt_init)(unsigned int); + #define LAUNCHSTACK_SIZE 256 static spinlock_t launch_lock __initdata; @@ -37,8 +40,8 @@ void __init prom_grab_secondary(void) { spin_lock(&launch_lock); - debug_vectors->cpustart(1, &prom_smp_bootstrap, - launchstack + LAUNCHSTACK_SIZE, 0); + pmon_cpustart(1, &prom_smp_bootstrap, + launchstack + LAUNCHSTACK_SIZE, 0); } /* @@ -47,23 +50,38 @@ void __init prom_grab_secondary(void) * We don't want to start the secondary CPU yet nor do we have a nice probing * feature in PMON so we just assume presence of the secondary core. */ -void prom_prepare_cpus(unsigned int max_cpus) +static char maxcpus_string[] __initdata = + KERN_WARNING "max_cpus set to 0; using 1 instead\n"; + +void __init prom_prepare_cpus(unsigned int max_cpus) { + int enabled = 0, i; + + if (max_cpus == 0) { + printk(maxcpus_string); + max_cpus = 1; + } + cpus_clear(phys_cpu_present_map); - /* - * The boot CPU - */ - cpu_set(0, phys_cpu_present_map); - __cpu_number_map[0] = 0; - __cpu_logical_map[0] = 0; + for (i = 0; i < 2; i++) { + if (i == max_cpus) + break; + + /* + * The boot CPU + */ + cpu_set(i, phys_cpu_present_map); + __cpu_number_map[i] = i; + __cpu_logical_map[i] = i; + enabled++; + } /* - * The secondary core + * Be paranoid. Enable the IPI only if we're really about to go SMP. */ - cpu_set(1, phys_cpu_present_map); - __cpu_number_map[1] = 1; - __cpu_logical_map[1] = 1; + if (enabled > 1) + set_c0_status(STATUSF_IP5); } /* @@ -95,6 +113,8 @@ void prom_cpus_done(void) */ void prom_init_secondary(void) { + mips_hpt_init(mips_hpt_read()); + set_c0_status(ST0_CO | ST0_IE | ST0_IM); } diff -puN include/asm-mips/mach-yosemite/cpu-feature-overrides.h~mips-pmc-sierra-updates include/asm-mips/mach-yosemite/cpu-feature-overrides.h --- 25/include/asm-mips/mach-yosemite/cpu-feature-overrides.h~mips-pmc-sierra-updates 2005-01-29 11:26:14.137598680 -0800 +++ 25-akpm/include/asm-mips/mach-yosemite/cpu-feature-overrides.h 2005-01-29 11:26:14.150596704 -0800 @@ -25,6 +25,7 @@ #define cpu_has_vtag_icache 0 #define cpu_has_dc_aliases 0 #define cpu_has_ic_fills_f_dc 0 +#define cpu_icache_snoops_remote_store 0 #define cpu_has_nofpuex 0 #define cpu_has_64bits 1 _