Author: andrew
Date: Wed Mar 25 10:59:42 2015
New Revision: 280558
URL: https://svnweb.freebsd.org/changeset/base/280558

Log:
  Add support for the Raspberry Pi 2. As the chip is based on the bcm2835 in
  the Raspberry Pi B we support most of the devices are already supported,
  however the base address has changed.
  
  A few items are not working, or missing. The main ones are:
   * DMA doesn't work in the sdhci driver.
   * Enabling vchiq halts the boot, may be interrupt related.
   * There is no U-Boot port yet so the DTB is embedded in the kernel.
  
  The last point will make it difficult to boot FreeBSD, however there is
  support for the Raspberry Pi 2 in the U-Boot git repo. As I have not tested
  this it is left as an open task to create a port to build.
  
  X-MFC:                When the above issues are fixed
  Sponsored by: ABT Systems Ltd

Added:
  head/sys/arm/broadcom/bcm2835/bcm2836.c   (contents, props changed)
  head/sys/arm/broadcom/bcm2835/bcm2836.h   (contents, props changed)
  head/sys/arm/broadcom/bcm2835/files.bcm2836   (contents, props changed)
  head/sys/arm/broadcom/bcm2835/std.bcm2836   (contents, props changed)
  head/sys/arm/conf/RPI2
     - copied, changed from r280125, head/sys/arm/conf/RPI-B
Modified:
  head/sys/arm/broadcom/bcm2835/bcm2835_intr.c
  head/sys/arm/broadcom/bcm2835/bcm2835_machdep.c
  head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c

Modified: head/sys/arm/broadcom/bcm2835/bcm2835_intr.c
==============================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2835_intr.c        Wed Mar 25 10:59:24 
2015        (r280557)
+++ head/sys/arm/broadcom/bcm2835/bcm2835_intr.c        Wed Mar 25 10:59:42 
2015        (r280558)
@@ -45,6 +45,10 @@ __FBSDID("$FreeBSD$");
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
+#ifdef SOC_BCM2836
+#include <arm/broadcom/bcm2835/bcm2836.h>
+#endif
+
 #define        INTC_PENDING_BASIC      0x00
 #define        INTC_PENDING_BANK1      0x04
 #define        INTC_PENDING_BANK2      0x08
@@ -61,10 +65,12 @@ __FBSDID("$FreeBSD$");
 #define        BANK2_START     (BANK1_START + 32)
 #define        BANK2_END       (BANK2_START + 32 - 1)
 #define        BANK3_START     (BANK2_START + 32)
+#define        BANK3_END       (BANK3_START + 32 - 1)
 
 #define        IS_IRQ_BASIC(n) (((n) >= 0) && ((n) < BANK1_START))
 #define        IS_IRQ_BANK1(n) (((n) >= BANK1_START) && ((n) <= BANK1_END))
 #define        IS_IRQ_BANK2(n) (((n) >= BANK2_START) && ((n) <= BANK2_END))
+#define        ID_IRQ_BCM2836(n) (((n) >= BANK3_START) && ((n) <= BANK3_END))
 #define        IRQ_BANK1(n)    ((n) - BANK1_START)
 #define        IRQ_BANK2(n)    ((n) - BANK2_START)
 
@@ -148,11 +154,19 @@ arm_get_next_irq(int last_irq)
        struct bcm_intc_softc *sc = bcm_intc_sc;
        uint32_t pending;
        int32_t irq = last_irq + 1;
+#ifdef SOC_BCM2836
+       int ret;
+#endif
 
        /* Sanity check */
        if (irq < 0)
                irq = 0;
 
