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"