Commit 1c0c13eb935c95fd2ca0b0aca6dd4860487fb242

Authored by Aurelien Jarno
Committed by Ralf Baechle
1 parent ea202c632a

[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>

Showing 14 changed files with 385 additions and 2 deletions Side-by-side Diff

... ... @@ -44,6 +44,20 @@
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
... ... @@ -535,6 +535,13 @@
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/
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
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 +}
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 +}
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");
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 +}
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 +}
arch/mips/kernel/cpu-probe.c
... ... @@ -159,6 +159,7 @@
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  
... ... @@ -793,6 +794,22 @@
793 794 }
794 795  
795 796  
  797 +static inline void cpu_probe_broadcom(struct cpuinfo_mips *c)
  798 +{
  799 + decode_configs(c);
  800 + switch (c->processor_id & 0xff00) {
  801 + case PRID_IMP_BCM3302:
  802 + c->cputype = CPU_BCM3302;
  803 + break;
  804 + case PRID_IMP_BCM4710:
  805 + c->cputype = CPU_BCM4710;
  806 + break;
  807 + default:
  808 + c->cputype = CPU_UNKNOWN;
  809 + break;
  810 + }
  811 +}
  812 +
796 813 __init void cpu_probe(void)
797 814 {
798 815 struct cpuinfo_mips *c = &current_cpu_data;
... ... @@ -814,6 +831,9 @@
814 831 break;
815 832 case PRID_COMP_SIBYTE:
816 833 cpu_probe_sibyte(c);
  834 + break;
  835 + case PRID_COMP_BROADCOM:
  836 + cpu_probe_broadcom(c);
817 837 break;
818 838 case PRID_COMP_SANDCRAFT:
819 839 cpu_probe_sandcraft(c);
arch/mips/kernel/proc.c
... ... @@ -82,6 +82,8 @@
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 };
arch/mips/mm/tlbex.c
... ... @@ -908,6 +908,8 @@
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);
include/asm-mips/bootinfo.h
... ... @@ -215,6 +215,12 @@
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);
include/asm-mips/cpu.h
... ... @@ -106,6 +106,13 @@
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  
... ... @@ -217,8 +224,9 @@
217 224 #define CPU_R14000 64
218 225 #define CPU_LOONGSON1 65
219 226 #define CPU_LOONGSON2 66
220   -
221   -#define CPU_LAST 66
  227 +#define CPU_BCM3302 67
  228 +#define CPU_BCM4710 68
  229 +#define CPU_LAST 68
222 230  
223 231 /*
224 232 * ISA Level encodings
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 */