+#ifdef SOC_BCM2836
+       if ((ret = bcm2836_get_next_irq(irq)) >= 0)
+               return (ret + BANK3_START);
+#endif
+
        /* TODO: should we mask last_irq? */
        if (irq < BANK1_START) {
                pending = intc_read_4(sc, INTC_PENDING_BASIC);
@@ -197,6 +211,10 @@ arm_mask_irq(uintptr_t nb)
                intc_write_4(sc, INTC_DISABLE_BANK1, (1 << IRQ_BANK1(nb)));
        else if (IS_IRQ_BANK2(nb))
                intc_write_4(sc, INTC_DISABLE_BANK2, (1 << IRQ_BANK2(nb)));
+#ifdef SOC_BCM2836
+       else if (ID_IRQ_BCM2836(nb))
+               bcm2836_mask_irq(nb - BANK3_START);
+#endif
        else
                printf("arm_mask_irq: Invalid IRQ number: %d\n", nb);
 }
@@ -213,6 +231,10 @@ arm_unmask_irq(uintptr_t nb)
                intc_write_4(sc, INTC_ENABLE_BANK1, (1 << IRQ_BANK1(nb)));
        else if (IS_IRQ_BANK2(nb))
                intc_write_4(sc, INTC_ENABLE_BANK2, (1 << IRQ_BANK2(nb)));
+#ifdef SOC_BCM2836
+       else if (ID_IRQ_BCM2836(nb))
+               bcm2836_unmask_irq(nb - BANK3_START);
+#endif
        else
                printf("arm_mask_irq: Invalid IRQ number: %d\n", nb);
 }

Modified: head/sys/arm/broadcom/bcm2835/bcm2835_machdep.c
==============================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2835_machdep.c     Wed Mar 25 10:59:24 
2015        (r280557)
+++ head/sys/arm/broadcom/bcm2835/bcm2835_machdep.c     Wed Mar 25 10:59:42 
2015        (r280558)
@@ -88,6 +88,7 @@ bcm2835_late_init(platform_t plat)
        }
 }
 
+#ifdef SOC_BCM2835
 /*
  * Set up static device mappings.
  * All on-chip peripherals exist in a 16MB range starting at 0x20000000.
@@ -100,6 +101,17 @@ bcm2835_devmap_init(platform_t plat)
        arm_devmap_add_entry(0x20000000, 0x01000000);
        return (0);
 }
+#endif
+
+#ifdef SOC_BCM2836
+static int
+bcm2836_devmap_init(platform_t plat)
+{
+
+       arm_devmap_add_entry(0x3f000000, 0x01000000);
+       return (0);
+}
+#endif
 
 struct arm32_dma_range *
 bus_dma_get_range(void)
@@ -121,6 +133,8 @@ cpu_reset()
        bcmwd_watchdog_reset();
        while (1);
 }
+
+#ifdef SOC_BCM2835
 static platform_method_t bcm2835_methods[] = {
        PLATFORMMETHOD(platform_devmap_init,    bcm2835_devmap_init),
        PLATFORMMETHOD(platform_lastaddr,       bcm2835_lastaddr),
@@ -128,6 +142,16 @@ static platform_method_t bcm2835_methods
 
        PLATFORMMETHOD_END,
 };
-
 FDT_PLATFORM_DEF(bcm2835, "bcm2835", 0, "raspberrypi,model-b");
+#endif
+
+#ifdef SOC_BCM2836
+static platform_method_t bcm2836_methods[] = {
+       PLATFORMMETHOD(platform_devmap_init,    bcm2836_devmap_init),
+       PLATFORMMETHOD(platform_lastaddr,       bcm2835_lastaddr),
+       PLATFORMMETHOD(platform_late_init,      bcm2835_late_init),
 
+       PLATFORMMETHOD_END,
+};
+FDT_PLATFORM_DEF(bcm2836, "bcm2836", 0, "brcm,bcm2709");
+#endif

Modified: head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
==============================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c       Wed Mar 25 10:59:24 
2015        (r280557)
+++ head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c       Wed Mar 25 10:59:42 
2015        (r280558)
@@ -68,8 +68,16 @@ __FBSDID("$FreeBSD$");
 #define dprintf(fmt, args...)
 #endif
 
+/* DMA doesn't yet work with the bcm3826 */
+#ifdef SOC_BCM2836
+#define        PIO_MODE        1
+#else
+#define        PIO_MODE        0
+#error
+#endif
+
 static int bcm2835_sdhci_hs = 1;
