svn commit: r280558 - in head/sys/arm: broadcom/bcm2835 conf

Andrew Turner andrew at FreeBSD.org
Wed Mar 25 10:59:46 UTC 2015


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


More information about the svn-src-head mailing list