Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[MIPS] Add support for BCM47XX CPUs.

Note that the BCM4710 does not support the wait instruction, this
is not a mistake in the code.

It originally comes from the OpenWrt patches.

Cc: Michael Buesch <mb@bu3sch.de>
Cc: Felix Fietkau <nbd@openwrt.org>
Cc: Florian Schirmer <jolt@tuxbox.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Aurelien Jarno and committed by
Ralf Baechle
1c0c13eb ea202c63

+385 -2
+14
arch/mips/Kconfig
··· 44 44 note that a kernel built with this option selected will not be 45 45 able to run on normal units. 46 46 47 + config BCM47XX 48 + bool "BCM47XX based boards" 49 + select DMA_NONCOHERENT 50 + select HW_HAS_PCI 51 + select IRQ_CPU 52 + select SYS_HAS_CPU_MIPS32_R1 53 + select SYS_SUPPORTS_32BIT_KERNEL 54 + select SYS_SUPPORTS_LITTLE_ENDIAN 55 + select SSB 56 + select SSB_DRIVER_MIPS 57 + select GENERIC_GPIO 58 + help 59 + Support for BCM47XX based boards 60 + 47 61 config MIPS_COBALT 48 62 bool "Cobalt Server" 49 63 select DMA_NONCOHERENT
+7
arch/mips/Makefile
··· 535 535 load-$(CONFIG_SIBYTE_BIGSUR) := 0xffffffff80100000 536 536 537 537 # 538 + # Broadcom BCM47XX boards 539 + # 540 + core-$(CONFIG_BCM47XX) += arch/mips/bcm47xx/ 541 + cflags-$(CONFIG_BCM47XX) += -Iinclude/asm-mips/mach-bcm47xx 542 + load-$(CONFIG_BCM47XX) := 0xffffffff80001000 543 + 544 + # 538 545 # SNI RM 539 546 # 540 547 core-$(CONFIG_SNI_RM) += arch/mips/sni/
+6
arch/mips/bcm47xx/Makefile
··· 1 + # 2 + # Makefile for the BCM47XX specific kernel interface routines 3 + # under Linux. 4 + # 5 + 6 + obj-y := irq.o prom.o serial.o setup.o time.o
+55
arch/mips/bcm47xx/irq.c
··· 1 + /* 2 + * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms of the GNU General Public License as published by the 6 + * Free Software Foundation; either version 2 of the License, or (at your 7 + * option) any later version. 8 + * 9 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 10 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 11 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 12 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 13 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 14 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 15 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 16 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 17 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 18 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 19 + * 20 + * You should have received a copy of the GNU General Public License along 21 + * with this program; if not, write to the Free Software Foundation, Inc., 22 + * 675 Mass Ave, Cambridge, MA 02139, USA. 23 + */ 24 + 25 + #include <linux/types.h> 26 + #include <linux/interrupt.h> 27 + #include <linux/irq.h> 28 + #include <asm/irq_cpu.h> 29 + 30 + void plat_irq_dispatch(void) 31 + { 32 + u32 cause; 33 + 34 + cause = read_c0_cause() & read_c0_status() & CAUSEF_IP; 35 + 36 + clear_c0_status(cause); 37 + 38 + if (cause & CAUSEF_IP7) 39 + do_IRQ(7); 40 + if (cause & CAUSEF_IP2) 41 + do_IRQ(2); 42 + if (cause & CAUSEF_IP3) 43 + do_IRQ(3); 44 + if (cause & CAUSEF_IP4) 45 + do_IRQ(4); 46 + if (cause & CAUSEF_IP5) 47 + do_IRQ(5); 48 + if (cause & CAUSEF_IP6) 49 + do_IRQ(6); 50 + } 51 + 52 + void __init arch_init_irq(void) 53 + { 54 + mips_cpu_irq_init(); 55 + }
+49
arch/mips/bcm47xx/prom.c
··· 1 + /* 2 + * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms of the GNU General Public License as published by the 6 + * Free Software Foundation; either version 2 of the License, or (at your 7 + * option) any later version. 8 + * 9 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 10 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 11 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 12 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 13 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 14 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 15 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 16 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 17 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 18 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 19 + * 20 + * You should have received a copy of the GNU General Public License along 21 + * with this program; if not, write to the Free Software Foundation, Inc., 22 + * 675 Mass Ave, Cambridge, MA 02139, USA. 23 + */ 24 + 25 + #include <linux/init.h> 26 + #include <asm/bootinfo.h> 27 + 28 + const char *get_system_type(void) 29 + { 30 + return "Broadcom BCM47XX"; 31 + } 32 + 33 + void __init prom_init(void) 34 + { 35 + unsigned long mem; 36 + 37 + /* Figure out memory size by finding aliases */ 38 + for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) { 39 + if (*(unsigned long *)((unsigned long)(prom_init) + mem) == 40 + *(unsigned long *)(prom_init)) 41 + break; 42 + } 43 + 44 + add_memory_region(0, mem, BOOT_MEM_RAM); 45 + } 46 + 47 + void __init prom_free_prom_memory(void) 48 + { 49 + }
+52
arch/mips/bcm47xx/serial.c
··· 1 + /* 2 + * This file is subject to the terms and conditions of the GNU General Public 3 + * License. See the file "COPYING" in the main directory of this archive 4 + * for more details. 5 + * 6 + * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net> 7 + */ 8 + 9 + #include <linux/module.h> 10 + #include <linux/init.h> 11 + #include <linux/serial.h> 12 + #include <linux/serial_8250.h> 13 + #include <linux/ssb/ssb.h> 14 + #include <bcm47xx.h> 15 + 16 + static struct plat_serial8250_port uart8250_data[5]; 17 + 18 + static struct platform_device uart8250_device = { 19 + .name = "serial8250", 20 + .id = PLAT8250_DEV_PLATFORM, 21 + .dev = { 22 + .platform_data = uart8250_data, 23 + }, 24 + }; 25 + 26 + static int __init uart8250_init(void) 27 + { 28 + int i; 29 + struct ssb_mipscore *mcore = &(ssb_bcm47xx.mipscore); 30 + 31 + memset(&uart8250_data, 0, sizeof(uart8250_data)); 32 + 33 + for (i = 0; i < mcore->nr_serial_ports; i++) { 34 + struct plat_serial8250_port *p = &(uart8250_data[i]); 35 + struct ssb_serial_port *ssb_port = &(mcore->serial_ports[i]); 36 + 37 + p->mapbase = (unsigned int) ssb_port->regs; 38 + p->membase = (void *) ssb_port->regs; 39 + p->irq = ssb_port->irq + 2; 40 + p->uartclk = ssb_port->baud_base; 41 + p->regshift = ssb_port->reg_shift; 42 + p->iotype = UPIO_MEM; 43 + p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; 44 + } 45 + return platform_device_register(&uart8250_device); 46 + } 47 + 48 + module_init(uart8250_init); 49 + 50 + MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>"); 51 + MODULE_LICENSE("GPL"); 52 + MODULE_DESCRIPTION("8250 UART probe driver for the BCM47XX platforms");
+79
arch/mips/bcm47xx/setup.c
··· 1 + /* 2 + * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> 3 + * Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org> 4 + * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> 5 + * Copyright (C) 2006 Michael Buesch <mb@bu3sch.de> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License as published by the 9 + * Free Software Foundation; either version 2 of the License, or (at your 10 + * option) any later version. 11 + * 12 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 13 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 14 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 15 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 16 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 17 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 18 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 21 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 + * 23 + * You should have received a copy of the GNU General Public License along 24 + * with this program; if not, write to the Free Software Foundation, Inc., 25 + * 675 Mass Ave, Cambridge, MA 02139, USA. 26 + */ 27 + 28 + #include <linux/types.h> 29 + #include <linux/ssb/ssb.h> 30 + #include <asm/reboot.h> 31 + #include <asm/time.h> 32 + #include <bcm47xx.h> 33 + 34 + struct ssb_bus ssb_bcm47xx; 35 + EXPORT_SYMBOL(ssb_bcm47xx); 36 + 37 + static void bcm47xx_machine_restart(char *command) 38 + { 39 + printk(KERN_ALERT "Please stand by while rebooting the system...\n"); 40 + local_irq_disable(); 41 + /* Set the watchdog timer to reset immediately */ 42 + ssb_chipco_watchdog_timer_set(&ssb_bcm47xx.chipco, 1); 43 + while (1) 44 + cpu_relax(); 45 + } 46 + 47 + static void bcm47xx_machine_halt(void) 48 + { 49 + /* Disable interrupts and watchdog and spin forever */ 50 + local_irq_disable(); 51 + ssb_chipco_watchdog_timer_set(&ssb_bcm47xx.chipco, 0); 52 + while (1) 53 + cpu_relax(); 54 + } 55 + 56 + static int bcm47xx_get_invariants(struct ssb_bus *bus, 57 + struct ssb_init_invariants *iv) 58 + { 59 + /* TODO: fill ssb_init_invariants using boardtype/boardrev 60 + * CFE environment variables. 61 + */ 62 + return 0; 63 + } 64 + 65 + void __init plat_mem_setup(void) 66 + { 67 + int err; 68 + 69 + err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, 70 + bcm47xx_get_invariants); 71 + if (err) 72 + panic("Failed to initialize SSB bus (err %d)\n", err); 73 + 74 + _machine_restart = bcm47xx_machine_restart; 75 + _machine_halt = bcm47xx_machine_halt; 76 + pm_power_off = bcm47xx_machine_halt; 77 + board_time_init = bcm47xx_time_init; 78 + } 79 +
+56
arch/mips/bcm47xx/time.c
··· 1 + /* 2 + * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms of the GNU General Public License as published by the 6 + * Free Software Foundation; either version 2 of the License, or (at your 7 + * option) any later version. 8 + * 9 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 10 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 11 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 12 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 13 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 14 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 15 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 16 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 17 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 18 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 19 + * 20 + * You should have received a copy of the GNU General Public License along 21 + * with this program; if not, write to the Free Software Foundation, Inc., 22 + * 675 Mass Ave, Cambridge, MA 02139, USA. 23 + */ 24 + 25 + 26 + #include <linux/init.h> 27 + #include <linux/ssb/ssb.h> 28 + #include <asm/time.h> 29 + #include <bcm47xx.h> 30 + 31 + void __init 32 + bcm47xx_time_init(void) 33 + { 34 + unsigned long hz; 35 + 36 + /* 37 + * Use deterministic values for initial counter interrupt 38 + * so that calibrate delay avoids encountering a counter wrap. 39 + */ 40 + write_c0_count(0); 41 + write_c0_compare(0xffff); 42 + 43 + hz = ssb_cpu_clock(&ssb_bcm47xx.mipscore) / 2; 44 + if (!hz) 45 + hz = 100000000; 46 + 47 + /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */ 48 + mips_hpt_frequency = hz; 49 + } 50 + 51 + void __init 52 + plat_timer_setup(struct irqaction *irq) 53 + { 54 + /* Enable the timer interrupt */ 55 + setup_irq(7, irq); 56 + }
+20
arch/mips/kernel/cpu-probe.c
··· 159 159 case CPU_5KC: 160 160 case CPU_25KF: 161 161 case CPU_PR4450: 162 + case CPU_BCM3302: 162 163 cpu_wait = r4k_wait; 163 164 break; 164 165 ··· 794 793 } 795 794 796 795 796 + static inline void cpu_probe_broadcom(struct cpuinfo_mips *c) 797 + { 798 + decode_configs(c); 799 + switch (c->processor_id & 0xff00) { 800 + case PRID_IMP_BCM3302: 801 + c->cputype = CPU_BCM3302; 802 + break; 803 + case PRID_IMP_BCM4710: 804 + c->cputype = CPU_BCM4710; 805 + break; 806 + default: 807 + c->cputype = CPU_UNKNOWN; 808 + break; 809 + } 810 + } 811 + 797 812 __init void cpu_probe(void) 798 813 { 799 814 struct cpuinfo_mips *c = &current_cpu_data; ··· 831 814 break; 832 815 case PRID_COMP_SIBYTE: 833 816 cpu_probe_sibyte(c); 817 + break; 818 + case PRID_COMP_BROADCOM: 819 + cpu_probe_broadcom(c); 834 820 break; 835 821 case PRID_COMP_SANDCRAFT: 836 822 cpu_probe_sandcraft(c);
+2
arch/mips/kernel/proc.c
··· 82 82 [CPU_VR4181] = "NEC VR4181", 83 83 [CPU_VR4181A] = "NEC VR4181A", 84 84 [CPU_SR71000] = "Sandcraft SR71000", 85 + [CPU_BCM3302] = "Broadcom BCM3302", 86 + [CPU_BCM4710] = "Broadcom BCM4710", 85 87 [CPU_PR4450] = "Philips PR4450", 86 88 [CPU_LOONGSON2] = "ICT Loongson-2", 87 89 };
+2
arch/mips/mm/tlbex.c
··· 908 908 case CPU_4KSC: 909 909 case CPU_20KC: 910 910 case CPU_25KF: 911 + case CPU_BCM3302: 912 + case CPU_BCM4710: 911 913 case CPU_LOONGSON2: 912 914 if (m4kc_tlbp_war()) 913 915 i_nop(p);
+6
include/asm-mips/bootinfo.h
··· 215 215 #define MACH_GROUP_WINDRIVER 28 /* Windriver boards */ 216 216 #define MACH_WRPPMC 1 217 217 218 + /* 219 + * Valid machtype for group Broadcom 220 + */ 221 + #define MACH_GROUP_BRCM 23 /* Broadcom */ 222 + #define MACH_BCM47XX 1 /* Broadcom BCM47XX */ 223 + 218 224 #define CL_SIZE COMMAND_LINE_SIZE 219 225 220 226 const char *get_system_type(void);
+10 -2
include/asm-mips/cpu.h
··· 106 106 #define PRID_IMP_SR71000 0x0400 107 107 108 108 /* 109 + * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM 110 + */ 111 + 112 + #define PRID_IMP_BCM4710 0x4000 113 + #define PRID_IMP_BCM3302 0x9000 114 + 115 + /* 109 116 * Definitions for 7:0 on legacy processors 110 117 */ 111 118 ··· 224 217 #define CPU_R14000 64 225 218 #define CPU_LOONGSON1 65 226 219 #define CPU_LOONGSON2 66 227 - 228 - #define CPU_LAST 66 220 + #define CPU_BCM3302 67 221 + #define CPU_BCM4710 68 222 + #define CPU_LAST 68 229 223 230 224 /* 231 225 * ISA Level encodings
+27
include/asm-mips/mach-bcm47xx/bcm47xx.h
··· 1 + /* 2 + * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net> 3 + * 4 + * This program is free software; you can redistribute it and/or 5 + * modify it under the terms of the GNU General Public License 6 + * as published by the Free Software Foundation; either version 2 7 + * of the License, or (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program; if not, write to the Free Software 16 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 + */ 18 + 19 + #ifndef __ASM_BCM47XX_H 20 + #define __ASM_BCM47XX_H 21 + 22 + /* SSB bus */ 23 + extern struct ssb_bus ssb_bcm47xx; 24 + 25 + extern void bcm47xx_time_init(void); 26 + 27 + #endif /* __ASM_BCM47XX_H */