-static int bcm2835_sdhci_pio_mode = 0;
+static int bcm2835_sdhci_pio_mode = PIO_MODE;
 
 TUNABLE_INT("hw.bcm2835.sdhci.hs", &bcm2835_sdhci_hs);
 TUNABLE_INT("hw.bcm2835.sdhci.pio_mode", &bcm2835_sdhci_pio_mode);

Added: head/sys/arm/broadcom/bcm2835/bcm2836.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm/broadcom/bcm2835/bcm2836.c     Wed Mar 25 10:59:42 2015        
(r280558)
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2015 Andrew Turner.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/ofw_bus.h>
+
+#include <arm/broadcom/bcm2835/bcm2836.h>
+
+#define        ARM_LOCAL_BASE  0x40000000
+#define        ARM_LOCAL_SIZE  0x00001000
+
+#define        ARM_LOCAL_CONTROL               0x00
+#define        ARM_LOCAL_PRESCALER             0x08
+#define         PRESCALER_19_2                 0x80000000 /* 19.2 MHz */
+#define        ARM_LOCAL_INT_TIMER(n)          (0x40 + (n) * 4)
+#define        ARM_LOCAL_INT_MAILBOX(n)        (0x50 + (n) * 4)
+#define        ARM_LOCAL_INT_PENDING(n)        (0x60 + (n) * 4)
+#define         INT_PENDING_MASK               0x0f
+
+/*
+ * A driver for features of the bcm2836.
+ */
+
+struct bcm2836_softc {
+       device_t         sc_dev;
+       struct resource *sc_mem;
+};
+
+static device_identify_t bcm2836_identify;
+static device_probe_t bcm2836_probe;
+static device_attach_t bcm2836_attach;
+
+struct bcm2836_softc *softc;
+
+static void
+bcm2836_identify(driver_t *driver, device_t parent)
+{
+
+       if (BUS_ADD_CHILD(parent, 0, "bcm2836", -1) == NULL)
+               device_printf(parent, "add child failed\n");
+}
+
+static int
+bcm2836_probe(device_t dev)
+{
+
+       if (softc != NULL)
+               return (ENXIO);
+
+       device_set_desc(dev, "Broadcom bcm2836");
+
+       return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bcm2836_attach(device_t dev)
+{
+       int i, rid;
+
+       softc = device_get_softc(dev);
+       softc->sc_dev = dev;
+
+       rid = 0;
+       softc->sc_mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+           ARM_LOCAL_BASE, ARM_LOCAL_BASE + ARM_LOCAL_SIZE, ARM_LOCAL_SIZE,
+           RF_ACTIVE);
+       if (softc->sc_mem == NULL) {
+               device_printf(dev, "could not allocate memory resource\n");
+               return (ENXIO);
+       }
+
+       bus_write_4(softc->sc_mem, ARM_LOCAL_CONTROL, 0);
+       bus_write_4(softc->sc_mem, ARM_LOCAL_PRESCALER, PRESCALER_19_2);
+
+       for (i = 0; i < 4; i++)
+               bus_write_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i), 0);
+
+       for (i = 0; i < 4; i++)
+               bus_write_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(i), 1);
+
+       return (0);
+}
+
+int
+bcm2836_get_next_irq(int last_irq)
+{
+       uint32_t reg;
+       int cpu;
+       int irq;
+
+       cpu = PCPU_GET(cpuid);
+
+       reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_PENDING(cpu));
+       reg &= INT_PENDING_MASK;
+       if (reg == 0)
+               return (-1);
+
+       irq = ffs(reg) - 1;
+
+       return (irq);
+}
+
+void
+bcm2836_mask_irq(uintptr_t irq)
+{
+       uint32_t reg;
+       int i;
+
+       for (i = 0; i < 4; i++) {
+               reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i));
+               reg &= ~(1 << irq);
+               bus_write_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i), reg);
+       }
+}
+
+void
+bcm2836_unmask_irq(uintptr_t irq)
+{
+       uint32_t reg;
+       int i;
+
+       for (i = 0; i < 4; i++) {
+               reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i));
+               reg |= (1 << irq);
+               bus_write_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i), reg);
+       }
+}
+
+static device_method_t bcm2836_methods[] = {
+       /* Device interface */
+       DEVMETHOD(device_identify,      bcm2836_identify),
+       DEVMETHOD(device_probe,         bcm2836_probe),
+       DEVMETHOD(device_attach,        bcm2836_attach),
+
+       DEVMETHOD_END
+};
+
+static devclass_t bcm2836_devclass;
+
+static driver_t bcm2836_driver = {
+       "bcm2836",
+       bcm2836_methods,
+       sizeof(struct bcm2836_softc),
+};
+
+EARLY_DRIVER_MODULE(bcm2836, nexus, bcm2836_driver, bcm2836_devclass, 0, 0,
+    BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);

Added: head/sys/arm/broadcom/bcm2835/bcm2836.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm/broadcom/bcm2835/bcm2836.h     Wed Mar 25 10:59:42 2015        
(r280558)
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2015 Andrew Turner.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BCM2815_BCM2836_H
+#define        _BCM2815_BCM2836_H
+
+int bcm2836_get_next_irq(int);
+void bcm2836_mask_irq(uintptr_t);
+void bcm2836_unmask_irq(uintptr_t);
+
+#endif

Added: head/sys/arm/broadcom/bcm2835/files.bcm2836
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm/broadcom/bcm2835/files.bcm2836 Wed Mar 25 10:59:42 2015        
(r280558)
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+arm/arm/cpufunc_asm_armv7.S                    standard
+arm/arm/generic_timer.c                                standard
+
+arm/broadcom/bcm2835/bcm2836.c                 standard

Added: head/sys/arm/broadcom/bcm2835/std.bcm2836
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm/broadcom/bcm2835/std.bcm2836   Wed Mar 25 10:59:42 2015        
(r280558)
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+machine        arm armv6
+cpu            CPU_CORTEXA
+makeoptions    CONF_CFLAGS="-march=armv7a"
+options        SOC_BCM2836
+
+files  "../broadcom/bcm2835/files.bcm2836"
+files  "../broadcom/bcm2835/files.bcm283x"
+

Copied and modified: head/sys/arm/conf/RPI2 (from r280125, 
head/sys/arm/conf/RPI-B)
==============================================================================
--- head/sys/arm/conf/RPI-B     Sun Mar 15 21:57:44 2015        (r280125, copy 
source)
+++ head/sys/arm/conf/RPI2      Wed Mar 25 10:59:42 2015        (r280558)
@@ -21,6 +21,7 @@
 ident          RPI-B
 
 include                "../broadcom/bcm2835/std.rpi"
+include                "../broadcom/bcm2835/std.bcm2836"
 
 options        HZ=100
 options        SCHED_4BSD              # 4BSD scheduler
@@ -80,7 +81,7 @@ options       INVARIANT_SUPPORT       # Extra sanit
 #options       BOOTP_NFSV3
 #options       BOOTP_WIRED_TO=ue0
 
-#options       ROOTDEVNAME=\"ufs:mmcsd0s2\"
+options        ROOTDEVNAME=\"ufs:mmcsd0s2\"
 
 device         bpf
 device         loop
@@ -129,13 +130,13 @@ device            smsc
 device         spibus
 device         bcm2835_spi
 
-device         vchiq
-device         sound
+#device                vchiq
+#device                sound
 
 # Flattened Device Tree
 options        FDT                     # Configure using FDT/DTB data
 # Note:  DTB is normally loaded and modified by RPi boot loader, then
 # handed to kernel via U-Boot and ubldr.
-#options       FDT_DTB_STATIC
-#makeoptions   FDT_DTS_FILE=rpi.dts
+options        FDT_DTB_STATIC
+makeoptions    FDT_DTS_FILE=rpi2.dts
 makeoptions    MODULES_EXTRA=dtb/rpi
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to