? sys/cscope.out ? sys/arch/amd64/conf/ZOOM ? sys/arch/arm/arm/cpu_in_cksum.S.new ? sys/arch/arm/arm/fdt_machdep.c.delete ? sys/arch/arm/arm/fdtbus_machdep.c.save ? sys/arch/arm/cortex/a9tmr.c.before ? sys/arch/arm/cortex/a9wdt.c.before ? sys/arch/arm/cortex/armperiph.c.before ? sys/arch/arm/cortex/gic.before ? sys/arch/arm/cortex/gtmr.c.before ? sys/arch/cats/conf/GENERIC.PROF ? sys/arch/evbarm/conf/RPI.test ? sys/dev/fdt/fdtbus.c.save ? sys/dev/fdt/fdtbus.c.save.1 ? sys/dev/fdt/fdtvar.h.save ? sys/dev/fdt/fdtvar.h.save.1 ? sys/dev/usb/cscope.out ? sys/external/bsd/vchiq/cscope.out ? sys/external/bsd/vchiq/dist/interface/cscope.out ? sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_debugfs.c ? sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_killable.h.no ? sys/modules/arch/hppa Index: sys/arch/arm/arm/fdtbus_machdep.c =================================================================== RCS file: sys/arch/arm/arm/fdtbus_machdep.c diff -N sys/arch/arm/arm/fdtbus_machdep.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/arm/fdtbus_machdep.c 3 Dec 2017 12:00:57 -0000 @@ -0,0 +1,197 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2017 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__KERNEL_RCSID(0, "$NetBSD$"); + +#include + +#include +#include +#include + +#include + +#include + +void fdtbus_inherit(struct fdtbus_simplebus *, struct fdtbus_cookie *, + int, bus_space_tag_t); + +bool +bus_space_is_equal(bus_space_tag_t t1, bus_space_tag_t t2) +{ + //return memcmp(&h1, &h2, sizeof(h1)) == 0; + + /* Rely on iobase checks for comparison */ + return true; +} + +/* + * Translate memory address if needed. + */ + +static int +arm_fdtbus_bs_map(void *cookie, bus_addr_t addr, bus_size_t size, int flag, + bus_space_handle_t *bshp) +{ + struct fdtbus_cookie *fc = cookie; + struct fdtbus_simplebus *fbus = fc->fc_bus; + bus_space_tag_t bst = fbus->fbus_pshift_bst[fc->fc_shift]; + + aprint_debug("%s: mapping addr %lx / %lx\n", __func__, addr, size); + + int parent = OF_parent(fbus->fbus_phandle); + if (parent == 0 || fbus->fbus_nranges == 0) + return bus_space_map(bst, addr, size, flag, bshp); + + struct fdtbus_range *range = fbus->fbus_ranges; + + /* For each range. */ + for (size_t i = 0; i < fbus->fbus_nranges; i++) { + uint64_t cba = range[i].fr_caddr; + uint64_t pba = range[i].fr_paddr; + uint64_t cl = range[i].fr_size; + + /* Try next, if we're not in the range. */ + if (addr < cba || (addr + size) >= (cba + cl)) + continue; + + addr -= cba; + addr += pba; + + return bus_space_map(bst, addr, size, flag, bshp); + } + + range = fbus->fbus_dmaranges; + + /* For each range. */ + for (size_t i = 0; i < fbus->fbus_ndmaranges; i++) { + uint64_t cba = range[i].fr_caddr; + uint64_t pba = range[i].fr_paddr; + uint64_t cl = range[i].fr_size; + + /* Try next, if we're not in the range. */ + if (addr < cba || (addr + size) >= (cba + cl)) + continue; + + addr -= cba; + addr += pba; + + return bus_space_map(bst, addr, size, flag, bshp); + } + + + return ESRCH; +} + +void +fdtbus_inherit(struct fdtbus_simplebus *fbus, struct fdtbus_cookie *fc, + int shift, bus_space_tag_t bst) +{ + memcpy(bst, fbus->fbus_pshift_bst[shift], sizeof(*bst)); + + bst->bs_cookie = fc; + bst->bs_map = arm_fdtbus_bs_map; + + fc->fc_bus = fbus; + fc->fc_shift = shift; + fc->fc_bst = bst; + + fbus->fbus_faa.faa_shift_bst[shift] = bst; +} + + +void +fdtbus_create_bus(struct fdt_softc *sc) +{ + struct fdtbus_simplebus *fbus = &sc->sc_fbus; + struct fdt_attach_args *faa = &sc->sc_fbus.fbus_faa; + + /* Default to parent tags */ + for (size_t i = 0; i < FDTBUS_NREGSHIFT; i++) { + KASSERTMSG(faa->faa_shift_bst[i] == fbus->fbus_pshift_bst[i], + "faa_bst %p pbst %p", faa->faa_shift_bst[i], + fbus->fbus_pshift_bst[i]); + } + KASSERTMSG(faa->faa_dmat == fbus->fbus_pdmat, "faa_dmat %p pdmat %p", + faa->faa_dmat, fbus->fbus_pdmat); + + /* Create new tag if we have non-zero length ranges propery */ + if (fbus->fbus_ranges && fbus->fbus_nranges > 0) { + + for (size_t i = 0; i < FDTBUS_NREGSHIFT; i++) { + struct fdtbus_cookie *fc = kmem_alloc(sizeof(*fc), + KM_SLEEP); + + bus_space_tag_t bst = NULL; + if (fbus->fbus_pshift_bst[i]) { + bst = kmem_alloc(sizeof(*bst), KM_SLEEP); + memcpy(bst, fbus->fbus_pshift_bst[i], sizeof(*bst)); + + bst->bs_cookie = fc; + bst->bs_map = arm_fdtbus_bs_map; + + fc->fc_bus = &sc->sc_fbus; + fc->fc_shift = i; + fc->fc_bst = bst; + } + + faa->faa_shift_bst[i] = bst; + } + } + if (fbus->fbus_dmaranges && fbus->fbus_ndmaranges > 0) { + struct arm32_bus_dma_tag *dmat = + kmem_alloc(sizeof(*dmat), KM_SLEEP); + memcpy(dmat, fbus->fbus_pdmat, sizeof(*dmat)); + + struct arm32_dma_range *drs = + kmem_alloc(sizeof(*drs) * fbus->fbus_ndmaranges, KM_SLEEP); + + for (size_t i = 0; i < fbus->fbus_ndmaranges; i++) { + struct fdtbus_range *fr = fbus->fbus_dmaranges; + struct arm32_dma_range *dr = &drs[i]; + + dr->dr_sysbase = fr->fr_paddr; + dr->dr_busbase = fr->fr_caddr; + dr->dr_len = fr->fr_size; + dr->dr_flags = 0; +#if 0 + if (dr->dr_len < physmem * PAGE_SIZE) { + dr->dr_len = physmem * PAGE_SIZE; + } +#endif + } + dmat->_ranges = drs; + dmat->_nranges = fbus->fbus_ndmaranges; + + faa->faa_dmat = dmat; + } +} Index: sys/arch/arm/arm32/arm32_kvminit.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/arm32/arm32_kvminit.c,v retrieving revision 1.40 diff -u -p -r1.40 arm32_kvminit.c --- sys/arch/arm/arm32/arm32_kvminit.c 6 Jul 2017 15:09:17 -0000 1.40 +++ sys/arch/arm/arm32/arm32_kvminit.c 3 Dec 2017 12:00:57 -0000 @@ -122,6 +122,7 @@ */ #include "opt_multiprocessor.h" +#include "opt_fdt.h" #include __KERNEL_RCSID(0, "$NetBSD: arm32_kvminit.c,v 1.40 2017/07/06 15:09:17 skrll Exp $"); @@ -142,6 +143,10 @@ __KERNEL_RCSID(0, "$NetBSD: arm32_kvmini #include #include +#if defined(FDT) +#include +#endif + #ifdef MULTIPROCESSOR #ifndef __HAVE_CPU_UAREA_ALLOC_IDLELWP #error __HAVE_CPU_UAREA_ALLOC_IDLELWP required to not waste pages for idlestack @@ -211,6 +216,11 @@ arm32_bootmem_init(paddr_t memstart, psi bmi->bmi_kernelstart = kernelstart; bmi->bmi_kernelend = KERN_VTOPHYS(bmi, round_page((vaddr_t)_end)); +#if defined(FDT) + fdt_add_reserved_memory_range(bmi->bmi_kernelstart, + bmi->bmi_kernelend - bmi->bmi_kernelstart); +#endif + #ifdef VERBOSE_INIT_ARM printf("%s: kernelend=%#lx\n", __func__, bmi->bmi_kernelend); #endif @@ -229,6 +239,7 @@ arm32_bootmem_init(paddr_t memstart, psi #endif pv++; +#if !defined(FDT) /* * Add a free block for any memory before the kernel. */ @@ -244,6 +255,7 @@ arm32_bootmem_init(paddr_t memstart, psi #endif pv++; } +#endif bmi->bmi_nfreeblocks = pv - bmi->bmi_freeblocks; @@ -358,6 +370,9 @@ valloc_pages(struct bootmem_info *bmi, p */ KASSERT((armreg_ttbr_read() & ~(L1_TABLE_SIZE - 1)) != free_pv->pv_pa); +#if defined(FDT) + fdt_add_reserved_memory_range(free_pv->pv_pa, nbytes); +#endif pv->pv_pa = free_pv->pv_pa; pv->pv_va = free_pv->pv_va; pv->pv_size = nbytes; Index: sys/arch/arm/broadcom/bcm2835_aux.c =================================================================== RCS file: sys/arch/arm/broadcom/bcm2835_aux.c diff -N sys/arch/arm/broadcom/bcm2835_aux.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/broadcom/bcm2835_aux.c 3 Dec 2017 12:00:57 -0000 @@ -0,0 +1,224 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2017 Jared D. McNeill + * 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 ``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 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 +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include +#include +#include + +#include + +#include + +/* Registers */ +#define BCMAUX_AUXIRQ_REG 0x00 +#define BCMAUX_AUXENB_REG 0x04 + +/* Clock IDs */ +#define BCMAUX_CLOCK_UART 0 +#define BCMAUX_CLOCK_SPI1 1 +#define BCMAUX_CLOCK_SPI2 2 +#define BCMAUX_NCLOCK 3 + +static int bcmaux_match(device_t, cfdata_t, void *); +static void bcmaux_attach(device_t, device_t, void *); + +static struct clk *bcmaux_decode(device_t, const void *, size_t); + +static const struct fdtbus_clock_controller_func bcmaux_fdt_funcs = { + .decode = bcmaux_decode +}; + +static struct clk *bcmaux_get(void *, const char *); +static void bcmaux_put(void *, struct clk *); +static u_int bcmaux_get_rate(void *, struct clk *); +static int bcmaux_enable(void *, struct clk *); +static int bcmaux_disable(void *, struct clk *); + +static const struct clk_funcs bcmaux_clk_funcs = { + .get = bcmaux_get, + .put = bcmaux_put, + .get_rate = bcmaux_get_rate, + .enable = bcmaux_enable, + .disable = bcmaux_disable, +}; + +struct bcmaux_clk { + struct clk base; + uint32_t mask; +}; + +struct bcmaux_softc { + device_t sc_dev; + int sc_phandle; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + + struct clk *sc_pclk; + + struct clk_domain sc_clkdom; + struct bcmaux_clk sc_clk[BCMAUX_NCLOCK]; +}; + +#define BCMAUX_READ(sc, reg) \ + bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) +#define BCMAUX_WRITE(sc, reg, val) \ + bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) + +CFATTACH_DECL_NEW(bcmaux_fdt, sizeof(struct bcmaux_softc), + bcmaux_match, bcmaux_attach, NULL, NULL); + +static int +bcmaux_match(device_t parent, cfdata_t cf, void *aux) +{ + const char * const compatible[] = { "brcm,bcm2835-aux", NULL }; + const struct fdt_attach_args *faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +bcmaux_attach(device_t parent, device_t self, void *aux) +{ + struct bcmaux_softc * const sc = device_private(self); + const struct fdt_attach_args *faa = aux; + const int phandle = faa->faa_phandle; + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + + sc->sc_dev = self; + sc->sc_phandle = phandle; + sc->sc_clkdom.funcs = &bcmaux_clk_funcs; + sc->sc_clkdom.priv = sc; + sc->sc_pclk = fdtbus_clock_get_index(phandle, 0); + if (sc->sc_pclk == NULL) { + aprint_error(": couldn't get parent clock\n"); + return; + } + sc->sc_bst = faa->faa_bst; + if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { + aprint_error(": couldn't map registers\n"); + return; + } + + sc->sc_clk[BCMAUX_CLOCK_UART].base.domain = &sc->sc_clkdom; + sc->sc_clk[BCMAUX_CLOCK_UART].base.name = "aux_uart"; + sc->sc_clk[BCMAUX_CLOCK_UART].mask = __BIT(0); + + sc->sc_clk[BCMAUX_CLOCK_SPI1].base.domain = &sc->sc_clkdom; + sc->sc_clk[BCMAUX_CLOCK_SPI1].base.name = "aux_spi1"; + sc->sc_clk[BCMAUX_CLOCK_SPI1].mask = __BIT(1); + + sc->sc_clk[BCMAUX_CLOCK_SPI2].base.domain = &sc->sc_clkdom; + sc->sc_clk[BCMAUX_CLOCK_SPI2].base.name = "aux_spi2"; + sc->sc_clk[BCMAUX_CLOCK_SPI2].mask = __BIT(2); + + aprint_naive("\n"); + aprint_normal("\n"); + + fdtbus_register_clock_controller(self, phandle, &bcmaux_fdt_funcs); +} + +static struct clk * +bcmaux_decode(device_t dev, const void *data, size_t len) +{ + struct bcmaux_softc * const sc = device_private(dev); + u_int clkid; + + if (len != 4) + return NULL; + + clkid = be32dec(data); + if (clkid >= BCMAUX_NCLOCK) + return NULL; + + return &sc->sc_clk[clkid].base; +} + +static struct clk * +bcmaux_get(void *priv, const char *name) +{ + struct bcmaux_softc * const sc = priv; + + for (size_t i = 0; i < BCMAUX_NCLOCK; i++) { + if (strcmp(name, sc->sc_clk[i].base.name) == 0) + return &sc->sc_clk[i].base; + } + + return NULL; +} + +static void +bcmaux_put(void *priv, struct clk *clk) +{ +} + +static u_int +bcmaux_get_rate(void *priv, struct clk *clk) +{ + struct bcmaux_softc * const sc = priv; + + return clk_get_rate(sc->sc_pclk); +} + +static int +bcmaux_enable(void *priv, struct clk *clk) +{ + struct bcmaux_softc * const sc = priv; + struct bcmaux_clk *auxclk = (struct bcmaux_clk *)clk; + uint32_t val; + + val = BCMAUX_READ(sc, BCMAUX_AUXENB_REG); + val |= auxclk->mask; + BCMAUX_WRITE(sc, BCMAUX_AUXENB_REG, val); + + return 0; +} + +static int +bcmaux_disable(void *priv, struct clk *clk) +{ + struct bcmaux_softc * const sc = priv; + struct bcmaux_clk *auxclk = (struct bcmaux_clk *)clk; + uint32_t val; + + val = BCMAUX_READ(sc, BCMAUX_AUXENB_REG); + val &= ~auxclk->mask; + BCMAUX_WRITE(sc, BCMAUX_AUXENB_REG, val); + + return 0; +} Index: sys/arch/arm/broadcom/bcm2835_bsc.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_bsc.c,v retrieving revision 1.7 diff -u -p -r1.7 bcm2835_bsc.c --- sys/arch/arm/broadcom/bcm2835_bsc.c 28 Oct 2017 00:37:12 -0000 1.7 +++ sys/arch/arm/broadcom/bcm2835_bsc.c 3 Dec 2017 12:00:57 -0000 @@ -29,9 +29,14 @@ #include __KERNEL_RCSID(0, "$NetBSD: bcm2835_bsc.c,v 1.7 2017/10/28 00:37:12 pgoyette Exp $"); +#if defined(_KERNEL_OPT) +#include "opt_kernhist.h" +#endif + #include #include #include +#include #include #include #include @@ -39,15 +44,10 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_bsc. #include -#include #include #include -#include -#if defined(_KERNEL_OPT) -#include "opt_kernhist.h" -#endif -#include +#include KERNHIST_DEFINE(bsciichist); @@ -55,10 +55,13 @@ struct bsciic_softc { device_t sc_dev; bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; - bus_size_t sc_ios; struct i2c_controller sc_i2c; kmutex_t sc_buslock; void *sc_inth; + + struct clk *sc_clk; + u_int sc_frequency; + u_int sc_clkrate; }; static int bsciic_match(device_t, cfdata_t, void *); @@ -86,32 +89,35 @@ bsciic_init(void) static int bsciic_match(device_t parent, cfdata_t match, void *aux) { - struct amba_attach_args * const aaa = aux; + const char * const compatible[] = { "brcm,bcm2835-i2c", NULL }; + struct fdt_attach_args * const faa = aux; - if (strcmp(aaa->aaa_name, "bcmbsc") != 0) - return 0; - - return 1; + return of_match_compatible(faa->faa_phandle, compatible); } static void bsciic_attach(device_t parent, device_t self, void *aux) { struct bsciic_softc * const sc = device_private(self); - struct amba_attach_args * const aaa = aux; + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; prop_dictionary_t prop = device_properties(self); struct i2cbus_attach_args iba; - u_int bscunit = ~0; bool disable = false; + static ONCE_DECL(control); + RUN_ONCE(&control, bsciic_init); + + bus_addr_t addr; + bus_size_t size; + + sc->sc_dev = self; + sc->sc_iot = faa->faa_bst; - switch (aaa->aaa_addr) { - case BCM2835_BSC0_BASE: - bscunit = 0; - break; - case BCM2835_BSC1_BASE: - bscunit = 1; - break; + int error = fdtbus_get_reg(phandle, 0, &addr, &size); + if (error) { + aprint_error(": unable to get device registers\n"); + return; } prop_dictionary_get_bool(prop, "disable", &disable); @@ -121,42 +127,43 @@ bsciic_attach(device_t parent, device_t return; } - aprint_naive("\n"); - aprint_normal(": BSC%u\n", bscunit); + /* Enable clock */ + sc->sc_clk = fdtbus_clock_get_index(phandle, 0); + if (sc->sc_clk == NULL) { + aprint_error(": couldn't acquire clock\n"); + return; + } - RUN_ONCE(&control, bsciic_init); + if (clk_enable(sc->sc_clk) != 0) { + aprint_error(": failed to enable clock\n"); + return; + } - sc->sc_dev = self; + sc->sc_frequency = clk_get_rate(sc->sc_clk); - mutex_init(&sc->sc_buslock, MUTEX_DEFAULT, IPL_NONE); + if (of_getprop_uint32(phandle, "clock-frequency", + &sc->sc_clkrate) != 0) { + sc->sc_clkrate = 100000; + } - sc->sc_iot = aaa->aaa_iot; - if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, aaa->aaa_size, 0, - &sc->sc_ioh) != 0) { + if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh)) { aprint_error_dev(sc->sc_dev, "unable to map device\n"); return; } - sc->sc_ios = aaa->aaa_size; - switch (aaa->aaa_addr) { - case BCM2835_BSC0_BASE: - /* SDA0 on GPIO0, SCL0 on GPIO1 */ - bcm2835gpio_function_select(0, BCM2835_GPIO_ALT0); - bcm2835gpio_function_select(1, BCM2835_GPIO_ALT0); - break; - case BCM2835_BSC1_BASE: - /* SDA1 on GPIO2, SCL1 on GPIO3 */ - bcm2835gpio_function_select(2, BCM2835_GPIO_ALT0); - bcm2835gpio_function_select(3, BCM2835_GPIO_ALT0); - break; - } + aprint_naive("\n"); + aprint_normal(": Broadcom Serial Controller\n"); + + mutex_init(&sc->sc_buslock, MUTEX_DEFAULT, IPL_NONE); /* clear FIFO, disable controller */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, BSC_C, BSC_C_CLEAR_CLEAR); bus_space_write_4(sc->sc_iot, sc->sc_ioh, BSC_S, BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE); + + u_int divider = howmany(sc->sc_frequency, sc->sc_clkrate); bus_space_write_4(sc->sc_iot, sc->sc_ioh, BSC_DIV, - __SHIFTIN(250000000/100000, BSC_DIV_CDIV)); // XXX may not be this + __SHIFTIN(divider, BSC_DIV_CDIV)); sc->sc_i2c.ic_cookie = sc; sc->sc_i2c.ic_acquire_bus = bsciic_acquire_bus; Index: sys/arch/arm/broadcom/bcm2835_cm.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_cm.c,v retrieving revision 1.1 diff -u -p -r1.1 bcm2835_cm.c --- sys/arch/arm/broadcom/bcm2835_cm.c 21 Nov 2015 07:41:29 -0000 1.1 +++ sys/arch/arm/broadcom/bcm2835_cm.c 3 Dec 2017 12:00:57 -0000 @@ -43,10 +43,12 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_cm.c #include #include -#include - #include +#include + +#include + struct bcm2835cm_softc { device_t sc_dev; @@ -63,45 +65,51 @@ static int bcmcm_match(device_t, cfdata_ static void bcmcm_attach(device_t, device_t, void *); static int bcmcm_wait(struct bcm2835cm_softc *, int, int); -CFATTACH_DECL_NEW(bcmcm_amba, sizeof(struct bcm2835cm_softc), +CFATTACH_DECL_NEW(bcmcm_fdt, sizeof(struct bcm2835cm_softc), bcmcm_match, bcmcm_attach, NULL, NULL); /* ARGSUSED */ static int bcmcm_match(device_t parent, cfdata_t match, void *aux) { - struct amba_attach_args *aaa = aux; - - if (strcmp(aaa->aaa_name, "bcmcm") != 0) - return 0; + const char * const compatible[] = { + "brcm,bcm2835-cprman", + NULL + }; + struct fdt_attach_args * const faa = aux; - if (aaa->aaa_addr != BCM2835_CM_BASE) - return 0; - - return 1; + return of_match_compatible(faa->faa_phandle, compatible); } static void bcmcm_attach(device_t parent, device_t self, void *aux) { struct bcm2835cm_softc *sc = device_private(self); - struct amba_attach_args *aaa = aux; + struct fdt_attach_args * const faa = aux; aprint_naive("\n"); aprint_normal(": CM\n"); sc->sc_dev = self; - sc->sc_iot = aaa->aaa_iot; + sc->sc_iot = faa->faa_bst; + const int phandle = faa->faa_phandle; + + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": missing 'reg' property\n"); + return; + } - if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, BCM2835_CM_SIZE, 0, - &sc->sc_ioh)) { + if (bus_space_map(faa->faa_bst, addr, size, 0, &sc->sc_ioh)) { aprint_error_dev(sc->sc_dev, "unable to map device\n"); - goto fail0; + return; } /* Success! */ -fail0: return; + return; } static int @@ -167,7 +175,8 @@ bcm_cm_set(enum bcm_cm_clock clk, uint32 div &= ~CM_DIV_PASSWD; div |= __SHIFTIN(CM_PASSWD, CM_DIV_PASSWD); - /* if clock is running, turn it off and wait for + /* + * if clock is running, turn it off and wait for * the cycle to end */ r = CM_READ(sc, ctlreg); Index: sys/arch/arm/broadcom/bcm2835_com.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_com.c,v retrieving revision 1.3 diff -u -p -r1.3 bcm2835_com.c --- sys/arch/arm/broadcom/bcm2835_com.c 31 Jul 2017 23:54:19 -0000 1.3 +++ sys/arch/arm/broadcom/bcm2835_com.c 3 Dec 2017 12:00:57 -0000 @@ -36,11 +36,12 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_com. #include #include -#include #include #include #include +#include + #include static int bcm_com_match(device_t, cfdata_t, void *); @@ -49,51 +50,115 @@ static void bcm_com_attach(device_t, dev CFATTACH_DECL_NEW(bcmcom, sizeof(struct com_softc), bcm_com_match, bcm_com_attach, NULL, NULL); +static const char * const compatible[] = { + "brcm,bcm2835-aux-uart", + NULL +}; + static int bcm_com_match(device_t parent, cfdata_t cf, void *aux) { - struct amba_attach_args *aaa = aux; + struct fdt_attach_args * const faa = aux; - return strcmp(aaa->aaa_name, "com") == 0; + return of_match_compatible(faa->faa_phandle, compatible); } static void bcm_com_attach(device_t parent, device_t self, void *aux) { struct com_softc * const sc = device_private(self); - struct amba_attach_args * const aaa = aux; - const prop_dictionary_t dict = device_properties(self); - bus_space_tag_t bst = &bcm2835_a4x_bs_tag; + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + + // XXX + bus_space_tag_t bst = faa->faa_shift_bst[2]; bus_space_handle_t bsh; + bus_addr_t addr; + bus_size_t size; void *ih; sc->sc_dev = self; sc->sc_type = COM_TYPE_BCMAUXUART; - prop_dictionary_get_uint32(dict, "frequency", &sc->sc_frequency); - if (sc->sc_frequency == 0) { - aprint_error(": couldn't get frequency\n"); + int error = fdtbus_get_reg(phandle, 0, &addr, &size); + if (error) { + aprint_error_dev(sc->sc_dev, "unable to map device\n"); return; } - sc->sc_frequency *= 2; - if (com_is_console(bst, aaa->aaa_addr, &bsh) == 0 && - bus_space_map(bst, aaa->aaa_addr, aaa->aaa_size, 0, &bsh) != 0) { + if (com_is_console(bst, addr, &bsh) == 0 && + bus_space_map(bst, addr, size, 0, &bsh) != 0) { aprint_error(": can't map device\n"); return; } - COM_INIT_REGS(sc->sc_regs, bst, bsh, aaa->aaa_addr); + /* Enable clocks */ + struct clk *clk; + for (int i = 0; (clk = fdtbus_clock_get_index(phandle, i)); i++) { + if (clk_enable(clk) != 0) { + aprint_error(": failed to enable clock #%d\n", i); + return; + } + /* First clock is UARTCLK */ + if (i == 0) + sc->sc_frequency = clk_get_rate(clk); + } + + sc->sc_frequency *= 2; + + COM_INIT_REGS(sc->sc_regs, bst, bsh, addr); com_attach_subr(sc); aprint_naive("\n"); - ih = intr_establish(aaa->aaa_intr, IPL_SERIAL, IST_LEVEL | IST_MPSAFE, + char intrstr[128]; + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error(": failed to decode interrupt\n"); + return; + } + + ih = fdtbus_intr_establish(phandle, 0, IPL_SERIAL, FDT_INTR_MPSAFE, comintr, sc); if (ih == NULL) { - aprint_error_dev(self, "failed to establish interrupt %d\n", - aaa->aaa_intr); + aprint_error_dev(self, "failed to establish interrupt %s\n", + intrstr); return; } - aprint_normal_dev(self, "interrupting on intr %d\n", aaa->aaa_intr); + aprint_normal_dev(self, "interrupting on %s\n", intrstr); } + +static int +bcmaux_com_console_match(int phandle) +{ + + return of_match_compatible(phandle, compatible); +} + +static void +bcmaux_com_console_consinit(struct fdt_attach_args *faa, u_int uart_freq) +{ + const int phandle = faa->faa_phandle; + bus_space_tag_t bst = faa->faa_shift_bst[2]; + bus_addr_t addr; + tcflag_t flags; + int speed; + + fdtbus_get_reg(phandle, 0, &addr, NULL); + speed = fdtbus_get_stdout_speed(); + if (speed < 0) + speed = 115200; /* default */ + flags = fdtbus_get_stdout_flags(); + + if (comcnattach(bst, addr, speed, uart_freq, COM_TYPE_BCMAUXUART, + flags)) + panic("Cannot initialize bcm com console"); + + cn_set_magic("+++++"); +} + +static const struct fdt_console bcmaux_com_console = { + .match = bcmaux_com_console_match, + .consinit = bcmaux_com_console_consinit, +}; + +FDT_CONSOLE(bcmcom, &bcmaux_com_console); Index: sys/arch/arm/broadcom/bcm2835_cprman.c =================================================================== RCS file: sys/arch/arm/broadcom/bcm2835_cprman.c diff -N sys/arch/arm/broadcom/bcm2835_cprman.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/broadcom/bcm2835_cprman.c 3 Dec 2017 12:00:58 -0000 @@ -0,0 +1,187 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2017 Jared D. McNeill + * 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 ``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 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 +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include +#include +#include + +#include + +#include + +#include + +enum { + CPRMAN_CLOCK_TIMER = 17, + CPRMAN_CLOCK_UART = 19, + CPRMAN_CLOCK_VPU = 20, + CPRMAN_CLOCK_V3D = 21, + CPRMAN_CLOCK_ISP = 22, + CPRMAN_CLOCK_H264 = 23, + CPRMAN_CLOCK_VEC = 24, + CPRMAN_CLOCK_HSM = 25, + CPRMAN_CLOCK_SDRAM = 26, + CPRMAN_CLOCK_TSENS = 27, + CPRMAN_CLOCK_EMMC = 28, + CPRMAN_CLOCK_PERIIMAGE = 29, + CPRMAN_CLOCK_PWM = 30, + CPRMAN_CLOCK_PCM = 31, + CPRMAN_NCLOCK +}; + +struct cprman_clk { + struct clk base; + u_int id; +}; + +struct cprman_softc { + device_t sc_dev; + int sc_phandle; + + struct clk_domain sc_clkdom; + struct cprman_clk sc_clk[CPRMAN_NCLOCK]; +}; + + +static struct clk * +cprman_decode(device_t dev, const void *data, size_t len) +{ + struct cprman_softc * const sc = device_private(dev); + struct cprman_clk *clk; + const u_int *spec = data; + u_int id; + + if (len != 4) + return NULL; + + id = be32toh(spec[0]); + + if (id >= CPRMAN_NCLOCK) + return NULL; + clk = &sc->sc_clk[id]; + if (clk->base.name == NULL) + return NULL; + + return &clk->base; +} + +static const struct fdtbus_clock_controller_func cprman_fdt_funcs = { + .decode = cprman_decode +}; + +static struct clk * +cprman_get(void *priv, const char *name) +{ + struct cprman_softc * const sc = priv; + u_int n; + + for (n = 0; n < __arraycount(sc->sc_clk); n++) { + if (sc->sc_clk[n].base.name == NULL) + continue; + if (strcmp(sc->sc_clk[n].base.name, name) == 0) + return &sc->sc_clk[n].base; + } + + return NULL; +} + +static void +cprman_put(void *priv, struct clk *clk) +{ +} + +static u_int +cprman_get_rate(void *priv, struct clk *baseclk) +{ + //struct cprman_softc * const sc = priv; + struct cprman_clk *clk = container_of(baseclk, struct cprman_clk, base); + + switch (clk->id) { + case CPRMAN_CLOCK_UART: + return bcm283x_clk_get_rate_uart(); + case CPRMAN_CLOCK_VPU: + return bcm283x_clk_get_rate_vpu(); + case CPRMAN_CLOCK_EMMC: + return bcm283x_clk_get_rate_emmc(); + default: + panic("unsupported clock id %d\n", clk->id); + } +} + +static const struct clk_funcs cprman_clk_funcs = { + .get = cprman_get, + .put = cprman_put, + .get_rate = cprman_get_rate, +}; + +static void +cprman_add_clock(struct cprman_softc *sc, u_int id, const char *name) +{ + sc->sc_clk[id].base.domain = &sc->sc_clkdom; + sc->sc_clk[id].base.name = name; + sc->sc_clk[id].id = id; +} + +static int +cprman_match(device_t parent, cfdata_t cf, void *aux) +{ + const char * const compatible[] = { "brcm,bcm2835-cprman", NULL }; + const struct fdt_attach_args *faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +cprman_attach(device_t parent, device_t self, void *aux) +{ + struct cprman_softc * const sc = device_private(self); + const struct fdt_attach_args *faa = aux; + const int phandle = faa->faa_phandle; + + sc->sc_dev = self; + sc->sc_phandle = phandle; + sc->sc_clkdom.funcs = &cprman_clk_funcs; + sc->sc_clkdom.priv = sc; + + cprman_add_clock(sc, CPRMAN_CLOCK_UART, "uart"); + cprman_add_clock(sc, CPRMAN_CLOCK_VPU, "vpu"); + cprman_add_clock(sc, CPRMAN_CLOCK_EMMC, "emmc"); + + aprint_naive("\n"); + aprint_normal(": BCM283x Clock Controller\n"); + + fdtbus_register_clock_controller(self, phandle, &cprman_fdt_funcs); +} + +CFATTACH_DECL_NEW(bcmcprman_fdt, sizeof(struct cprman_softc), + cprman_match, cprman_attach, NULL, NULL); Index: sys/arch/arm/broadcom/bcm2835_dmac.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_dmac.c,v retrieving revision 1.15 diff -u -p -r1.15 bcm2835_dmac.c --- sys/arch/arm/broadcom/bcm2835_dmac.c 1 Jun 2017 02:45:05 -0000 1.15 +++ sys/arch/arm/broadcom/bcm2835_dmac.c 3 Dec 2017 12:00:58 -0000 @@ -39,12 +39,15 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_dmac #include #include -#include #include #include #include +#include + +#include + #define BCM_DMAC_CHANNELMASK 0x00000fff struct bcm_dmac_softc; @@ -68,6 +71,8 @@ struct bcm_dmac_softc { device_t sc_dev; bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; + int sc_phandle; + kmutex_t sc_lock; struct bcm_dmac_channel *sc_channels; int sc_nchannels; @@ -88,21 +93,19 @@ static int bcm_dmac_intr(void *); void bcm_dmac_dump_regs(void); #endif -CFATTACH_DECL_NEW(bcmdmac_amba, sizeof(struct bcm_dmac_softc), +CFATTACH_DECL_NEW(bcmdmac_fdt, sizeof(struct bcm_dmac_softc), bcm_dmac_match, bcm_dmac_attach, NULL, NULL); static int bcm_dmac_match(device_t parent, cfdata_t cf, void *aux) { - struct amba_attach_args *aaa = aux; - - if (strcmp(aaa->aaa_name, "bcmdmac") != 0) - return 0; + const char * const compatible[] = { + "brcm,bcm2835-dma", + NULL + }; + struct fdt_attach_args * const faa = aux; - if (aaa->aaa_addr != BCM2835_DMA0_BASE) - return 0; - - return 1; + return of_match_compatible(faa->faa_phandle, compatible); } static void @@ -110,16 +113,26 @@ bcm_dmac_attach(device_t parent, device_ { struct bcm_dmac_softc *sc = device_private(self); const prop_dictionary_t cfg = device_properties(self); + struct fdt_attach_args * const faa = aux; struct bcm_dmac_channel *ch; - struct amba_attach_args *aaa = aux; uint32_t val; int index; + const int phandle = faa->faa_phandle; + sc->sc_dev = self; - sc->sc_iot = aaa->aaa_iot; + sc->sc_iot = faa->faa_bst; + sc->sc_phandle = phandle; + + bus_addr_t addr; + bus_size_t size; - if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, aaa->aaa_size, 0, - &sc->sc_ioh)) { + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": missing 'reg' property\n"); + return; + } + + if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh)) { aprint_error(": unable to map device\n"); return; } @@ -212,11 +225,21 @@ bcm_dmac_alloc(enum bcm_dmac_type type, return NULL; KASSERT(ch->ch_ih == NULL); - ch->ch_ih = intr_establish(BCM2835_INT_DMA0 + ch->ch_index, - ipl, IST_LEVEL, bcm_dmac_intr, ch); + + const int phandle = sc->sc_phandle; + char intrstr[128]; + + if (!fdtbus_intr_str(phandle, ch->ch_index, intrstr, sizeof(intrstr))) { + aprint_error(": failed to decode interrupt\n"); + return NULL; + } + + ch->ch_ih = fdtbus_intr_establish(phandle, ch->ch_index, ipl, 0, + bcm_dmac_intr, ch); if (ch->ch_ih == NULL) { aprint_error_dev(sc->sc_dev, - "failed to establish interrupt for DMA%d\n", ch->ch_index); + "failed to establish interrupt for DMA%d and %s\n", ch->ch_index, + intrstr); ch->ch_callback = NULL; ch->ch_callbackarg = NULL; ch = NULL; @@ -240,7 +263,7 @@ bcm_dmac_free(struct bcm_dmac_channel *c DMAC_WRITE(sc, DMAC_CS(ch->ch_index), val); mutex_enter(&sc->sc_lock); - intr_disestablish(ch->ch_ih); + fdtbus_intr_disestablish(sc->sc_phandle, ch->ch_ih); ch->ch_ih = NULL; ch->ch_callback = NULL; ch->ch_callbackarg = NULL; Index: sys/arch/arm/broadcom/bcm2835_dwctwo.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_dwctwo.c,v retrieving revision 1.7 diff -u -p -r1.7 bcm2835_dwctwo.c --- sys/arch/arm/broadcom/bcm2835_dwctwo.c 23 Apr 2016 10:15:27 -0000 1.7 +++ sys/arch/arm/broadcom/bcm2835_dwctwo.c 3 Dec 2017 12:00:58 -0000 @@ -40,7 +40,8 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_dwct #include #include -#include + +#include #include #include @@ -56,6 +57,7 @@ struct bcmdwc2_softc { struct dwc2_softc sc_dwc2; void *sc_ih; + int sc_phandle; }; static struct dwc2_core_params bcmdwc2_params = { @@ -99,12 +101,14 @@ CFATTACH_DECL_NEW(bcmdwctwo, sizeof(stru static int bcmdwc2_match(device_t parent, struct cfdata *match, void *aux) { - struct amba_attach_args *aaa = aux; - - if (strcmp(aaa->aaa_name, "dwctwo") != 0) - return 0; + const char * const compatible[] = { + "brcm,bcm2708-usb", + "brcm,bcm2835-usb", + NULL + }; + struct fdt_attach_args * const faa = aux; - return 1; + return of_match_compatible(faa->faa_phandle, compatible); } /* ARGSUSED */ @@ -112,44 +116,57 @@ static void bcmdwc2_attach(device_t parent, device_t self, void *aux) { struct bcmdwc2_softc *sc = device_private(self); - struct amba_attach_args *aaa = aux; + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + bus_addr_t addr; + bus_size_t size; int error; - sc->sc_dwc2.sc_dev = self; + aprint_naive(": USB controller\n"); + aprint_normal(": USB controller\n"); - sc->sc_dwc2.sc_iot = aaa->aaa_iot; - sc->sc_dwc2.sc_bus.ub_dmatag = aaa->aaa_dmat; + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + + sc->sc_phandle = phandle; + sc->sc_dwc2.sc_dev = self; + sc->sc_dwc2.sc_iot = faa->faa_bst; + sc->sc_dwc2.sc_bus.ub_dmatag = faa->faa_dmat; sc->sc_dwc2.sc_params = &bcmdwc2_params; - error = bus_space_map(aaa->aaa_iot, aaa->aaa_addr, aaa->aaa_size, 0, - &sc->sc_dwc2.sc_ioh); + error = bus_space_map(faa->faa_bst, addr, size, 0, &sc->sc_dwc2.sc_ioh); if (error) { - aprint_error_dev(self, - "can't map registers for %s: %d\n", aaa->aaa_name, error); + aprint_error(": couldn't map device\n"); return; } - aprint_naive(": USB controller\n"); - aprint_normal(": USB controller\n"); + char intrstr[128]; + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error(": failed to decode interrupt\n"); + return; + } - sc->sc_ih = intr_establish(aaa->aaa_intr, IPL_VM, - IST_LEVEL | IST_MPSAFE, dwc2_intr, &sc->sc_dwc2); + sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM, FDT_INTR_MPSAFE, + dwc2_intr, &sc->sc_dwc2); if (sc->sc_ih == NULL) { - aprint_error_dev(self, "failed to establish interrupt %d\n", - aaa->aaa_intr); + aprint_error_dev(self, "failed to establish interrupt %s\n", + intrstr); goto fail; } - config_defer(self, bcmdwc2_deferred); + aprint_normal_dev(self, "interrupting on %s\n", intrstr); + config_interrupts(self, bcmdwc2_deferred); return; fail: if (sc->sc_ih) { - intr_disestablish(sc->sc_ih); + fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih); sc->sc_ih = NULL; } - bus_space_unmap(sc->sc_dwc2.sc_iot, sc->sc_dwc2.sc_ioh, aaa->aaa_size); + bus_space_unmap(sc->sc_dwc2.sc_iot, sc->sc_dwc2.sc_ioh, size); } static void Index: sys/arch/arm/broadcom/bcm2835_emmc.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_emmc.c,v retrieving revision 1.31 diff -u -p -r1.31 bcm2835_emmc.c --- sys/arch/arm/broadcom/bcm2835_emmc.c 30 Jul 2017 16:54:36 -0000 1.31 +++ sys/arch/arm/broadcom/bcm2835_emmc.c 3 Dec 2017 12:00:58 -0000 @@ -43,13 +43,16 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_emmc #include #include -#include #include #include #include #include +#include + +#include + enum bcmemmc_dma_state { EMMC_DMA_STATE_IDLE, EMMC_DMA_STATE_BUSY, @@ -64,6 +67,7 @@ struct bcmemmc_softc { bus_size_t sc_ios; struct sdhc_host *sc_hosts[1]; void *sc_ih; + int sc_phandle; kcondvar_t sc_cv; @@ -91,12 +95,13 @@ CFATTACH_DECL_NEW(bcmemmc, sizeof(struct static int bcmemmc_match(device_t parent, struct cfdata *match, void *aux) { - struct amba_attach_args *aaa = aux; + const char * const compatible[] = { + "brcm,bcm2835-sdhci", + NULL + }; + struct fdt_attach_args * const faa = aux; - if (strcmp(aaa->aaa_name, "emmc") != 0) - return 0; - - return 1; + return of_match_compatible(faa->faa_phandle, compatible); } /* ARGSUSED */ @@ -104,14 +109,13 @@ static void bcmemmc_attach(device_t parent, device_t self, void *aux) { struct bcmemmc_softc *sc = device_private(self); + struct fdt_attach_args * const faa = aux; prop_dictionary_t dict = device_properties(self); - struct amba_attach_args *aaa = aux; - prop_number_t frequency; bool disable = false; int error; sc->sc.sc_dev = self; - sc->sc.sc_dmat = aaa->aaa_dmat; + sc->sc.sc_dmat = faa->faa_dmat; sc->sc.sc_flags = 0; sc->sc.sc_flags |= SDHC_FLAG_32BIT_ACCESS; sc->sc.sc_flags |= SDHC_FLAG_HOSTCAPS; @@ -121,7 +125,7 @@ bcmemmc_attach(device_t parent, device_t sc->sc.sc_host = sc->sc_hosts; sc->sc.sc_clkbase = 50000; /* Default to 50MHz */ - sc->sc_iot = aaa->aaa_iot; + sc->sc_iot = faa->faa_bst; prop_dictionary_get_bool(dict, "disable", &disable); if (disable) { @@ -130,34 +134,55 @@ bcmemmc_attach(device_t parent, device_t return; } - /* Fetch the EMMC clock frequency from property if set. */ - frequency = prop_dictionary_get(dict, "frequency"); - if (frequency != NULL) { - sc->sc.sc_clkbase = prop_number_integer_value(frequency) / 1000; + bus_addr_t addr; + bus_size_t size; + + const int phandle = faa->faa_phandle; + error = fdtbus_get_reg(phandle, 0, &addr, &size); + if (error) { + aprint_error_dev(sc->sc.sc_dev, "unable to map device\n"); + return; + } + sc->sc_phandle = phandle; + + /* Enable clocks */ + struct clk *clk; + for (int i = 0; (clk = fdtbus_clock_get_index(phandle, i)); i++) { + if (clk_enable(clk) != 0) { + aprint_error(": failed to enable clock #%d\n", i); + return; + } + if (i == 0) + sc->sc.sc_clkbase = clk_get_rate(clk) / 1000; } + aprint_debug_dev(self, "ref freq %u kHz\n", sc->sc.sc_clkbase); - error = bus_space_map(sc->sc_iot, aaa->aaa_addr, aaa->aaa_size, 0, - &sc->sc_ioh); + error = bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh); if (error) { - aprint_error(": can't map registers for %s: %d\n", - aaa->aaa_name, error); + aprint_error_dev(sc->sc.sc_dev, "unable to map device\n"); return; } - sc->sc_iob = aaa->aaa_addr; - sc->sc_ios = aaa->aaa_size; + sc->sc_iob = addr; + sc->sc_ios = size; aprint_naive(": SDHC controller\n"); aprint_normal(": SDHC controller\n"); - sc->sc_ih = intr_establish(aaa->aaa_intr, IPL_SDMMC, IST_LEVEL, sdhc_intr, - &sc->sc); + char intrstr[128]; + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error(": failed to decode interrupt\n"); + return; + } + + sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_SDMMC, IST_LEVEL, + sdhc_intr, &sc->sc); if (sc->sc_ih == NULL) { - aprint_error_dev(self, "failed to establish interrupt %d\n", - aaa->aaa_intr); + aprint_error_dev(self, "failed to establish interrupt %s\n", + intrstr); goto fail; } - aprint_normal_dev(self, "interrupting on intr %d\n", aaa->aaa_intr); + aprint_normal_dev(self, "interrupting on %s\n", intrstr); #if NBCMDMAC > 0 sc->sc_dmac = bcm_dmac_alloc(BCM_DMAC_TYPE_NORMAL, IPL_SDMMC, @@ -213,7 +238,7 @@ done: fail: /* XXX add bus_dma failure cleanup */ if (sc->sc_ih) { - intr_disestablish(sc->sc_ih); + fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih); sc->sc_ih = NULL; } bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); @@ -236,7 +261,7 @@ bcmemmc_attach_i(device_t self) fail: /* XXX add bus_dma failure cleanup */ if (sc->sc_ih) { - intr_disestablish(sc->sc_ih); + fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih); sc->sc_ih = NULL; } bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); @@ -248,6 +273,7 @@ bcmemmc_xfer_data_dma(struct sdhc_softc { struct bcmemmc_softc * const sc = device_private(sdhc_sc->sc_dev); kmutex_t *plock = sdhc_host_lock(sc->sc_hosts[0]); + const bus_addr_t ad_sdhcdata = sc->sc_iob + SDHC_DATA; size_t seg; int error; @@ -272,8 +298,7 @@ bcmemmc_xfer_data_dma(struct sdhc_softc if ((sc->sc_cblk[seg].cb_txfr_len & 0xf) == 0) sc->sc_cblk[seg].cb_ti |= DMAC_TI_DEST_WIDTH; sc->sc_cblk[seg].cb_ti |= DMAC_TI_SRC_DREQ; - sc->sc_cblk[seg].cb_source_ad = - sc->sc_iob + SDHC_DATA; + sc->sc_cblk[seg].cb_source_ad = ad_sdhcdata; sc->sc_cblk[seg].cb_dest_ad = cmd->c_dmamap->dm_segs[seg].ds_addr; } else { @@ -288,8 +313,7 @@ bcmemmc_xfer_data_dma(struct sdhc_softc sc->sc_cblk[seg].cb_ti |= DMAC_TI_WAIT_RESP; sc->sc_cblk[seg].cb_source_ad = cmd->c_dmamap->dm_segs[seg].ds_addr; - sc->sc_cblk[seg].cb_dest_ad = - sc->sc_iob + SDHC_DATA; + sc->sc_cblk[seg].cb_dest_ad = ad_sdhcdata; } sc->sc_cblk[seg].cb_stride = 0; if (seg == cmd->c_dmamap->dm_nsegs - 1) { Index: sys/arch/arm/broadcom/bcm2835_genfb.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_genfb.c,v retrieving revision 1.7 diff -u -p -r1.7 bcm2835_genfb.c --- sys/arch/arm/broadcom/bcm2835_genfb.c 5 Sep 2014 21:15:42 -0000 1.7 +++ sys/arch/arm/broadcom/bcm2835_genfb.c 3 Dec 2017 12:00:58 -0000 @@ -41,7 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_genf #include #include -#include +#include #include @@ -73,16 +73,17 @@ CFATTACH_DECL_NEW(bcmgenfb, sizeof(struc static int bcmgenfb_match(device_t parent, cfdata_t match, void *aux) { - struct amba_attach_args *aaa = aux; + const char * const compatible[] = { "brcm,bcm2835-vc4", NULL }; + struct fdt_attach_args * const faa = aux; - return !strcmp(aaa->aaa_name, "fb"); + return of_match_compatible(faa->faa_phandle, compatible); } static void bcmgenfb_attach(device_t parent, device_t self, void *aux) { struct bcmgenfb_softc *sc = device_private(self); - struct amba_attach_args *aaa = aux; + struct fdt_attach_args * const faa = aux; prop_dictionary_t dict = device_properties(self); static const struct genfb_ops zero_ops; struct genfb_ops ops = zero_ops; @@ -90,7 +91,7 @@ bcmgenfb_attach(device_t parent, device_ int error; sc->sc_gen.sc_dev = self; - sc->sc_iot = aaa->aaa_iot; + sc->sc_iot = faa->faa_bst; sc->sc_wstype = WSDISPLAY_TYPE_VC4; prop_dictionary_get_uint32(dict, "wsdisplay_type", &sc->sc_wstype); Index: sys/arch/arm/broadcom/bcm2835_gpio.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_gpio.c,v retrieving revision 1.5 diff -u -p -r1.5 bcm2835_gpio.c --- sys/arch/arm/broadcom/bcm2835_gpio.c 9 Nov 2017 21:37:52 -0000 1.5 +++ sys/arch/arm/broadcom/bcm2835_gpio.c 3 Dec 2017 12:00:58 -0000 @@ -1,11 +1,11 @@ /* $NetBSD: bcm2835_gpio.c,v 1.5 2017/11/09 21:37:52 skrll Exp $ */ /*- - * Copyright (c) 2014 The NetBSD Foundation, Inc. + * Copyright (c) 2013, 2014, 2017 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation - * by Frank Kardel. + * by Jonathan A. Kollasch, Frank Kardel and Nick Hudson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -38,8 +38,6 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_gpio * see: http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf */ -#include "gpio.h" - #include #include #include @@ -47,15 +45,16 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_gpio #include #include #include +#include #include -#include #include -#include #include #include -#include + +#include +#include /* #define BCM2835_GPIO_DEBUG */ #ifdef BCM2835_GPIO_DEBUG @@ -65,98 +64,191 @@ int bcm2835gpiodebug = 3; #define DPRINTF(l, x) #endif +#define BCMGPIO_MAXPINS 54 + struct bcmgpio_softc { device_t sc_dev; bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; struct gpio_chipset_tag sc_gpio_gc; - gpio_pin_t sc_gpio_pins[32]; + + kmutex_t sc_lock; + gpio_pin_t sc_gpio_pins[BCMGPIO_MAXPINS]; +}; + +struct bcmgpio_pin { + int pin_no; + u_int pin_flags; + bool pin_actlo; }; + static int bcmgpio_match(device_t, cfdata_t, void *); static void bcmgpio_attach(device_t, device_t, void *); -#if NGPIO > 0 -static int bcm2835gpio_gpio_pin_read(void *, int); -static void bcm2835gpio_gpio_pin_write(void *, int, int); -static void bcm2835gpio_gpio_pin_ctl(void *, int, int); -#endif +static int bcm2835gpio_gpio_pin_read(void *, int); +static void bcm2835gpio_gpio_pin_write(void *, int, int); +static void bcm2835gpio_gpio_pin_ctl(void *, int, int); + +u_int bcm283x_pin_getfunc(const struct bcmgpio_softc * const, u_int); +void bcm283x_pin_setfunc(const struct bcmgpio_softc * const, u_int, + u_int); +void bcm283x_pin_setpull(const struct bcmgpio_softc * const, u_int, + u_int); + +static int bcm283x_pinctrl_set_config(device_t, const void *, size_t); + +static void * bcmgpio_fdt_acquire(device_t, const void *, size_t, int); +static void bcmgpio_fdt_release(device_t, void *); +static int bcmgpio_fdt_read(device_t, void *, bool); +static void bcmgpio_fdt_write(device_t, void *, int, bool); + +static struct fdtbus_gpio_controller_func bcmgpio_funcs = { + .acquire = bcmgpio_fdt_acquire, + .release = bcmgpio_fdt_release, + .read = bcmgpio_fdt_read, + .write = bcmgpio_fdt_write +}; CFATTACH_DECL_NEW(bcmgpio, sizeof(struct bcmgpio_softc), bcmgpio_match, bcmgpio_attach, NULL, NULL); + +static struct fdtbus_pinctrl_controller_func bcm283x_pinctrl_funcs = { + .set_config = bcm283x_pinctrl_set_config, +}; + static int -bcmgpio_match(device_t parent, cfdata_t cf, void *aux) +bcm283x_pinctrl_set_config(device_t dev, const void *data, size_t len) { - struct amba_attach_args * const aaa = aux; + struct bcmgpio_softc * const sc = device_private(dev); - if (strcmp(aaa->aaa_name, "bcmgpio") != 0) - return 0; + if (len != 4) + return -1; - return 1; + const int phandle = fdtbus_get_phandle_from_native(be32dec(data)); + + /* + * Required: brcm,pins + * Optional: brcm,function, brcm,pull + */ + + int pins_len; + const u_int *pins = fdtbus_get_prop(phandle, "brcm,pins", &pins_len); + + if (pins == NULL) + return -1; + + int pull_len = 0; + const u_int *pull = fdtbus_get_prop(phandle, "brcm,pull", &pull_len); + + int func_len = 0; + const u_int *func = fdtbus_get_prop(phandle, "brcm,function", &func_len); + + if (!pull && !func) { + aprint_error_dev(dev, "one of brcm,pull or brcm,funcion must " + "be specified"); + return -1; + } + + const int npins = pins_len / 4; + const int npull = pull_len / 4; + const int nfunc = func_len / 4; + + if (npull > 1 && npull != npins) { + aprint_error_dev(dev, "brcm,pull must have 1 or %d entries", + npins); + return -1; + } + if (nfunc > 1 && nfunc != npins) { + aprint_error_dev(dev, "brcm,function must have 1 or %d entries", + npins); + return -1; + } + + mutex_enter(&sc->sc_lock); + + for (int i = 0; i < npins; i++) { + const u_int pin = be32toh(pins[i]); + + if (pin > BCMGPIO_MAXPINS) + continue; + if (pull) { + const int value = be32toh(pull[npull == 1 ? 0 : i]); + bcm283x_pin_setpull(sc, pin, value); + } + if (func) { + const int value = be32toh(func[nfunc == 1 ? 0 : i]); + bcm283x_pin_setfunc(sc, pin, value); + } + } + + mutex_exit(&sc->sc_lock); + + return 0; +} + +static int +bcmgpio_match(device_t parent, cfdata_t cf, void *aux) +{ + const char * const compatible[] = { "brcm,bcm2835-gpio", NULL }; + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); } static void bcmgpio_attach(device_t parent, device_t self, void *aux) { struct bcmgpio_softc * const sc = device_private(self); -#if NGPIO > 0 - struct amba_attach_args *aaa = aux; + struct fdt_attach_args * const faa = aux; struct gpiobus_attach_args gba; - int pin, minpin, maxpin; + bus_addr_t addr; + bus_size_t size; u_int func; int error; -#endif + int pin; - sc->sc_dev = self; - -#if NGPIO > 0 - if (device_unit(sc->sc_dev) > 1) { - aprint_naive(" NO GPIO\n"); - aprint_normal(": NO GPIO\n"); + const int phandle = faa->faa_phandle; + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); return; - } else if (device_unit(sc->sc_dev) == 1) { - maxpin = 53; - minpin = 32; - } else { - maxpin = 31; - minpin = 0; } + sc->sc_dev = self; + aprint_naive("\n"); - aprint_normal(": GPIO [%d...%d]\n", minpin, maxpin); + aprint_normal(": GPIO controller\n"); - sc->sc_iot = aaa->aaa_iot; - error = bus_space_map(sc->sc_iot, aaa->aaa_addr, aaa->aaa_size, 0, - &sc->sc_ioh); + sc->sc_iot = faa->faa_bst; + error = bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh); if (error) { - aprint_error_dev(self, - "can't map registers for %s: %d\n", aaa->aaa_name, error); + aprint_error_dev(self, "couldn't map registers\n"); return; } - for (pin = minpin; pin <= maxpin; pin++) { - int epin = pin - minpin; + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); - sc->sc_gpio_pins[epin].pin_num = epin; + for (pin = 0; pin < BCMGPIO_MAXPINS; pin++) { + sc->sc_gpio_pins[pin].pin_num = pin; /* * find out pins still available for GPIO */ - func = bcm2835gpio_function_read(pin); + func = bcm283x_pin_getfunc(sc, pin); if (func == BCM2835_GPIO_IN || func == BCM2835_GPIO_OUT) { - sc->sc_gpio_pins[epin].pin_caps = GPIO_PIN_INPUT | + sc->sc_gpio_pins[pin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_PUSHPULL | GPIO_PIN_TRISTATE | GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN; /* read initial state */ - sc->sc_gpio_pins[epin].pin_state = - bcm2835gpio_gpio_pin_read(sc, epin); + sc->sc_gpio_pins[pin].pin_state = + bcm2835gpio_gpio_pin_read(sc, pin); DPRINTF(1, ("%s: attach pin %d\n", device_xname(sc->sc_dev), pin)); } else { - sc->sc_gpio_pins[epin].pin_caps = 0; - sc->sc_gpio_pins[epin].pin_state = 0; + sc->sc_gpio_pins[pin].pin_caps = 0; + sc->sc_gpio_pins[pin].pin_state = 0; DPRINTF(1, ("%s: skip pin %d - func = 0x%x\n", device_xname(sc->sc_dev), pin, func)); } } @@ -168,36 +260,42 @@ bcmgpio_attach(device_t parent, device_t sc->sc_gpio_gc.gp_pin_ctl = bcm2835gpio_gpio_pin_ctl; gba.gba_gc = &sc->sc_gpio_gc; - gba.gba_pins = sc->sc_gpio_pins; - gba.gba_npins = maxpin - minpin + 1; + for (pin = 0; pin < BCMGPIO_MAXPINS;) { + const int npins = MIN(BCMGPIO_MAXPINS - pin, 32); + gba.gba_pins = &sc->sc_gpio_pins[pin]; + gba.gba_npins = npins; + config_found_ia(self, "gpiobus", &gba, gpiobus_print); + pin += npins; + } - config_found_ia(self, "gpiobus", &gba, gpiobus_print); -#else - aprint_normal_dev(sc->sc_dev, "no GPIO configured in kernel"); -#endif + fdtbus_register_gpio_controller(self, faa->faa_phandle, &bcmgpio_funcs); + + for (int child = OF_child(phandle); child; child = OF_peer(child)) { + if (!of_hasprop(child, "brcm,pins")) + continue; + fdtbus_register_pinctrl_config(self, child, + &bcm283x_pinctrl_funcs); + } + + fdtbus_pinctrl_configure(); } -#if NGPIO > 0 /* GPIO support functions */ static int bcm2835gpio_gpio_pin_read(void *arg, int pin) { struct bcmgpio_softc *sc = arg; - int epin = pin + device_unit(sc->sc_dev) * 32; uint32_t val; int res; - if (device_unit(sc->sc_dev) > 1) { - return 0; - } - val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, - BCM2835_GPIO_GPLEV(epin / BCM2835_GPIO_GPLEV_PINS_PER_REGISTER)); + BCM2835_GPIO_GPLEV(pin / BCM2835_GPIO_GPLEV_PINS_PER_REGISTER)); - res = val & (1 << (epin % BCM2835_GPIO_GPLEV_PINS_PER_REGISTER)) ? + res = val & (1 << (pin % BCM2835_GPIO_GPLEV_PINS_PER_REGISTER)) ? GPIO_PIN_HIGH : GPIO_PIN_LOW; - DPRINTF(2, ("%s: gpio_read pin %d->%d\n", device_xname(sc->sc_dev), epin, (res == GPIO_PIN_HIGH))); + DPRINTF(2, ("%s: gpio_read pin %d->%d\n", device_xname(sc->sc_dev), + pin, (res == GPIO_PIN_HIGH))); return res; } @@ -206,43 +304,97 @@ static void bcm2835gpio_gpio_pin_write(void *arg, int pin, int value) { struct bcmgpio_softc *sc = arg; - int epin = pin + device_unit(sc->sc_dev) * 32; bus_size_t reg; - if (device_unit(sc->sc_dev) > 1) { - return; - } - if (value == GPIO_PIN_HIGH) { - reg = BCM2835_GPIO_GPSET(epin / BCM2835_GPIO_GPSET_PINS_PER_REGISTER); + reg = BCM2835_GPIO_GPSET(pin / BCM2835_GPIO_GPSET_PINS_PER_REGISTER); } else { - reg = BCM2835_GPIO_GPCLR(epin / BCM2835_GPIO_GPCLR_PINS_PER_REGISTER); + reg = BCM2835_GPIO_GPCLR(pin / BCM2835_GPIO_GPCLR_PINS_PER_REGISTER); } - bus_space_write_4(sc->sc_iot, sc->sc_ioh, - reg, 1 << (epin % BCM2835_GPIO_GPSET_PINS_PER_REGISTER)); - DPRINTF(2, ("%s: gpio_write pin %d<-%d\n", device_xname(sc->sc_dev), epin, (value == GPIO_PIN_HIGH))); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg, + 1 << (pin % BCM2835_GPIO_GPSET_PINS_PER_REGISTER)); + + DPRINTF(2, ("%s: gpio_write pin %d<-%d\n", device_xname(sc->sc_dev), + pin, (value == GPIO_PIN_HIGH))); +} + + +void +bcm283x_pin_setfunc(const struct bcmgpio_softc * const sc, u_int pin, + u_int func) +{ + const u_int mask = (1 << BCM2835_GPIO_GPFSEL_BITS_PER_PIN) - 1; + const u_int regid = (pin / BCM2835_GPIO_GPFSEL_PINS_PER_REGISTER); + const u_int shift = (pin % BCM2835_GPIO_GPFSEL_PINS_PER_REGISTER) * + BCM2835_GPIO_GPFSEL_BITS_PER_PIN; + uint32_t v; + + KASSERT(mutex_owned(&sc->sc_lock)); + KASSERT(func <= mask); + + v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, BCM2835_GPIO_GPFSEL(regid)); + + if (((v >> shift) & mask) == func) { + return; + } + + DPRINTF(2, ("%s: gpio_write pin %d<-%d\n", device_xname(sc->sc_dev), + pin, func)); + + v &= ~(mask << shift); + v |= (func << shift); + + bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_GPIO_GPFSEL(regid), v); +} + +u_int +bcm283x_pin_getfunc(const struct bcmgpio_softc * const sc, u_int pin) +{ + const u_int mask = (1 << BCM2835_GPIO_GPFSEL_BITS_PER_PIN) - 1; + const u_int regid = (pin / BCM2835_GPIO_GPFSEL_PINS_PER_REGISTER); + const u_int shift = (pin % BCM2835_GPIO_GPFSEL_PINS_PER_REGISTER) * + BCM2835_GPIO_GPFSEL_BITS_PER_PIN; + uint32_t v; + + v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, BCM2835_GPIO_GPFSEL(regid)); + + return ((v >> shift) & mask); +} + +void +bcm283x_pin_setpull(const struct bcmgpio_softc * const sc, u_int pin, u_int pud) +{ + + KASSERT(mutex_owned(&sc->sc_lock)); + + const u_int mask = 1 << (pin % BCM2835_GPIO_GPPUD_PINS_PER_REGISTER); + const u_int regid = (pin / BCM2835_GPIO_GPPUD_PINS_PER_REGISTER); + + bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_GPIO_GPPUD, pud); + delay(1); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_GPIO_GPPUDCLK(regid), mask); + delay(1); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_GPIO_GPPUD, 0); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_GPIO_GPPUDCLK(regid), 0); } + static void bcm2835gpio_gpio_pin_ctl(void *arg, int pin, int flags) { struct bcmgpio_softc *sc = arg; uint32_t cmd; - int epin = pin + device_unit(sc->sc_dev) * 32; - - if (device_unit(sc->sc_dev) > 1) { - return; - } - DPRINTF(2, ("%s: gpio_ctl pin %d flags 0x%x\n", device_xname(sc->sc_dev), epin, flags)); + DPRINTF(2, ("%s: gpio_ctl pin %d flags 0x%x\n", device_xname(sc->sc_dev), pin, flags)); + mutex_enter(&sc->sc_lock); if (flags & (GPIO_PIN_OUTPUT|GPIO_PIN_INPUT)) { if ((flags & GPIO_PIN_INPUT) || !(flags & GPIO_PIN_OUTPUT)) { /* for safety INPUT will overide output */ - bcm2835gpio_function_select(epin, BCM2835_GPIO_IN); + bcm283x_pin_setfunc(sc, pin, BCM2835_GPIO_IN); } else { - bcm2835gpio_function_select(epin, BCM2835_GPIO_OUT); + bcm283x_pin_setfunc(sc, pin, BCM2835_GPIO_OUT); } } @@ -254,19 +406,81 @@ bcm2835gpio_gpio_pin_ctl(void *arg, int } /* set up control signal */ - bus_space_write_4(sc->sc_iot, sc->sc_ioh, - BCM2835_GPIO_GPPUD, cmd); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_GPIO_GPPUD, cmd); delay(1); /* wait 150 cycles */ /* set clock signal */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, - BCM2835_GPIO_GPPUDCLK(device_unit(sc->sc_dev)), - 1 << (epin % BCM2835_GPIO_GPPUD_PINS_PER_REGISTER)); + BCM2835_GPIO_GPPUDCLK(pin / BCM2835_GPIO_GPLEV_PINS_PER_REGISTER), + 1 << (pin % BCM2835_GPIO_GPPUD_PINS_PER_REGISTER)); delay(1); /* wait 150 cycles */ /* reset control signal and clock */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, - BCM2835_GPIO_GPPUD, BCM2835_GPIO_GPPUD_PULLOFF); + BCM2835_GPIO_GPPUD, BCM2835_GPIO_GPPUD_PULLOFF); bus_space_write_4(sc->sc_iot, sc->sc_ioh, - BCM2835_GPIO_GPPUDCLK(device_unit(sc->sc_dev)), - 0); + BCM2835_GPIO_GPPUDCLK(pin / BCM2835_GPIO_GPLEV_PINS_PER_REGISTER), + 0); + mutex_exit(&sc->sc_lock); +} + +static void * +bcmgpio_fdt_acquire(device_t dev, const void *data, size_t len, int flags) +{ + struct bcmgpio_softc *sc = device_private(dev); + struct bcmgpio_pin *gpin; + const u_int *gpio = data; + + if (len != 12) + return NULL; + + const u_int pin = be32toh(gpio[1]); + const bool actlo = be32toh(gpio[2]) & 1; + + if (pin >= BCMGPIO_MAXPINS) + return NULL; + + gpin = kmem_alloc(sizeof(*gpin), KM_SLEEP); + gpin->pin_no = pin; + gpin->pin_flags = flags; + gpin->pin_actlo = actlo; + + bcm2835gpio_gpio_pin_ctl(sc, gpin->pin_no, gpin->pin_flags); + + return gpin; +} + +static void +bcmgpio_fdt_release(device_t dev, void *priv) +{ + struct bcmgpio_softc *sc = device_private(dev); + struct bcmgpio_pin *gpin = priv; + + bcm2835gpio_gpio_pin_ctl(sc, gpin->pin_no, GPIO_PIN_INPUT); + kmem_free(gpin, sizeof(*gpin)); +} + +static int +bcmgpio_fdt_read(device_t dev, void *priv, bool raw) +{ + struct bcmgpio_softc *sc = device_private(dev); + struct bcmgpio_pin *gpin = priv; + int val; + + val = bcm2835gpio_gpio_pin_read(sc, gpin->pin_no); + + if (!raw && gpin->pin_actlo) + val = !val; + + return val; +} + +static void +bcmgpio_fdt_write(device_t dev, void *priv, int val, bool raw) +{ + struct bcmgpio_softc *sc = device_private(dev); + struct bcmgpio_pin *gpin = priv; + + if (!raw && gpin->pin_actlo) + val = !val; + + bcm2835gpio_gpio_pin_write(sc, gpin->pin_no, val); } -#endif /* NGPIO > 0 */ Index: sys/arch/arm/broadcom/bcm2835_gpio_subr.c =================================================================== RCS file: sys/arch/arm/broadcom/bcm2835_gpio_subr.c diff -N sys/arch/arm/broadcom/bcm2835_gpio_subr.c --- sys/arch/arm/broadcom/bcm2835_gpio_subr.c 30 Jul 2017 17:32:59 -0000 1.5 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,103 +0,0 @@ -/* $NetBSD: bcm2835_gpio_subr.c,v 1.5 2017/07/30 17:32:59 jmcneill Exp $ */ - -/* - * Copyright (c) 2013 Jonathan A. Kollasch - * 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 -__KERNEL_RCSID(0, "$NetBSD: bcm2835_gpio_subr.c,v 1.5 2017/07/30 17:32:59 jmcneill Exp $"); - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -void -bcm2835gpio_function_select(u_int pin, u_int func) -{ - const paddr_t iop = BCM2835_PERIPHERALS_BUS_TO_PHYS(BCM2835_GPIO_BASE); - const bus_space_tag_t iot = &bcm2835_bs_tag; - const bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(iop); - const u_int mask = (1 << BCM2835_GPIO_GPFSEL_BITS_PER_PIN) - 1; - const u_int regid = (pin / BCM2835_GPIO_GPFSEL_PINS_PER_REGISTER); - const u_int shift = (pin % BCM2835_GPIO_GPFSEL_PINS_PER_REGISTER) * - BCM2835_GPIO_GPFSEL_BITS_PER_PIN; - uint32_t v; - - KASSERT(func <= mask); - - v = bus_space_read_4(iot, ioh, BCM2835_GPIO_GPFSEL(regid)); - - if (((v >> shift) & mask) == func) { - return; - } - - aprint_debug("bcm2835: changing FSEL%u to %#o\n", pin, func); - - v &= ~(mask << shift); - v |= (func << shift); - - bus_space_write_4(iot, ioh, BCM2835_GPIO_GPFSEL(regid), v); -} - -u_int -bcm2835gpio_function_read(u_int pin) -{ - const paddr_t iop = BCM2835_PERIPHERALS_BUS_TO_PHYS(BCM2835_GPIO_BASE); - const bus_space_tag_t iot = &bcm2835_bs_tag; - const bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(iop); - const u_int mask = (1 << BCM2835_GPIO_GPFSEL_BITS_PER_PIN) - 1; - const u_int regid = (pin / BCM2835_GPIO_GPFSEL_PINS_PER_REGISTER); - const u_int shift = (pin % BCM2835_GPIO_GPFSEL_PINS_PER_REGISTER) * - BCM2835_GPIO_GPFSEL_BITS_PER_PIN; - uint32_t v; - - v = bus_space_read_4(iot, ioh, BCM2835_GPIO_GPFSEL(regid)); - - return ((v >> shift) & mask); -} - -void -bcm2835gpio_function_setpull(u_int pin, u_int pud) -{ - const paddr_t iop = BCM2835_PERIPHERALS_BUS_TO_PHYS(BCM2835_GPIO_BASE); - const bus_space_tag_t iot = &bcm2835_bs_tag; - const bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(iop); - const u_int mask = 1 << (pin % BCM2835_GPIO_GPPUD_PINS_PER_REGISTER); - const u_int regid = (pin / BCM2835_GPIO_GPPUD_PINS_PER_REGISTER); - - bus_space_write_4(iot, ioh, BCM2835_GPIO_GPPUD, pud); - delay(1); - bus_space_write_4(iot, ioh, BCM2835_GPIO_GPPUDCLK(regid), mask); - delay(1); - bus_space_write_4(iot, ioh, BCM2835_GPIO_GPPUD, 0); - bus_space_write_4(iot, ioh, BCM2835_GPIO_GPPUDCLK(regid), 0); -} Index: sys/arch/arm/broadcom/bcm2835_gpio_subr.h =================================================================== RCS file: sys/arch/arm/broadcom/bcm2835_gpio_subr.h diff -N sys/arch/arm/broadcom/bcm2835_gpio_subr.h --- sys/arch/arm/broadcom/bcm2835_gpio_subr.h 30 Jul 2017 17:32:59 -0000 1.3 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,38 +0,0 @@ -/* $NetBSD: bcm2835_gpio_subr.h,v 1.3 2017/07/30 17:32:59 jmcneill Exp $ */ - -/* - * Copyright (c) 2013 Jonathan A. Kollasch - * 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. - */ - -#ifndef _BROADCOM_BCM2835_GPIO_SUBR_H_ -#define _BROADCOM_BCM2835_GPIO_SUBR_H_ - -#include - -void bcm2835gpio_function_select(u_int, u_int); -u_int bcm2835gpio_function_read(u_int); -void bcm2835gpio_function_setpull(u_int, u_int); - -#endif /* _BROADCOM_BCM2835_GPIOVAR_H_ */ Index: sys/arch/arm/broadcom/bcm2835_gpioreg.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_gpioreg.h,v retrieving revision 1.3 diff -u -p -r1.3 bcm2835_gpioreg.h --- sys/arch/arm/broadcom/bcm2835_gpioreg.h 22 Apr 2014 18:51:35 -0000 1.3 +++ sys/arch/arm/broadcom/bcm2835_gpioreg.h 3 Dec 2017 12:00:58 -0000 @@ -46,20 +46,23 @@ #define BCM2835_GPIO_GPLEN(x) (0x070 + (x) * sizeof(uint32_t)) #define BCM2835_GPIO_GPAREN(x) (0x07C + (x) * sizeof(uint32_t)) #define BCM2835_GPIO_GPAFEN(x) (0x088 + (x) * sizeof(uint32_t)) + #define BCM2835_GPIO_GPPUD (0x094) -#define BCM2835_GPIO_GPPUD_PULLOFF 0x0 -#define BCM2835_GPIO_GPPUD_PULLDOWN 0x1 -#define BCM2835_GPIO_GPPUD_PULLUP 0x2 +/* brcm,pull property */ +#define BCM2835_GPIO_GPPUD_PULLOFF 0x0 +#define BCM2835_GPIO_GPPUD_PULLDOWN 0x1 +#define BCM2835_GPIO_GPPUD_PULLUP 0x2 #define BCM2835_GPIO_GPPUDCLK(x) (0x098 + (x) * sizeof(uint32_t)) #define BCM2835_GPIO_GPPUD_PINS_PER_REGISTER 32 -#define BCM2835_GPIO_IN 00 -#define BCM2835_GPIO_OUT 01 -#define BCM2835_GPIO_ALT5 02 -#define BCM2835_GPIO_ALT4 03 -#define BCM2835_GPIO_ALT0 04 -#define BCM2835_GPIO_ALT1 05 -#define BCM2835_GPIO_ALT2 06 -#define BCM2835_GPIO_ALT3 07 +/* brcm,function property */ +#define BCM2835_GPIO_IN 0 +#define BCM2835_GPIO_OUT 1 +#define BCM2835_GPIO_ALT5 2 +#define BCM2835_GPIO_ALT4 3 +#define BCM2835_GPIO_ALT0 4 +#define BCM2835_GPIO_ALT1 5 +#define BCM2835_GPIO_ALT2 6 +#define BCM2835_GPIO_ALT3 7 #endif /* _BROADCOM_BCM2835_GPIOREG_H_ */ Index: sys/arch/arm/broadcom/bcm2835_intr.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_intr.c,v retrieving revision 1.14 diff -u -p -r1.14 bcm2835_intr.c --- sys/arch/arm/broadcom/bcm2835_intr.c 7 Nov 2017 09:05:05 -0000 1.14 +++ sys/arch/arm/broadcom/bcm2835_intr.c 3 Dec 2017 12:00:58 -0000 @@ -42,6 +42,8 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_intr #include #include +#include + #include #include @@ -49,10 +51,15 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_intr #include #include -#include +#include #include #include +#include + +static void bcm2835_irq_handler(void *); +static void bcm2836mp_intr_init(void *, struct cpu_info *); + static void bcm2835_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t); static void bcm2835_pic_block_irqs(struct pic_softc *, size_t, uint32_t); static int bcm2835_pic_find_pending_irqs(struct pic_softc *); @@ -60,7 +67,6 @@ static void bcm2835_pic_establish_irq(st static void bcm2835_pic_source_name(struct pic_softc *, int, char *, size_t); -#if defined(BCM2836) static void bcm2836mp_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t); static void bcm2836mp_pic_block_irqs(struct pic_softc *, size_t, uint32_t); static int bcm2836mp_pic_find_pending_irqs(struct pic_softc *); @@ -72,17 +78,34 @@ int bcm2836mp_ipi_handler(void *); static void bcm2836mp_cpu_init(struct pic_softc *, struct cpu_info *); static void bcm2836mp_send_ipi(struct pic_softc *, const kcpuset_t *, u_long); #endif -#endif + +static int bcm2835_icu_fdt_decode_irq(u_int *); +static void *bcm2835_icu_fdt_establish(device_t, u_int *, int, int, + int (*)(void *), void *); +static void bcm2835_icu_fdt_disestablish(device_t, void *); +static bool bcm2835_icu_fdt_intrstr(device_t, u_int *, char *, size_t); + +static int bcm2836mp_icu_fdt_decode_irq(u_int *); +static void *bcm2836mp_icu_fdt_establish(device_t, u_int *, int, int, + int (*)(void *), void *); +static void bcm2836mp_icu_fdt_disestablish(device_t, void *); +static bool bcm2836mp_icu_fdt_intrstr(device_t, u_int *, char *, size_t); static int bcm2835_icu_match(device_t, cfdata_t, void *); static void bcm2835_icu_attach(device_t, device_t, void *); +static void +bcm2835_set_priority(struct pic_softc *pic, int ipl) +{ +} + static struct pic_ops bcm2835_picops = { .pic_unblock_irqs = bcm2835_pic_unblock_irqs, .pic_block_irqs = bcm2835_pic_block_irqs, .pic_find_pending_irqs = bcm2835_pic_find_pending_irqs, .pic_establish_irq = bcm2835_pic_establish_irq, .pic_source_name = bcm2835_pic_source_name, + .pic_set_priority = bcm2835_set_priority, }; struct pic_softc bcm2835_pic = { @@ -91,7 +114,6 @@ struct pic_softc bcm2835_pic = { .pic_name = "bcm2835 pic", }; -#if defined(BCM2836) static struct pic_ops bcm2836mp_picops = { .pic_unblock_irqs = bcm2836mp_pic_unblock_irqs, .pic_block_irqs = bcm2836mp_pic_block_irqs, @@ -111,15 +133,28 @@ struct pic_softc bcm2836mp_pic[BCM2836_N .pic_name = "bcm2836 pic", } }; -#endif + +static struct fdtbus_interrupt_controller_func bcm2835icu_fdt_funcs = { + .establish = bcm2835_icu_fdt_establish, + .disestablish = bcm2835_icu_fdt_disestablish, + .intrstr = bcm2835_icu_fdt_intrstr +}; + +static struct fdtbus_interrupt_controller_func bcm2836mpicu_fdt_funcs = { + .establish = bcm2836mp_icu_fdt_establish, + .disestablish = bcm2836mp_icu_fdt_disestablish, + .intrstr = bcm2836mp_icu_fdt_intrstr +}; struct bcm2835icu_softc { device_t sc_dev; bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; - struct pic_softc *sc_pic; + + int sc_phandle; }; +struct bcm2835icu_softc *bcml1icu_sc; struct bcm2835icu_softc *bcmicu_sc; #define read_bcm2835reg(o) \ @@ -154,12 +189,10 @@ static const char * const bcm2835_source "GPU0 Halted", "GPU1 Halted", "Illegal #1", "Illegal #0" }; -#if defined(BCM2836) static const char * const bcm2836mp_sources[BCM2836_NIRQPERCPU] = { "cntpsirq", "cntpnsirq", "cnthpirq", "cntvirq", "mailbox0", "mailbox1", "mailbox2", "mailbox3", }; -#endif #define BCM2836_INTBIT_GPUPENDING __BIT(8) @@ -175,46 +208,82 @@ CFATTACH_DECL_NEW(bcmicu, sizeof(struct static int bcm2835_icu_match(device_t parent, cfdata_t cf, void *aux) { - struct amba_attach_args *aaa = aux; - - if (strcmp(aaa->aaa_name, "icu") != 0) - return 0; + const char * const compatible[] = { + "brcm,bcm2708-armctrl-ic", + "brcm,bcm2709-armctrl-ic", + "brcm,bcm2835-armctrl-ic", + "brcm,bcm2836-armctrl-ic", + "brcm,bcm2836-l1-intc", + NULL + }; + struct fdt_attach_args * const faa = aux; - return 1; + return of_match_compatible(faa->faa_phandle, compatible); } static void bcm2835_icu_attach(device_t parent, device_t self, void *aux) { - struct bcm2835icu_softc *sc = device_private(self); - struct amba_attach_args *aaa = aux; + struct bcm2835icu_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + struct fdtbus_interrupt_controller_func *ifuncs; + const int phandle = faa->faa_phandle; + bus_addr_t addr; + bus_size_t size; + bus_space_handle_t ioh; + int error; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } sc->sc_dev = self; - sc->sc_iot = aaa->aaa_iot; - sc->sc_pic = &bcm2835_pic; + sc->sc_iot = faa->faa_bst; - if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, aaa->aaa_size, 0, - &sc->sc_ioh)) { - aprint_error_dev(self, "unable to map device\n"); + if (bus_space_map(sc->sc_iot, addr, size, 0, &ioh) != 0) { + aprint_error(": couldn't map device\n"); return; } - bcmicu_sc = sc; + sc->sc_ioh = ioh; + sc->sc_phandle = phandle; -#if defined(BCM2836) + const char * const local_intc[] = { "brcm,bcm2836-l1-intc", NULL }; + if (of_match_compatible(faa->faa_phandle, local_intc)) { #if defined(MULTIPROCESSOR) - aprint_normal(": Multiprocessor"); - bcm2836mp_intr_init(curcpu()); -#else - pic_add(&bcm2836mp_pic[0], BCM2836_INT_BASECPUN(0)); + aprint_normal(": Multiprocessor"); #endif -#endif /* BCM2836 */ - pic_add(sc->sc_pic, BCM2835_INT_BASE); + bcml1icu_sc = sc; + bus_space_write_4(sc->sc_iot, sc->sc_ioh, + BCM2836_LOCAL_CONTROL, 0); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, + BCM2836_LOCAL_PRESCALER, 0x80000000); + + ifuncs = &bcm2836mpicu_fdt_funcs; + + bcm2836mp_intr_init(self, curcpu()); + arm_fdt_cpu_hatch_register(self, bcm2836mp_intr_init); + } else { + if (bcml1icu_sc == NULL) + arm_fdt_irq_set_handler(bcm2835_irq_handler); + bcmicu_sc = sc; + sc->sc_ioh = ioh; + sc->sc_phandle = phandle; + pic_add(&bcm2835_pic, BCM2835_INT_BASE); + ifuncs = &bcm2835icu_fdt_funcs; + } + + error = fdtbus_register_interrupt_controller(self, phandle, ifuncs); + if (error != 0) { + aprint_error(": couldn't register with fdtbus: %d\n", error); + return; + } aprint_normal("\n"); } -void +static void bcm2835_irq_handler(void *frame) { struct cpu_info * const ci = curcpu(); @@ -229,7 +298,7 @@ bcm2835_irq_handler(void *frame) if (cpuid == 0) { ipl_mask = bcm2835_pic_find_pending_irqs(&bcm2835_pic); } -#if defined(BCM2836) +#if defined(SOC_BCM2836) ipl_mask |= bcm2836mp_pic_find_pending_irqs(&bcm2836mp_pic[cpuid]); #endif @@ -315,14 +384,74 @@ bcm2835_pic_source_name(struct pic_softc strlcpy(buf, bcm2835_sources[irq], len); } +static int +bcm2835_icu_fdt_decode_irq(u_int *specifier) +{ + u_int base; + + if (!specifier) + return -1; + + /* 1st cell is the bank number. 0 = ARM, 1 = GPU0, 2 = GPU1 */ + /* 2nd cell is the irq relative to that bank */ + + const u_int bank = be32toh(specifier[0]); + switch (bank) { + case 0: + base = BCM2835_INT_BASICBASE; + break; + case 1: + base = BCM2835_INT_GPU0BASE; + break; + case 2: + base = BCM2835_INT_GPU1BASE; + break; + default: + return -1; + } + const u_int off = be32toh(specifier[1]); + + return base + off; +} + +static void * +bcm2835_icu_fdt_establish(device_t dev, u_int *specifier, int ipl, int flags, + int (*func)(void *), void *arg) +{ + int iflags = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0; + int irq; + + irq = bcm2835_icu_fdt_decode_irq(specifier); + if (irq == -1) + return NULL; -#if defined(BCM2836) + return intr_establish(irq, ipl, IST_LEVEL | iflags, func, arg); +} + +static void +bcm2835_icu_fdt_disestablish(device_t dev, void *ih) +{ + intr_disestablish(ih); +} + +static bool +bcm2835_icu_fdt_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen) +{ + int irq; + + irq = bcm2835_icu_fdt_decode_irq(specifier); + if (irq == -1) + return false; + + snprintf(buf, buflen, "icu irq %d", irq); + + return true; +} #define BCM2836MP_TIMER_IRQS __BITS(3,0) #define BCM2836MP_MAILBOX_IRQS __BITS(4,4) -#define BCM2836MP_ALL_IRQS \ - (BCM2836MP_TIMER_IRQS | BCM2836MP_MAILBOX_IRQS) +#define BCM2836MP_ALL_IRQS (BCM2836MP_TIMER_IRQS | BCM2836MP_MAILBOX_IRQS) static void bcm2836mp_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase, @@ -330,32 +459,34 @@ bcm2836mp_pic_unblock_irqs(struct pic_so { struct cpu_info * const ci = curcpu(); const cpuid_t cpuid = ci->ci_cpuid; + const bus_space_tag_t iot = bcml1icu_sc->sc_iot; + const bus_space_handle_t ioh = bcml1icu_sc->sc_ioh; KASSERT(pic == &bcm2836mp_pic[cpuid]); KASSERT(irqbase == 0); if (irq_mask & BCM2836MP_TIMER_IRQS) { uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_TIMER_IRQS); - uint32_t val = bus_space_read_4(al_iot, al_ioh, + uint32_t val = bus_space_read_4(iot, ioh, BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid)); val |= mask; - bus_space_write_4(al_iot, al_ioh, + bus_space_write_4(iot, ioh, BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid), val); - bus_space_barrier(al_iot, al_ioh, + bus_space_barrier(iot, ioh, BCM2836_LOCAL_TIMER_IRQ_CONTROL_BASE, BCM2836_LOCAL_TIMER_IRQ_CONTROL_SIZE, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE); } if (irq_mask & BCM2836MP_MAILBOX_IRQS) { uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_MAILBOX_IRQS); - uint32_t val = bus_space_read_4(al_iot, al_ioh, + uint32_t val = bus_space_read_4(iot, ioh, BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid)); val |= mask; - bus_space_write_4(al_iot, al_ioh, + bus_space_write_4(iot, ioh, BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid), val); - bus_space_barrier(al_iot, al_ioh, + bus_space_barrier(iot, ioh, BCM2836_LOCAL_MAILBOX_IRQ_CONTROL_BASE, BCM2836_LOCAL_MAILBOX_IRQ_CONTROL_SIZE, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE); @@ -370,25 +501,27 @@ bcm2836mp_pic_block_irqs(struct pic_soft { struct cpu_info * const ci = curcpu(); const cpuid_t cpuid = ci->ci_cpuid; + const bus_space_tag_t iot = bcml1icu_sc->sc_iot; + const bus_space_handle_t ioh = bcml1icu_sc->sc_ioh; KASSERT(pic == &bcm2836mp_pic[cpuid]); KASSERT(irqbase == 0); if (irq_mask & BCM2836MP_TIMER_IRQS) { uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_TIMER_IRQS); - uint32_t val = bus_space_read_4(al_iot, al_ioh, + uint32_t val = bus_space_read_4(iot, ioh, BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid)); val &= ~mask; - bus_space_write_4(al_iot, al_ioh, + bus_space_write_4(iot, ioh, BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid), val); } if (irq_mask & BCM2836MP_MAILBOX_IRQS) { uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_MAILBOX_IRQS); - uint32_t val = bus_space_read_4(al_iot, al_ioh, + uint32_t val = bus_space_read_4(iot, ioh, BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid)); val &= ~mask; - bus_space_write_4(al_iot, al_ioh, + bus_space_write_4(iot, ioh, BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid), val); } @@ -409,7 +542,7 @@ bcm2836mp_pic_find_pending_irqs(struct p bcm2835_barrier(); - lpending = bus_space_read_4(al_iot, al_ioh, + lpending = bus_space_read_4(bcml1icu_sc->sc_iot, bcml1icu_sc->sc_ioh, BCM2836_LOCAL_INTC_IRQPENDINGN(cpuid)); lpending &= ~BCM2836_INTBIT_GPUPENDING; @@ -438,16 +571,15 @@ bcm2836mp_pic_source_name(struct pic_sof } -#ifdef MULTIPROCESSOR +#if defined(MULTIPROCESSOR) static void bcm2836mp_cpu_init(struct pic_softc *pic, struct cpu_info *ci) { /* Enable IRQ and not FIQ */ - bus_space_write_4(al_iot, al_ioh, + bus_space_write_4(bcml1icu_sc->sc_iot, bcml1icu_sc->sc_ioh, BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(ci->ci_cpuid), 1); } - static void bcm2836mp_send_ipi(struct pic_softc *pic, const kcpuset_t *kcp, u_long ipi) { @@ -457,7 +589,7 @@ bcm2836mp_send_ipi(struct pic_softc *pic const cpuid_t cpuid = pic - &bcm2836mp_pic[0]; - bus_space_write_4(al_iot, al_ioh, + bus_space_write_4(bcml1icu_sc->sc_iot, bcml1icu_sc->sc_ioh, BCM2836_LOCAL_MAILBOX0_SETN(cpuid), __BIT(ipi)); } @@ -468,10 +600,10 @@ bcm2836mp_ipi_handler(void *priv) const cpuid_t cpuid = ci->ci_cpuid; uint32_t ipimask, bit; - ipimask = bus_space_read_4(al_iot, al_ioh, + ipimask = bus_space_read_4(bcml1icu_sc->sc_iot, bcml1icu_sc->sc_ioh, BCM2836_LOCAL_MAILBOX0_CLRN(cpuid)); - bus_space_write_4(al_iot, al_ioh, BCM2836_LOCAL_MAILBOX0_CLRN(cpuid), - ipimask); + bus_space_write_4(bcml1icu_sc->sc_iot, bcml1icu_sc->sc_ioh, + BCM2836_LOCAL_MAILBOX0_CLRN(cpuid), ipimask); while ((bit = ffs(ipimask)) > 0) { const u_int ipi = bit - 1; @@ -507,27 +639,72 @@ bcm2836mp_ipi_handler(void *priv) return 1; } +#endif -void -bcm2836mp_intr_init(struct cpu_info *ci) +static void +bcm2836mp_intr_init(void *priv, struct cpu_info *ci) { const cpuid_t cpuid = ci->ci_cpuid; struct pic_softc * const pic = &bcm2836mp_pic[cpuid]; +#if defined(MULTIPROCESSOR) pic->pic_cpus = ci->ci_kcpuset; +#endif pic_add(pic, BCM2836_INT_BASECPUN(cpuid)); +#if defined(MULTIPROCESSOR) intr_establish(BCM2836_INT_MAILBOX0_CPUN(cpuid), IPL_HIGH, IST_LEVEL | IST_MPSAFE, bcm2836mp_ipi_handler, NULL); - +#endif /* clock interrupt will attach with gtmr */ if (cpuid == 0) return; - +#if defined(SOC_BCM2836) intr_establish(BCM2836_INT_CNTVIRQ_CPUN(cpuid), IPL_CLOCK, IST_LEVEL | IST_MPSAFE, gtmr_intr, NULL); -} #endif +} -#endif +static int +bcm2836mp_icu_fdt_decode_irq(u_int *specifier) +{ + if (!specifier) + return -1; + return be32toh(specifier[0]) + BCM2836_INT_LOCALBASE; +} + +static void * +bcm2836mp_icu_fdt_establish(device_t dev, u_int *specifier, int ipl, int flags, + int (*func)(void *), void *arg) +{ + int iflags = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0; + int irq; + + irq = bcm2836mp_icu_fdt_decode_irq(specifier); + if (irq == -1) + return NULL; + + return intr_establish(irq, ipl, IST_LEVEL | iflags, func, arg); +} + +static void +bcm2836mp_icu_fdt_disestablish(device_t dev, void *ih) +{ + intr_disestablish(ih); +} + +static bool +bcm2836mp_icu_fdt_intrstr(device_t dev, u_int *specifier, char *buf, + size_t buflen) +{ + int irq; + + irq = bcm2836mp_icu_fdt_decode_irq(specifier); + if (irq == -1) + return false; + + snprintf(buf, buflen, "local_intc irq %d", irq); + + return true; +} Index: sys/arch/arm/broadcom/bcm2835_intr.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_intr.h,v retrieving revision 1.3 diff -u -p -r1.3 bcm2835_intr.h --- sys/arch/arm/broadcom/bcm2835_intr.h 29 Jul 2015 10:47:58 -0000 1.3 +++ sys/arch/arm/broadcom/bcm2835_intr.h 3 Dec 2017 12:00:58 -0000 @@ -32,18 +32,10 @@ #ifndef _BCM2835_INTR_H_ #define _BCM2835_INTR_H_ -#define ARM_IRQ_HANDLER _C_LABEL(bcm2835_irq_handler) - #ifndef _LOCORE -void bcm2835_irq_handler(void *); - -#define PIC_MAXSOURCES 96 + (4*32) -#define PIC_MAXMAXSOURCES 96 + (4*32) + 32 - -#include - -void bcm2836mp_intr_init(struct cpu_info *); +CTASSERT(PIC_MAXSOURCES >= 96 + (4*32)); +CTASSERT(PIC_MAXMAXSOURCES >= 96 + (4*32) + 32); #endif /* _LOCORE */ Index: sys/arch/arm/broadcom/bcm2835_mbox.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_mbox.c,v retrieving revision 1.11 diff -u -p -r1.11 bcm2835_mbox.c --- sys/arch/arm/broadcom/bcm2835_mbox.c 29 Jul 2015 14:22:49 -0000 1.11 +++ sys/arch/arm/broadcom/bcm2835_mbox.c 3 Dec 2017 12:00:58 -0000 @@ -40,11 +40,12 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_mbox #include #include -#include #include #include #include +#include + struct bcm2835mbox_softc { device_t sc_dev; device_t sc_platdev; @@ -74,45 +75,59 @@ CFATTACH_DECL_NEW(bcmmbox, sizeof(struct static int bcmmbox_match(device_t parent, cfdata_t match, void *aux) { - struct amba_attach_args *aaa = aux; - - if (strcmp(aaa->aaa_name, "bcmmbox") != 0) - return 0; + const char * const compatible[] = { "brcm,bcm2835-mbox", NULL }; + struct fdt_attach_args * const faa = aux; - return 1; + return of_match_compatible(faa->faa_phandle, compatible); } static void bcmmbox_attach(device_t parent, device_t self, void *aux) { struct bcm2835mbox_softc *sc = device_private(self); - struct amba_attach_args *aaa = aux; + struct fdt_attach_args * const faa = aux; struct bcmmbox_attach_args baa; + const int phandle = faa->faa_phandle; int i; aprint_naive("\n"); aprint_normal(": VC mailbox\n"); sc->sc_dev = self; - sc->sc_iot = aaa->aaa_iot; - sc->sc_dmat = aaa->aaa_dmat; + sc->sc_iot = faa->faa_bst; + sc->sc_dmat = faa->faa_dmat; mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_VM); for (i = 0; i < BCM2835_MBOX_NUMCHANNELS; ++i) cv_init(&sc->sc_chan[i], "bcmmbox"); - if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, BCM2835_MBOX_SIZE, 0, - &sc->sc_ioh)) { + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get register address\n"); + return; + } + + if (bus_space_map(faa->faa_bst, addr, size, 0, &sc->sc_ioh) != 0) { aprint_error_dev(sc->sc_dev, "unable to map device\n"); return; } - sc->sc_intrh = intr_establish(aaa->aaa_intr, IPL_VM, IST_LEVEL, + char intrstr[128]; + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error(": failed to decode interrupt\n"); + return; + } + + sc->sc_intrh = fdtbus_intr_establish(phandle, 0, IPL_VM, IST_LEVEL, bcmmbox_intr, sc); if (sc->sc_intrh == NULL) { - aprint_error_dev(sc->sc_dev, "unable to establish interrupt\n"); + aprint_error_dev(self, "failed to establish interrupt %s\n", + intrstr); return; } + aprint_normal_dev(self, "interrupting on %s\n", intrstr); /* enable mbox interrupt */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_MBOX_CFG, @@ -121,7 +136,7 @@ bcmmbox_attach(device_t parent, device_t if (bcm2835mbox_sc == NULL) bcm2835mbox_sc = sc; - baa.baa_dmat = aaa->aaa_dmat; + baa.baa_dmat = sc->sc_dmat; sc->sc_platdev = config_found_ia(self, "bcmmboxbus", &baa, NULL); } Index: sys/arch/arm/broadcom/bcm2835_mbox_subr.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_mbox_subr.c,v retrieving revision 1.4 diff -u -p -r1.4 bcm2835_mbox_subr.c --- sys/arch/arm/broadcom/bcm2835_mbox_subr.c 7 Oct 2014 08:30:05 -0000 1.4 +++ sys/arch/arm/broadcom/bcm2835_mbox_subr.c 3 Dec 2017 12:00:58 -0000 @@ -39,7 +39,6 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_mbox #include #include -#include #include #include #include Index: sys/arch/arm/broadcom/bcm2835_obio.c =================================================================== RCS file: sys/arch/arm/broadcom/bcm2835_obio.c diff -N sys/arch/arm/broadcom/bcm2835_obio.c --- sys/arch/arm/broadcom/bcm2835_obio.c 30 Jul 2017 23:48:32 -0000 1.28 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,349 +0,0 @@ -/* $NetBSD: bcm2835_obio.c,v 1.28 2017/07/30 23:48:32 jmcneill Exp $ */ - -/*- - * Copyright (c) 2012, 2014 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Nick Hudson - * - * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 -__KERNEL_RCSID(0, "$NetBSD: bcm2835_obio.c,v 1.28 2017/07/30 23:48:32 jmcneill Exp $"); - -#include "locators.h" -#include "obio.h" - -#include "opt_bcm283x.h" - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -struct obio_softc { - device_t sc_dev; - bus_dma_tag_t sc_dmat; - struct arm32_dma_range sc_dmarange[1]; - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh; - bus_addr_t sc_base; - bus_size_t sc_size; -}; - -static bool obio_attached; - -/* prototypes */ -static int obio_match(device_t, cfdata_t, void *); -static void obio_attach(device_t, device_t, void *); -static int obio_print(void *, const char *); - -/* attach structures */ -CFATTACH_DECL_NEW(obio, sizeof(struct obio_softc), - obio_match, obio_attach, NULL, NULL); - -/* - * List of port-specific devices to attach to the AMBA AXI bus. - */ -static const struct ambadev_locators bcm2835_ambadev_locs[] = { - { - /* Interrupt controller */ - .ad_name = "icu", - .ad_addr = BCM2835_ARMICU_BASE, - .ad_size = BCM2835_ARMICU_SIZE, - .ad_intr = -1, - }, -#if defined(BCM2836) - { - /* GTMR */ - .ad_name = "armgtmr", - .ad_intr = BCM2836_INT_CNTVIRQ_CPUN(0), - }, -#endif - { - /* Mailbox */ - .ad_name = "bcmmbox", - .ad_addr = BCM2835_ARMMBOX_BASE, - .ad_size = BCM2835_ARMMBOX_SIZE, - .ad_intr = BCM2835_INT_ARMMAILBOX - }, -#if !defined(BCM2836) - { - /* System Timer */ - .ad_name = "bcmtmr", - .ad_addr = BCM2835_STIMER_BASE, - .ad_size = BCM2835_STIMER_SIZE, - .ad_intr = BCM2835_INT_TIMER3, - }, -#endif - { - /* VCHIQ */ - .ad_name = "bcmvchiq", - .ad_addr = BCM2835_VCHIQ_BASE, - .ad_size = BCM2835_VCHIQ_SIZE, - .ad_intr = BCM2835_INT_ARMDOORBELL0, - }, - { - /* Power Management, Reset controller and Watchdog registers */ - .ad_name = "bcmpm", - .ad_addr = BCM2835_PM_BASE, - .ad_size = BCM2835_PM_SIZE, - .ad_intr = -1, - }, - { - /* DMA Controller */ - .ad_name = "bcmdmac", - .ad_addr = BCM2835_DMA0_BASE, - .ad_size = BCM2835_DMA0_SIZE, - .ad_intr = -1, - }, - { - /* Random number generator */ - .ad_name = "bcmrng", - .ad_addr = BCM2835_RNG_BASE, - .ad_size = BCM2835_RNG_SIZE, - .ad_intr = -1, - }, - { - /* Uart 0 */ - .ad_name = "plcom", - .ad_addr = BCM2835_UART0_BASE, - .ad_size = BCM2835_UART0_SIZE, - .ad_intr = BCM2835_INT_UART0, - }, - { - /* AUX UART */ - .ad_name = "com", - .ad_addr = BCM2835_AUX_UART_BASE, - .ad_size = BCM2835_AUX_UART_SIZE, - .ad_intr = BCM2835_INT_AUX, - }, - { - /* Framebuffer */ - .ad_name = "fb", - .ad_addr = 0, - .ad_size = 0, - .ad_intr = -1, - }, - { - /* SD host interface */ - .ad_name = "sdhost", - .ad_addr = BCM2835_SDHOST_BASE, - .ad_size = BCM2835_SDHOST_SIZE, - .ad_intr = BCM2835_INT_SDHOST, - }, - { - /* eMMC interface */ - .ad_name = "emmc", - .ad_addr = BCM2835_EMMC_BASE, - .ad_size = BCM2835_EMMC_SIZE, - .ad_intr = BCM2835_INT_EMMC, - }, - { - /* DesignWare_OTG USB controller */ - .ad_name = "dwctwo", - .ad_addr = BCM2835_USB_BASE, - .ad_size = BCM2835_USB_SIZE, - .ad_intr = BCM2835_INT_USB, - }, - { - .ad_name = "bcmspi", - .ad_addr = BCM2835_SPI0_BASE, - .ad_size = BCM2835_SPI0_SIZE, - .ad_intr = BCM2835_INT_SPI0, - }, - { - .ad_name = "bcmbsc", - .ad_addr = BCM2835_BSC0_BASE, - .ad_size = BCM2835_BSC_SIZE, - .ad_intr = BCM2835_INT_BSC, - }, - { - .ad_name = "bcmbsc", - .ad_addr = BCM2835_BSC1_BASE, - .ad_size = BCM2835_BSC_SIZE, - .ad_intr = BCM2835_INT_BSC, - }, - { - /* gpio */ - .ad_name = "bcmgpio", - .ad_addr = BCM2835_GPIO_BASE, - .ad_size = BCM2835_GPIO_SIZE, - .ad_intr = -1, - }, - { - /* gpio */ - .ad_name = "bcmgpio", - .ad_addr = BCM2835_GPIO_BASE, - .ad_size = BCM2835_GPIO_SIZE, - .ad_intr = -1, - }, - { - /* Clock Manager */ - .ad_name = "bcmcm", - .ad_addr = BCM2835_CM_BASE, - .ad_size = BCM2835_CM_SIZE, - .ad_intr = -1, - }, - { - /* PWM Controller */ - .ad_name = "bcmpwm", - .ad_addr = BCM2835_PWM_BASE, - .ad_size = BCM2835_PWM_SIZE, - .ad_intr = -1, - }, - { - /* Terminator */ - .ad_name = NULL, - } -}; - - -static int -obio_match(device_t parent, cfdata_t match, void *aux) -{ - - return 1; -} - -bus_space_tag_t al_iot = &bcm2835_bs_tag; -bus_space_handle_t al_ioh; - -static void -obio_attach(device_t parent, device_t self, void *aux) -{ - struct obio_softc *sc = device_private(self); - const struct ambadev_locators *ad = bcm2835_ambadev_locs; - struct amba_attach_args aaa; - int locs[OBIOCF_NLOCS]; - - if (obio_attached) - return; - - obio_attached = true; - - sc->sc_dev = self; - sc->sc_dmat = &bcm2835_bus_dma_tag; - - sc->sc_dmarange[0].dr_sysbase = 0; -#if defined(BCM2836) - sc->sc_dmarange[0].dr_busbase = BCM2835_BUSADDR_CACHE_DIRECT; -#else - sc->sc_dmarange[0].dr_busbase = BCM2835_BUSADDR_CACHE_COHERENT; -#endif - sc->sc_dmarange[0].dr_len = physmem * PAGE_SIZE; - bcm2835_bus_dma_tag._ranges = sc->sc_dmarange; - bcm2835_bus_dma_tag._nranges = __arraycount(sc->sc_dmarange); - - aprint_normal("\n"); - - /* Set up the attach args. */ - aaa.aaa_iot = &bcm2835_bs_tag; - aaa.aaa_dmat = sc->sc_dmat; - -#if defined(BCM2836) - if (bus_space_map(al_iot, BCM2836_ARM_LOCAL_BASE, BCM2836_ARM_LOCAL_SIZE, - 0, &al_ioh)) { - aprint_error(": unable to map local space\n"); - return; - } - - bus_space_write_4(al_iot, al_ioh, BCM2836_LOCAL_CONTROL, 0); - bus_space_write_4(al_iot, al_ioh, BCM2836_LOCAL_PRESCALER, 0x80000000); -#endif - - for (; ad->ad_name != NULL; ad++) { - aprint_debug("dev=%s[%u], addr=%lx:+%lx\n", - ad->ad_name, ad->ad_instance, ad->ad_addr, ad->ad_size); - if (strcmp(ad->ad_name, "armgtmr") == 0) { - struct mpcore_attach_args mpcaa = { - .mpcaa_name = "armgtmr", - .mpcaa_irq = ad->ad_intr, - }; - - config_found(self, &mpcaa, NULL); - continue; - } - - aaa.aaa_name = ad->ad_name; - aaa.aaa_addr = ad->ad_addr; - aaa.aaa_size = ad->ad_size; - aaa.aaa_intr = ad->ad_intr; - /* ad->ad_instance; */ - - locs[OBIOCF_ADDR] = ad->ad_addr; - locs[OBIOCF_SIZE] = ad->ad_size; - locs[OBIOCF_INTR] = ad->ad_intr; - - config_found_sm_loc(self, "obio", locs, &aaa, obio_print, - config_stdsubmatch); - } - - return; -} - - -static int -obio_print(void *aux, const char *name) -{ - struct amba_attach_args *aaa = aux; - - if (name) - aprint_normal("%s at %s", aaa->aaa_name, name); - else { -#if 0 - if (aaa->aaa_unit != OBIOCF_UNIT_DEFAULT) - aprint_normal(" unit %d", aaa->aaa_unit); - if (aaa->aaa_addr != OBIOCF_ADDR_DEFAULT) { - aprint_normal(" addr 0x%lx", aaa->aaa_addr); - if (aaa->aaa_size > 0) - aprint_normal("-0x%lx", - aaa->aaa_addr + aaa->aaa_size - 1); - } -#endif - if (aaa->aaa_intr != OBIOCF_INTR_DEFAULT) - aprint_normal(" intr %d", aaa->aaa_intr); - } - - return UNCONF; -} - -#ifdef MULTIPROCESSOR -void -bcm2836_cpu_hatch(struct cpu_info *ci) -{ - - bcm2836mp_intr_init(ci); - - gtmr_init_cpu_clock(ci); -} -#endif Index: sys/arch/arm/broadcom/bcm2835_plcom.c =================================================================== RCS file: sys/arch/arm/broadcom/bcm2835_plcom.c diff -N sys/arch/arm/broadcom/bcm2835_plcom.c --- sys/arch/arm/broadcom/bcm2835_plcom.c 6 Jan 2017 14:55:37 -0000 1.4 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,106 +0,0 @@ -/* $NetBSD: bcm2835_plcom.c,v 1.4 2017/01/06 14:55:37 skrll Exp $ */ - -/*- - * Copyright (c) 2012 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Nick Hudson - * - * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -/* Interface to plcom (PL011) serial driver. */ - -#include -__KERNEL_RCSID(0, "$NetBSD: bcm2835_plcom.c,v 1.4 2017/01/06 14:55:37 skrll Exp $"); - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -static int bcm2835_plcom_match(device_t, cfdata_t, void *); -static void bcm2835_plcom_attach(device_t, device_t, void *); - -CFATTACH_DECL_NEW(bcmplcom, sizeof(struct plcom_softc), - bcm2835_plcom_match, bcm2835_plcom_attach, NULL, NULL); - -static int -bcm2835_plcom_match(device_t parent, cfdata_t cf, void *aux) -{ - struct amba_attach_args *aaa = aux; - - if (strcmp(aaa->aaa_name, "plcom") != 0) - return 0; - - return 1; -} - -static void -bcm2835_plcom_attach(device_t parent, device_t self, void *aux) -{ - struct plcom_softc *sc = device_private(self); - prop_dictionary_t dict = device_properties(self); - struct amba_attach_args *aaa = aux; - void *ih; - - sc->sc_dev = self; - sc->sc_frequency = BCM2835_UART0_CLK; - - /* Fetch the UART clock frequency from property if set. */ - prop_number_t frequency = prop_dictionary_get(dict, "frequency"); - if (frequency != NULL) { - sc->sc_frequency = prop_number_integer_value(frequency); - } - - sc->sc_hwflags = PLCOM_HW_TXFIFO_DISABLE; - sc->sc_swflags = 0; - sc->sc_set_mcr = NULL; - sc->sc_set_mcr_arg = NULL; - - sc->sc_pi.pi_type = PLCOM_TYPE_PL011; - sc->sc_pi.pi_flags = PLC_FLAG_32BIT_ACCESS; - sc->sc_pi.pi_iot = aaa->aaa_iot; - sc->sc_pi.pi_iobase = aaa->aaa_addr; - - if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, PL011COM_UART_SIZE, 0, - &sc->sc_pi.pi_ioh)) { - aprint_error_dev(sc->sc_dev, "unable to map device\n"); - return; - } - - plcom_attach_subr(sc); - ih = intr_establish(aaa->aaa_intr, IPL_SERIAL, IST_LEVEL, plcomintr, sc); - if (ih == NULL) - panic("%s: cannot install interrupt handler", - device_xname(sc->sc_dev)); -} Index: sys/arch/arm/broadcom/bcm2835_pm.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_pm.c,v retrieving revision 1.3 diff -u -p -r1.3 bcm2835_pm.c --- sys/arch/arm/broadcom/bcm2835_pm.c 14 Apr 2013 15:11:52 -0000 1.3 +++ sys/arch/arm/broadcom/bcm2835_pm.c 3 Dec 2017 12:00:58 -0000 @@ -1,7 +1,7 @@ -/* $NetBSD: bcm2835_pm.c,v 1.3 2013/04/14 15:11:52 skrll Exp $ */ +/* $NetBSD$ */ /*- - * Copyright (c) 2012 The NetBSD Foundation, Inc. + * Copyright (c) 2012, 2016 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: bcm2835_pm.c,v 1.3 2013/04/14 15:11:52 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD$"); #include @@ -43,10 +43,11 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_pm.c #include -#include #include #include -#include +#include + +#include #ifndef BCM2835_PM_DEFAULT_PERIOD #define BCM2835_PM_DEFAULT_PERIOD 15 /* seconds */ @@ -62,7 +63,7 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_pm.c #define BCM2835_PM_WDOG 0x24 #define BCM2835_PM_WDOG_TIMEMASK 0x000fffff -struct bcm2835pm_softc { +struct bcm2835pmwdog_softc { device_t sc_dev; bus_space_tag_t sc_iot; @@ -71,48 +72,54 @@ struct bcm2835pm_softc { struct sysmon_wdog sc_smw; }; -static struct bcm2835pm_softc *bcm2835pm_sc; +static struct bcm2835pmwdog_softc *bcm2835pmwdog_sc; -static int bcmpm_match(device_t, cfdata_t, void *); -static void bcmpm_attach(device_t, device_t, void *); +static int bcmpmwdog_match(device_t, cfdata_t, void *); +static void bcmpmwdog_attach(device_t, device_t, void *); -static void bcmpm_wdog_set_timeout(struct bcm2835pm_softc *, uint32_t); +static void bcmpmwdog_set_timeout(struct bcm2835pmwdog_softc *, uint32_t); -static int bcmpm_wdog_setmode(struct sysmon_wdog *); -static int bcmpm_wdog_tickle(struct sysmon_wdog *); +static int bcmpmwdog_setmode(struct sysmon_wdog *); +static int bcmpmwdog_tickle(struct sysmon_wdog *); -CFATTACH_DECL_NEW(bcmpm_amba, sizeof(struct bcm2835pm_softc), - bcmpm_match, bcmpm_attach, NULL, NULL); +CFATTACH_DECL_NEW(bcmpmwdog_fdt, sizeof(struct bcm2835pmwdog_softc), + bcmpmwdog_match, bcmpmwdog_attach, NULL, NULL); /* ARGSUSED */ static int -bcmpm_match(device_t parent, cfdata_t match, void *aux) +bcmpmwdog_match(device_t parent, cfdata_t match, void *aux) { - struct amba_attach_args *aaa = aux; - - if (strcmp(aaa->aaa_name, "bcmpm") != 0) - return 0; + const char * const compatible[] = { "brcm,bcm2835-pm-wdt", NULL }; + struct fdt_attach_args * const faa = aux; - return 1; + return of_match_compatible(faa->faa_phandle, compatible); } static void -bcmpm_attach(device_t parent, device_t self, void *aux) +bcmpmwdog_attach(device_t parent, device_t self, void *aux) { - struct bcm2835pm_softc *sc = device_private(self); - struct amba_attach_args *aaa = aux; + struct bcm2835pmwdog_softc *sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; aprint_naive("\n"); aprint_normal(": Power management, Reset and Watchdog controller\n"); - if (bcm2835pm_sc == NULL) - bcm2835pm_sc = sc; + if (bcm2835pmwdog_sc == NULL) + bcm2835pmwdog_sc = sc; sc->sc_dev = self; - sc->sc_iot = aaa->aaa_iot; + sc->sc_iot = faa->faa_bst; + + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get register address\n"); + return; + } - if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, BCM2835_PM_SIZE, 0, - &sc->sc_ioh)) { + if (bus_space_map(faa->faa_bst, addr, size, 0, &sc->sc_ioh) != 0) { aprint_error_dev(sc->sc_dev, "unable to map device\n"); return; } @@ -120,15 +127,15 @@ bcmpm_attach(device_t parent, device_t s /* watchdog */ sc->sc_smw.smw_name = device_xname(sc->sc_dev); sc->sc_smw.smw_cookie = sc; - sc->sc_smw.smw_setmode = bcmpm_wdog_setmode; - sc->sc_smw.smw_tickle = bcmpm_wdog_tickle; + sc->sc_smw.smw_setmode = bcmpmwdog_setmode; + sc->sc_smw.smw_tickle = bcmpmwdog_tickle; sc->sc_smw.smw_period = BCM2835_PM_DEFAULT_PERIOD; if (sysmon_wdog_register(&sc->sc_smw) != 0) aprint_error_dev(self, "couldn't register watchdog\n"); } static void -bcmpm_wdog_set_timeout(struct bcm2835pm_softc *sc, uint32_t ticks) +bcmpmwdog_set_timeout(struct bcm2835pmwdog_softc *sc, uint32_t ticks) { uint32_t tmp, rstc, wdog; @@ -146,9 +153,9 @@ bcmpm_wdog_set_timeout(struct bcm2835pm_ } static int -bcmpm_wdog_setmode(struct sysmon_wdog *smw) +bcmpmwdog_setmode(struct sysmon_wdog *smw) { - struct bcm2835pm_softc *sc = smw->smw_cookie; + struct bcm2835pmwdog_softc *sc = smw->smw_cookie; int error = 0; if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) { @@ -159,19 +166,19 @@ bcmpm_wdog_setmode(struct sysmon_wdog *s smw->smw_period = BCM2835_PM_DEFAULT_PERIOD; if (smw->smw_period > (BCM2835_PM_WDOG_TIMEMASK >> 16)) return EINVAL; - error = bcmpm_wdog_tickle(smw); + error = bcmpmwdog_tickle(smw); } return error; } static int -bcmpm_wdog_tickle(struct sysmon_wdog *smw) +bcmpmwdog_tickle(struct sysmon_wdog *smw) { - struct bcm2835pm_softc *sc = smw->smw_cookie; + struct bcm2835pmwdog_softc *sc = smw->smw_cookie; uint32_t timeout = smw->smw_period << 16; - bcmpm_wdog_set_timeout(sc, timeout); + bcmpmwdog_set_timeout(sc, timeout); return 0; } @@ -179,8 +186,8 @@ bcmpm_wdog_tickle(struct sysmon_wdog *sm void bcm2835_system_reset(void) { - struct bcm2835pm_softc *sc = bcm2835pm_sc; + struct bcm2835pmwdog_softc *sc = bcm2835pmwdog_sc; uint32_t timeout = 10; - bcmpm_wdog_set_timeout(sc, timeout); + bcmpmwdog_set_timeout(sc, timeout); } Index: sys/arch/arm/broadcom/bcm2835_pmvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_pmvar.h,v retrieving revision 1.1 diff -u -p -r1.1 bcm2835_pmvar.h --- sys/arch/arm/broadcom/bcm2835_pmvar.h 26 Jul 2012 06:21:57 -0000 1.1 +++ sys/arch/arm/broadcom/bcm2835_pmvar.h 3 Dec 2017 12:00:58 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: bcm2835_pmvar.h,v 1.1 2012/07/26 06:21:57 skrll Exp $ */ +/* $NetBSD$ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -29,9 +29,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _ARM_BROADCOM_BCM2835_PM_VAR_H_ -#define _ARM_BROADCOM_BCM2835_PM_VAR_H_ +#ifndef _ARM_BROADCOM_BCM2835_PMWDOG_VAR_H_ +#define _ARM_BROADCOM_BCM2835_PMWDOG_VAR_H_ void bcm2835_system_reset(void); -#endif /* _ARM_BROADCOM_BCM2835_PM_VAR_H_ */ +#endif /* _ARM_BROADCOM_BCM2835_PMWDOG_VAR_H_ */ Index: sys/arch/arm/broadcom/bcm2835_pmwdog.c =================================================================== RCS file: sys/arch/arm/broadcom/bcm2835_pmwdog.c diff -N sys/arch/arm/broadcom/bcm2835_pmwdog.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/broadcom/bcm2835_pmwdog.c 3 Dec 2017 12:00:58 -0000 @@ -0,0 +1,193 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2012, 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__KERNEL_RCSID(0, "$NetBSD$"); + + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#ifndef BCM2835_PM_DEFAULT_PERIOD +#define BCM2835_PM_DEFAULT_PERIOD 15 /* seconds */ +#endif + +#define BCM2835_PM_PASSWORD 0x5a000000 + +#define BCM2835_PM_RSTC 0x1c +#define BCM2835_PM_RSTC_CONFIGMASK 0x00000030 +#define BCM2835_PM_RSTC_FULL_RESET 0x00000020 +#define BCM2835_PM_RSTC_RESET 0x00000102 + +#define BCM2835_PM_WDOG 0x24 +#define BCM2835_PM_WDOG_TIMEMASK 0x000fffff + +struct bcm2835pmwdog_softc { + device_t sc_dev; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + struct sysmon_wdog sc_smw; +}; + +static struct bcm2835pmwdog_softc *bcm2835pmwdog_sc; + +static int bcmpmwdog_match(device_t, cfdata_t, void *); +static void bcmpmwdog_attach(device_t, device_t, void *); + +static void bcmpmwdog_set_timeout(struct bcm2835pmwdog_softc *, uint32_t); + +static int bcmpmwdog_setmode(struct sysmon_wdog *); +static int bcmpmwdog_tickle(struct sysmon_wdog *); + +CFATTACH_DECL_NEW(bcmpmwdog_fdt, sizeof(struct bcm2835pmwdog_softc), + bcmpmwdog_match, bcmpmwdog_attach, NULL, NULL); + +/* ARGSUSED */ +static int +bcmpmwdog_match(device_t parent, cfdata_t match, void *aux) +{ + const char * const compatible[] = { "brcm,bcm2835-pm-wdt", NULL }; + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +bcmpmwdog_attach(device_t parent, device_t self, void *aux) +{ + struct bcm2835pmwdog_softc *sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + + aprint_naive("\n"); + aprint_normal(": Power management, Reset and Watchdog controller\n"); + + if (bcm2835pmwdog_sc == NULL) + bcm2835pmwdog_sc = sc; + + sc->sc_dev = self; + sc->sc_iot = faa->faa_bst; + + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get register address\n"); + return; + } + + if (bus_space_map(faa->faa_bst, addr, size, 0, &sc->sc_ioh) != 0) { + aprint_error_dev(sc->sc_dev, "unable to map device\n"); + return; + } + + /* watchdog */ + sc->sc_smw.smw_name = device_xname(sc->sc_dev); + sc->sc_smw.smw_cookie = sc; + sc->sc_smw.smw_setmode = bcmpmwdog_setmode; + sc->sc_smw.smw_tickle = bcmpmwdog_tickle; + sc->sc_smw.smw_period = BCM2835_PM_DEFAULT_PERIOD; + if (sysmon_wdog_register(&sc->sc_smw) != 0) + aprint_error_dev(self, "couldn't register watchdog\n"); +} + +static void +bcmpmwdog_set_timeout(struct bcm2835pmwdog_softc *sc, uint32_t ticks) +{ + uint32_t tmp, rstc, wdog; + + tmp = bus_space_read_4(sc->sc_iot, sc->sc_ioh, BCM2835_PM_RSTC); + + rstc = wdog = BCM2835_PM_PASSWORD; + + rstc |= tmp & ~BCM2835_PM_RSTC_CONFIGMASK; + rstc |= BCM2835_PM_RSTC_FULL_RESET; + + wdog |= ticks & BCM2835_PM_WDOG_TIMEMASK; + + bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_PM_WDOG, wdog); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_PM_RSTC, rstc); +} + +static int +bcmpmwdog_setmode(struct sysmon_wdog *smw) +{ + struct bcm2835pmwdog_softc *sc = smw->smw_cookie; + int error = 0; + + if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) { + bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_PM_RSTC, + BCM2835_PM_PASSWORD | BCM2835_PM_RSTC_RESET); + } else { + if (smw->smw_period == WDOG_PERIOD_DEFAULT) + smw->smw_period = BCM2835_PM_DEFAULT_PERIOD; + if (smw->smw_period > (BCM2835_PM_WDOG_TIMEMASK >> 16)) + return EINVAL; + error = bcmpmwdog_tickle(smw); + } + + return error; +} + +static int +bcmpmwdog_tickle(struct sysmon_wdog *smw) +{ + struct bcm2835pmwdog_softc *sc = smw->smw_cookie; + uint32_t timeout = smw->smw_period << 16; + + bcmpmwdog_set_timeout(sc, timeout); + + return 0; +} + +void +bcm2835_system_reset(void) +{ + struct bcm2835pmwdog_softc *sc = bcm2835pmwdog_sc; + uint32_t timeout = 10; + + bcmpmwdog_set_timeout(sc, timeout); +} Index: sys/arch/arm/broadcom/bcm2835_pmwdogvar.h =================================================================== RCS file: sys/arch/arm/broadcom/bcm2835_pmwdogvar.h diff -N sys/arch/arm/broadcom/bcm2835_pmwdogvar.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/broadcom/bcm2835_pmwdogvar.h 3 Dec 2017 12:00:58 -0000 @@ -0,0 +1,37 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef _ARM_BROADCOM_BCM2835_PMWDOG_VAR_H_ +#define _ARM_BROADCOM_BCM2835_PMWDOG_VAR_H_ + +void bcm2835_system_reset(void); + +#endif /* _ARM_BROADCOM_BCM2835_PMWDOG_VAR_H_ */ Index: sys/arch/arm/broadcom/bcm2835_pwm.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_pwm.c,v retrieving revision 1.2 diff -u -p -r1.2 bcm2835_pwm.c --- sys/arch/arm/broadcom/bcm2835_pwm.c 2 Feb 2016 13:55:50 -0000 1.2 +++ sys/arch/arm/broadcom/bcm2835_pwm.c 3 Dec 2017 12:00:58 -0000 @@ -50,10 +50,11 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_pwm. #include #include -#include #include +#include + struct bcm_pwm_channel { struct bcm2835pwm_softc *sc; uint32_t ctlmask, stamask, gapomask; @@ -69,6 +70,7 @@ struct bcm2835pwm_softc { bus_space_handle_t sc_ioh; bus_addr_t sc_iob; + struct clk *sc_clk; int sc_clockrate; struct bcm_pwm_channel sc_channels[2]; kmutex_t sc_lock; @@ -83,45 +85,58 @@ static int bcmpwm_match(device_t, cfdata static void bcmpwm_attach(device_t, device_t, void *); static int bcmpwm_wait(struct bcm2835pwm_softc *); -CFATTACH_DECL_NEW(bcmpwm_amba, sizeof(struct bcm2835pwm_softc), +CFATTACH_DECL_NEW(bcmpwm, sizeof(struct bcm2835pwm_softc), bcmpwm_match, bcmpwm_attach, NULL, NULL); /* ARGSUSED */ static int bcmpwm_match(device_t parent, cfdata_t match, void *aux) { - struct amba_attach_args *aaa = aux; - - if (strcmp(aaa->aaa_name, "bcmpwm") != 0) - return 0; + const char * const compatible[] = { "brcm,bcm2835-pwm", NULL }; + struct fdt_attach_args * const faa = aux; - if (aaa->aaa_addr != BCM2835_PWM_BASE) - return 0; - - return 1; + return of_match_compatible(faa->faa_phandle, compatible); } static void bcmpwm_attach(device_t parent, device_t self, void *aux) { struct bcm2835pwm_softc *sc = device_private(self); - struct amba_attach_args *aaa = aux; - const prop_dictionary_t cfg = device_properties(self); - - aprint_naive("\n"); - aprint_normal(": PWM\n"); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + bus_size_t size; sc->sc_dev = self; - sc->sc_iot = aaa->aaa_iot; - sc->sc_iob = aaa->aaa_addr; + sc->sc_iot = faa->faa_bst; + + int error = fdtbus_get_reg(phandle, 0, &sc->sc_iob, &size); + if (error) { + aprint_error(": failed to get registers\n"); + return; + } - if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, BCM2835_PWM_SIZE, 0, + if (bus_space_map(sc->sc_iot, sc->sc_iob, size, 0, &sc->sc_ioh)) { aprint_error_dev(sc->sc_dev, "unable to map device\n"); - goto fail0; + return; } - prop_dictionary_get_uint32(cfg, "pwmclockrate", &sc->sc_clockrate); + sc->sc_clk = fdtbus_clock_get_index(phandle, 0); + if (sc->sc_clk == NULL) { + aprint_error(": couldn't get clk\n"); + return; + } + + error = clk_enable(sc->sc_clk); + if (error != 0) { + aprint_error(": couldn't enable clk\n"); + return; + } + + aprint_naive("\n"); + aprint_normal(": Pulse Width Modulator\n"); + + sc->sc_clockrate = clk_get_rate(sc->sc_clk); sc->sc_channels[0].sc = sc; sc->sc_channels[0].ctlmask = PWM_CTL_MSEN1 | PWM_CTL_USEF1 | @@ -153,7 +168,7 @@ bcmpwm_attach(device_t parent, device_t /* Success! */ -fail0: return; + return; } struct bcm_pwm_channel * Index: sys/arch/arm/broadcom/bcm2835_rng.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_rng.c,v retrieving revision 1.12 diff -u -p -r1.12 bcm2835_rng.c --- sys/arch/arm/broadcom/bcm2835_rng.c 17 Dec 2016 15:24:35 -0000 1.12 +++ sys/arch/arm/broadcom/bcm2835_rng.c 3 Dec 2017 12:00:58 -0000 @@ -40,10 +40,11 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_rng. #include #include -#include #include #include +#include + #define RNG_CTRL 0x00 #define RNG_CTRL_EN __BIT(0) #define RNG_STATUS 0x04 @@ -66,35 +67,43 @@ static int bcmrng_match(device_t, cfdata static void bcmrng_attach(device_t, device_t, void *); static void bcmrng_get(size_t, void *); -CFATTACH_DECL_NEW(bcmrng_amba, sizeof(struct bcm2835rng_softc), +CFATTACH_DECL_NEW(bcmrng_fdt, sizeof(struct bcm2835rng_softc), bcmrng_match, bcmrng_attach, NULL, NULL); /* ARGSUSED */ static int bcmrng_match(device_t parent, cfdata_t match, void *aux) { - struct amba_attach_args *aaa = aux; - - if (strcmp(aaa->aaa_name, "bcmrng") != 0) - return 0; + const char * const compatible[] = { "brcm,bcm2835-rng", NULL }; + struct fdt_attach_args * const faa = aux; - return 1; + return of_match_compatible(faa->faa_phandle, compatible); } static void bcmrng_attach(device_t parent, device_t self, void *aux) { struct bcm2835rng_softc *sc = device_private(self); - struct amba_attach_args *aaa = aux; + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; uint32_t ctrl; + bus_addr_t addr; + bus_size_t size; + int error; aprint_naive("\n"); aprint_normal(": RNG\n"); sc->sc_dev = self; - sc->sc_iot = aaa->aaa_iot; + sc->sc_iot = faa->faa_bst; + + error = fdtbus_get_reg(phandle, 0, &addr, &size); + if (error) { + aprint_error_dev(sc->sc_dev, "unable to map device\n"); + return; + } - if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, BCM2835_RNG_SIZE, 0, + if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh)) { aprint_error_dev(sc->sc_dev, "unable to map device\n"); return; Index: sys/arch/arm/broadcom/bcm2835_sdhost.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_sdhost.c,v retrieving revision 1.3 diff -u -p -r1.3 bcm2835_sdhost.c --- sys/arch/arm/broadcom/bcm2835_sdhost.c 16 Aug 2017 20:54:19 -0000 1.3 +++ sys/arch/arm/broadcom/bcm2835_sdhost.c 3 Dec 2017 12:00:58 -0000 @@ -29,6 +29,8 @@ #include __KERNEL_RCSID(0, "$NetBSD: bcm2835_sdhost.c,v 1.3 2017/08/16 20:54:19 jmcneill Exp $"); +#include "bcmdmac.h" + #include #include #include @@ -38,13 +40,16 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_sdho #include #include -#include #include #include #include #include +#include + +#include + #define SDCMD 0x00 #define SDCMD_NEW __BIT(15) #define SDCMD_FAIL __BIT(14) @@ -172,29 +177,42 @@ CFATTACH_DECL_NEW(bcmsdhost, sizeof(stru static int sdhost_match(device_t parent, cfdata_t cf, void *aux) { - struct amba_attach_args * const aaa = aux; + const char * const compatible[] = { + "brcm,bcm2835-sdhost", + NULL + }; + struct fdt_attach_args * const faa = aux; - return strcmp(aaa->aaa_name, "sdhost") == 0; + return of_match_compatible(faa->faa_phandle, compatible); } static void sdhost_attach(device_t parent, device_t self, void *aux) { struct sdhost_softc * const sc = device_private(self); - struct amba_attach_args * const aaa = aux; + struct fdt_attach_args * const faa = aux; prop_dictionary_t dict = device_properties(self); bool disable = false; sc->sc_dev = self; - sc->sc_bst = aaa->aaa_iot; - sc->sc_dmat = aaa->aaa_dmat; - sc->sc_addr = aaa->aaa_addr; + sc->sc_bst = faa->faa_bst; + sc->sc_dmat = faa->faa_dmat; + + const int phandle = faa->faa_phandle; + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": missing 'reg' property\n"); + return; + } + + sc->sc_addr = addr; mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_BIO); cv_init(&sc->sc_intr_cv, "sdhostintr"); cv_init(&sc->sc_dma_cv, "sdhostdma"); - if (bus_space_map(sc->sc_bst, aaa->aaa_addr, aaa->aaa_size, 0, - &sc->sc_bsh) != 0) { + if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { aprint_error(": couldn't map registers\n"); return; } @@ -208,11 +226,15 @@ sdhost_attach(device_t parent, device_t aprint_normal(": disabled\n"); return; } - - prop_dictionary_get_uint32(dict, "frequency", &sc->sc_rate); - if (sc->sc_rate == 0) { - aprint_error_dev(self, "couldn't get clock frequency\n"); - return; + /* Enable clocks */ + struct clk *clk; + for (int i = 0; (clk = fdtbus_clock_get_index(phandle, i)); i++) { + if (clk_enable(clk) != 0) { + aprint_error(": failed to enable clock #%d\n", i); + return; + } + if (i == 0) + sc->sc_rate = clk_get_rate(clk); } aprint_debug_dev(self, "ref freq %u Hz\n", sc->sc_rate); @@ -222,14 +244,20 @@ sdhost_attach(device_t parent, device_t return; } - sc->sc_ih = intr_establish(aaa->aaa_intr, IPL_SDMMC, IST_LEVEL, - sdhost_intr, sc); + char intrstr[128]; + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error(": failed to decode interrupt\n"); + return; + } + + sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_SDMMC, + FDT_INTR_MPSAFE, sdhost_intr, sc); if (sc->sc_ih == NULL) { - aprint_error_dev(self, "failed to establish interrupt %d\n", - aaa->aaa_intr); + aprint_error_dev(self, "failed to establish interrupt %s\n", + intrstr); return; } - aprint_normal_dev(self, "interrupting on intr %d\n", aaa->aaa_intr); + aprint_normal_dev(self, "interrupting on %s\n", intrstr); config_interrupts(self, sdhost_attach_i); } @@ -335,6 +363,8 @@ sdhost_dma_transfer(struct sdhost_softc __SHIFTIN(13, DMAC_TI_PERMAP); /* SD HOST */ sc->sc_cblk[seg].cb_txfr_len = cmd->c_dmamap->dm_segs[seg].ds_len; + const bus_addr_t ad_sddata = sc->sc_addr + SDDATA; + /* * All transfers are assumed to be multiples of 32-bits. */ @@ -349,8 +379,7 @@ sdhost_dma_transfer(struct sdhost_softc if ((sc->sc_cblk[seg].cb_txfr_len & 0xf) == 0) sc->sc_cblk[seg].cb_ti |= DMAC_TI_DEST_WIDTH; sc->sc_cblk[seg].cb_ti |= DMAC_TI_SRC_DREQ; - sc->sc_cblk[seg].cb_source_ad = - sc->sc_addr + SDDATA; + sc->sc_cblk[seg].cb_source_ad = ad_sddata; sc->sc_cblk[seg].cb_dest_ad = cmd->c_dmamap->dm_segs[seg].ds_addr; } else { @@ -365,9 +394,9 @@ sdhost_dma_transfer(struct sdhost_softc sc->sc_cblk[seg].cb_ti |= DMAC_TI_WAIT_RESP; sc->sc_cblk[seg].cb_source_ad = cmd->c_dmamap->dm_segs[seg].ds_addr; - sc->sc_cblk[seg].cb_dest_ad = - sc->sc_addr + SDDATA; + sc->sc_cblk[seg].cb_dest_ad = ad_sddata; } + sc->sc_cblk[seg].cb_stride = 0; if (seg == cmd->c_dmamap->dm_nsegs - 1) { sc->sc_cblk[seg].cb_ti |= DMAC_TI_INTEN; @@ -602,7 +631,6 @@ sdhost_exec_command(sdmmc_chipset_handle #endif goto done; } - cmdval = SDCMD_NEW; if (!ISSET(cmd->c_flags, SCF_RSP_PRESENT)) cmdval |= SDCMD_NORESP; Index: sys/arch/arm/broadcom/bcm2835_space.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_space.c,v retrieving revision 1.13 diff -u -p -r1.13 bcm2835_space.c --- sys/arch/arm/broadcom/bcm2835_space.c 28 Nov 2017 08:39:31 -0000 1.13 +++ sys/arch/arm/broadcom/bcm2835_space.c 3 Dec 2017 12:00:58 -0000 @@ -46,6 +46,8 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_spac /* Prototypes for all the bus_space structure functions */ bs_protos(bcm2835); bs_protos(bcm2835_a4x); +bs_protos(bcm2836); +bs_protos(bcm2836_a4x); bs_protos(generic); bs_protos(generic_armv4); bs_protos(a4x); @@ -289,37 +291,252 @@ struct bus_space bcm2835_a4x_bs_tag = { }; +/* + * This is for RPI2 and above + */ +struct bus_space bcm2836_bs_tag = { + /* cookie */ + (void *) 0, + + /* mapping/unmapping */ + bcm2836_bs_map, + bcm2835_bs_unmap, + bcm2835_bs_subregion, + + /* allocation/deallocation */ + bcm2835_bs_alloc, /* not implemented */ + bcm2835_bs_free, /* not implemented */ + + /* get kernel virtual address */ + bcm2835_bs_vaddr, + + /* mmap */ + bcm2835_bs_mmap, + + /* barrier */ + bcm2835_bs_barrier, + + /* read (single) */ + generic_bs_r_1, + NSWAP(generic_armv4_bs_r_2), + NSWAP(generic_bs_r_4), + bs_notimpl_bs_r_8, + + /* read multiple */ + generic_bs_rm_1, + NSWAP(generic_armv4_bs_rm_2), + NSWAP(generic_bs_rm_4), + bs_notimpl_bs_rm_8, + + /* read region */ + generic_bs_rr_1, + NSWAP(generic_armv4_bs_rr_2), + NSWAP(generic_bs_rr_4), + bs_notimpl_bs_rr_8, + + /* write (single) */ + generic_bs_w_1, + NSWAP(generic_armv4_bs_w_2), + NSWAP(generic_bs_w_4), + bs_notimpl_bs_w_8, + + /* write multiple */ + generic_bs_wm_1, + NSWAP(generic_armv4_bs_wm_2), + NSWAP(generic_bs_wm_4), + bs_notimpl_bs_wm_8, + + /* write region */ + generic_bs_wr_1, + NSWAP(generic_armv4_bs_wr_2), + NSWAP(generic_bs_wr_4), + bs_notimpl_bs_wr_8, + + /* set multiple */ + bs_notimpl_bs_sm_1, + bs_notimpl_bs_sm_2, + bs_notimpl_bs_sm_4, + bs_notimpl_bs_sm_8, + + /* set region */ + generic_bs_sr_1, + NSWAP(generic_armv4_bs_sr_2), + NSWAP(generic_bs_sr_4), + bs_notimpl_bs_sr_8, + + /* copy */ + bs_notimpl_bs_c_1, + generic_armv4_bs_c_2, + bs_notimpl_bs_c_4, + bs_notimpl_bs_c_8, + +#ifdef __BUS_SPACE_HAS_STREAM_METHODS + /* read (single) */ + generic_bs_r_1, + NSWAP(generic_armv4_bs_r_2), + NSWAP(generic_bs_r_4), + bs_notimpl_bs_r_8, + + /* read multiple */ + generic_bs_rm_1, + NSWAP(generic_armv4_bs_rm_2), + NSWAP(generic_bs_rm_4), + bs_notimpl_bs_rm_8, + + /* read region */ + generic_bs_rr_1, + NSWAP(generic_armv4_bs_rr_2), + NSWAP(generic_bs_rr_4), + bs_notimpl_bs_rr_8, + + /* write (single) */ + generic_bs_w_1, + NSWAP(generic_armv4_bs_w_2), + NSWAP(generic_bs_w_4), + bs_notimpl_bs_w_8, + + /* write multiple */ + generic_bs_wm_1, + NSWAP(generic_armv4_bs_wm_2), + NSWAP(generic_bs_wm_4), + bs_notimpl_bs_wm_8, + + /* write region */ + generic_bs_wr_1, + NSWAP(generic_armv4_bs_wr_2), + NSWAP(generic_bs_wr_4), + bs_notimpl_bs_wr_8, +#endif +}; + +struct bus_space bcm2836_a4x_bs_tag = { + /* cookie */ + (void *) 0, + + /* mapping/unmapping */ + bcm2836_bs_map, + bcm2835_bs_unmap, + bcm2835_a4x_bs_subregion, + + /* allocation/deallocation */ + bcm2835_bs_alloc, /* not implemented */ + bcm2835_bs_free, /* not implemented */ + + /* get kernel virtual address */ + bcm2835_bs_vaddr, + + /* mmap */ + bcm2835_a4x_bs_mmap, + + /* barrier */ + bcm2835_bs_barrier, + + /* read (single) */ + a4x_bs_r_1, + NSWAP(a4x_bs_r_2), + NSWAP(a4x_bs_r_4), + bs_notimpl_bs_r_8, + + /* read multiple */ + a4x_bs_rm_1, + NSWAP(a4x_bs_rm_2), + NSWAP(a4x_bs_rm_4), + bs_notimpl_bs_rm_8, + + /* read region */ + bs_notimpl_bs_rr_1, + bs_notimpl_bs_rr_2, + bs_notimpl_bs_rr_4, + bs_notimpl_bs_rr_8, + + /* write (single) */ + a4x_bs_w_1, + NSWAP(a4x_bs_w_2), + NSWAP(a4x_bs_w_4), + bs_notimpl_bs_w_8, + + /* write multiple */ + a4x_bs_wm_1, + NSWAP(a4x_bs_wm_2), + NSWAP(a4x_bs_wm_4), + bs_notimpl_bs_wm_8, + + /* write region */ + bs_notimpl_bs_wr_1, + bs_notimpl_bs_wr_2, + bs_notimpl_bs_wr_4, + bs_notimpl_bs_wr_8, + + /* set multiple */ + bs_notimpl_bs_sm_1, + bs_notimpl_bs_sm_2, + bs_notimpl_bs_sm_4, + bs_notimpl_bs_sm_8, + + /* set region */ + bs_notimpl_bs_sr_1, + bs_notimpl_bs_sr_2, + bs_notimpl_bs_sr_4, + bs_notimpl_bs_sr_8, + + /* copy */ + bs_notimpl_bs_c_1, + bs_notimpl_bs_c_2, + bs_notimpl_bs_c_4, + bs_notimpl_bs_c_8, + +#ifdef __BUS_SPACE_HAS_STREAM_METHODS + /* read (single) */ + a4x_bs_r_1, + NSWAP(a4x_bs_r_2), + NSWAP(a4x_bs_r_4), + bs_notimpl_bs_r_8, + + /* read multiple */ + a4x_bs_rm_1, + NSWAP(a4x_bs_rm_2), + NSWAP(a4x_bs_rm_4), + bs_notimpl_bs_rm_8, + + /* read region */ + bs_notimpl_bs_rr_1, + bs_notimpl_bs_rr_2, + bs_notimpl_bs_rr_4, + bs_notimpl_bs_rr_8, + + /* write (single) */ + a4x_bs_w_1, + NSWAP(a4x_bs_w_2), + NSWAP(a4x_bs_w_4), + bs_notimpl_bs_w_8, + + /* write multiple */ + a4x_bs_wm_1, + NSWAP(a4x_bs_wm_2), + NSWAP(a4x_bs_wm_4), + bs_notimpl_bs_wm_8, + + /* write region */ + bs_notimpl_bs_wr_1, + bs_notimpl_bs_wr_2, + bs_notimpl_bs_wr_4, + bs_notimpl_bs_wr_8, +#endif + +}; + + int -bcm2835_bs_map(void *t, bus_addr_t ba, bus_size_t size, int flag, +bcm283x_bs_map(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *); + +int +bcm283x_bs_map(void *t, bus_addr_t ba, bus_size_t size, int flag, bus_space_handle_t *bshp) { u_long startpa, endpa, pa; vaddr_t va; - const struct pmap_devmap *pd; - bool match = false; - - /* Attempt to find the PA device mapping */ - if (ba >= BCM2835_PERIPHERALS_BASE_BUS && - ba < BCM2835_PERIPHERALS_BASE_BUS + BCM2835_PERIPHERALS_SIZE) { - match = true; - pa = BCM2835_PERIPHERALS_BUS_TO_PHYS(ba); - - } -#ifdef BCM2836 - if (ba >= BCM2836_ARM_LOCAL_BASE && - ba < BCM2836_ARM_LOCAL_BASE + BCM2836_ARM_LOCAL_SIZE) { - match = true; - pa = ba; - } -#endif - if (match && (pd = pmap_devmap_find_pa(pa, size)) != NULL) { - /* Device was statically mapped. */ - *bshp = pd->pd_va + (pa - pd->pd_pa); - return 0; - } - - /* Now assume bus address so convert to PA */ + /* Convert BA to PA */ pa = ba & ~BCM2835_BUSADDR_CACHE_MASK; startpa = trunc_page(pa); @@ -346,6 +563,62 @@ bcm2835_bs_map(void *t, bus_addr_t ba, b return 0; } +int +bcm2835_bs_map(void *t, bus_addr_t ba, bus_size_t size, int flag, + bus_space_handle_t *bshp) +{ + const struct pmap_devmap *pd; + bool match = false; + u_long pa; + + /* Attempt to find the PA device mapping */ + if (ba >= BCM2835_PERIPHERALS_BASE_BUS && + ba < BCM2835_PERIPHERALS_BASE_BUS + BCM2835_PERIPHERALS_SIZE) { + match = true; + pa = BCM2835_PERIPHERALS_BUS_TO_PHYS(ba); + + } + + if (match && (pd = pmap_devmap_find_pa(pa, size)) != NULL) { + /* Device was statically mapped. */ + *bshp = pd->pd_va + (pa - pd->pd_pa); + return 0; + } + + return bcm283x_bs_map(t, ba, size, flag, bshp); +} + +int +bcm2836_bs_map(void *t, bus_addr_t ba, bus_size_t size, int flag, + bus_space_handle_t *bshp) +{ + const struct pmap_devmap *pd; + bool match = false; + u_long pa; + + /* Attempt to find the PA device mapping */ + if (ba >= BCM2835_PERIPHERALS_BASE_BUS && + ba < BCM2835_PERIPHERALS_BASE_BUS + BCM2835_PERIPHERALS_SIZE) { + match = true; + pa = BCM2836_PERIPHERALS_BUS_TO_PHYS(ba); + + } + + if (ba >= BCM2836_ARM_LOCAL_BASE && + ba < BCM2836_ARM_LOCAL_BASE + BCM2836_ARM_LOCAL_SIZE) { + match = true; + pa = ba; + } + + if (match && (pd = pmap_devmap_find_pa(pa, size)) != NULL) { + /* Device was statically mapped. */ + *bshp = pd->pd_va + (pa - pd->pd_pa); + return 0; + } + + return bcm283x_bs_map(t, ba, size, flag, bshp); +} + void bcm2835_bs_unmap(void *t, bus_space_handle_t bsh, bus_size_t size) { Index: sys/arch/arm/broadcom/bcm2835_spi.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_spi.c,v retrieving revision 1.4 diff -u -p -r1.4 bcm2835_spi.c --- sys/arch/arm/broadcom/bcm2835_spi.c 29 Jul 2015 14:22:49 -0000 1.4 +++ sys/arch/arm/broadcom/bcm2835_spi.c 3 Dec 2017 12:00:58 -0000 @@ -40,16 +40,17 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_spi. #include #include -#include #include #include -#include + +#include + +#include struct bcmspi_softc { device_t sc_dev; bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; - bus_size_t sc_ios; void *sc_intrh; struct spi_controller sc_spi; SIMPLEQ_HEAD(,spi_transfer) sc_q; @@ -78,43 +79,56 @@ CFATTACH_DECL_NEW(bcmspi, sizeof(struct static int bcmspi_match(device_t parent, cfdata_t cf, void *aux) { - struct amba_attach_args * const aaa = aux; - - if (strcmp(aaa->aaa_name, "bcmspi") != 0) - return 0; + const char * const compatible[] = { + "brcm,bcm2835-spi", + NULL + }; + struct fdt_attach_args * const faa = aux; - return 1; + return of_match_compatible(faa->faa_phandle, compatible); } static void bcmspi_attach(device_t parent, device_t self, void *aux) { - struct amba_attach_args * const aaa = aux; struct bcmspi_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; struct spibus_attach_args sba; aprint_naive("\n"); aprint_normal(": SPI\n"); sc->sc_dev = self; + sc->sc_iot = faa->faa_bst; SIMPLEQ_INIT(&sc->sc_q); - sc->sc_iot = aaa->aaa_iot; - if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, aaa->aaa_size, 0, - &sc->sc_ioh) != 0) { + + const int phandle = faa->faa_phandle; + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": missing 'reg' property\n"); + return; + } + + if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) { aprint_error_dev(sc->sc_dev, "unable to map device\n"); return; } - sc->sc_ios = aaa->aaa_size; - for (u_int pin = 7; pin <= 11; pin++) - bcm2835gpio_function_select(pin, BCM2835_GPIO_ALT0); + char intrstr[128]; + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error(": failed to decode interrupt\n"); + return; + } - sc->sc_intrh = intr_establish(aaa->aaa_intr, IPL_VM, IST_LEVEL, + sc->sc_intrh = fdtbus_intr_establish(phandle, 0, IPL_VM, 0, bcmspi_intr, sc); if (sc->sc_intrh == NULL) { aprint_error_dev(sc->sc_dev, "unable to establish interrupt\n"); return; } + aprint_normal_dev(self, "interrupting on %s\n", intrstr); sc->sc_spi.sct_cookie = sc; sc->sc_spi.sct_configure = bcmspi_configure; Index: sys/arch/arm/broadcom/bcm2835_tmr.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_tmr.c,v retrieving revision 1.8 diff -u -p -r1.8 bcm2835_tmr.c --- sys/arch/arm/broadcom/bcm2835_tmr.c 21 Sep 2017 19:28:14 -0000 1.8 +++ sys/arch/arm/broadcom/bcm2835_tmr.c 3 Dec 2017 12:00:58 -0000 @@ -39,9 +39,16 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_tmr. #include #include -#include #include #include +#include + +#include + +#include + +/* Use the 3rd timer*/ +#define BCMTIMER 3 #define BCM2835_STIMER_CS 0x00 #define BCM2835_STIMER_M0 __BIT(0) @@ -65,6 +72,8 @@ struct bcm2835tmr_softc { bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; + + void *sc_ih; }; static int bcmtmr_match(device_t, cfdata_t, void *); @@ -73,6 +82,7 @@ static void bcmtmr_attach(device_t, devi static int clockhandler(void *); static u_int bcm2835tmr_get_timecount(struct timecounter *); +void bcm2835_tmr_setstatclockrate(int); static struct bcm2835tmr_softc *bcm2835tmr_sc; @@ -87,26 +97,26 @@ static struct timecounter bcm2835tmr_tim .tc_next = NULL, }; -CFATTACH_DECL_NEW(bcmtmr_amba, sizeof(struct bcm2835tmr_softc), +CFATTACH_DECL_NEW(bcmtmr_fdt, sizeof(struct bcm2835tmr_softc), bcmtmr_match, bcmtmr_attach, NULL, NULL); /* ARGSUSED */ static int bcmtmr_match(device_t parent, cfdata_t match, void *aux) { - struct amba_attach_args *aaa = aux; - - if (strcmp(aaa->aaa_name, "bcmtmr") != 0) - return 0; - - return 1; + const char * const compatible[] = { + "brcm,bcm2835-system-timer", + NULL + }; + struct fdt_attach_args * const faa = aux; + return of_match_compatible(faa->faa_phandle, compatible); } static void bcmtmr_attach(device_t parent, device_t self, void *aux) { struct bcm2835tmr_softc *sc = device_private(self); - struct amba_attach_args *aaa = aux; + struct fdt_attach_args * const faa = aux; aprint_naive("\n"); aprint_normal(": VC System Timer\n"); @@ -115,14 +125,37 @@ bcmtmr_attach(device_t parent, device_t bcm2835tmr_sc = sc; sc->sc_dev = self; - sc->sc_iot = aaa->aaa_iot; + sc->sc_iot = faa->faa_bst; + const int phandle = faa->faa_phandle; + + bus_addr_t addr; + bus_size_t size; - if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, BCM2835_STIMER_SIZE, 0, - &sc->sc_ioh)) { + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": missing 'reg' property\n"); + return; + } + + if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) { aprint_error_dev(sc->sc_dev, "unable to map device\n"); return; } + char intrstr[128]; + if (!fdtbus_intr_str(phandle, BCMTIMER, intrstr, sizeof(intrstr))) { + aprint_error(": failed to decode interrupt\n"); + return; + } + + sc->sc_ih = fdtbus_intr_establish(phandle, BCMTIMER, IPL_CLOCK, + FDT_INTR_MPSAFE, clockhandler, NULL); + if (sc->sc_ih == NULL) { + aprint_error(": failed to establish interrupt on %s\n", + intrstr); + return; + } + aprint_normal_dev(self, "interrupting on %s\n", intrstr); + bcm2835tmr_timecounter.tc_name = device_xname(self); } @@ -130,7 +163,6 @@ void cpu_initclocks(void) { struct bcm2835tmr_softc *sc = bcm2835tmr_sc; - void *clock_ih; uint32_t stcl; KASSERT(sc != NULL); @@ -143,16 +175,12 @@ cpu_initclocks(void) stcl += counts_per_hz; bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_STIMER_C3, stcl); - clock_ih = intr_establish(BCM2835_INT_TIMER3, IPL_CLOCK, IST_LEVEL, - clockhandler, NULL); - if (clock_ih == NULL) - panic("%s: unable to register timer interrupt", __func__); tc_init(&bcm2835tmr_timecounter); } void -delay(unsigned int n) +bcm2835_tmr_delay(unsigned int n) { struct bcm2835tmr_softc *sc = bcm2835tmr_sc; uint32_t last, curr; Index: sys/arch/arm/broadcom/bcm2835reg.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835reg.h,v retrieving revision 1.20 diff -u -p -r1.20 bcm2835reg.h --- sys/arch/arm/broadcom/bcm2835reg.h 30 Jul 2017 23:48:32 -0000 1.20 +++ sys/arch/arm/broadcom/bcm2835reg.h 3 Dec 2017 12:00:58 -0000 @@ -40,14 +40,20 @@ #include "opt_bcm283x.h" -#ifdef BCM2836 -#define BCM2835_PERIPHERALS_BASE 0x3f000000 -#else -#define BCM2835_PERIPHERALS_BASE 0x20000000 +#if defined(SOC_BCM2835) + defined(SOC_BCM2836) != 1 +#error Must define SOC_BCM2835 or SOC_BCM2836, and not both #endif -#define BCM2835_PERIPHERALS_SIZE 0x01000000 /* 16MBytes */ +#define BCM2836_PERIPHERALS_BASE 0x3f000000 +#define BCM2835_PERIPHERALS_BASE 0x20000000 +#define BCM2835_PERIPHERALS_SIZE 0x01000000 /* 16MBytes */ #define BCM2835_PERIPHERALS_BASE_BUS 0x7e000000 + +#define BCM2836_PERIPHERALS_PHYS_TO_BUS(a) \ + ((a) - BCM2836_PERIPHERALS_BASE + BCM2835_PERIPHERALS_BASE_BUS) +#define BCM2836_PERIPHERALS_BUS_TO_PHYS(a) \ + ((a) - BCM2835_PERIPHERALS_BASE_BUS + BCM2836_PERIPHERALS_BASE) + #define BCM2835_PERIPHERALS_PHYS_TO_BUS(a) \ ((a) - BCM2835_PERIPHERALS_BASE + BCM2835_PERIPHERALS_BASE_BUS) #define BCM2835_PERIPHERALS_BUS_TO_PHYS(a) \ @@ -106,6 +112,9 @@ #define BCM2835_PERIPHERALS_VBASE \ BCM2835_IOPHYSTOVIRT(BCM2835_PERIPHERALS_BASE) +#define BCM2836_PERIPHERALS_VBASE \ + BCM2835_IOPHYSTOVIRT(BCM2836_PERIPHERALS_BASE) + #define BCM2835_ARMICU_BASE (BCM2835_ARM_BASE + 0x0200) #define BCM2835_ARMICU_SIZE 0x200 @@ -132,7 +141,12 @@ #define BCM2835_INTC_ENABLEBASE (BCM2835_INTC_BASE + 0x10) #define BCM2835_INTC_DISABLEBASE (BCM2835_INTC_BASE + 0x1c) -#if defined(BCM2836) +#if defined(SOC_BCM2836) +#define BCM2835_INT_BASE BCM2836_NIRQ +#else +#define BCM2835_INT_BASE 0 +#endif /* !BCM2836 */ + #define BCM2836_NCPUS 4 #define BCM2836_NIRQPERCPU 32 @@ -140,8 +154,6 @@ #define BCM2836_INT_BASECPUN(n) (BCM2836_INT_LOCALBASE + ((n) * BCM2836_NIRQPERCPU)) #define BCM2836_NIRQ (BCM2836_NIRQPERCPU * BCM2836_NCPUS) -#define BCM2835_INT_BASE BCM2836_NIRQ - #define BCM2836_INT_CNTPSIRQ 0 #define BCM2836_INT_CNTPNSIRQ 1 #define BCM2836_INT_CNTHPIRQ 2 @@ -161,9 +173,6 @@ #define BCM2836_INT_CNTVIRQ_CPUN(n) (BCM2836_INT_BASECPUN(n) + BCM2836_INT_CNTVIRQ) #define BCM2836_INT_CNTHPIRQ_CPUN(n) (BCM2836_INT_BASECPUN(n) + BCM2836_INT_CNTHPIRQ) #define BCM2836_INT_MAILBOX0_CPUN(n) (BCM2836_INT_BASECPUN(n) + BCM2836_INT_MAILBOX0) -#else -#define BCM2835_INT_BASE 0 -#endif /* !BCM2836 */ /* Periperal Interrupt sources */ #define BCM2835_NIRQ 96 Index: sys/arch/arm/broadcom/bcm2835var.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835var.h,v retrieving revision 1.2 diff -u -p -r1.2 bcm2835var.h --- sys/arch/arm/broadcom/bcm2835var.h 28 Feb 2015 09:34:34 -0000 1.2 +++ sys/arch/arm/broadcom/bcm2835var.h 3 Dec 2017 12:00:58 -0000 @@ -37,6 +37,8 @@ extern struct bus_space bcm2835_bs_tag; extern struct bus_space bcm2835_a4x_bs_tag; +extern struct bus_space bcm2836_bs_tag; +extern struct bus_space bcm2836_a4x_bs_tag; extern struct arm32_bus_dma_tag bcm2835_bus_dma_tag; extern bus_space_tag_t al_iot; @@ -44,6 +46,12 @@ extern bus_space_handle_t al_ioh; bus_dma_tag_t bcm2835_bus_dma_init(struct arm32_bus_dma_tag *); +void bcm2835_tmr_delay(unsigned int); + void bcm2836_cpu_hatch(struct cpu_info *); +u_int bcm283x_clk_get_rate_uart(void); +u_int bcm283x_clk_get_rate_vpu(void); +u_int bcm283x_clk_get_rate_emmc(void); + #endif /* _ARM_BROADCOM_BCM2835_VAR_H_ */ Index: sys/arch/arm/broadcom/bcm283x_platform.c =================================================================== RCS file: sys/arch/arm/broadcom/bcm283x_platform.c diff -N sys/arch/arm/broadcom/bcm283x_platform.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/broadcom/bcm283x_platform.c 3 Dec 2017 12:00:59 -0000 @@ -0,0 +1,1300 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2017 Jared D. McNeill + * 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 ``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 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 +__KERNEL_RCSID(0, "$NetBSD$"); + +#include "opt_arm_debug.h" +#include "opt_bcm283x.h" +#include "opt_cpuoptions.h" +#include "opt_ddb.h" +#include "opt_evbarm_boardtype.h" +#include "opt_kgdb.h" +#include "opt_fdt.h" +#include "opt_rpi.h" +#include "opt_vcprop.h" + +#include "sdhc.h" +#include "bcmsdhost.h" +#include "bcmdwctwo.h" +#include "bcmspi.h" +#include "bsciic.h" +#include "plcom.h" +#include "com.h" +#include "genfb.h" +#include "ukbd.h" + +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include + +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include + +#if NGENFB > 0 +#include +#include +#include +#endif + +#if NUKBD > 0 +#include +#endif + +#ifdef DDB +#include +#include +#include +#endif + +void bcm283x_platform_early_putchar(vaddr_t, paddr_t, char c); +void bcm2835_platform_early_putchar(char c); +void bcm2836_platform_early_putchar(char c); +void bcm2837_platform_early_putchar(char c); + +extern void bcmgenfb_set_console_dev(device_t dev); +void bcmgenfb_set_ioctl(int(*)(void *, void *, u_long, void *, int, struct lwp *)); +extern void bcmgenfb_ddb_trap_callback(int where); +static int rpi_ioctl(void *, void *, u_long, void *, int, lwp_t *); + +extern struct bus_space armv7_generic_bs_tag; +extern struct bus_space armv7_generic_a4x_bs_tag; +extern struct arm32_bus_dma_tag armv7_generic_dma_tag; + +/* Prototypes for all the bus_space structure functions */ +bs_protos(bcm2835); +bs_protos(bcm2835_a4x); +bs_protos(armv7_generic); +bs_protos(armv7_generic_a4x); +bs_protos(generic); +bs_protos(generic_armv4); +bs_protos(a4x); +bs_protos(bs_notimpl); + +#if 0 +#if __ARMEB__ +#define NSWAP(n) n ## _swap +#else +#define NSWAP(n) n +#endif +#endif + +struct arm32_dma_range bcm2835_dma_ranges[] = { + [0] = { + .dr_sysbase = 0, + .dr_busbase = BCM2835_BUSADDR_CACHE_COHERENT, + } +}; + +struct arm32_dma_range bcm2836_dma_ranges[] = { + [0] = { + .dr_sysbase = 0, + .dr_busbase = BCM2835_BUSADDR_CACHE_DIRECT, + } +}; + + +#if defined(SOC_BCM2835) +static const struct pmap_devmap * +bcm2835_platform_devmap(void) +{ + static const struct pmap_devmap devmap[] = { + DEVMAP_ENTRY(BCM2835_PERIPHERALS_VBASE, BCM2835_PERIPHERALS_BASE, + BCM2835_PERIPHERALS_SIZE), /* 16Mb */ + + DEVMAP_ENTRY_END + }; + + return devmap; +} +#endif + +#if defined(SOC_BCM2836) +static const struct pmap_devmap * +bcm2836_platform_devmap(void) +{ + static const struct pmap_devmap devmap[] = { + DEVMAP_ENTRY(BCM2836_PERIPHERALS_VBASE, BCM2836_PERIPHERALS_BASE, + BCM2835_PERIPHERALS_SIZE), /* 16Mb */ + + /* This overlaps memory!!! (or does it?) */ + DEVMAP_ENTRY(BCM2836_ARM_LOCAL_VBASE, BCM2836_ARM_LOCAL_BASE, + BCM2836_ARM_LOCAL_SIZE), + + DEVMAP_ENTRY_END + }; + + return devmap; +} +#endif + +/* + * Macros to translate between physical and virtual for a subset of the + * kernel address space. *Not* for general use. + */ + +#define KERN_VTOPDIFF KERNEL_BASE_VOFFSET +#define KERN_VTOPHYS(va) ((paddr_t)((vaddr_t)va - KERN_VTOPDIFF)) +#define KERN_PHYSTOV(pa) ((vaddr_t)((paddr_t)pa + KERN_VTOPDIFF)) + + +#ifndef RPI_FB_WIDTH +#define RPI_FB_WIDTH 1280 +#endif +#ifndef RPI_FB_HEIGHT +#define RPI_FB_HEIGHT 720 +#endif + +int uart_clk = BCM2835_UART0_CLK; +int core_clk; + +static struct __aligned(16) { + struct vcprop_buffer_hdr vb_hdr; + struct vcprop_tag_clockrate vbt_uartclockrate; + struct vcprop_tag_clockrate vbt_vpuclockrate; + struct vcprop_tag end; +} vb_uart = { + .vb_hdr = { + .vpb_len = sizeof(vb_uart), + .vpb_rcode = VCPROP_PROCESS_REQUEST, + }, + .vbt_uartclockrate = { + .tag = { + .vpt_tag = VCPROPTAG_GET_CLOCKRATE, + .vpt_len = VCPROPTAG_LEN(vb_uart.vbt_uartclockrate), + .vpt_rcode = VCPROPTAG_REQUEST + }, + .id = VCPROP_CLK_UART + }, + .vbt_vpuclockrate = { + .tag = { + .vpt_tag = VCPROPTAG_GET_CLOCKRATE, + .vpt_len = VCPROPTAG_LEN(vb_uart.vbt_vpuclockrate), + .vpt_rcode = VCPROPTAG_REQUEST + }, + .id = VCPROP_CLK_CORE + }, + .end = { + .vpt_tag = VCPROPTAG_NULL + } +}; + +static struct __aligned(16) { + struct vcprop_buffer_hdr vb_hdr; + struct vcprop_tag_fwrev vbt_fwrev; + struct vcprop_tag_boardmodel vbt_boardmodel; + struct vcprop_tag_boardrev vbt_boardrev; + struct vcprop_tag_macaddr vbt_macaddr; + struct vcprop_tag_memory vbt_memory; + struct vcprop_tag_boardserial vbt_serial; + struct vcprop_tag_dmachan vbt_dmachan; + struct vcprop_tag_cmdline vbt_cmdline; + struct vcprop_tag_clockrate vbt_emmcclockrate; + struct vcprop_tag_clockrate vbt_armclockrate; + struct vcprop_tag_clockrate vbt_vpuclockrate; + struct vcprop_tag end; +} vb = { + .vb_hdr = { + .vpb_len = sizeof(vb), + .vpb_rcode = VCPROP_PROCESS_REQUEST, + }, + .vbt_fwrev = { + .tag = { + .vpt_tag = VCPROPTAG_GET_FIRMWAREREV, + .vpt_len = VCPROPTAG_LEN(vb.vbt_fwrev), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .vbt_boardmodel = { + .tag = { + .vpt_tag = VCPROPTAG_GET_BOARDMODEL, + .vpt_len = VCPROPTAG_LEN(vb.vbt_boardmodel), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .vbt_boardrev = { + .tag = { + .vpt_tag = VCPROPTAG_GET_BOARDREVISION, + .vpt_len = VCPROPTAG_LEN(vb.vbt_boardrev), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .vbt_macaddr = { + .tag = { + .vpt_tag = VCPROPTAG_GET_MACADDRESS, + .vpt_len = VCPROPTAG_LEN(vb.vbt_macaddr), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .vbt_memory = { + .tag = { + .vpt_tag = VCPROPTAG_GET_ARMMEMORY, + .vpt_len = VCPROPTAG_LEN(vb.vbt_memory), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .vbt_serial = { + .tag = { + .vpt_tag = VCPROPTAG_GET_BOARDSERIAL, + .vpt_len = VCPROPTAG_LEN(vb.vbt_serial), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .vbt_dmachan = { + .tag = { + .vpt_tag = VCPROPTAG_GET_DMACHAN, + .vpt_len = VCPROPTAG_LEN(vb.vbt_dmachan), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .vbt_cmdline = { + .tag = { + .vpt_tag = VCPROPTAG_GET_CMDLINE, + .vpt_len = VCPROPTAG_LEN(vb.vbt_cmdline), + .vpt_rcode = VCPROPTAG_REQUEST + }, + }, + .vbt_emmcclockrate = { + .tag = { + .vpt_tag = VCPROPTAG_GET_CLOCKRATE, + .vpt_len = VCPROPTAG_LEN(vb.vbt_emmcclockrate), + .vpt_rcode = VCPROPTAG_REQUEST + }, + .id = VCPROP_CLK_EMMC + }, + .vbt_armclockrate = { + .tag = { + .vpt_tag = VCPROPTAG_GET_CLOCKRATE, + .vpt_len = VCPROPTAG_LEN(vb.vbt_armclockrate), + .vpt_rcode = VCPROPTAG_REQUEST + }, + .id = VCPROP_CLK_ARM + }, + .vbt_vpuclockrate = { + .tag = { + .vpt_tag = VCPROPTAG_GET_CLOCKRATE, + .vpt_len = VCPROPTAG_LEN(vb.vbt_vpuclockrate), + .vpt_rcode = VCPROPTAG_REQUEST + }, + .id = VCPROP_CLK_CORE + }, + .end = { + .vpt_tag = VCPROPTAG_NULL + } +}; + +#if NGENFB > 0 +static struct __aligned(16) { + struct vcprop_buffer_hdr vb_hdr; + struct vcprop_tag_edidblock vbt_edid; + struct vcprop_tag end; +} vb_edid = { + .vb_hdr = { + .vpb_len = sizeof(vb_edid), + .vpb_rcode = VCPROP_PROCESS_REQUEST, + }, + .vbt_edid = { + .tag = { + .vpt_tag = VCPROPTAG_GET_EDID_BLOCK, + .vpt_len = VCPROPTAG_LEN(vb_edid.vbt_edid), + .vpt_rcode = VCPROPTAG_REQUEST, + }, + .blockno = 0, + }, + .end = { + .vpt_tag = VCPROPTAG_NULL + } +}; + +static struct __aligned(16) { + struct vcprop_buffer_hdr vb_hdr; + struct vcprop_tag_fbres vbt_res; + struct vcprop_tag_fbres vbt_vres; + struct vcprop_tag_fbdepth vbt_depth; + struct vcprop_tag_fbalpha vbt_alpha; + struct vcprop_tag_allocbuf vbt_allocbuf; + struct vcprop_tag_blankscreen vbt_blank; + struct vcprop_tag_fbpitch vbt_pitch; + struct vcprop_tag end; +} vb_setfb = { + .vb_hdr = { + .vpb_len = sizeof(vb_setfb), + .vpb_rcode = VCPROP_PROCESS_REQUEST, + }, + .vbt_res = { + .tag = { + .vpt_tag = VCPROPTAG_SET_FB_RES, + .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_res), + .vpt_rcode = VCPROPTAG_REQUEST, + }, + .width = 0, + .height = 0, + }, + .vbt_vres = { + .tag = { + .vpt_tag = VCPROPTAG_SET_FB_VRES, + .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_vres), + .vpt_rcode = VCPROPTAG_REQUEST, + }, + .width = 0, + .height = 0, + }, + .vbt_depth = { + .tag = { + .vpt_tag = VCPROPTAG_SET_FB_DEPTH, + .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_depth), + .vpt_rcode = VCPROPTAG_REQUEST, + }, + .bpp = 32, + }, + .vbt_alpha = { + .tag = { + .vpt_tag = VCPROPTAG_SET_FB_ALPHA_MODE, + .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_alpha), + .vpt_rcode = VCPROPTAG_REQUEST, + }, + .state = VCPROP_ALPHA_IGNORED, + }, + .vbt_allocbuf = { + .tag = { + .vpt_tag = VCPROPTAG_ALLOCATE_BUFFER, + .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_allocbuf), + .vpt_rcode = VCPROPTAG_REQUEST, + }, + .address = PAGE_SIZE, /* alignment */ + }, + .vbt_blank = { + .tag = { + .vpt_tag = VCPROPTAG_BLANK_SCREEN, + .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_blank), + .vpt_rcode = VCPROPTAG_REQUEST, + }, + .state = VCPROP_BLANK_OFF, + }, + .vbt_pitch = { + .tag = { + .vpt_tag = VCPROPTAG_GET_FB_PITCH, + .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_pitch), + .vpt_rcode = VCPROPTAG_REQUEST, + }, + }, + .end = { + .vpt_tag = VCPROPTAG_NULL, + }, +}; + +#endif + +static int rpi_video_on = WSDISPLAYIO_VIDEO_ON; + +#if defined(RPI_HWCURSOR) +#define CURSOR_BITMAP_SIZE (64 * 8) +#define CURSOR_ARGB_SIZE (64 * 64 * 4) +static uint32_t hcursor = 0; +static bus_addr_t pcursor = 0; +static uint32_t *cmem = NULL; +static int cursor_x = 0, cursor_y = 0, hot_x = 0, hot_y = 0, cursor_on = 0; +static uint32_t cursor_cmap[4]; +static uint8_t cursor_mask[8 * 64], cursor_bitmap[8 * 64]; +#endif + +u_int +bcm283x_clk_get_rate_uart(void) +{ + + if (vcprop_tag_success_p(&vb_uart.vbt_uartclockrate.tag)) + return vb_uart.vbt_uartclockrate.rate; + return 0; +} + +u_int +bcm283x_clk_get_rate_vpu(void) +{ + + if (vcprop_tag_success_p(&vb.vbt_vpuclockrate.tag) && + vb.vbt_vpuclockrate.rate > 0) { + return vb.vbt_vpuclockrate.rate; + } + return 0; +} + +u_int +bcm283x_clk_get_rate_emmc(void) +{ + + if (vcprop_tag_success_p(&vb.vbt_emmcclockrate.tag) && + vb.vbt_emmcclockrate.rate > 0) { + return vb.vbt_emmcclockrate.rate; + } + return 0; +} + + + +static void +bcm283x_uartinit(bus_space_tag_t iot, bus_space_handle_t ioh) +{ + uint32_t res; + + bcm2835_mbox_write(iot, ioh, BCMMBOX_CHANARM2VC, + KERN_VTOPHYS(&vb_uart)); + + bcm2835_mbox_read(iot, ioh, BCMMBOX_CHANARM2VC, &res); + + cpu_dcache_inv_range((vaddr_t)&vb_uart, sizeof(vb_uart)); + + if (vcprop_tag_success_p(&vb_uart.vbt_uartclockrate.tag)) + uart_clk = vb_uart.vbt_uartclockrate.rate; + if (vcprop_tag_success_p(&vb_uart.vbt_vpuclockrate.tag)) + core_clk = vb_uart.vbt_vpuclockrate.rate; +} + +#if defined(SOC_BCM2835) +static void +bcm2835_uartinit(void) +{ + const paddr_t pa = BCM2835_PERIPHERALS_BUS_TO_PHYS(BCM2835_ARMMBOX_BASE); + const bus_space_tag_t iot = &bcm2835_bs_tag; + const bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(pa); + + bcm283x_uartinit(iot, ioh); +} +#endif + +#if defined(SOC_BCM2836) +static void +bcm2836_uartinit(void) +{ + const paddr_t pa = BCM2836_PERIPHERALS_BUS_TO_PHYS(BCM2835_ARMMBOX_BASE); + const bus_space_tag_t iot = &bcm2836_bs_tag; + const bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(pa); + + bcm283x_uartinit(iot, ioh); +} +#endif + +#define BCM283x_MINIMUM_SPLIT (128U * 1024 * 1024) + +static void +bcm283x_bootparams(bus_space_tag_t iot, bus_space_handle_t ioh) +{ + uint32_t res; + + bcm2835_mbox_write(iot, ioh, BCMMBOX_CHANPM, ( +#if (NSDHC > 0) + (1 << VCPM_POWER_SDCARD) | +#endif +#if (NPLCOM > 0) + (1 << VCPM_POWER_UART0) | +#endif +#if (NBCMDWCTWO > 0) + (1 << VCPM_POWER_USB) | +#endif +#if (NBSCIIC > 0) + (1 << VCPM_POWER_I2C0) | (1 << VCPM_POWER_I2C1) | + /* (1 << VCPM_POWER_I2C2) | */ +#endif +#if (NBCMSPI > 0) + (1 << VCPM_POWER_SPI) | +#endif + 0) << 4); + + bcm2835_mbox_write(iot, ioh, BCMMBOX_CHANARM2VC, KERN_VTOPHYS(&vb)); + + bcm2835_mbox_read(iot, ioh, BCMMBOX_CHANARM2VC, &res); + + cpu_dcache_inv_range((vaddr_t)&vb, sizeof(vb)); + + // Needed? + if (!vcprop_buffer_success_p(&vb.vb_hdr)) { + bootconfig.dramblocks = 1; + bootconfig.dram[0].address = 0x0; + bootconfig.dram[0].pages = atop(BCM283x_MINIMUM_SPLIT); + return; + } + + struct vcprop_tag_memory *vptp_mem = &vb.vbt_memory; + + if (vcprop_tag_success_p(&vptp_mem->tag)) { + size_t n = vcprop_tag_resplen(&vptp_mem->tag) / + sizeof(struct vcprop_memory); + + bootconfig.dramblocks = 0; + + for (int i = 0; i < n && i < DRAM_BLOCKS; i++) { + bootconfig.dram[i].address = vptp_mem->mem[i].base; + bootconfig.dram[i].pages = atop(vptp_mem->mem[i].size); + bootconfig.dramblocks++; + } + } + + if (vcprop_tag_success_p(&vb.vbt_armclockrate.tag)) + curcpu()->ci_data.cpu_cc_freq = vb.vbt_armclockrate.rate; + +#ifdef VERBOSE_INIT_ARM + if (vcprop_tag_success_p(&vb.vbt_armclockrate.tag)) + printf("%s: arm clock %d\n", __func__, + vb.vbt_armclockrate.rate); + if (vcprop_tag_success_p(&vb.vbt_fwrev.tag)) + printf("%s: firmware rev %x\n", __func__, + vb.vbt_fwrev.rev); + if (vcprop_tag_success_p(&vb.vbt_macaddr.tag)) + printf("%s: mac-address %llx\n", __func__, + vb.vbt_macaddr.addr); + if (vcprop_tag_success_p(&vb.vbt_boardmodel.tag)) + printf("%s: board model %x\n", __func__, + vb.vbt_boardmodel.model); + if (vcprop_tag_success_p(&vb.vbt_boardrev.tag)) + printf("%s: board rev %x\n", __func__, + vb.vbt_boardrev.rev); + if (vcprop_tag_success_p(&vb.vbt_serial.tag)) + printf("%s: board serial %llx\n", __func__, + vb.vbt_serial.sn); + if (vcprop_tag_success_p(&vb.vbt_dmachan.tag)) + printf("%s: DMA channel mask 0x%08x\n", __func__, + vb.vbt_dmachan.mask); + + if (vcprop_tag_success_p(&vb.vbt_cmdline.tag)) + printf("%s: cmdline %s\n", __func__, + vb.vbt_cmdline.cmdline); +#endif +} + +#if defined(SOC_BCM2835) +static void +bcm2835_bootparams(void) +{ + const paddr_t pa = BCM2835_PERIPHERALS_BUS_TO_PHYS(BCM2835_ARMMBOX_BASE); + const bus_space_tag_t iot = &bcm2835_bs_tag; + const bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(pa); + + bcm283x_bootparams(iot, ioh); +} +#endif + +#if defined(SOC_BCM2836) +static void +bcm2836_bootparams(void) +{ + const paddr_t pa = BCM2836_PERIPHERALS_BUS_TO_PHYS(BCM2835_ARMMBOX_BASE); + const bus_space_tag_t iot = &bcm2836_bs_tag; + const bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(pa); + + bcm283x_bootparams(iot, ioh); +} + +static void +bcm2836_bootstrap(void) +{ + arm_cpu_max = 4; + extern int cortex_mmuinfo; + + cortex_mmuinfo = armreg_ttbr_read(); +#ifdef VERBOSE_INIT_ARM + printf("%s: cortex_mmuinfo %x\n", __func__, cortex_mmuinfo); +#endif + + extern void cortex_mpstart(void); + + for (size_t i = 1; i < arm_cpu_max; i++) { + bus_space_tag_t iot = &bcm2836_bs_tag; + bus_space_handle_t ioh = BCM2836_ARM_LOCAL_VBASE; + + bus_space_write_4(iot, ioh, + BCM2836_LOCAL_MAILBOX3_SETN(i), + (uint32_t)cortex_mpstart); + } + + /* Wake up AP in case firmware has placed it in WFE state */ + __asm __volatile("sev" ::: "memory"); + + for (int loop = 0; loop < 16; loop++) { + if (arm_cpu_hatched == __BITS(arm_cpu_max - 1, 1)) + break; + gtmr_delay(10000); + } + + for (size_t i = 1; i < arm_cpu_max; i++) { + if ((arm_cpu_hatched & (1 << i)) == 0) { + printf("%s: warning: cpu%zu failed to hatch\n", + __func__, i); + } + } +} + +#endif /* SOC_BCM2836 */ + +#if NGENFB > 0 +static bool +rpi_fb_parse_mode(const char *s, uint32_t *pwidth, uint32_t *pheight) +{ + char *x; + + if (strncmp(s, "disable", 7) == 0) + return false; + + x = strchr(s, 'x'); + if (x) { + *pwidth = strtoul(s, NULL, 10); + *pheight = strtoul(x + 1, NULL, 10); + } + + return true; +} + +static bool +rpi_fb_get_edid_mode(uint32_t *pwidth, uint32_t *pheight) +{ + struct edid_info ei; + uint8_t edid_data[1024]; + uint32_t res; + int error; + + error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_edid, + sizeof(vb_edid), &res); + if (error) { + printf("%s: mbox request failed (%d)\n", __func__, error); + return false; + } + + if (!vcprop_buffer_success_p(&vb_edid.vb_hdr) || + !vcprop_tag_success_p(&vb_edid.vbt_edid.tag) || + vb_edid.vbt_edid.status != 0) + return false; + + memset(edid_data, 0, sizeof(edid_data)); + memcpy(edid_data, vb_edid.vbt_edid.data, + sizeof(vb_edid.vbt_edid.data)); + edid_parse(edid_data, &ei); +#ifdef VERBOSE_INIT_ARM + edid_print(&ei); +#endif + + if (ei.edid_preferred_mode) { + *pwidth = ei.edid_preferred_mode->hdisplay; + *pheight = ei.edid_preferred_mode->vdisplay; + } + + return true; +} + +/* + * Initialize framebuffer console. + * + * Some notes about boot parameters: + * - If "fb=disable" is present, ignore framebuffer completely. + * - If "fb=x is present, use the specified mode. + * - If "console=fb" is present, attach framebuffer to console. + */ +static bool +rpi_fb_init(prop_dictionary_t dict, void *aux) +{ + uint32_t width = 0, height = 0; + uint32_t res; + char *ptr; + int integer; + int error; + bool is_bgr = true; + + if (get_bootconf_option(boot_args, "fb", + BOOTOPT_TYPE_STRING, &ptr)) { + if (rpi_fb_parse_mode(ptr, &width, &height) == false) + return false; + } + if (width == 0 || height == 0) { + rpi_fb_get_edid_mode(&width, &height); + } + if (width == 0 || height == 0) { + width = RPI_FB_WIDTH; + height = RPI_FB_HEIGHT; + } + + vb_setfb.vbt_res.width = width; + vb_setfb.vbt_res.height = height; + vb_setfb.vbt_vres.width = width; + vb_setfb.vbt_vres.height = height; + error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_setfb, + sizeof(vb_setfb), &res); + if (error) { + printf("%s: mbox request failed (%d)\n", __func__, error); + return false; + } + + if (!vcprop_buffer_success_p(&vb_setfb.vb_hdr) || + !vcprop_tag_success_p(&vb_setfb.vbt_res.tag) || + !vcprop_tag_success_p(&vb_setfb.vbt_vres.tag) || + !vcprop_tag_success_p(&vb_setfb.vbt_depth.tag) || + !vcprop_tag_success_p(&vb_setfb.vbt_allocbuf.tag) || + !vcprop_tag_success_p(&vb_setfb.vbt_blank.tag) || + !vcprop_tag_success_p(&vb_setfb.vbt_pitch.tag)) { + printf("%s: prop tag failed\n", __func__); + return false; + } + +#ifdef VERBOSE_INIT_ARM + printf("%s: addr = 0x%x size = %d\n", __func__, + vb_setfb.vbt_allocbuf.address, + vb_setfb.vbt_allocbuf.size); + printf("%s: depth = %d\n", __func__, vb_setfb.vbt_depth.bpp); + printf("%s: pitch = %d\n", __func__, + vb_setfb.vbt_pitch.linebytes); + printf("%s: width = %d height = %d\n", __func__, + vb_setfb.vbt_res.width, vb_setfb.vbt_res.height); + printf("%s: vwidth = %d vheight = %d\n", __func__, + vb_setfb.vbt_vres.width, vb_setfb.vbt_vres.height); +#endif + + if (vb_setfb.vbt_allocbuf.address == 0 || + vb_setfb.vbt_allocbuf.size == 0 || + vb_setfb.vbt_res.width == 0 || + vb_setfb.vbt_res.height == 0 || + vb_setfb.vbt_vres.width == 0 || + vb_setfb.vbt_vres.height == 0 || + vb_setfb.vbt_pitch.linebytes == 0) { + printf("%s: failed to set mode %ux%u\n", __func__, + width, height); + return false; + } + + prop_dictionary_set_uint32(dict, "width", vb_setfb.vbt_res.width); + prop_dictionary_set_uint32(dict, "height", vb_setfb.vbt_res.height); + prop_dictionary_set_uint8(dict, "depth", vb_setfb.vbt_depth.bpp); + prop_dictionary_set_uint16(dict, "linebytes", + vb_setfb.vbt_pitch.linebytes); + prop_dictionary_set_uint32(dict, "address", + vb_setfb.vbt_allocbuf.address); + + /* + * Old firmware uses BGR. New firmware uses RGB. The get and set + * pixel order mailbox properties don't seem to work. The firmware + * adds a kernel cmdline option bcm2708_fb.fbswap=<0|1>, so use it + * to determine pixel order. 0 means BGR, 1 means RGB. + * + * See https://github.com/raspberrypi/linux/issues/514 + */ + if (get_bootconf_option(boot_args, "bcm2708_fb.fbswap", + BOOTOPT_TYPE_INT, &integer)) { + is_bgr = integer == 0; + } + prop_dictionary_set_bool(dict, "is_bgr", is_bgr); + + /* if "genfb.type=" is passed in cmdline, override wsdisplay type */ + if (get_bootconf_option(boot_args, "genfb.type", + BOOTOPT_TYPE_INT, &integer)) { + prop_dictionary_set_uint32(dict, "wsdisplay_type", integer); + } + +#if defined(RPI_HWCURSOR) + struct fdt_attach_args *faa = aux; + bus_space_handle_t hc; + + hcursor = rpi_alloc_mem(CURSOR_ARGB_SIZE, PAGE_SIZE, + MEM_FLAG_L1_NONALLOCATING | MEM_FLAG_HINT_PERMALOCK); + pcursor = rpi_lock_mem(hcursor); +#ifdef RPI_IOCTL_DEBUG + printf("hcursor: %08x\n", hcursor); + printf("pcursor: %08x\n", (uint32_t)pcursor); + printf("fb: %08x\n", (uint32_t)vb_setfb.vbt_allocbuf.address); +#endif + if (bus_space_map(faa->faa_bst, pcursor, CURSOR_ARGB_SIZE, + BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_PREFETCHABLE, &hc) != 0) { + printf("couldn't map cursor memory\n"); + } else { + int i, j, k; + + cmem = bus_space_vaddr(faa->faa_bst, hc); + k = 0; + for (j = 0; j < 64; j++) { + for (i = 0; i < 64; i++) { + cmem[i + k] = + ((i & 8) ^ (j & 8)) ? 0xa0ff0000 : 0xa000ff00; + } + k += 64; + } + cpu_dcache_wb_range((vaddr_t)cmem, CURSOR_ARGB_SIZE); + rpi_fb_initcursor(pcursor, 0, 0); +#ifdef RPI_IOCTL_DEBUG + rpi_fb_movecursor(600, 400, 1); +#else + rpi_fb_movecursor(cursor_x, cursor_y, cursor_on); +#endif + } +#endif + + return true; +} + + +#if defined(RPI_HWCURSOR) +static int +rpi_fb_do_cursor(struct wsdisplay_cursor *cur) +{ + int pos = 0; + int shape = 0; + + if (cur->which & WSDISPLAY_CURSOR_DOCUR) { + if (cursor_on != cur->enable) { + cursor_on = cur->enable; + pos = 1; + } + } + if (cur->which & WSDISPLAY_CURSOR_DOHOT) { + + hot_x = cur->hot.x; + hot_y = cur->hot.y; + pos = 1; + shape = 1; + } + if (cur->which & WSDISPLAY_CURSOR_DOPOS) { + + cursor_x = cur->pos.x; + cursor_y = cur->pos.y; + pos = 1; + } + if (cur->which & WSDISPLAY_CURSOR_DOCMAP) { + int i; + uint32_t val; + + for (i = 0; i < min(cur->cmap.count, 3); i++) { + val = (cur->cmap.red[i] << 16 ) | + (cur->cmap.green[i] << 8) | + (cur->cmap.blue[i] ) | + 0xff000000; + cursor_cmap[i + cur->cmap.index + 2] = val; + } + shape = 1; + } + if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) { + int err; + + err = copyin(cur->mask, cursor_mask, CURSOR_BITMAP_SIZE); + err += copyin(cur->image, cursor_bitmap, CURSOR_BITMAP_SIZE); + if (err != 0) + return EFAULT; + shape = 1; + } + if (shape) { + int i, j, idx; + uint8_t mask; + + for (i = 0; i < CURSOR_BITMAP_SIZE; i++) { + mask = 0x01; + for (j = 0; j < 8; j++) { + idx = ((cursor_mask[i] & mask) ? 2 : 0) | + ((cursor_bitmap[i] & mask) ? 1 : 0); + cmem[i * 8 + j] = cursor_cmap[idx]; + mask = mask << 1; + } + } + /* just in case */ + cpu_dcache_wb_range((vaddr_t)cmem, CURSOR_ARGB_SIZE); + rpi_fb_initcursor(pcursor, hot_x, hot_y); + } + if (pos) { + rpi_fb_movecursor(cursor_x, cursor_y, cursor_on); + } + return 0; +} +#endif + +static int +rpi_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, lwp_t *l) +{ + + switch (cmd) { + case WSDISPLAYIO_SVIDEO: + { + int d = *(int *)data; + if (d == rpi_video_on) + return 0; + rpi_video_on = d; + rpi_fb_set_video(d); +#if defined(RPI_HWCURSOR) + rpi_fb_movecursor(cursor_x, cursor_y, + d ? cursor_on : 0); +#endif + } + return 0; + case WSDISPLAYIO_GVIDEO: + *(int *)data = rpi_video_on; + return 0; +#if defined(RPI_HWCURSOR) + case WSDISPLAYIO_GCURPOS: + { + struct wsdisplay_curpos *cp = (void *)data; + + cp->x = cursor_x; + cp->y = cursor_y; + } + return 0; + case WSDISPLAYIO_SCURPOS: + { + struct wsdisplay_curpos *cp = (void *)data; + + cursor_x = cp->x; + cursor_y = cp->y; + rpi_fb_movecursor(cursor_x, cursor_y, cursor_on); + } + return 0; + case WSDISPLAYIO_GCURMAX: + { + struct wsdisplay_curpos *cp = (void *)data; + + cp->x = 64; + cp->y = 64; + } + return 0; + case WSDISPLAYIO_SCURSOR: + { + struct wsdisplay_cursor *cursor = (void *)data; + + return rpi_fb_do_cursor(cursor); + } +#endif + default: + return EPASSTHROUGH; + } +} + +#endif + +SYSCTL_SETUP(sysctl_machdep_rpi, "sysctl machdep subtree setup (rpi)") +{ + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL, + NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READONLY, + CTLTYPE_INT, "firmware_revision", NULL, NULL, 0, + &vb.vbt_fwrev.rev, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READONLY, + CTLTYPE_INT, "board_model", NULL, NULL, 0, + &vb.vbt_boardmodel.model, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READONLY, + CTLTYPE_INT, "board_revision", NULL, NULL, 0, + &vb.vbt_boardrev.rev, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_HEX|CTLFLAG_PRIVATE, + CTLTYPE_QUAD, "serial", NULL, NULL, 0, + &vb.vbt_serial.sn, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); +} + +#if 0 +static void +bcm283x_stdout(void) +{ + void *fdt_data = __UNCONST(fdtbus_get_data()); + const int chosen_off = fdt_path_offset(fdt_data, "/chosen"); + + if (match_bootconf_option(boot_args, "console", "fb")) { +#if 0 + const int framebuffer_off = + fdt_path_offset(fdt_data, "/chosen/framebuffer"); + if (chosen_off >= 0) + fdt_setprop_string(fdt_data, chosen_off, "stdout-path", + "/soc/serial@7e201000"); +#endif + } else { + if (chosen_off >= 0) + fdt_setprop_string(fdt_data, chosen_off, "stdout-path", + "/soc/serial@7e201000"); + } +} +#endif + + +#if defined(SOC_BCM2835) +static void +bcm2835_platform_bootstrap(void) +{ + +// bcm283x_stdout(); +// + bcm2835_uartinit(); + + bcm2835_bootparams(); +} +#endif + +#if defined(SOC_BCM2836) +static void +bcm2836_platform_bootstrap(void) +{ + + bcm2836_uartinit(); + + bcm2836_bootparams(); + + bcm2836_bootstrap(); +} +#endif + +#if defined(SOC_BCM2835) +static void +bcm2835_platform_init_attach_args(struct fdt_attach_args *faa) +{ + + faa->faa_shift_bst[0] = &bcm2835_bs_tag; + faa->faa_shift_bst[2] = &bcm2835_a4x_bs_tag; + faa->faa_dmat = &bcm2835_bus_dma_tag; + + bcm2835_bus_dma_tag._ranges = bcm2835_dma_ranges; + bcm2835_bus_dma_tag._nranges = __arraycount(bcm2835_dma_ranges); + bcm2835_dma_ranges[0].dr_len = physmem * PAGE_SIZE; +} +#endif + +#if defined(SOC_BCM2836) +static void +bcm2836_platform_init_attach_args(struct fdt_attach_args *faa) +{ + + faa->faa_shift_bst[0] = &bcm2836_bs_tag; + faa->faa_shift_bst[2] = &bcm2836_a4x_bs_tag; + faa->faa_dmat = &bcm2835_bus_dma_tag; + + bcm2835_bus_dma_tag._ranges = bcm2836_dma_ranges; + bcm2835_bus_dma_tag._nranges = __arraycount(bcm2836_dma_ranges); + bcm2836_dma_ranges[0].dr_len = physmem * PAGE_SIZE; +} +#endif + + +void +bcm283x_platform_early_putchar(vaddr_t va, paddr_t pa, char c) +{ + volatile uint32_t *uartaddr = + (armreg_sctlr_read() & CPU_CONTROL_MMU_ENABLE) ? + (volatile uint32_t *)va : + (volatile uint32_t *)pa; + + while ((uartaddr[PL01XCOM_FR / 4] & PL01X_FR_TXFF) != 0) + continue; + + uartaddr[PL01XCOM_DR / 4] = c; + + while ((uartaddr[PL01XCOM_FR / 4] & PL01X_FR_TXFE) == 0) + continue; +} + +void +bcm2835_platform_early_putchar(char c) +{ + paddr_t pa = BCM2835_PERIPHERALS_BUS_TO_PHYS(BCM2835_UART0_BASE); + vaddr_t va = BCM2835_IOPHYSTOVIRT(pa); + + bcm283x_platform_early_putchar(va, pa, c); +} + +void +bcm2836_platform_early_putchar(char c) +{ + paddr_t pa = BCM2836_PERIPHERALS_BUS_TO_PHYS(BCM2835_UART0_BASE); + vaddr_t va = BCM2835_IOPHYSTOVIRT(pa); + + bcm283x_platform_early_putchar(va, pa, c); +} + +#define BCM283x_REF_FREQ 19200000 + +void +bcm2837_platform_early_putchar(char c) +{ +#define AUCONSADDR_PA BCM2836_PERIPHERALS_BUS_TO_PHYS(BCM2835_AUX_UART_BASE) +#define AUCONSADDR_VA BCM2835_IOPHYSTOVIRT(AUCONSADDR_PA) + volatile uint32_t *uartaddr = + (armreg_sctlr_read() & CPU_CONTROL_MMU_ENABLE) ? + (volatile uint32_t *)AUCONSADDR_VA : + (volatile uint32_t *)AUCONSADDR_PA; + + while ((uartaddr[com_lsr] & LSR_TXRDY) == 0) + ; + + uartaddr[com_data] = c; +} + +static void +bcm283x_platform_device_register(device_t dev, void *aux) +{ + prop_dictionary_t dict = device_properties(dev); + + if (device_is_a(dev, "bcmdmac") && + vcprop_tag_success_p(&vb.vbt_dmachan.tag)) { + prop_dictionary_set_uint32(dict, + "chanmask", vb.vbt_dmachan.mask); + } +#if NSDHC > 0 + if (booted_device == NULL && + device_is_a(dev, "ld") && + device_is_a(device_parent(dev), "sdmmc")) { + booted_partition = 0; + booted_device = dev; + } +#endif + if (device_is_a(dev, "usmsc") && + vcprop_tag_success_p(&vb.vbt_macaddr.tag)) { + const uint8_t enaddr[ETHER_ADDR_LEN] = { + (vb.vbt_macaddr.addr >> 0) & 0xff, + (vb.vbt_macaddr.addr >> 8) & 0xff, + (vb.vbt_macaddr.addr >> 16) & 0xff, + (vb.vbt_macaddr.addr >> 24) & 0xff, + (vb.vbt_macaddr.addr >> 32) & 0xff, + (vb.vbt_macaddr.addr >> 40) & 0xff + }; + + prop_data_t pd = prop_data_create_data(enaddr, ETHER_ADDR_LEN); + KASSERT(pd != NULL); + if (prop_dictionary_set(device_properties(dev), "mac-address", + pd) == false) { + aprint_error_dev(dev, + "WARNING: Unable to set mac-address property\n"); + } + prop_object_release(pd); + } + +#if NGENFB > 0 + if (device_is_a(dev, "genfb")) { + char *ptr; + + bcmgenfb_set_console_dev(dev); + bcmgenfb_set_ioctl(&rpi_ioctl); +#ifdef DDB + db_trap_callback = bcmgenfb_ddb_trap_callback; +#endif + + if (rpi_fb_init(dict, aux) == false) + return; + if (get_bootconf_option(boot_args, "console", + BOOTOPT_TYPE_STRING, &ptr) && strncmp(ptr, "fb", 2) == 0) { + prop_dictionary_set_bool(dict, "is_console", true); +#if NUKBD > 0 + /* allow ukbd to be the console keyboard */ + ukbd_cnattach(); +#endif + } else { + prop_dictionary_set_bool(dict, "is_console", false); + } + } +#endif +} + +static u_int +bcm283x_platform_uart_freq(void) +{ + + return uart_clk; +} + +#if defined(SOC_BCM2835) +static const struct arm_platform bcm2835_platform = { + .devmap = bcm2835_platform_devmap, + .bootstrap = bcm2835_platform_bootstrap, + .init_attach_args = bcm2835_platform_init_attach_args, + .early_putchar = bcm2835_platform_early_putchar, + .device_register = bcm283x_platform_device_register, + .reset = bcm2835_system_reset, + .delay = bcm2835_tmr_delay, + .uart_freq = bcm283x_platform_uart_freq, +}; + +ARM_PLATFORM(bcm2835, "brcm,bcm2835", &bcm2835_platform); +#endif + +#if defined(SOC_BCM2836) +static u_int +bcm2837_platform_uart_freq(void) +{ + + return core_clk * 2; +} + +static const struct arm_platform bcm2836_platform = { + .devmap = bcm2836_platform_devmap, + .bootstrap = bcm2836_platform_bootstrap, + .init_attach_args = bcm2836_platform_init_attach_args, + .early_putchar = bcm2836_platform_early_putchar, + .device_register = bcm283x_platform_device_register, + .reset = bcm2835_system_reset, + .delay = gtmr_delay, + .uart_freq = bcm283x_platform_uart_freq, +}; + +static const struct arm_platform bcm2837_platform = { + .devmap = bcm2836_platform_devmap, + .bootstrap = bcm2836_platform_bootstrap, + .init_attach_args = bcm2836_platform_init_attach_args, + .early_putchar = bcm2837_platform_early_putchar, + .device_register = bcm283x_platform_device_register, + .reset = bcm2835_system_reset, + .delay = gtmr_delay, + .uart_freq = bcm2837_platform_uart_freq, +}; + +ARM_PLATFORM(bcm2836, "brcm,bcm2836", &bcm2836_platform); +ARM_PLATFORM(bcm2837, "brcm,bcm2837", &bcm2837_platform); +#endif Index: sys/arch/arm/broadcom/bcm_amba.h =================================================================== RCS file: sys/arch/arm/broadcom/bcm_amba.h diff -N sys/arch/arm/broadcom/bcm_amba.h --- sys/arch/arm/broadcom/bcm_amba.h 26 Jul 2012 06:21:57 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,29 +0,0 @@ -/* $NetBSD: bcm_amba.h,v 1.1 2012/07/26 06:21:57 skrll Exp $ */ - -#ifndef _ARM_BROADCOM_BCM_AMBA_H_ -#define _ARM_BROADCOM_BCM_AMBA_H_ - -/* Broadcom AMBA AXI Peripheral Bus */ - -struct amba_attach_args { - const char *aaa_name; /* name */ - bus_space_tag_t aaa_iot; /* Bus tag */ - bus_addr_t aaa_addr; /* Address */ - bus_size_t aaa_size; /* Size of peripheral address space */ - int aaa_intr; /* IRQ number */ - bus_dma_tag_t aaa_dmat; /* DMA channel */ -}; - -struct ambadev_locators { - const char *ad_name; - bus_addr_t ad_addr; - bus_size_t ad_size; - int ad_instance; - int ad_intr; -}; - -extern struct bus_space bcm2835_bs_tag; -extern struct arm32_bus_dma_tag bcm2835_bus_dma_tag; -// extern const struct ambadev_locators *md_ambadev_locs; - -#endif /* _ARM_BROADCOM_BCM_AMBA_H_ */ Index: sys/arch/arm/broadcom/files.bcm2835 =================================================================== RCS file: /cvsroot/src/sys/arch/arm/broadcom/files.bcm2835,v retrieving revision 1.28 diff -u -p -r1.28 files.bcm2835 --- sys/arch/arm/broadcom/files.bcm2835 30 Jul 2017 23:48:32 -0000 1.28 +++ sys/arch/arm/broadcom/files.bcm2835 3 Dec 2017 12:00:59 -0000 @@ -3,98 +3,96 @@ # Configuration info for Broadcom BCM2835 ARM Peripherals # -defflag opt_bcm283x.h BCM2836 - include "arch/arm/pic/files.pic" -define bcmmboxbus { } - +file arch/arm/arm32/arm32_boot.c +file arch/arm/arm32/arm32_kvminit.c +file arch/arm/arm32/arm32_reboot.c file arch/arm/arm32/irq_dispatch.S +file arch/arm/arm32/armv7_generic_space.c +file arch/arm/arm32/armv7_generic_dma.c +file arch/arm/arm/bus_space_a4x.S + file arch/arm/broadcom/bcm2835_dma.c file arch/arm/broadcom/bcm2835_mbox_subr.c -# OBIO just an attach point -device obio { [addr=-1], [size=0], [intr=-1] - } : bus_space_generic, pic, pic_splfuncs -attach obio at mainbus -file arch/arm/broadcom/bcm2835_obio.c obio needs-count - -# OBIO files -file arch/arm/broadcom/bcm2835_space.c obio -file arch/arm/arm/bus_space_a4x.S obio +file arch/arm/broadcom/bcm283x_platform.c + +define mpcorebus { } # ARMv7 Generic Timer -device armgtmr -attach armgtmr at obio -file arch/arm/cortex/gtmr.c armgtmr +device armgtmr +attach armgtmr at mpcorebus +file arch/arm/cortex/gtmr.c armgtmr + +define bcmmboxbus { } + +file arch/arm/broadcom/bcm2835_space.c # Interrupt Controller (BCM2835_ARMICU_BASE) #, pic_splfuncs device bcmicu: pic, pic_splfuncs -attach bcmicu at obio with bcmicu +attach bcmicu at fdt with bcmicu file arch/arm/broadcom/bcm2835_intr.c bcmicu # VC Mailbox (BCM2835_ARMMBOX_BASE) device bcmmbox: bcmmboxbus -attach bcmmbox at obio with bcmmbox +attach bcmmbox at fdt with bcmmbox file arch/arm/broadcom/bcm2835_mbox.c bcmmbox # System Timer (BCM2835_TIMER_BASE) device bcmtmr -attach bcmtmr at obio with bcmtmr_amba -file arch/arm/broadcom/bcm2835_tmr.c bcmtmr & !bcm2836 +attach bcmtmr at fdt with bcmtmr_fdt +file arch/arm/broadcom/bcm2835_tmr.c bcmtmr & !soc_bcm2836 # Power Management, Reset Controller, and Watchdog (BCM2835_PM_BASE) -device bcmpm: sysmon_wdog -attach bcmpm at obio with bcmpm_amba -file arch/arm/broadcom/bcm2835_pm.c bcmpm +device watchdog: sysmon_wdog +attach watchdog at fdt with bcmpmwdog_fdt +file arch/arm/broadcom/bcm2835_pmwdog.c bcmpmwdog_fdt # Random number generator (BCM2835_RNG_BASE) device bcmrng -attach bcmrng at obio with bcmrng_amba +attach bcmrng at fdt with bcmrng_fdt file arch/arm/broadcom/bcm2835_rng.c bcmrng -# UART Interface (BCM2835_UART0_BASE) -attach plcom at obio with bcmplcom -file arch/arm/broadcom/bcm2835_plcom.c bcmplcom +# AUX +device bcmaux +attach bcmaux at fdt with bcmaux_fdt +file arch/arm/broadcom/bcm2835_aux.c bcmaux # AUX UART (BCM2835_AUX_UART_BASE) -attach com at obio with bcmcom +attach com at fdt with bcmcom file arch/arm/broadcom/bcm2835_com.c bcmcom # External Mass Media Controller (BCM2835_EMMC_BASE) -attach sdhc at obio with bcmemmc +attach sdhc at fdt with bcmemmc file arch/arm/broadcom/bcm2835_emmc.c bcmemmc # SD Host Controller (BCM2835_SDHOST_BASE) device sdhost: sdmmcbus -attach sdhost at obio with bcmsdhost +attach sdhost at fdt with bcmsdhost file arch/arm/broadcom/bcm2835_sdhost.c bcmsdhost needs-flag # DMA Controller (BCM2835_DMA0_BASE) device bcmdmac -attach bcmdmac at obio with bcmdmac_amba +attach bcmdmac at fdt with bcmdmac_fdt file arch/arm/broadcom/bcm2835_dmac.c bcmdmac needs-flag # USB (BCM2835_USB_BASE) -attach dwctwo at obio with bcmdwctwo +attach dwctwo at fdt with bcmdwctwo file arch/arm/broadcom/bcm2835_dwctwo.c bcmdwctwo needs-flag -# GPIO misc. functions -define bcm2835_gpio_subr -file arch/arm/broadcom/bcm2835_gpio_subr.c bcm2835_gpio_subr - # SPI controller (BCM2835_SPI0_BASE) device bcmspi: spibus, bcm2835_gpio_subr -attach bcmspi at obio +attach bcmspi at fdt file arch/arm/broadcom/bcm2835_spi.c bcmspi needs-flag # BSC (I2C) controller (BCM2835_BSC[01]_BASE) device bsciic: i2cbus, bcm2835_gpio_subr -attach bsciic at obio +attach bsciic at fdt file arch/arm/broadcom/bcm2835_bsc.c bsciic needs-flag # Generic framebuffer console driver -attach genfb at obio with bcmgenfb: edid +attach genfb at fdt with bcmgenfb: edid file arch/arm/broadcom/bcm2835_genfb.c bcmgenfb needs-flag # VCHIQ @@ -107,16 +105,20 @@ file arch/arm/broadcom/bcm2835_vcaudio.c # GPIO device bcmgpio: gpiobus -attach bcmgpio at obio +attach bcmgpio at fdt file arch/arm/broadcom/bcm2835_gpio.c # Clock Manager (BCM2835_CM_BASE) -device bcmcm -attach bcmcm at obio with bcmcm_amba -file arch/arm/broadcom/bcm2835_cm.c bcmcm needs-flag +device bcmcprman +attach bcmcprman at fdt with bcmcprman_fdt +file arch/arm/broadcom/bcm2835_cprman.c bcmcprman needs-flag # PWM Controller (BCM2835_PWM_BASE) device bcmpwm -attach bcmpwm at obio with bcmpwm_amba +attach bcmpwm at fdt with bcmpwm file arch/arm/broadcom/bcm2835_pwm.c bcmpwm needs-flag +# SOC parameters +defflag opt_bcm283x.h SOC_BCM2836 +defflag opt_bcm283x.h SOC_BCM2835 + Index: sys/arch/arm/conf/files.arm =================================================================== RCS file: /cvsroot/src/sys/arch/arm/conf/files.arm,v retrieving revision 1.136 diff -u -p -r1.136 files.arm --- sys/arch/arm/conf/files.arm 10 Nov 2017 22:07:30 -0000 1.136 +++ sys/arch/arm/conf/files.arm 3 Dec 2017 12:00:59 -0000 @@ -190,6 +190,7 @@ file arch/arm/arm/cpufunc_asm_ixp12x0.S file arch/arm/arm/cpufunc_asm_sheeva.S cpu_sheeva file arch/arm/arm/cpu_exec.c file arch/arm/arm/fusu.S +file arch/arm/arm/fdtbus_machdep.c fdt file arch/arm/arm/idle_machdep.c file arch/arm/arm/lock_cas.S file arch/arm/arm/process_machdep.c Index: sys/arch/arm/cortex/a9_mpsubr.S =================================================================== RCS file: /cvsroot/src/sys/arch/arm/cortex/a9_mpsubr.S,v retrieving revision 1.53 diff -u -p -r1.53 a9_mpsubr.S --- sys/arch/arm/cortex/a9_mpsubr.S 10 Nov 2017 22:54:20 -0000 1.53 +++ sys/arch/arm/cortex/a9_mpsubr.S 3 Dec 2017 12:00:59 -0000 @@ -44,10 +44,10 @@ #define CALL(f) bl _C_LABEL(f) #else #define CALL(f) \ - movw ip, #:lower16:_C_LABEL(f); \ - movt ip, #:upper16:_C_LABEL(f); \ - sub ip, ip, #KERNEL_BASE_VOFFSET; \ - blx ip + movw fp, #:lower16:_C_LABEL(f); \ + movt fp, #:upper16:_C_LABEL(f); \ + sub fp, fp, #KERNEL_BASE_VOFFSET; \ + blx fp #endif #if defined(CPU_CORTEXA7) || defined(CPU_CORTEXA15) || defined(CPU_CORTEXA17) \ Index: sys/arch/arm/fdt/arm_fdt.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/fdt/arm_fdt.c,v retrieving revision 1.6 diff -u -p -r1.6 arm_fdt.c --- sys/arch/arm/fdt/arm_fdt.c 21 Sep 2017 19:28:37 -0000 1.6 +++ sys/arch/arm/fdt/arm_fdt.c 3 Dec 2017 12:00:59 -0000 @@ -33,6 +33,7 @@ __KERNEL_RCSID(0, "$NetBSD: arm_fdt.c,v #include #include +#include #include #include #include @@ -44,9 +45,14 @@ __KERNEL_RCSID(0, "$NetBSD: arm_fdt.c,v #include +#include + static int arm_fdt_match(device_t, cfdata_t, void *); static void arm_fdt_attach(device_t, device_t, void *); +extern struct bus_space armv7_generic_bs_tag; +extern struct bus_space armv7_generic_a4x_bs_tag; + CFATTACH_DECL_NEW(arm_fdt, 0, arm_fdt_match, arm_fdt_attach, NULL, NULL); @@ -74,19 +80,35 @@ arm_fdt_match(device_t parent, cfdata_t void arm_fdt_attach(device_t parent, device_t self, void *aux) { - const struct arm_platform *plat = arm_fdt_platform(); struct fdt_attach_args faa; aprint_naive("\n"); aprint_normal("\n"); - plat->init_attach_args(&faa); + arm_fdt_init_attach_args(&faa); faa.faa_name = ""; faa.faa_phandle = OF_peer(0); + faa.faa_quiet = 0; config_found(self, &faa, NULL); } +void +arm_fdt_init_attach_args(struct fdt_attach_args *faa) +{ + KASSERT(CPU_IS_ARMV7_P() || CPU_IS_ARMV6_P()); + + extern struct bus_space armv7_generic_bs_tag; + extern struct bus_space armv7_generic_a4x_bs_tag; + extern struct arm32_bus_dma_tag armv7_generic_dma_tag; + + memset(faa->faa_shift_bst, 0, sizeof(faa->faa_shift_bst)); + faa->faa_shift_bst[0] = &armv7_generic_bs_tag; + faa->faa_shift_bst[2] = &armv7_generic_a4x_bs_tag; + faa->faa_dmat = &armv7_generic_dma_tag; +} + + const struct arm_platform * arm_fdt_platform(void) { @@ -182,6 +204,7 @@ arm_fdt_memory_dump(paddr_t pa) } } + #ifdef __HAVE_GENERIC_CPU_INITCLOCKS void cpu_initclocks(void) Index: sys/arch/arm/fdt/arm_fdtvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/fdt/arm_fdtvar.h,v retrieving revision 1.7 diff -u -p -r1.7 arm_fdtvar.h --- sys/arch/arm/fdt/arm_fdtvar.h 24 Aug 2017 13:06:23 -0000 1.7 +++ sys/arch/arm/fdt/arm_fdtvar.h 3 Dec 2017 12:00:59 -0000 @@ -34,9 +34,17 @@ */ struct fdt_attach_args; +struct fdtbus_simplebus; + +struct fdtbus_cookie { + struct fdtbus_simplebus *fc_bus; + size_t fc_shift; + bus_space_tag_t fc_bst; +}; struct arm_platform { const struct pmap_devmap * (*devmap)(void); + void (*bootstrap)(void); void (*init_attach_args)(struct fdt_attach_args *); void (*early_putchar)(char); @@ -65,6 +73,8 @@ TAILQ_HEAD(arm_platlist, arm_platform_in const struct arm_platform * arm_fdt_platform(void); +void arm_fdt_init_attach_args(struct fdt_attach_args *); + void arm_fdt_cpu_hatch_register(void *, void (*)(void *, struct cpu_info *)); void arm_fdt_cpu_hatch(struct cpu_info *); Index: sys/arch/arm/fdt/cpu_fdt.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/fdt/cpu_fdt.c,v retrieving revision 1.3 diff -u -p -r1.3 cpu_fdt.c --- sys/arch/arm/fdt/cpu_fdt.c 18 Sep 2017 16:58:04 -0000 1.3 +++ sys/arch/arm/fdt/cpu_fdt.c 3 Dec 2017 12:00:59 -0000 @@ -32,6 +32,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu_fdt.c,v #include #include #include +#include #include #include Index: sys/arch/arm/vexpress/vexpress_platform.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/vexpress/vexpress_platform.c,v retrieving revision 1.4 diff -u -p -r1.4 vexpress_platform.c --- sys/arch/arm/vexpress/vexpress_platform.c 22 Oct 2017 20:35:32 -0000 1.4 +++ sys/arch/arm/vexpress/vexpress_platform.c 3 Dec 2017 12:00:59 -0000 @@ -167,9 +167,18 @@ vexpress_platform_bootstrap(void) } } + static void vexpress_platform_init_attach_args(struct fdt_attach_args *faa) { +#if 0 + /* + * both serial0 and l.. hang off the same bus + */ + static bus_space... + + memcpy(bst, &armv7_generic_bs_tag +#endif faa->faa_bst = &armv7_generic_bs_tag; faa->faa_a4x_bst = &armv7_generic_a4x_bs_tag; faa->faa_dmat = &armv7_generic_dma_tag; Index: sys/arch/evbarm/compile/rpi-mkknlimg.sh =================================================================== RCS file: sys/arch/evbarm/compile/rpi-mkknlimg.sh diff -N sys/arch/evbarm/compile/rpi-mkknlimg.sh --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/evbarm/compile/rpi-mkknlimg.sh 3 Dec 2017 12:01:00 -0000 @@ -0,0 +1,58 @@ +#!/bin/sh + +# $NetBSD$ +# +# Tag an RPI kernel so the firmware will load device tree + +# https://github.com/raspberrypi/linux/commit/5b2523aae9c5beb443315a7814633fc740992d07 + +magic_rptl=1280594002 # 'RPTL' +magic_283x=2016622642 # '283x' +magic_ddtk= +magic_dtok=1263490116 +magic_kver= + +if [ $# -ne 2 ] ; then + echo usage: $0 input output 1>&2 + exit 1 +fi + +input=$1; shift +output=$1; shift + +enc() +{ + local _x=$1; shift + printf $( printf '\\%o' $_x ) +} + +le32enc() +{ + local _x=$1; shift + enc $(( ( $_x >> 0 ) & 0xff )) + enc $(( ( $_x >> 8 ) & 0xff )) + enc $(( ( $_x >> 16 ) & 0xff )) + enc $(( ( $_x >> 24 ) & 0xff )) +} + +{ + cat ${input} + + # marker + le32enc 0 + le32enc 0 + + le32enc 1 + le32enc 4 + le32enc $magic_283x + le32enc 1 + le32enc 4 + le32enc $magic_dtok + + # length ( 9 * 4 + 8) + le32enc 44 + le32enc 4 + le32enc $magic_rptl +} > ${output} + +exit Index: sys/arch/evbarm/conf/GENERIC.common =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/conf/GENERIC.common,v retrieving revision 1.23 diff -u -p -r1.23 GENERIC.common --- sys/arch/evbarm/conf/GENERIC.common 12 Oct 2017 20:03:38 -0000 1.23 +++ sys/arch/evbarm/conf/GENERIC.common 3 Dec 2017 12:01:00 -0000 @@ -112,7 +112,7 @@ options KDTRACE_HOOKS # kernel DTrace h #options LOCKDEBUG #options PMAP_DEBUG # Enable pmap_debug_level code #options IPKDB # remote kernel debugging -#options VERBOSE_INIT_ARM # verbose bootstraping messages +options VERBOSE_INIT_ARM # verbose bootstraping messages options DDB # in-kernel debugger options DDB_ONPANIC=1 options DDB_HISTORY_SIZE=100 # Enable history editing in DDB Index: sys/arch/evbarm/conf/RPI =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/conf/RPI,v retrieving revision 1.77 diff -u -p -r1.77 RPI --- sys/arch/evbarm/conf/RPI 5 Nov 2017 09:05:20 -0000 1.77 +++ sys/arch/evbarm/conf/RPI 3 Dec 2017 12:01:00 -0000 @@ -7,9 +7,20 @@ include "arch/evbarm/conf/std.rpi" include "arch/evbarm/conf/GENERIC.common" -# CPU options +makeoptions DTSGNUARCH="arm arm64" +makeoptions DTSSUBDIR="broadcom" + +makeoptions DTS=" + bcm2835-rpi-a.dts + bcm2835-rpi-a-plus.dts + bcm2835-rpi-b.dts + bcm2835-rpi-b-plus.dts + bcm2835-rpi-b-rev2.dts + bcm2835-rpi-zero.dts +" options CPU_ARM1176 +options SOC_BCM2835 options TPIDRPRW_IS_CURLWP options ARM11_COMPAT_MMU options __HAVE_MM_MD_CACHE_ALIASING @@ -42,27 +53,46 @@ options PLCONSOLE config netbsd root on ? type ? -# The main bus device -mainbus0 at root +# Device tree support +armfdt0 at root +fdt* at fdtbus? # The CPU(s) -cpu* at mainbus? +cpus* at fdt? pass 0 +cpu* at cpus? -# OBIO -obio0 at mainbus? +fclock* at fdt? pass 0 # Interrupt Controller -bcmicu0 at obio? +bcmicu* at fdt? pass 1 + +# System timer +bcmtmr0 at fdt? pass 1 + +# Clock manager +bcmcprman0 at fdt? pass 1 + +# AUX +bcmaux0 at fdt? pass 2 + +# pulse width modulator manager +#bcmpwm0 at fdt? + +fregulator* at fdt? +gpiokeys* at fdt? + +# GPIO LEDs +gpioleds* at fdt? # VC Mailbox -bcmmbox0 at obio? -vcmbox0 at bcmmbox0 +bcmmbox* at fdt? +vcmbox* at bcmmbox? # DMA Controller -bcmdmac0 at obio? +bcmdmac0 at fdt? # VCHIQ -vchiq0 at obio? +vchiq0 at fdt? # AUDS vcaudio0 at vchiq0 @@ -71,42 +101,38 @@ audio* at audiobus? spkr* at audio? # PC speaker (synthesized) # PL011 uart -plcom0 at obio? +plcom* at fdt? # AUX UART -com0 at obio? +com0 at fdt? # Framebuffer console -genfb0 at obio? +genfb0 at fdt? wsdisplay* at genfb? options VCONS_DRAW_INTR #options RPI_HWCURSOR -# System timer -bcmtmr0 at obio? - # Power management, Reset controller and Watchdog registers -bcmpm0 at obio? +watchdog0 at fdt? # Random number generator -bcmrng0 at obio? +bcmrng0 at fdt? # GPIO -bcmgpio0 at obio? # pins 0 ... 31 -bcmgpio1 at obio? # pins 32 ... 53 +bcmgpio* at fdt? # Arasan SD/MMC Interface -sdhc* at obio? -sdmmc* at sdhc? +sdhc* at fdt? +sdmmc* at sdhc? # SD host controller -sdhost* at obio? -sdmmc* at sdhost? +sdhost* at fdt? +sdmmc* at sdhost? ld* at sdmmc? # On-board USB -dwctwo* at obio? +dwctwo* at fdt? usb* at dwctwo? # USB device drivers @@ -141,7 +167,7 @@ urlphy* at mii? phy ? # Realtek RTL815 ukphy* at mii? phy ? # generic unknown PHYs # Broadcom Serial Control (I2C) -bsciic* at obio? +bsciic* at fdt? iic* at i2cbus? # 'DS3231 Raspberry Pi RTC Board Real Time Clock Module for Arduino' @@ -152,7 +178,7 @@ iic* at i2cbus? #dsrtc* at iic1 addr 0x6f flags 7940 # SPI controller -bcmspi* at obio? +bcmspi* at fdt? spi* at spibus? # MCP3x0x ADC @@ -210,6 +236,7 @@ options WSDISPLAY_DEFAULTSCREENS=4 #pseudo-device pflog # PF log if # miscellaneous pseudo-devices +pseudo-device openfirm # wscons pseudo-devices pseudo-device wsmux # mouse & keyboard multiplexor Index: sys/arch/evbarm/conf/RPI2 =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/conf/RPI2,v retrieving revision 1.3 diff -u -p -r1.3 RPI2 --- sys/arch/evbarm/conf/RPI2 14 Mar 2015 19:06:14 -0000 1.3 +++ sys/arch/evbarm/conf/RPI2 3 Dec 2017 12:01:00 -0000 @@ -7,19 +7,27 @@ include "arch/evbarm/conf/RPI" no options CPU_ARM1176 +no options SOC_BCM2835 no options TPIDRPRW_IS_CURLWP no options ARM11_COMPAT_MMU no options __HAVE_MM_MD_CACHE_ALIASING no makeoptions CPUFLAGS +no makeoptions DTS -options BCM2836 +options SOC_BCM2836 options CPU_CORTEXA7 options MULTIPROCESSOR -options CORTEX_PMC +#options CORTEX_PMC options TPIDRPRW_IS_CURCPU makeoptions CPUFLAGS="-mcpu=cortex-a7 -mfpu=neon" +options __HAVE_GENERIC_CPU_INITCLOCKS +makeoptions DTS=" + bcm2836-rpi-2-b.dts + bcm2837-rpi-3-b.dts +" # Architecture options -no bcmtmr0 at obio? # System Timer -armgtmr0 at obio? # ARM Generic Timer +no bcmtmr0 at fdt? # System Timer +gtmr* at fdt? pass 1 # ARM Generic Timer +armgtmr0 at gtmr? Index: sys/arch/evbarm/conf/files.rpi =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/conf/files.rpi,v retrieving revision 1.8 diff -u -p -r1.8 files.rpi --- sys/arch/evbarm/conf/files.rpi 20 May 2016 16:40:40 -0000 1.8 +++ sys/arch/evbarm/conf/files.rpi 3 Dec 2017 12:01:00 -0000 @@ -3,16 +3,10 @@ # Raspberry Pi # -file arch/arm/arm32/arm32_boot.c -file arch/arm/arm32/arm32_kvminit.c -file arch/arm/arm32/arm32_reboot.c - -file arch/evbarm/rpi/rpi_machdep.c file arch/evbarm/rpi/vcprop_subr.c makeoptions "COPTS.vcprop_subr.c"+="-fno-stack-protector" -# Kernel boot arguments -defparam opt_machdep.h BOOT_ARGS +include "arch/evbarm/conf/files.fdt" # CPU support and integrated peripherals include "arch/arm/broadcom/files.bcm2835" Index: sys/arch/evbarm/conf/mk.rpi =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/conf/mk.rpi,v retrieving revision 1.4 diff -u -p -r1.4 mk.rpi --- sys/arch/evbarm/conf/mk.rpi 28 Feb 2015 09:34:34 -0000 1.4 +++ sys/arch/evbarm/conf/mk.rpi 3 Dec 2017 12:01:00 -0000 @@ -10,8 +10,12 @@ GENASSYM_EXTRAS+= ${THISARM}/rpi/genassy KERNEL_BASE_PHYS=0x00008000 KERNEL_BASE_VIRT=0x80008000 +MKKNLIMG= ${THISARM}/compile/rpi-mkknlimg.sh + SYSTEM_LD_TAIL_EXTRA+=; \ echo ${OBJCOPY} -S -O binary $@ $@.bin; \ - ${OBJCOPY} -S -O binary $@ $@.bin + ${OBJCOPY} -S -O binary $@ $@.bin; \ + echo ${MKKNLIMG} $@.bin $@.img; \ + ${HOST_SH} ${MKKNLIMG} $@.bin $@.img; -EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin@} +EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.img@} Index: sys/arch/evbarm/conf/std.rpi =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/conf/std.rpi,v retrieving revision 1.19 diff -u -p -r1.19 std.rpi --- sys/arch/evbarm/conf/std.rpi 28 Feb 2015 09:34:34 -0000 1.19 +++ sys/arch/evbarm/conf/std.rpi 3 Dec 2017 12:01:00 -0000 @@ -8,12 +8,14 @@ include "arch/evbarm/conf/std.evbarm" # Pull in Raspberry Pi config definitions. include "arch/evbarm/conf/files.rpi" +options FDT # Flattened Device Tree support +options DRAM_BLOCKS=256 options MODULAR options MODULAR_DEFAULT_AUTOLOAD options FPU_VFP options __HAVE_CPU_COUNTER -options __HAVE_FAST_SOFTINTS # should be in types.h options __HAVE_CPU_UAREA_ALLOC_IDLELWP +options __HAVE_FAST_SOFTINTS # should be in types.h options __HAVE_MM_MD_DIRECT_MAPPED_PHYS options ARM_HAS_VBAR options KERNEL_BASE_EXT=0x80000000 @@ -22,5 +24,5 @@ options EVBARM_BOARDTYPE="rpi" makeoptions BOARDMKFRAG="${THISARM}/conf/mk.rpi" makeoptions LOADADDRESS="0x80008000" -options ARM_INTR_IMPL="" +options ARM_INTR_IMPL="" options ARM_GENERIC_TODR Index: sys/arch/evbarm/fdt/fdt_machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/fdt/fdt_machdep.c,v retrieving revision 1.15 diff -u -p -r1.15 fdt_machdep.c --- sys/arch/evbarm/fdt/fdt_machdep.c 9 Nov 2017 21:38:48 -0000 1.15 +++ sys/arch/evbarm/fdt/fdt_machdep.c 3 Dec 2017 12:01:00 -0000 @@ -108,14 +108,6 @@ static void fdt_device_register(device_t static void fdt_reset(void); static void fdt_powerdown(void); -#ifdef PMAP_NEED_ALLOC_POOLPAGE -static struct boot_physmem bp_lowgig = { - .bp_pages = (KERNEL_VM_BASE - KERNEL_BASE) / NBPG, - .bp_freelist = VM_FREELIST_ISADMA, - .bp_flags = 0 -}; -#endif - #ifdef VERBOSE_INIT_ARM static void fdt_putchar(char c) @@ -183,7 +175,7 @@ fdt_get_memory(uint64_t *paddr, uint64_t } } -static void +void fdt_add_reserved_memory_range(uint64_t addr, uint64_t size) { int error; @@ -372,14 +364,14 @@ initarm(void *arg) DPRINT(" devmap"); pmap_devmap_register(plat->devmap()); - DPRINT(" bootstrap"); - plat->bootstrap(); - /* Heads up ... Setup the CPU / MMU / TLB functions. */ DPRINT(" cpufunc"); if (set_cpufuncs()) panic("cpu not recognized!"); + DPRINT(" bootstrap"); + plat->bootstrap(); + /* * If stdout-path is specified on the command line, override the * value in /chosen/stdout-path before initializing console. @@ -440,11 +432,13 @@ initarm(void *arg) /* Parse ramdisk info */ fdt_probe_initrd(&initrd_start, &initrd_end); - /* Populate bootconfig structure for the benefit of pmap.c. */ + /* + * Populate bootconfig structure for the benefit of + * dodumpsys + */ fdt_build_bootconfig(memory_addr, memory_size); - arm32_bootmem_init(bootconfig.dram[0].address, memory_size, - KERNEL_BASE_PHYS); + arm32_bootmem_init(memory_addr, memory_size, KERNEL_BASE_PHYS); arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_HIGH, 0, plat->devmap(), mapallmem_p); @@ -452,16 +446,30 @@ initarm(void *arg) parse_mi_bootargs(boot_args); + #define MAX_PHYSMEM 4 + static struct boot_physmem fdt_physmem[MAX_PHYSMEM]; + int nfdt_physmem = 0; + struct extent_region *er; + + LIST_FOREACH(er, &fdt_memory_ext->ex_regions, er_link) { + DPRINTF(" %lx - %lx\n", er->er_start, er->er_end); + struct boot_physmem *bp = &fdt_physmem[nfdt_physmem++]; + + KASSERT(nfdt_physmem < MAX_PHYSMEM); + bp->bp_start = atop(er->er_start); + bp->bp_pages = atop(er->er_end - er->er_start); + bp->bp_freelist = VM_FREELIST_DEFAULT; + #ifdef PMAP_NEED_ALLOC_POOLPAGE - bp_lowgig.bp_start = memory_addr / NBPG; - if (atop(ram_size) > bp_lowgig.bp_pages) { - arm_poolpage_vmfreelist = bp_lowgig.bp_freelist; - return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, - &bp_lowgig, 1); - } + if (atop(memory_size) > bp->bp_pages) { + arm_poolpage_vmfreelist = VM_FREELIST_DIRECTMAP; + bp->bp_freelist = VM_FREELIST_DIRECTMAP; + } #endif + } - return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0); + return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, fdt_physmem, + nfdt_physmem); } static void Index: sys/arch/evbarm/fdt/platform.h =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/fdt/platform.h,v retrieving revision 1.1 diff -u -p -r1.1 platform.h --- sys/arch/evbarm/fdt/platform.h 30 May 2017 10:27:53 -0000 1.1 +++ sys/arch/evbarm/fdt/platform.h 3 Dec 2017 12:01:00 -0000 @@ -29,6 +29,10 @@ #ifndef _EVBARM_FDT_PLATFORM_H #define _EVBARM_FDT_PLATFORM_H +#ifndef __ASSEMBLER__ +void fdt_add_reserved_memory_range(uint64_t, uint64_t); +#endif + #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS #define KERNEL_VM_BASE 0xc0000000 #define KERNEL_VM_SIZE 0x20000000 /* 0x20000000 = 512MB */ Index: sys/arch/evbarm/include/vmparam.h =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/include/vmparam.h,v retrieving revision 1.30 diff -u -p -r1.30 vmparam.h --- sys/arch/evbarm/include/vmparam.h 2 Nov 2017 09:42:44 -0000 1.30 +++ sys/arch/evbarm/include/vmparam.h 3 Dec 2017 12:01:00 -0000 @@ -84,6 +84,7 @@ #define VM_NFREELIST 2 #define VM_FREELIST_DEFAULT 0 #define VM_FREELIST_ISADMA 1 +#define VM_FREELIST_DIRECTMAP 1 #endif /* _KERNEL || _KMEMUSER */ Index: sys/arch/evbarm/rpi/genassym.cf =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/rpi/genassym.cf,v retrieving revision 1.2 diff -u -p -r1.2 genassym.cf --- sys/arch/evbarm/rpi/genassym.cf 28 Feb 2015 09:34:34 -0000 1.2 +++ sys/arch/evbarm/rpi/genassym.cf 3 Dec 2017 12:01:01 -0000 @@ -29,12 +29,14 @@ # POSSIBILITY OF SUCH DAMAGE. # -include +include -define RPI_KERNEL_IO_VBASE RPI_KERNEL_IO_VBASE -define RPI_KERNEL_IO_PBASE RPI_KERNEL_IO_PBASE -define RPI_KERNEL_IO_VSIZE RPI_KERNEL_IO_VSIZE +define BCM2836_PERIPHERALS_VBASE BCM2836_PERIPHERALS_VBASE +define BCM2835_PERIPHERALS_VBASE BCM2835_PERIPHERALS_VBASE +define BCM2836_PERIPHERALS_BASE BCM2836_PERIPHERALS_BASE +define BCM2835_PERIPHERALS_BASE BCM2835_PERIPHERALS_BASE +define BCM2835_PERIPHERALS_SIZE BCM2835_PERIPHERALS_SIZE -define RPI_KERNEL_LOCAL_VBASE RPI_KERNEL_LOCAL_VBASE -define RPI_KERNEL_LOCAL_PBASE RPI_KERNEL_LOCAL_PBASE -define RPI_KERNEL_LOCAL_VSIZE RPI_KERNEL_LOCAL_VSIZE +define BCM2836_ARM_LOCAL_VBASE BCM2836_ARM_LOCAL_VBASE +define BCM2836_ARM_LOCAL_BASE BCM2836_ARM_LOCAL_BASE +define BCM2836_ARM_LOCAL_SIZE BCM2836_ARM_LOCAL_SIZE Index: sys/arch/evbarm/rpi/rpi.h =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/rpi/rpi.h,v retrieving revision 1.4 diff -u -p -r1.4 rpi.h --- sys/arch/evbarm/rpi/rpi.h 28 Feb 2015 09:34:34 -0000 1.4 +++ sys/arch/evbarm/rpi/rpi.h 3 Dec 2017 12:01:01 -0000 @@ -43,20 +43,6 @@ #define KERNEL_VM_BASE 0xc0000000 #define KERNEL_VM_SIZE (BCM2835_PERIPHERALS_VBASE - KERNEL_VM_BASE) -/* - * BCM2835 ARM Peripherals - */ -#define RPI_KERNEL_IO_VBASE BCM2835_PERIPHERALS_VBASE -#define RPI_KERNEL_IO_PBASE BCM2835_PERIPHERALS_BASE -#define RPI_KERNEL_IO_VSIZE BCM2835_PERIPHERALS_SIZE - -/* - * BCM2836 Local control block - */ -#define RPI_KERNEL_LOCAL_VBASE BCM2836_ARM_LOCAL_VBASE -#define RPI_KERNEL_LOCAL_PBASE BCM2836_ARM_LOCAL_BASE -#define RPI_KERNEL_LOCAL_VSIZE BCM2836_ARM_LOCAL_SIZE - #define RPI_REF_FREQ 19200000 #endif /* _EVBARM_RPI_RPI_H */ Index: sys/arch/evbarm/rpi/rpi2_start.S =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/rpi/rpi2_start.S,v retrieving revision 1.3 diff -u -p -r1.3 rpi2_start.S --- sys/arch/evbarm/rpi/rpi2_start.S 17 Dec 2015 08:02:42 -0000 1.3 +++ sys/arch/evbarm/rpi/rpi2_start.S 3 Dec 2017 12:01:01 -0000 @@ -40,27 +40,32 @@ RCSID("$NetBSD: rpi2_start.S,v 1.3 2015/12/17 08:02:42 skrll Exp $") +#if defined(KERNEL_BASES_EQUAL) +#define CALL(f) bl _C_LABEL(f) +#else +#define CALL(f) \ + movw fp, #:lower16:_C_LABEL(f); \ + movt fp, #:upper16:_C_LABEL(f); \ + sub fp, fp, #KERNEL_BASE_VOFFSET; \ + blx fp +#endif + #if defined(VERBOSE_INIT_ARM) -#define XPUTC(n) mov r0, n; bl plputc +#define XPUTC(n) mov r0, n; CALL(bcm2836_platform_early_putchar) #if KERNEL_BASE_VOFFSET == 0 -#define XPUTC2(n) mov r0, n; bl plputc +#define XPUTC2(n) mov r0, n; CALL(bcm2836_platform_early_putchar) #else #define XPUTC2(n) mov r0, n; blx r11 #endif -#ifdef __ARMEB__ -#define COM_BSWAP -#endif -#define COM_MULT 4 #else #define XPUTC(n) #define XPUTC2(n) #endif -#define INIT_MEMSIZE 128 -#define TEMP_L1_TABLE (KERNEL_BASE - KERNEL_BASE_VOFFSET + INIT_MEMSIZE * L1_S_SIZE - L1_TABLE_SIZE) - -#define MD_CPU_HATCH _C_LABEL(bcm2836_cpu_hatch) +#define INIT_MEMSIZE (0x40000000 / L1_S_SIZE) +#define TEMP_L1_TABLE (KERNEL_BASE - KERNEL_BASE_VOFFSET + 128 * L1_S_SIZE - L1_TABLE_SIZE) +#define MD_CPU_HATCH _C_LABEL(arm_fdt_cpu_hatch) /* * Kernel start routine for RPI2 board. * At this point, this code has been loaded into SDRAM @@ -81,8 +86,8 @@ _C_LABEL(rpi_start): /* * Save any arguments passed to us. */ - movw r4, #:lower16:rpi_boot_regs - movt r4, #:upper16:rpi_boot_regs + movw r4, #:lower16:uboot_args + movt r4, #:upper16:uboot_args #if KERNEL_BASE_VOFFSET != 0 /* * But since .start is at 0x40000000 and .text is at 0x8000000, we @@ -95,6 +100,7 @@ _C_LABEL(rpi_start): stmia r4, {r0-r3} // Save the arguments + XPUTC(#'X') /* * Setup the CPU */ @@ -124,11 +130,12 @@ _C_LABEL(rpi_start): #else /* * After the MMU is on, we can execute in the normal .text segment - * so setup the lr to be in .text. Cache the address for plputc - * before we go. + * so setup the lr to be in .text. Cache the address for + * bcm283x_platform_early_putchar before we go. */ #if defined(VERBOSE_INIT_ARM) - adr r11, plputc @ for XPUTC2 + movw r11, #:lower16:bcm2836_platform_early_putchar + movt r11, #:upper16:bcm2836_platform_early_putchar #endif movw lr, #:lower16:1f movt lr, #:upper16:1f @@ -165,83 +172,6 @@ _C_LABEL(rpi_start): #include -#if defined(VERBOSE_INIT_ARM) - -#define PL01XCOM_FR 0x18 /* Flag Register */ -#define PL01XCOM_DR 0x00 /* Data Register */ -#define PL01X_FR_TXFE 0x080 /* Transmit fifo empty */ - -#define COM_DATA PL01XCOM_DR -#define COM_LSR PL01XCOM_FR -#define LSR_TSRE PL01X_FR_TXFE -#define COM_MULT 4 - -#define CONSADDR 0x3f201000 - -#define TIMO 0x25000 -#ifndef COM_MULT -#define COM_MULT 1 -#endif - .global _C_LABEL(plputc) -_C_LABEL(plputc): - - mov r2, #TIMO - movw r3, #:lower16:CONSADDR - movt r3, #:upper16:CONSADDR -1: -#if COM_MULT == 1 - ldrb r1, [r3, #(COM_LSR*COM_MULT)] -#else -#if COM_MULT == 2 - ldrh r1, [r3, #(COM_LSR*COM_MULT)] -#elif COM_MULT == 4 - ldr r1, [r3, #(COM_LSR*COM_MULT)] -#endif -#ifdef COM_BSWAP - lsr r1, r1, #(COM_MULT-1)*8 -#endif -#endif - tst r1, #LSR_TSRE - bne 2f - subs r2, r2, #1 - bne 1b -2: -#if COM_MULT == 1 - strb r0, [r3, #COM_DATA] -#else -#ifdef COM_BSWAP - lsl r0, r0, #(COM_MULT-1)*8 -#endif -#if COM_MULT == 2 - strh r0, [r3, #COM_DATA] -#else - str r0, [r3, #COM_DATA] -#endif -#endif - - mov r2, #TIMO -3: -#if COM_MULT == 1 - ldrb r1, [r3, #(COM_LSR*COM_MULT)] -#else -#if COM_MULT == 2 - ldrh r1, [r3, #(COM_LSR*COM_MULT)] -#elif COM_MULT == 4 - ldr r1, [r3, #(COM_LSR*COM_MULT)] -#endif -#ifdef COM_BSWAP - lsr r1, r1, #(COM_MULT-1)*8 -#endif -#endif - tst r1, #LSR_TSRE - bne 4f - subs r2, r2, #1 - bne 3b -4: - bx lr -#endif /* VERBOSE_INIT_ARM */ - - .Lmmu_init_table: /* Map KERNEL_BASE VA to SDRAM PA, write-back cacheable, shareable */ MMU_INIT(KERNEL_BASE, KERNEL_BASE - KERNEL_BASE_VOFFSET, INIT_MEMSIZE, @@ -255,15 +185,18 @@ _C_LABEL(plputc): #endif /* Map the 16MB of peripherals */ - MMU_INIT(RPI_KERNEL_IO_VBASE, RPI_KERNEL_IO_PBASE, - (RPI_KERNEL_IO_VSIZE + L1_S_SIZE - 1) / L1_S_SIZE, + MMU_INIT(BCM2836_PERIPHERALS_VBASE, BCM2836_PERIPHERALS_BASE, + (BCM2835_PERIPHERALS_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN) /* Map the 16MB of peripherals */ - MMU_INIT(RPI_KERNEL_IO_PBASE, RPI_KERNEL_IO_PBASE, - (RPI_KERNEL_IO_VSIZE + L1_S_SIZE - 1) / L1_S_SIZE, + MMU_INIT(BCM2836_PERIPHERALS_BASE, BCM2836_PERIPHERALS_BASE, + (BCM2835_PERIPHERALS_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN) + MMU_INIT(BCM2836_ARM_LOCAL_VBASE, BCM2836_ARM_LOCAL_BASE, + (BCM2836_ARM_LOCAL_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, + L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN) /* end of table */ MMU_INIT(0, 0, 0, 0) Index: sys/arch/evbarm/rpi/rpi_machdep.c =================================================================== RCS file: sys/arch/evbarm/rpi/rpi_machdep.c diff -N sys/arch/evbarm/rpi/rpi_machdep.c --- sys/arch/evbarm/rpi/rpi_machdep.c 7 Nov 2017 09:05:05 -0000 1.82 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,1407 +0,0 @@ -/* $NetBSD: rpi_machdep.c,v 1.82 2017/11/07 09:05:05 ryo Exp $ */ - -/*- - * Copyright (c) 2012 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Nick Hudson - * - * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 -__KERNEL_RCSID(0, "$NetBSD: rpi_machdep.c,v 1.82 2017/11/07 09:05:05 ryo Exp $"); - -#include "opt_arm_debug.h" -#include "opt_bcm283x.h" -#include "opt_cpuoptions.h" -#include "opt_ddb.h" -#include "opt_evbarm_boardtype.h" -#include "opt_kgdb.h" -#include "opt_multiprocessor.h" -#include "opt_rpi.h" -#include "opt_vcprop.h" - -#include "sdhc.h" -#include "bcmsdhost.h" -#include "bcmdwctwo.h" -#include "bcmspi.h" -#include "bsciic.h" -#include "plcom.h" -#include "com.h" -#include "genfb.h" -#include "ukbd.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include - -#ifdef DDB -#include -#include -#include -#endif - -#if NPLCOM > 0 -#include -#include -#endif - -#if NCOM > 0 -#include -#endif - -#if NGENFB > 0 -#include -#include -#include -#endif - -#if NUKBD > 0 -#include -#endif - -extern int KERNEL_BASE_phys[]; -extern int KERNEL_BASE_virt[]; - -BootConfig bootconfig; /* Boot config storage */ -static char bootargs[VCPROP_MAXCMDLINE]; -char *boot_args = NULL; - -static void rpi_bootparams(void); -static void rpi_device_register(device_t, void *); - -/* - * Macros to translate between physical and virtual for a subset of the - * kernel address space. *Not* for general use. - */ - -#define KERN_VTOPDIFF KERNEL_BASE_VOFFSET -#define KERN_VTOPHYS(va) ((paddr_t)((vaddr_t)va - KERN_VTOPDIFF)) -#define KERN_PHYSTOV(pa) ((vaddr_t)((paddr_t)pa + KERN_VTOPDIFF)) - -#ifndef RPI_FB_WIDTH -#define RPI_FB_WIDTH 1280 -#endif -#ifndef RPI_FB_HEIGHT -#define RPI_FB_HEIGHT 720 -#endif - -int uart_clk = BCM2835_UART0_CLK; - -#define PLCONADDR BCM2835_UART0_BASE - -#ifndef CONSDEVNAME -#define CONSDEVNAME "plcom" -#endif - -#ifndef PLCONSPEED -#define PLCONSPEED B115200 -#endif -#ifndef PLCONMODE -#define PLCONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ -#endif -#ifndef PLCOMCNUNIT -#define PLCOMCNUNIT -1 -#endif - -#if (NPLCOM > 0) -static const bus_addr_t consaddr = (bus_addr_t)PLCONADDR; - -int plcomcnspeed = PLCONSPEED; -int plcomcnmode = PLCONMODE; -#endif - -#include "opt_kgdb.h" -#if (NPLCOM == 0) -#error Enable plcom for KGDB support -#endif -#ifdef KGDB -#include -static void kgdb_port_init(void); -#endif - -#if (NPLCOM > 0 && (defined(PLCONSOLE) || defined(KGDB))) -static struct plcom_instance rpi_pi = { - .pi_type = PLCOM_TYPE_PL011, - .pi_flags = PLC_FLAG_32BIT_ACCESS, - .pi_iot = &bcm2835_bs_tag, - .pi_size = BCM2835_UART0_SIZE - }; -#endif - -/* Smallest amount of RAM start.elf could give us. */ -#define RPI_MINIMUM_SPLIT (128U * 1024 * 1024) - -static struct __aligned(16) { - struct vcprop_buffer_hdr vb_hdr; - struct vcprop_tag_clockrate vbt_uartclockrate; - struct vcprop_tag_clockrate vbt_coreclockrate; - struct vcprop_tag_boardrev vbt_boardrev; - struct vcprop_tag end; -} vb_uart = { - .vb_hdr = { - .vpb_len = sizeof(vb_uart), - .vpb_rcode = VCPROP_PROCESS_REQUEST, - }, - .vbt_uartclockrate = { - .tag = { - .vpt_tag = VCPROPTAG_GET_CLOCKRATE, - .vpt_len = VCPROPTAG_LEN(vb_uart.vbt_uartclockrate), - .vpt_rcode = VCPROPTAG_REQUEST - }, - .id = VCPROP_CLK_UART - }, - .vbt_coreclockrate = { - .tag = { - .vpt_tag = VCPROPTAG_GET_CLOCKRATE, - .vpt_len = VCPROPTAG_LEN(vb_uart.vbt_coreclockrate), - .vpt_rcode = VCPROPTAG_REQUEST - }, - .id = VCPROP_CLK_CORE - }, - .vbt_boardrev = { - .tag = { - .vpt_tag = VCPROPTAG_GET_BOARDREVISION, - .vpt_len = VCPROPTAG_LEN(vb_uart.vbt_boardrev), - .vpt_rcode = VCPROPTAG_REQUEST - }, - }, - .end = { - .vpt_tag = VCPROPTAG_NULL - } -}; - -static struct __aligned(16) { - struct vcprop_buffer_hdr vb_hdr; - struct vcprop_tag_fwrev vbt_fwrev; - struct vcprop_tag_boardmodel vbt_boardmodel; - struct vcprop_tag_boardrev vbt_boardrev; - struct vcprop_tag_macaddr vbt_macaddr; - struct vcprop_tag_memory vbt_memory; - struct vcprop_tag_boardserial vbt_serial; - struct vcprop_tag_dmachan vbt_dmachan; - struct vcprop_tag_cmdline vbt_cmdline; - struct vcprop_tag_clockrate vbt_emmcclockrate; - struct vcprop_tag_clockrate vbt_armclockrate; - struct vcprop_tag_clockrate vbt_coreclockrate; - struct vcprop_tag end; -} vb = { - .vb_hdr = { - .vpb_len = sizeof(vb), - .vpb_rcode = VCPROP_PROCESS_REQUEST, - }, - .vbt_fwrev = { - .tag = { - .vpt_tag = VCPROPTAG_GET_FIRMWAREREV, - .vpt_len = VCPROPTAG_LEN(vb.vbt_fwrev), - .vpt_rcode = VCPROPTAG_REQUEST - }, - }, - .vbt_boardmodel = { - .tag = { - .vpt_tag = VCPROPTAG_GET_BOARDMODEL, - .vpt_len = VCPROPTAG_LEN(vb.vbt_boardmodel), - .vpt_rcode = VCPROPTAG_REQUEST - }, - }, - .vbt_boardrev = { - .tag = { - .vpt_tag = VCPROPTAG_GET_BOARDREVISION, - .vpt_len = VCPROPTAG_LEN(vb.vbt_boardrev), - .vpt_rcode = VCPROPTAG_REQUEST - }, - }, - .vbt_macaddr = { - .tag = { - .vpt_tag = VCPROPTAG_GET_MACADDRESS, - .vpt_len = VCPROPTAG_LEN(vb.vbt_macaddr), - .vpt_rcode = VCPROPTAG_REQUEST - }, - }, - .vbt_memory = { - .tag = { - .vpt_tag = VCPROPTAG_GET_ARMMEMORY, - .vpt_len = VCPROPTAG_LEN(vb.vbt_memory), - .vpt_rcode = VCPROPTAG_REQUEST - }, - }, - .vbt_serial = { - .tag = { - .vpt_tag = VCPROPTAG_GET_BOARDSERIAL, - .vpt_len = VCPROPTAG_LEN(vb.vbt_serial), - .vpt_rcode = VCPROPTAG_REQUEST - }, - }, - .vbt_dmachan = { - .tag = { - .vpt_tag = VCPROPTAG_GET_DMACHAN, - .vpt_len = VCPROPTAG_LEN(vb.vbt_dmachan), - .vpt_rcode = VCPROPTAG_REQUEST - }, - }, - .vbt_cmdline = { - .tag = { - .vpt_tag = VCPROPTAG_GET_CMDLINE, - .vpt_len = VCPROPTAG_LEN(vb.vbt_cmdline), - .vpt_rcode = VCPROPTAG_REQUEST - }, - }, - .vbt_emmcclockrate = { - .tag = { - .vpt_tag = VCPROPTAG_GET_CLOCKRATE, - .vpt_len = VCPROPTAG_LEN(vb.vbt_emmcclockrate), - .vpt_rcode = VCPROPTAG_REQUEST - }, - .id = VCPROP_CLK_EMMC - }, - .vbt_armclockrate = { - .tag = { - .vpt_tag = VCPROPTAG_GET_CLOCKRATE, - .vpt_len = VCPROPTAG_LEN(vb.vbt_armclockrate), - .vpt_rcode = VCPROPTAG_REQUEST - }, - .id = VCPROP_CLK_ARM - }, - .vbt_coreclockrate = { - .tag = { - .vpt_tag = VCPROPTAG_GET_CLOCKRATE, - .vpt_len = VCPROPTAG_LEN(vb.vbt_coreclockrate), - .vpt_rcode = VCPROPTAG_REQUEST - }, - .id = VCPROP_CLK_CORE - }, - .end = { - .vpt_tag = VCPROPTAG_NULL - } -}; - -#if NGENFB > 0 -static struct __aligned(16) { - struct vcprop_buffer_hdr vb_hdr; - struct vcprop_tag_edidblock vbt_edid; - struct vcprop_tag end; -} vb_edid = { - .vb_hdr = { - .vpb_len = sizeof(vb_edid), - .vpb_rcode = VCPROP_PROCESS_REQUEST, - }, - .vbt_edid = { - .tag = { - .vpt_tag = VCPROPTAG_GET_EDID_BLOCK, - .vpt_len = VCPROPTAG_LEN(vb_edid.vbt_edid), - .vpt_rcode = VCPROPTAG_REQUEST, - }, - .blockno = 0, - }, - .end = { - .vpt_tag = VCPROPTAG_NULL - } -}; - -static struct __aligned(16) { - struct vcprop_buffer_hdr vb_hdr; - struct vcprop_tag_fbres vbt_res; - struct vcprop_tag_fbres vbt_vres; - struct vcprop_tag_fbdepth vbt_depth; - struct vcprop_tag_fbalpha vbt_alpha; - struct vcprop_tag_allocbuf vbt_allocbuf; - struct vcprop_tag_blankscreen vbt_blank; - struct vcprop_tag_fbpitch vbt_pitch; - struct vcprop_tag end; -} vb_setfb = { - .vb_hdr = { - .vpb_len = sizeof(vb_setfb), - .vpb_rcode = VCPROP_PROCESS_REQUEST, - }, - .vbt_res = { - .tag = { - .vpt_tag = VCPROPTAG_SET_FB_RES, - .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_res), - .vpt_rcode = VCPROPTAG_REQUEST, - }, - .width = 0, - .height = 0, - }, - .vbt_vres = { - .tag = { - .vpt_tag = VCPROPTAG_SET_FB_VRES, - .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_vres), - .vpt_rcode = VCPROPTAG_REQUEST, - }, - .width = 0, - .height = 0, - }, - .vbt_depth = { - .tag = { - .vpt_tag = VCPROPTAG_SET_FB_DEPTH, - .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_depth), - .vpt_rcode = VCPROPTAG_REQUEST, - }, - .bpp = 32, - }, - .vbt_alpha = { - .tag = { - .vpt_tag = VCPROPTAG_SET_FB_ALPHA_MODE, - .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_alpha), - .vpt_rcode = VCPROPTAG_REQUEST, - }, - .state = VCPROP_ALPHA_IGNORED, - }, - .vbt_allocbuf = { - .tag = { - .vpt_tag = VCPROPTAG_ALLOCATE_BUFFER, - .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_allocbuf), - .vpt_rcode = VCPROPTAG_REQUEST, - }, - .address = PAGE_SIZE, /* alignment */ - }, - .vbt_blank = { - .tag = { - .vpt_tag = VCPROPTAG_BLANK_SCREEN, - .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_blank), - .vpt_rcode = VCPROPTAG_REQUEST, - }, - .state = VCPROP_BLANK_OFF, - }, - .vbt_pitch = { - .tag = { - .vpt_tag = VCPROPTAG_GET_FB_PITCH, - .vpt_len = VCPROPTAG_LEN(vb_setfb.vbt_pitch), - .vpt_rcode = VCPROPTAG_REQUEST, - }, - }, - .end = { - .vpt_tag = VCPROPTAG_NULL, - }, -}; - -extern void bcmgenfb_set_console_dev(device_t dev); -void bcmgenfb_set_ioctl(int(*)(void *, void *, u_long, void *, int, struct lwp *)); -extern void bcmgenfb_ddb_trap_callback(int where); -static int rpi_ioctl(void *, void *, u_long, void *, int, lwp_t *); - -static int rpi_video_on = WSDISPLAYIO_VIDEO_ON; - -#if defined(RPI_HWCURSOR) -#define CURSOR_BITMAP_SIZE (64 * 8) -#define CURSOR_ARGB_SIZE (64 * 64 * 4) -static uint32_t hcursor = 0; -static bus_addr_t pcursor = 0; -static uint32_t *cmem = NULL; -static int cursor_x = 0, cursor_y = 0, hot_x = 0, hot_y = 0, cursor_on = 0; -static uint32_t cursor_cmap[4]; -static uint8_t cursor_mask[8 * 64], cursor_bitmap[8 * 64]; -#endif -#endif - -/* - * Return true if this model Raspberry Pi has Bluetooth/Wi-Fi support - */ -static bool -rpi_rev_has_btwifi(uint32_t rev) -{ - if ((rev & VCPROP_REV_ENCFLAG) == 0) - return false; - - switch (__SHIFTOUT(rev, VCPROP_REV_MODEL)) { - case RPI_MODEL_B_PI3: - case RPI_MODEL_ZERO_W: - return true; - default: - return false; - } -} - -static void -rpi_uartinit(void) -{ - const paddr_t pa = BCM2835_PERIPHERALS_BUS_TO_PHYS(BCM2835_ARMMBOX_BASE); - const bus_space_tag_t iot = &bcm2835_bs_tag; - const bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(pa); - uint32_t res; - - bcm2835_mbox_write(iot, ioh, BCMMBOX_CHANARM2VC, KERN_VTOPHYS(&vb_uart)); - - bcm2835_mbox_read(iot, ioh, BCMMBOX_CHANARM2VC, &res); - - cpu_dcache_inv_range((vaddr_t)&vb_uart, sizeof(vb_uart)); - - if (vcprop_tag_success_p(&vb_uart.vbt_boardrev.tag)) { - if (rpi_rev_has_btwifi(vb_uart.vbt_boardrev.rev)) { -#if NCOM > 0 - /* Enable AUX UART on GPIO header */ - bcm2835gpio_function_select(14, BCM2835_GPIO_ALT5); - bcm2835gpio_function_select(15, BCM2835_GPIO_ALT5); -#else - /* Enable UART0 (PL011) on GPIO header */ - bcm2835gpio_function_select(14, BCM2835_GPIO_ALT0); - bcm2835gpio_function_select(15, BCM2835_GPIO_ALT0); -#endif - } - } - - if (vcprop_tag_success_p(&vb_uart.vbt_uartclockrate.tag)) - uart_clk = vb_uart.vbt_uartclockrate.rate; -} - - -static void -rpi_pinctrl(void) -{ -#if NBCMSDHOST > 0 - if (rpi_rev_has_btwifi(vb.vbt_boardrev.rev)) { - /* - * If the sdhost driver is present, map the SD card slot to the - * SD host controller and the sdhci driver to the SDIO pins. - */ - for (int pin = 48; pin <= 53; pin++) { - /* Enable SDHOST on SD card slot */ - bcm2835gpio_function_select(pin, BCM2835_GPIO_ALT0); - } - for (int pin = 34; pin <= 39; pin++) { - /* Enable SDHCI on SDIO */ - bcm2835gpio_function_select(pin, BCM2835_GPIO_ALT3); - bcm2835gpio_function_setpull(pin, - pin == 34 ? BCM2835_GPIO_GPPUD_PULLOFF : - BCM2835_GPIO_GPPUD_PULLUP); - } - } -#endif - - if (rpi_rev_has_btwifi(vb.vbt_boardrev.rev)) { -#if NCOM > 0 - /* Enable UART0 (PL011) on BT */ - bcm2835gpio_function_select(32, BCM2835_GPIO_ALT3); - bcm2835gpio_function_select(33, BCM2835_GPIO_ALT3); -#else - /* Enable AUX UART on BT */ - bcm2835gpio_function_select(32, BCM2835_GPIO_ALT5); - bcm2835gpio_function_select(33, BCM2835_GPIO_ALT5); -#endif - bcm2835gpio_function_setpull(32, BCM2835_GPIO_GPPUD_PULLOFF); - bcm2835gpio_function_setpull(33, BCM2835_GPIO_GPPUD_PULLUP); - bcm2835gpio_function_select(43, BCM2835_GPIO_ALT0); - bcm2835gpio_function_setpull(43, BCM2835_GPIO_GPPUD_PULLOFF); - } -} - - -static void -rpi_bootparams(void) -{ - const paddr_t pa = BCM2835_PERIPHERALS_BUS_TO_PHYS(BCM2835_ARMMBOX_BASE); - const bus_space_tag_t iot = &bcm2835_bs_tag; - const bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(pa); - uint32_t res; - - bcm2835_mbox_write(iot, ioh, BCMMBOX_CHANPM, ( -#if (NSDHC > 0) - (1 << VCPM_POWER_SDCARD) | -#endif -#if (NPLCOM > 0) - (1 << VCPM_POWER_UART0) | -#endif -#if (NBCMDWCTWO > 0) - (1 << VCPM_POWER_USB) | -#endif -#if (NBSCIIC > 0) - (1 << VCPM_POWER_I2C0) | (1 << VCPM_POWER_I2C1) | - /* (1 << VCPM_POWER_I2C2) | */ -#endif -#if (NBCMSPI > 0) - (1 << VCPM_POWER_SPI) | -#endif - 0) << 4); - - bcm2835_mbox_write(iot, ioh, BCMMBOX_CHANARM2VC, KERN_VTOPHYS(&vb)); - - bcm2835_mbox_read(iot, ioh, BCMMBOX_CHANARM2VC, &res); - - cpu_dcache_inv_range((vaddr_t)&vb, sizeof(vb)); - - if (!vcprop_buffer_success_p(&vb.vb_hdr)) { - bootconfig.dramblocks = 1; - bootconfig.dram[0].address = 0x0; - bootconfig.dram[0].pages = atop(RPI_MINIMUM_SPLIT); - return; - } - - struct vcprop_tag_memory *vptp_mem = &vb.vbt_memory; - - if (vcprop_tag_success_p(&vptp_mem->tag)) { - size_t n = vcprop_tag_resplen(&vptp_mem->tag) / - sizeof(struct vcprop_memory); - - bootconfig.dramblocks = 0; - - for (int i = 0; i < n && i < DRAM_BLOCKS; i++) { - bootconfig.dram[i].address = vptp_mem->mem[i].base; - bootconfig.dram[i].pages = atop(vptp_mem->mem[i].size); - bootconfig.dramblocks++; - } - } - - if (vcprop_tag_success_p(&vb.vbt_armclockrate.tag)) - curcpu()->ci_data.cpu_cc_freq = vb.vbt_armclockrate.rate; - -#ifdef VERBOSE_INIT_ARM - if (vcprop_tag_success_p(&vb.vbt_fwrev.tag)) - printf("%s: firmware rev %x\n", __func__, - vb.vbt_fwrev.rev); - if (vcprop_tag_success_p(&vb.vbt_macaddr.tag)) - printf("%s: mac-address %llx\n", __func__, - vb.vbt_macaddr.addr); - if (vcprop_tag_success_p(&vb.vbt_boardmodel.tag)) - printf("%s: board model %x\n", __func__, - vb.vbt_boardmodel.model); - if (vcprop_tag_success_p(&vb.vbt_boardrev.tag)) - printf("%s: board rev %x\n", __func__, - vb.vbt_boardrev.rev); - if (vcprop_tag_success_p(&vb.vbt_serial.tag)) - printf("%s: board serial %llx\n", __func__, - vb.vbt_serial.sn); - if (vcprop_tag_success_p(&vb.vbt_dmachan.tag)) - printf("%s: DMA channel mask 0x%08x\n", __func__, - vb.vbt_dmachan.mask); - - if (vcprop_tag_success_p(&vb.vbt_cmdline.tag)) - printf("%s: cmdline %s\n", __func__, - vb.vbt_cmdline.cmdline); -#endif -} - - -static void -rpi_bootstrap(void) -{ -#ifdef BCM2836 -#define RPI_CPU_MAX 4 - -#ifdef MULTIPROCESSOR - extern int cortex_mmuinfo; - - arm_cpu_max = RPI_CPU_MAX; - cortex_mmuinfo = armreg_ttbr_read(); - -#ifdef VERBOSE_INIT_ARM - printf("%s: %d cpus present\n", __func__, arm_cpu_max); - printf("%s: cortex_mmuinfo %x\n", __func__, cortex_mmuinfo); -#endif -#endif /* MULTIPROCESSOR */ - - /* - * Even if no options MULTIPROCESSOR, - * It is need to initialize the secondary CPU, - * and go into wfi loop (cortex_mpstart), - * otherwise system would be freeze... - */ - extern void cortex_mpstart(void); - - for (size_t i = 1; i < RPI_CPU_MAX; i++) { - bus_space_tag_t iot = &bcm2835_bs_tag; - bus_space_handle_t ioh = BCM2836_ARM_LOCAL_VBASE; - - bus_space_write_4(iot, ioh, - BCM2836_LOCAL_MAILBOX3_SETN(i), - (uint32_t)cortex_mpstart); - - int timeout = 20; - while (timeout-- > 0) { - uint32_t val; - - val = bus_space_read_4(iot, ioh, - BCM2836_LOCAL_MAILBOX3_CLRN(i)); - if (val == 0) - break; - } - } -#endif /* BCM2836 */ - -#ifdef MULTIPROCESSOR - /* Wake up APs in case firmware has placed them in WFE state */ - __asm __volatile("sev"); - - for (int loop = 0; loop < 16; loop++) { - if (arm_cpu_hatched == __BITS(arm_cpu_max - 1, 1)) - break; - gtmr_delay(10000); - } - - for (size_t i = 1; i < arm_cpu_max; i++) { - if ((arm_cpu_hatched & (1 << i)) == 0) { - printf("%s: warning: cpu%zu failed to hatch\n", - __func__, i); - } - } -#endif /* MULTIPROCESSOR */ -} - -/* - * Static device mappings. These peripheral registers are mapped at - * fixed virtual addresses very early in initarm() so that we can use - * them while booting the kernel, and stay at the same address - * throughout whole kernel's life time. - * - * We use this table twice; once with bootstrap page table, and once - * with kernel's page table which we build up in initarm(). - * - * Since we map these registers into the bootstrap page table using - * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map - * registers segment-aligned and segment-rounded in order to avoid - * using the 2nd page tables. - */ - -#define _A(a) ((a) & ~L1_S_OFFSET) -#define _S(s) (((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1)) - -static const struct pmap_devmap rpi_devmap[] = { - { - _A(RPI_KERNEL_IO_VBASE), - _A(RPI_KERNEL_IO_PBASE), - _S(RPI_KERNEL_IO_VSIZE), /* 16Mb */ - VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, - }, -#if defined(BCM2836) - { - _A(RPI_KERNEL_LOCAL_VBASE), - _A(RPI_KERNEL_LOCAL_PBASE), - _S(RPI_KERNEL_LOCAL_VSIZE), - VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, - }, -#endif - { 0, 0, 0, 0, 0 } -}; - -#undef _A -#undef _S - -/* - * u_int initarm(...) - * - * Initial entry point on startup. This gets called before main() is - * entered. - * It should be responsible for setting up everything that must be - * in place when main is called. - * This includes - * Taking a copy of the boot configuration structure. - * Initialising the physical console so characters can be printed. - * Setting up page tables for the kernel - */ -u_int -initarm(void *arg) -{ - - /* - * Heads up ... Setup the CPU / MMU / TLB functions - */ - if (set_cpufuncs()) - panic("cpu not recognized!"); - - /* map some peripheral registers */ - pmap_devmap_bootstrap((vaddr_t)armreg_ttbr_read() & -L1_TABLE_SIZE, - rpi_devmap); - - cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); - - rpi_uartinit(); - - consinit(); - - /* Talk to the user */ -#define BDSTR(s) _BDSTR(s) -#define _BDSTR(s) #s - printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n"); - -#ifdef CORTEX_PMC - cortex_pmc_ccnt_init(); -#endif - - rpi_bootparams(); - - rpi_bootstrap(); - - if (vcprop_tag_success_p(&vb.vbt_armclockrate.tag)) { - curcpu()->ci_data.cpu_cc_freq = vb.vbt_armclockrate.rate; -#ifdef VERBOSE_INIT_ARM - printf("%s: arm clock %d\n", __func__, - vb.vbt_armclockrate.rate); -#endif - } - -#ifdef VERBOSE_INIT_ARM - printf("initarm: Configuring system ...\n"); -#endif - - psize_t ram_size = bootconfig.dram[0].pages * PAGE_SIZE; - -#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS - if (ram_size > KERNEL_VM_BASE - KERNEL_BASE) { - printf("%s: dropping RAM size from %luMB to %uMB\n", - __func__, (unsigned long) (ram_size >> 20), - (KERNEL_VM_BASE - KERNEL_BASE) >> 20); - ram_size = KERNEL_VM_BASE - KERNEL_BASE; - } -#endif - - /* - * If MEMSIZE specified less than what we really have, limit ourselves - * to that. - */ -#ifdef MEMSIZE - if (ram_size == 0 || ram_size > (unsigned)MEMSIZE * 1024 * 1024) - ram_size = (unsigned)MEMSIZE * 1024 * 1024; -#else - KASSERTMSG(ram_size > 0, "RAM size unknown and MEMSIZE undefined"); -#endif - - arm32_bootmem_init(bootconfig.dram[0].address, ram_size, - (uintptr_t)KERNEL_BASE_phys); - -#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS - const bool mapallmem_p = true; - KASSERT(ram_size <= KERNEL_VM_BASE - KERNEL_BASE); -#else - const bool mapallmem_p = false; -#endif - - arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_HIGH, 0, rpi_devmap, - mapallmem_p); - - cpu_reset_address = bcm2835_system_reset; - -#ifdef VERBOSE_INIT_ARM - printf("done.\n"); -#endif - -#ifdef KGDB - kgdb_port_init(); -#endif - -#ifdef __HAVE_MEMORY_DISK__ - md_root_setconf(memory_disk, sizeof memory_disk); -#endif - - if (vcprop_tag_success_p(&vb.vbt_cmdline.tag)) - strlcpy(bootargs, vb.vbt_cmdline.cmdline, sizeof(bootargs)); - boot_args = bootargs; - parse_mi_bootargs(boot_args); - -#ifdef BOOTHOWTO - boothowto |= BOOTHOWTO; -#endif - - /* we've a specific device_register routine */ - evbarm_device_register = rpi_device_register; - - /* Change pinctrl settings */ - rpi_pinctrl(); - - return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0); -} - -static void -consinit_plcom(void) -{ -#if (NPLCOM > 0 && defined(PLCONSOLE)) - /* - * Initialise the diagnostic serial console - * This allows a means of generating output during initarm(). - */ - rpi_pi.pi_iobase = consaddr; - - plcomcnattach(&rpi_pi, plcomcnspeed, uart_clk, - plcomcnmode, PLCOMCNUNIT); -#endif -} - -static void -consinit_com(void) -{ -#if NCOM > 0 - bus_space_tag_t iot = &bcm2835_a4x_bs_tag; - const bus_addr_t addr = BCM2835_AUX_UART_BASE; - const int speed = B115200; - u_int freq = 0; - const u_int flags = TTYDEF_CFLAG; - - if (vcprop_tag_success_p(&vb_uart.vbt_coreclockrate.tag)) - freq = vb.vbt_coreclockrate.rate * 2; - - comcnattach(iot, addr, speed, freq, COM_TYPE_BCMAUXUART, flags); -#endif -} - -void -consinit(void) -{ - static int consinit_called = 0; - bool use_auxuart = false; - - if (consinit_called != 0) - return; - - consinit_called = 1; - -#if NCOM > 0 - if (vcprop_tag_success_p(&vb_uart.vbt_boardrev.tag) && - rpi_rev_has_btwifi(vb_uart.vbt_boardrev.rev)) { - use_auxuart = true; - } -#endif - - if (use_auxuart) - consinit_com(); - else - consinit_plcom(); -} - -#ifdef KGDB -#if !defined(KGDB_PLCOMUNIT) || !defined(KGDB_DEVRATE) || !defined(KGDB_CONMODE) -#error Specify KGDB_PLCOMUNIT, KGDB_DEVRATE and KGDB_CONMODE for KGDB. -#endif - -void -static kgdb_port_init(void) -{ - static int kgdbsinit_called = 0; - int res; - - if (kgdbsinit_called != 0) - return; - - kgdbsinit_called = 1; - - rpi_pi.pi_iobase = consaddr; - - res = plcom_kgdb_attach(&rpi_pi, KGDB_DEVRATE, uart_clk, - KGDB_CONMODE, KGDB_PLCOMUNIT); - if (res) - panic("KGDB uart can not be initialized, err=%d.", res); -} -#endif - -#if NGENFB > 0 -static bool -rpi_fb_parse_mode(const char *s, uint32_t *pwidth, uint32_t *pheight) -{ - char *x; - - if (strncmp(s, "disable", 7) == 0) - return false; - - x = strchr(s, 'x'); - if (x) { - *pwidth = strtoul(s, NULL, 10); - *pheight = strtoul(x + 1, NULL, 10); - } - - return true; -} - -static bool -rpi_fb_get_edid_mode(uint32_t *pwidth, uint32_t *pheight) -{ - struct edid_info ei; - uint8_t edid_data[1024]; - uint32_t res; - int error; - - error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_edid, - sizeof(vb_edid), &res); - if (error) { - printf("%s: mbox request failed (%d)\n", __func__, error); - return false; - } - - if (!vcprop_buffer_success_p(&vb_edid.vb_hdr) || - !vcprop_tag_success_p(&vb_edid.vbt_edid.tag) || - vb_edid.vbt_edid.status != 0) - return false; - - memset(edid_data, 0, sizeof(edid_data)); - memcpy(edid_data, vb_edid.vbt_edid.data, - sizeof(vb_edid.vbt_edid.data)); - edid_parse(edid_data, &ei); -#ifdef VERBOSE_INIT_ARM - edid_print(&ei); -#endif - - if (ei.edid_preferred_mode) { - *pwidth = ei.edid_preferred_mode->hdisplay; - *pheight = ei.edid_preferred_mode->vdisplay; - } - - return true; -} - -/* - * Initialize framebuffer console. - * - * Some notes about boot parameters: - * - If "fb=disable" is present, ignore framebuffer completely. - * - If "fb=x is present, use the specified mode. - * - If "console=fb" is present, attach framebuffer to console. - */ -static bool -rpi_fb_init(prop_dictionary_t dict, void *aux) -{ - uint32_t width = 0, height = 0; - uint32_t res; - char *ptr; - int integer; - int error; - bool is_bgr = true; - - if (get_bootconf_option(boot_args, "fb", - BOOTOPT_TYPE_STRING, &ptr)) { - if (rpi_fb_parse_mode(ptr, &width, &height) == false) - return false; - } - if (width == 0 || height == 0) { - rpi_fb_get_edid_mode(&width, &height); - } - if (width == 0 || height == 0) { - width = RPI_FB_WIDTH; - height = RPI_FB_HEIGHT; - } - - vb_setfb.vbt_res.width = width; - vb_setfb.vbt_res.height = height; - vb_setfb.vbt_vres.width = width; - vb_setfb.vbt_vres.height = height; - error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_setfb, - sizeof(vb_setfb), &res); - if (error) { - printf("%s: mbox request failed (%d)\n", __func__, error); - return false; - } - - if (!vcprop_buffer_success_p(&vb_setfb.vb_hdr) || - !vcprop_tag_success_p(&vb_setfb.vbt_res.tag) || - !vcprop_tag_success_p(&vb_setfb.vbt_vres.tag) || - !vcprop_tag_success_p(&vb_setfb.vbt_depth.tag) || - !vcprop_tag_success_p(&vb_setfb.vbt_allocbuf.tag) || - !vcprop_tag_success_p(&vb_setfb.vbt_blank.tag) || - !vcprop_tag_success_p(&vb_setfb.vbt_pitch.tag)) { - printf("%s: prop tag failed\n", __func__); - return false; - } - -#ifdef VERBOSE_INIT_ARM - printf("%s: addr = 0x%x size = %d\n", __func__, - vb_setfb.vbt_allocbuf.address, - vb_setfb.vbt_allocbuf.size); - printf("%s: depth = %d\n", __func__, vb_setfb.vbt_depth.bpp); - printf("%s: pitch = %d\n", __func__, - vb_setfb.vbt_pitch.linebytes); - printf("%s: width = %d height = %d\n", __func__, - vb_setfb.vbt_res.width, vb_setfb.vbt_res.height); - printf("%s: vwidth = %d vheight = %d\n", __func__, - vb_setfb.vbt_vres.width, vb_setfb.vbt_vres.height); -#endif - - if (vb_setfb.vbt_allocbuf.address == 0 || - vb_setfb.vbt_allocbuf.size == 0 || - vb_setfb.vbt_res.width == 0 || - vb_setfb.vbt_res.height == 0 || - vb_setfb.vbt_vres.width == 0 || - vb_setfb.vbt_vres.height == 0 || - vb_setfb.vbt_pitch.linebytes == 0) { - printf("%s: failed to set mode %ux%u\n", __func__, - width, height); - return false; - } - - prop_dictionary_set_uint32(dict, "width", vb_setfb.vbt_res.width); - prop_dictionary_set_uint32(dict, "height", vb_setfb.vbt_res.height); - prop_dictionary_set_uint8(dict, "depth", vb_setfb.vbt_depth.bpp); - prop_dictionary_set_uint16(dict, "linebytes", - vb_setfb.vbt_pitch.linebytes); - prop_dictionary_set_uint32(dict, "address", - vb_setfb.vbt_allocbuf.address); - - /* - * Old firmware uses BGR. New firmware uses RGB. The get and set - * pixel order mailbox properties don't seem to work. The firmware - * adds a kernel cmdline option bcm2708_fb.fbswap=<0|1>, so use it - * to determine pixel order. 0 means BGR, 1 means RGB. - * - * See https://github.com/raspberrypi/linux/issues/514 - */ - if (get_bootconf_option(boot_args, "bcm2708_fb.fbswap", - BOOTOPT_TYPE_INT, &integer)) { - is_bgr = integer == 0; - } - prop_dictionary_set_bool(dict, "is_bgr", is_bgr); - - /* if "genfb.type=" is passed in cmdline, override wsdisplay type */ - if (get_bootconf_option(boot_args, "genfb.type", - BOOTOPT_TYPE_INT, &integer)) { - prop_dictionary_set_uint32(dict, "wsdisplay_type", integer); - } - -#if defined(RPI_HWCURSOR) - struct amba_attach_args *aaa = aux; - bus_space_handle_t hc; - - hcursor = rpi_alloc_mem(CURSOR_ARGB_SIZE, PAGE_SIZE, - MEM_FLAG_L1_NONALLOCATING | MEM_FLAG_HINT_PERMALOCK); - pcursor = rpi_lock_mem(hcursor); -#ifdef RPI_IOCTL_DEBUG - printf("hcursor: %08x\n", hcursor); - printf("pcursor: %08x\n", (uint32_t)pcursor); - printf("fb: %08x\n", (uint32_t)vb_setfb.vbt_allocbuf.address); -#endif - if (bus_space_map(aaa->aaa_iot, pcursor, CURSOR_ARGB_SIZE, - BUS_SPACE_MAP_LINEAR|BUS_SPACE_MAP_PREFETCHABLE, &hc) != 0) { - printf("couldn't map cursor memory\n"); - } else { - int i, j, k; - - cmem = bus_space_vaddr(aaa->aaa_iot, hc); - k = 0; - for (j = 0; j < 64; j++) { - for (i = 0; i < 64; i++) { - cmem[i + k] = - ((i & 8) ^ (j & 8)) ? 0xa0ff0000 : 0xa000ff00; - } - k += 64; - } - cpu_dcache_wb_range((vaddr_t)cmem, CURSOR_ARGB_SIZE); - rpi_fb_initcursor(pcursor, 0, 0); -#ifdef RPI_IOCTL_DEBUG - rpi_fb_movecursor(600, 400, 1); -#else - rpi_fb_movecursor(cursor_x, cursor_y, cursor_on); -#endif - } -#endif - - return true; -} - - -#if defined(RPI_HWCURSOR) -static int -rpi_fb_do_cursor(struct wsdisplay_cursor *cur) -{ - int pos = 0; - int shape = 0; - - if (cur->which & WSDISPLAY_CURSOR_DOCUR) { - if (cursor_on != cur->enable) { - cursor_on = cur->enable; - pos = 1; - } - } - if (cur->which & WSDISPLAY_CURSOR_DOHOT) { - - hot_x = cur->hot.x; - hot_y = cur->hot.y; - pos = 1; - shape = 1; - } - if (cur->which & WSDISPLAY_CURSOR_DOPOS) { - - cursor_x = cur->pos.x; - cursor_y = cur->pos.y; - pos = 1; - } - if (cur->which & WSDISPLAY_CURSOR_DOCMAP) { - int i; - uint32_t val; - - for (i = 0; i < min(cur->cmap.count, 3); i++) { - val = (cur->cmap.red[i] << 16 ) | - (cur->cmap.green[i] << 8) | - (cur->cmap.blue[i] ) | - 0xff000000; - cursor_cmap[i + cur->cmap.index + 2] = val; - } - shape = 1; - } - if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) { - int err; - - err = copyin(cur->mask, cursor_mask, CURSOR_BITMAP_SIZE); - err += copyin(cur->image, cursor_bitmap, CURSOR_BITMAP_SIZE); - if (err != 0) - return EFAULT; - shape = 1; - } - if (shape) { - int i, j, idx; - uint8_t mask; - - for (i = 0; i < CURSOR_BITMAP_SIZE; i++) { - mask = 0x01; - for (j = 0; j < 8; j++) { - idx = ((cursor_mask[i] & mask) ? 2 : 0) | - ((cursor_bitmap[i] & mask) ? 1 : 0); - cmem[i * 8 + j] = cursor_cmap[idx]; - mask = mask << 1; - } - } - /* just in case */ - cpu_dcache_wb_range((vaddr_t)cmem, CURSOR_ARGB_SIZE); - rpi_fb_initcursor(pcursor, hot_x, hot_y); - } - if (pos) { - rpi_fb_movecursor(cursor_x, cursor_y, cursor_on); - } - return 0; -} -#endif - -static int -rpi_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, lwp_t *l) -{ - - switch (cmd) { - case WSDISPLAYIO_SVIDEO: - { - int d = *(int *)data; - if (d == rpi_video_on) - return 0; - rpi_video_on = d; - rpi_fb_set_video(d); -#if defined(RPI_HWCURSOR) - rpi_fb_movecursor(cursor_x, cursor_y, - d ? cursor_on : 0); -#endif - } - return 0; - case WSDISPLAYIO_GVIDEO: - *(int *)data = rpi_video_on; - return 0; -#if defined(RPI_HWCURSOR) - case WSDISPLAYIO_GCURPOS: - { - struct wsdisplay_curpos *cp = (void *)data; - - cp->x = cursor_x; - cp->y = cursor_y; - } - return 0; - case WSDISPLAYIO_SCURPOS: - { - struct wsdisplay_curpos *cp = (void *)data; - - cursor_x = cp->x; - cursor_y = cp->y; - rpi_fb_movecursor(cursor_x, cursor_y, cursor_on); - } - return 0; - case WSDISPLAYIO_GCURMAX: - { - struct wsdisplay_curpos *cp = (void *)data; - - cp->x = 64; - cp->y = 64; - } - return 0; - case WSDISPLAYIO_SCURSOR: - { - struct wsdisplay_cursor *cursor = (void *)data; - - return rpi_fb_do_cursor(cursor); - } -#endif - default: - return EPASSTHROUGH; - } -} - -#endif - -static void -rpi_device_register(device_t dev, void *aux) -{ - prop_dictionary_t dict = device_properties(dev); - -#if defined(BCM2836) - if (device_is_a(dev, "armgtmr")) { - /* - * The frequency of the generic timer is the reference - * frequency. - */ - prop_dictionary_set_uint32(dict, "frequency", RPI_REF_FREQ); - return; - } -#endif - - if (device_is_a(dev, "plcom") && - vcprop_tag_success_p(&vb_uart.vbt_uartclockrate.tag) && - vb_uart.vbt_uartclockrate.rate > 0) { - prop_dictionary_set_uint32(dict, - "frequency", vb_uart.vbt_uartclockrate.rate); - } - if (device_is_a(dev, "com") && - vcprop_tag_success_p(&vb.vbt_coreclockrate.tag) && - vb.vbt_coreclockrate.rate > 0) { - prop_dictionary_set_uint32(dict, - "frequency", vb.vbt_coreclockrate.rate); - } - if (device_is_a(dev, "bcmdmac") && - vcprop_tag_success_p(&vb.vbt_dmachan.tag)) { - prop_dictionary_set_uint32(dict, - "chanmask", vb.vbt_dmachan.mask); - } - if (device_is_a(dev, "sdhc") && - vcprop_tag_success_p(&vb.vbt_emmcclockrate.tag) && - vb.vbt_emmcclockrate.rate > 0) { - prop_dictionary_set_uint32(dict, - "frequency", vb.vbt_emmcclockrate.rate); - } - if (device_is_a(dev, "sdhost") && - vcprop_tag_success_p(&vb.vbt_coreclockrate.tag) && - vb.vbt_coreclockrate.rate > 0) { - prop_dictionary_set_uint32(dict, - "frequency", vb.vbt_coreclockrate.rate); - if (!rpi_rev_has_btwifi(vb.vbt_boardrev.rev)) { - /* No btwifi and sdhost driver is present */ - prop_dictionary_set_bool(dict, "disable", true); - } - } - if (booted_device == NULL && - device_is_a(dev, "ld") && - device_is_a(device_parent(dev), "sdmmc")) { - booted_partition = 0; - booted_device = dev; - } - if (device_is_a(dev, "usmsc") && - vcprop_tag_success_p(&vb.vbt_macaddr.tag)) { - const uint8_t enaddr[ETHER_ADDR_LEN] = { - (vb.vbt_macaddr.addr >> 0) & 0xff, - (vb.vbt_macaddr.addr >> 8) & 0xff, - (vb.vbt_macaddr.addr >> 16) & 0xff, - (vb.vbt_macaddr.addr >> 24) & 0xff, - (vb.vbt_macaddr.addr >> 32) & 0xff, - (vb.vbt_macaddr.addr >> 40) & 0xff - }; - - prop_data_t pd = prop_data_create_data(enaddr, ETHER_ADDR_LEN); - KASSERT(pd != NULL); - if (prop_dictionary_set(device_properties(dev), "mac-address", - pd) == false) { - aprint_error_dev(dev, - "WARNING: Unable to set mac-address property\n"); - } - prop_object_release(pd); - } - -#if NGENFB > 0 - if (device_is_a(dev, "genfb")) { - char *ptr; - - bcmgenfb_set_console_dev(dev); - bcmgenfb_set_ioctl(&rpi_ioctl); -#ifdef DDB - db_trap_callback = bcmgenfb_ddb_trap_callback; -#endif - - if (rpi_fb_init(dict, aux) == false) - return; - if (get_bootconf_option(boot_args, "console", - BOOTOPT_TYPE_STRING, &ptr) && strncmp(ptr, "fb", 2) == 0) { - prop_dictionary_set_bool(dict, "is_console", true); -#if NUKBD > 0 - /* allow ukbd to be the console keyboard */ - ukbd_cnattach(); -#endif - } else { - prop_dictionary_set_bool(dict, "is_console", false); - } - } -#endif - - /* BSC0 is used internally on some boards */ - if (device_is_a(dev, "bsciic") && - ((struct amba_attach_args *)aux)->aaa_addr == BCM2835_BSC0_BASE) { - if (rpi_rev_has_btwifi(vb.vbt_boardrev.rev)) { - prop_dictionary_set_bool(dict, "disable", true); - } - } -} - -SYSCTL_SETUP(sysctl_machdep_rpi, "sysctl machdep subtree setup (rpi)") -{ - sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL, - NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL); - - sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT|CTLFLAG_READONLY, - CTLTYPE_INT, "firmware_revision", NULL, NULL, 0, - &vb.vbt_fwrev.rev, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); - - sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT|CTLFLAG_READONLY, - CTLTYPE_INT, "board_model", NULL, NULL, 0, - &vb.vbt_boardmodel.model, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); - - sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT|CTLFLAG_READONLY, - CTLTYPE_INT, "board_revision", NULL, NULL, 0, - &vb.vbt_boardrev.rev, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); - - sysctl_createv(clog, 0, NULL, NULL, - CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_HEX|CTLFLAG_PRIVATE, - CTLTYPE_QUAD, "serial", NULL, NULL, 0, - &vb.vbt_serial.sn, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL); -} Index: sys/arch/evbarm/rpi/rpi_start.S =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/rpi/rpi_start.S,v retrieving revision 1.14 diff -u -p -r1.14 rpi_start.S --- sys/arch/evbarm/rpi/rpi_start.S 27 Mar 2015 11:42:28 -0000 1.14 +++ sys/arch/evbarm/rpi/rpi_start.S 3 Dec 2017 12:01:01 -0000 @@ -83,10 +83,11 @@ #include "opt_bcm283x.h" -#if defined(BCM2836) +#if defined(SOC_BCM2836) #include #else +#include "opt_arm_debug.h" #include "opt_cputypes.h" #include "opt_cpuoptions.h" @@ -96,6 +97,13 @@ RCSID("$NetBSD: rpi_start.S,v 1.14 2015/03/27 11:42:28 skrll Exp $") + +#if defined(VERBOSE_INIT_ARM) +#define XPUTC(n) mov r0, n; bl bcm283x_platform_early_putchar +#else +#define XPUTC(n) +#endif + /* * Workaround Erratum 411920 * @@ -128,7 +136,7 @@ RCSID("$NetBSD: rpi_start.S,v 1.14 2015/ .global _C_LABEL(rpi_start) _C_LABEL(rpi_start): - adr r8, rpi_boot_regs + ldr r8, Luboot_args stmia r8!, {r0-r3} mrs r0, cpsr @@ -273,15 +281,22 @@ _C_LABEL(rpi_start): nop /* NOTREACHED */ + Ll1_s_frame: .word L1_S_FRAME Ltemp_l1_table: /* Put the temporary L1 translation table just below the kernel. */ - .word 0x4000 + //.word 0x4000 + //.word (KERNEL_BASE - KERNEL_BASE_VOFFSET + 128 * L1_S_SIZE - L1_TABLE_SIZE) + .word (128 * L1_S_SIZE - L1_TABLE_SIZE) Lstart: .word start + +Luboot_args: + .word uboot_args + /* * Coprocessor register initialization values */ @@ -337,25 +352,27 @@ Lctl_ID_dis: #endif mmu_init_table: - /* Add 1MB of VA==PA at 0x00000000 so we can keep the kernel going */ - MMU_INIT(0x0, 0x0, - (_end - KERNEL_BASE + 2 * L1_S_SIZE - 1), - L1_S_PROTO | L1_S_APv6_KRW) + /* + * Map 256MB of VA==PA at 0x00000000 so we can keep the kernel going + * and get access to the FDT the firmware loads + */ + MMU_INIT(0x0, 0x0, 0x10000000, L1_S_PROTO | L1_S_APv6_KRW) MMU_INIT(KERNEL_BASE, 0x0, (_end - KERNEL_BASE + 2 * L1_S_SIZE - 1), L1_S_PROTO | L1_S_APv6_KRW | L1_S_B | L1_S_C) /* Map the 16MB of peripherals */ - MMU_INIT(RPI_KERNEL_IO_VBASE, RPI_KERNEL_IO_PBASE, - (RPI_KERNEL_IO_VSIZE + L1_S_SIZE - 1), + MMU_INIT(BCM2835_PERIPHERALS_VBASE, BCM2835_PERIPHERALS_BASE, + (BCM2835_PERIPHERALS_SIZE + L1_S_SIZE - 1), + L1_S_PROTO | L1_S_APv6_KRW) + + /* Map the 16MB of peripherals */ + MMU_INIT(BCM2835_PERIPHERALS_BASE, BCM2835_PERIPHERALS_BASE, + (BCM2835_PERIPHERALS_SIZE + L1_S_SIZE - 1), L1_S_PROTO | L1_S_APv6_KRW) /* end of table */ MMU_INIT(0, 0, 0, 0) #endif - - .globl _C_LABEL(rpi_boot_regs) -rpi_boot_regs: - .space 4 * 4 Index: sys/arch/evbarm/rpi/vcprop_subr.c =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/rpi/vcprop_subr.c,v retrieving revision 1.3 diff -u -p -r1.3 vcprop_subr.c --- sys/arch/evbarm/rpi/vcprop_subr.c 9 Nov 2017 21:39:48 -0000 1.3 +++ sys/arch/evbarm/rpi/vcprop_subr.c 3 Dec 2017 12:01:01 -0000 @@ -39,7 +39,6 @@ #include #include -#include #include #include Index: sys/dev/fdt/fdt_subr.c =================================================================== RCS file: /cvsroot/src/sys/dev/fdt/fdt_subr.c,v retrieving revision 1.19 diff -u -p -r1.19 fdt_subr.c --- sys/dev/fdt/fdt_subr.c 19 Sep 2017 22:55:49 -0000 1.19 +++ sys/dev/fdt/fdt_subr.c 3 Dec 2017 12:01:12 -0000 @@ -81,7 +81,7 @@ fdtbus_phandle2offset(int phandle) } -static int +int fdtbus_get_addr_cells(int phandle) { uint32_t addr_cells; @@ -92,13 +92,13 @@ fdtbus_get_addr_cells(int phandle) return addr_cells; } -static int +int fdtbus_get_size_cells(int phandle) { uint32_t size_cells; if (of_getprop_uint32(phandle, "#size-cells", &size_cells)) - size_cells = 0; + size_cells = 1; return size_cells; } @@ -143,7 +143,7 @@ fdtbus_get_path(int phandle, char *buf, return true; } -static uint64_t +uint64_t fdtbus_get_cells(const uint8_t *buf, int cells) { switch (cells) { @@ -154,50 +154,6 @@ fdtbus_get_cells(const uint8_t *buf, int } } -static uint64_t -fdtbus_decode_range(int phandle, uint64_t paddr) -{ - const int parent = OF_parent(phandle); - if (parent == -1) - return paddr; - const uint8_t *buf; - int len; - - buf = fdt_getprop(fdtbus_get_data(), - fdtbus_phandle2offset(phandle), "ranges", &len); - if (buf == NULL) - return paddr; - - if (len == 0) { - /* pass through to parent */ - return fdtbus_decode_range(parent, paddr); - } - - const int addr_cells = fdtbus_get_addr_cells(phandle); - const int size_cells = fdtbus_get_size_cells(phandle); - const int paddr_cells = fdtbus_get_addr_cells(OF_parent(parent)); - if (addr_cells == -1 || size_cells == -1 || paddr_cells == -1) - return paddr; - - while (len > 0) { - uint64_t cba, pba, cl; - cba = fdtbus_get_cells(buf, addr_cells); - buf += addr_cells * 4; - pba = fdtbus_get_cells(buf, paddr_cells); - buf += paddr_cells * 4; - cl = fdtbus_get_cells(buf, size_cells); - buf += size_cells * 4; - - if (paddr >= cba && paddr < cba + cl) - return fdtbus_decode_range(parent, pba) + (paddr - cba); - - len -= (addr_cells + paddr_cells + size_cells) * 4; - } - - /* No mapping found */ - return paddr; -} - int fdtbus_get_reg_byname(int phandle, const char *name, bus_addr_t *paddr, bus_size_t *psize) @@ -225,7 +181,7 @@ fdtbus_get_reg_byname(int phandle, const } int -fdtbus_get_reg(int phandle, u_int index, bus_addr_t *paddr, bus_size_t *psize) +fdtbus_get_reg(int phandle, u_int index, bus_addr_t *baddr, bus_size_t *bsize) { uint64_t addr, size; int error; @@ -237,16 +193,16 @@ fdtbus_get_reg(int phandle, u_int index, if (sizeof(bus_addr_t) == 4 && (addr + size) > 0x100000000) return ERANGE; - if (paddr) - *paddr = (bus_addr_t)addr; - if (psize) - *psize = (bus_size_t)size; + if (baddr) + *baddr = (bus_addr_t)addr; + if (bsize) + *bsize = (bus_size_t)size; return 0; } int -fdtbus_get_reg64(int phandle, u_int index, uint64_t *paddr, uint64_t *psize) +fdtbus_get_reg64(int phandle, u_int index, uint64_t *baddr, uint64_t *bsize) { uint64_t addr, size; const uint8_t *buf; @@ -274,15 +230,10 @@ fdtbus_get_reg64(int phandle, u_int inde buf += addr_cells * 4; size = fdtbus_get_cells(buf, size_cells); - if (paddr) { - *paddr = fdtbus_decode_range(OF_parent(phandle), addr); - const char *name = fdt_get_name(fdtbus_get_data(), - fdtbus_phandle2offset(phandle), NULL); - aprint_debug("fdt: [%s] decoded addr #%u: %llx -> %llx\n", - name, index, addr, *paddr); - } - if (psize) - *psize = size; + if (baddr) + *baddr = addr; + if (bsize) + *bsize = size; return 0; } Index: sys/dev/fdt/fdtbus.c =================================================================== RCS file: /cvsroot/src/sys/dev/fdt/fdtbus.c,v retrieving revision 1.15 diff -u -p -r1.15 fdtbus.c --- sys/dev/fdt/fdtbus.c 27 Aug 2017 19:13:31 -0000 1.15 +++ sys/dev/fdt/fdtbus.c 3 Dec 2017 12:01:12 -0000 @@ -60,12 +60,6 @@ struct fdt_node { static TAILQ_HEAD(, fdt_node) fdt_nodes = TAILQ_HEAD_INITIALIZER(fdt_nodes); -struct fdt_softc { - device_t sc_dev; - int sc_phandle; - struct fdt_attach_args sc_faa; -}; - static int fdt_match(device_t, cfdata_t, void *); static void fdt_attach(device_t, device_t, void *); static int fdt_scan_submatch(device_t, cfdata_t, const int *, void *); @@ -80,6 +74,75 @@ static const char * const fdtbus_compati CFATTACH_DECL_NEW(fdt, sizeof(struct fdt_softc), fdt_match, fdt_attach, NULL, NULL); +void fdtbus_attach(int phandle, struct fdt_softc *sc); + +static int +fdt_range(struct fdt_softc *sc, int phandle, const char *name, + struct fdtbus_range **rangesp, size_t *nrangesp) +{ + struct fdtbus_range *ranges = NULL; + size_t nranges = 0; + + const size_t elen = + (sc->sc_pcells + sc->sc_acells + sc->sc_scells) * sizeof(uint32_t); + + int len; + const uint8_t *buf = fdt_getprop(fdtbus_get_data(), + fdtbus_phandle2offset(phandle), name, &len); + + if (len > 0 && len >= elen && (len % elen) == 0) { + nranges = len / elen; + ranges = kmem_zalloc(nranges * sizeof(*ranges), KM_SLEEP); + + size_t count = 0; + while (len > 0) { + uint64_t cba = fdtbus_get_cells(buf, sc->sc_acells); + buf += sc->sc_acells * sizeof(uint32_t); + len -= sc->sc_acells * sizeof(uint32_t); + + uint64_t pba = fdtbus_get_cells(buf, sc->sc_pcells); + buf += sc->sc_pcells * sizeof(uint32_t); + len -= sc->sc_pcells * sizeof(uint32_t); + + uint64_t cs = fdtbus_get_cells(buf, sc->sc_scells); + buf += sc->sc_scells * sizeof(uint32_t); + len -= sc->sc_scells * sizeof(uint32_t); + + ranges[count].fr_caddr = cba; + ranges[count].fr_paddr = pba; + ranges[count].fr_size = cs; + count++; + } + KASSERT(nranges == count); + } + *nrangesp = nranges; + *rangesp = ranges; + + return 0; +} + +void +fdtbus_attach(int phandle, struct fdt_softc *sc) +{ + + sc->sc_pcells = fdtbus_get_addr_cells(OF_parent(phandle)); + sc->sc_acells = fdtbus_get_addr_cells(phandle); + sc->sc_scells = fdtbus_get_size_cells(phandle); + + fdt_range(sc, phandle, "ranges", &sc->sc_fbus.fbus_ranges, + &sc->sc_fbus.fbus_nranges); + fdt_range(sc, phandle, "dma-ranges", &sc->sc_fbus.fbus_dmaranges, + &sc->sc_fbus.fbus_ndmaranges); + + aprint_debug_dev(sc->sc_dev, "ranges %zu dma_ranges %zu\n", + sc->sc_fbus.fbus_nranges, sc->sc_fbus.fbus_ndmaranges); + + /* + * Create bus_space and bus_dma tags appropriate for platform + */ + fdtbus_create_bus(sc); +} + static int fdt_match(device_t parent, cfdata_t cf, void *aux) { @@ -115,8 +178,12 @@ fdt_attach(device_t parent, device_t sel int len, child; sc->sc_dev = self; - sc->sc_phandle = phandle; - sc->sc_faa = *faa; + sc->sc_fbus.fbus_phandle = phandle; + + memcpy(sc->sc_fbus.fbus_pshift_bst, faa->faa_shift_bst, + sizeof(sc->sc_fbus.fbus_pshift_bst)); + sc->sc_fbus.fbus_pdmat = faa->faa_dmat; + sc->sc_fbus.fbus_faa = *faa; aprint_naive("\n"); len = OF_getproplen(phandle, "model"); @@ -132,6 +199,8 @@ fdt_attach(device_t parent, device_t sel aprint_normal("\n"); } + fdtbus_attach(phandle, sc); + for (child = OF_child(phandle); child; child = OF_peer(child)) { if (!fdtbus_status_okay(child)) continue; @@ -182,7 +251,7 @@ static void fdt_init_attach_args(struct fdt_softc *sc, struct fdt_node *node, bool quiet, struct fdt_attach_args *faa) { - *faa = sc->sc_faa; + *faa = sc->sc_fbus.fbus_faa; faa->faa_phandle = node->n_phandle; faa->faa_name = node->n_name; faa->faa_quiet = quiet; @@ -242,7 +311,9 @@ fdt_scan(struct fdt_softc *sc, int pass) if (node->n_dev != NULL) continue; - fdt_init_attach_args(sc, node, quiet, &faa); + struct fdt_softc *csc = device_private(node->n_bus); + + fdt_init_attach_args(csc, node, quiet, &faa); /* * Attach the device. Index: sys/dev/fdt/fdtvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/fdt/fdtvar.h,v retrieving revision 1.27 diff -u -p -r1.27 fdtvar.h --- sys/dev/fdt/fdtvar.h 22 Oct 2017 13:56:49 -0000 1.27 +++ sys/dev/fdt/fdtvar.h 3 Dec 2017 12:01:12 -0000 @@ -40,14 +40,56 @@ #include +#define FDTBUS_NREGSHIFT 3 + struct fdt_attach_args { const char *faa_name; - bus_space_tag_t faa_bst; - bus_space_tag_t faa_a4x_bst; + + bus_space_tag_t faa_shift_bst[FDTBUS_NREGSHIFT]; bus_dma_tag_t faa_dmat; + int faa_phandle; int faa_quiet; }; +#define faa_bst faa_shift_bst[0] + +/* Upto 64-bit support */ +struct fdtbus_range { + uint64_t fr_caddr; + uint64_t fr_paddr; + uint64_t fr_size; +}; + +struct fdtbus_simplebus { + int fbus_phandle; + bus_space_tag_t fbus_pshift_bst[FDTBUS_NREGSHIFT]; +#define sc_pbst sc_pshift_bst[0] + + bus_dma_tag_t fbus_pdmat; + + struct fdtbus_range * + fbus_ranges; + size_t fbus_nranges; + + struct fdtbus_range * + fbus_dmaranges; + size_t fbus_ndmaranges; + + struct fdt_attach_args + fbus_faa; +}; + +struct fdt_softc { + device_t sc_dev; +// int sc_phandle; + + size_t sc_acells; + size_t sc_scells; + size_t sc_pcells; + + struct fdtbus_simplebus + sc_fbus; +}; /* flags for fdtbus_intr_establish */ #define FDT_INTR_MPSAFE __BIT(0) @@ -214,6 +256,8 @@ _FDT_CONSOLE_REGISTER(_name) TAILQ_HEAD(fdt_conslist, fdt_console_info); +//void fdtbus_attach(int, struct fdt_softc *); + int fdtbus_register_interrupt_controller(device_t, int, const struct fdtbus_interrupt_controller_func *); int fdtbus_register_i2c_controller(device_t, int, @@ -304,6 +348,9 @@ bool fdtbus_set_data(const void *); const void * fdtbus_get_data(void); int fdtbus_phandle2offset(int); int fdtbus_offset2phandle(int); +int fdtbus_get_addr_cells(int); +int fdtbus_get_size_cells(int); +uint64_t fdtbus_get_cells(const uint8_t *, int); bool fdtbus_get_path(int, char *, size_t); const struct fdt_console *fdtbus_get_console(void); @@ -321,4 +368,11 @@ const char * fdtbus_get_string_index(int int fdtbus_print(void *, const char *); +#if 0 +int fdtbus_bs_map(bus_space_tag_t, bus_addr_t, bus_size_t, int, + bus_space_handle_t *); +#endif + +void fdtbus_create_bus(struct fdt_softc *); + #endif /* _DEV_FDT_FDTVAR_H */ Index: sys/external/bsd/vchiq/conf/files.vchiq =================================================================== RCS file: /cvsroot/src/sys/external/bsd/vchiq/conf/files.vchiq,v retrieving revision 1.2 diff -u -p -r1.2 files.vchiq --- sys/external/bsd/vchiq/conf/files.vchiq 19 Sep 2013 14:43:39 -0000 1.2 +++ sys/external/bsd/vchiq/conf/files.vchiq 3 Dec 2017 12:01:16 -0000 @@ -6,7 +6,7 @@ define vchiqbus { } device vchiq: vchiqbus -attach vchiq at obio +attach vchiq at fdt file external/bsd/vchiq/dist/interface/compat/vchi_bsd.c vchiq file external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_2835_arm.c vchiq file external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_arm.c vchiq Index: sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_2835_arm.c =================================================================== RCS file: /cvsroot/src/sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_2835_arm.c,v retrieving revision 1.19 diff -u -p -r1.19 vchiq_2835_arm.c --- sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_2835_arm.c 1 Jun 2017 02:45:12 -0000 1.19 +++ sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_2835_arm.c 3 Dec 2017 12:01:16 -0000 @@ -54,6 +54,7 @@ #include "vchiq_arm.h" #include "vchiq_2835.h" +#include "vchiq_netbsd.h" #include "vchiq_connected.h" #define MAX_FRAGMENTS (VCHIQ_NUM_CURRENT_BULKS * 2) @@ -64,6 +65,7 @@ typedef struct vchiq_2835_state_struct { } VCHIQ_2835_ARM_STATE_T; /* BSD DMA */ +static bus_dma_tag_t dma_tag; static bus_dmamap_t dma_map; static unsigned int g_cache_line_size = CACHE_LINE_SIZE; @@ -74,6 +76,11 @@ static char *g_free_fragments; struct semaphore g_free_fragments_sema; static struct semaphore g_free_fragments_mutex; +void +vchiq_platform_attach(bus_dma_tag_t tag) +{ + dma_tag = tag; +} int __init vchiq_platform_init(VCHIQ_STATE_T *state) @@ -98,7 +105,7 @@ vchiq_platform_init(VCHIQ_STATE_T *state frag_mem_size = PAGE_ALIGN(g_fragments_size * MAX_FRAGMENTS); dma_nsegs = __arraycount(dma_segs); - err = bus_dmamem_alloc(&bcm2835_bus_dma_tag, + err = bus_dmamem_alloc(dma_tag, slot_mem_size + frag_mem_size, PAGE_SIZE, 0, dma_segs, dma_nsegs, &dma_nsegs, BUS_DMA_WAITOK); if (err) { @@ -107,7 +114,7 @@ vchiq_platform_init(VCHIQ_STATE_T *state goto failed_alloc; } - err = bus_dmamem_map(&bcm2835_bus_dma_tag, + err = bus_dmamem_map(dma_tag, dma_segs, dma_nsegs, slot_mem_size + frag_mem_size, (void **)&slot_mem, BUS_DMA_COHERENT | BUS_DMA_WAITOK); if (err) { @@ -116,7 +123,7 @@ vchiq_platform_init(VCHIQ_STATE_T *state goto failed_alloc; } - err = bus_dmamap_create(&bcm2835_bus_dma_tag, + err = bus_dmamap_create(dma_tag, slot_mem_size + frag_mem_size, 1, /* maxsize, nsegments */ slot_mem_size + frag_mem_size, 0, /* maxsegsize, boundary */ BUS_DMA_WAITOK, @@ -127,7 +134,7 @@ vchiq_platform_init(VCHIQ_STATE_T *state goto failed_alloc; } - err = bus_dmamap_load(&bcm2835_bus_dma_tag, dma_map, slot_mem, + err = bus_dmamap_load(dma_tag, dma_map, slot_mem, slot_mem_size + frag_mem_size, NULL, BUS_DMA_WAITOK); if (err) { vchiq_log_error(vchiq_core_log_level, "cannot load DMA map (%d)", err); @@ -173,10 +180,10 @@ vchiq_platform_init(VCHIQ_STATE_T *state /* Send the base address of the slots to VideoCore */ dsb(); /* Ensure all writes have completed */ - bus_dmamap_sync(&bcm2835_bus_dma_tag, dma_map, 0, slot_mem_size, + bus_dmamap_sync(dma_tag, dma_map, 0, slot_mem_size, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); bcm_mbox_write(BCM2835_MBOX_CHAN_VCHIQ, (unsigned int)slot_phys); - bus_dmamap_sync(&bcm2835_bus_dma_tag, dma_map, 0, slot_mem_size, + bus_dmamap_sync(dma_tag, dma_map, 0, slot_mem_size, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); vchiq_log_info(vchiq_arm_log_level, @@ -190,9 +197,9 @@ vchiq_platform_init(VCHIQ_STATE_T *state failed_vchiq_init: failed_init_slots: failed_load: - bus_dmamap_unload(&bcm2835_bus_dma_tag, dma_map); + bus_dmamap_unload(dma_tag, dma_map); failed_alloc: - bus_dmamap_destroy(&bcm2835_bus_dma_tag, dma_map); + bus_dmamap_destroy(dma_tag, dma_map); return err; } @@ -201,8 +208,8 @@ void __exit vchiq_platform_exit(VCHIQ_STATE_T *state) { - bus_dmamap_unload(&bcm2835_bus_dma_tag, dma_map); - bus_dmamap_destroy(&bcm2835_bus_dma_tag, dma_map); + bus_dmamap_unload(dma_tag, dma_map); + bus_dmamap_destroy(dma_tag, dma_map); } @@ -291,26 +298,26 @@ vchiq_prepare_bulk_data(VCHIQ_BULK_T *bu (maxsegs * sizeof(unsigned long)); bi->proc = curproc; - ret = bus_dmamem_alloc(&bcm2835_bus_dma_tag, bi->pagelist_size, + ret = bus_dmamem_alloc(dma_tag, bi->pagelist_size, 0 /*CACHE_LINE_SIZE*/, 0, bi->pagelist_sgs, __arraycount(bi->pagelist_sgs), &nsegs, BUS_DMA_WAITOK); if (ret != 0) goto fail1; - ret = bus_dmamem_map(&bcm2835_bus_dma_tag, bi->pagelist_sgs, nsegs, + ret = bus_dmamem_map(dma_tag, bi->pagelist_sgs, nsegs, bi->pagelist_size, &bi->pagelist, BUS_DMA_COHERENT | BUS_DMA_WAITOK); if (ret != 0) goto fail2; pagelist = bi->pagelist; - ret = bus_dmamap_create(&bcm2835_bus_dma_tag, bi->pagelist_size, + ret = bus_dmamap_create(dma_tag, bi->pagelist_size, nsegs, bi->pagelist_size, 0, BUS_DMA_WAITOK, &bi->pagelist_map); if (ret != 0) goto fail3; - ret = bus_dmamap_load(&bcm2835_bus_dma_tag, bi->pagelist_map, pagelist, + ret = bus_dmamap_load(dma_tag, bi->pagelist_map, pagelist, bi->pagelist_size, NULL, BUS_DMA_WAITOK | BUS_DMA_WRITE); if (ret != 0) goto fail4; @@ -326,13 +333,13 @@ vchiq_prepare_bulk_data(VCHIQ_BULK_T *bu } } - ret = bus_dmamap_create(&bcm2835_bus_dma_tag, size, maxsegs, size, 0, + ret = bus_dmamap_create(dma_tag, size, maxsegs, size, 0, BUS_DMA_WAITOK, &bi->dmamap); if (ret != 0) goto fail6; - ret = bus_dmamap_load(&bcm2835_bus_dma_tag, bi->dmamap, buf, size, + ret = bus_dmamap_load(dma_tag, bi->dmamap, buf, size, curproc, BUS_DMA_WAITOK | dmaflags); if (ret != 0) @@ -382,7 +389,7 @@ vchiq_prepare_bulk_data(VCHIQ_BULK_T *bu up(&g_free_fragments_mutex); pagelist->type = PAGELIST_READ_WITH_FRAGMENTS + (fragments - g_fragments_base) / g_fragments_size; - bus_dmamap_sync(&bcm2835_bus_dma_tag, dma_map, + bus_dmamap_sync(dma_tag, dma_map, (char *)fragments - g_fragments_base, sizeof(*fragments), BUS_DMASYNC_PREREAD); } @@ -393,33 +400,33 @@ vchiq_prepare_bulk_data(VCHIQ_BULK_T *bu */ bulk->remote_data = bi; - bus_dmamap_sync(&bcm2835_bus_dma_tag, bi->pagelist_map, 0, + bus_dmamap_sync(dma_tag, bi->pagelist_map, 0, bi->pagelist_size, BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(&bcm2835_bus_dma_tag, bi->dmamap, 0, bi->size, + bus_dmamap_sync(dma_tag, bi->dmamap, 0, bi->size, pagelist->type == PAGELIST_WRITE ? BUS_DMASYNC_PREWRITE : BUS_DMASYNC_PREREAD); return VCHIQ_SUCCESS; fail7: - bus_dmamap_destroy(&bcm2835_bus_dma_tag, bi->dmamap); + bus_dmamap_destroy(dma_tag, bi->dmamap); fail6: if (IS_USER_ADDRESS(bi->buf)) uvm_vsunlock(curproc->p_vmspace, bi->buf, bi->size); fail5: - bus_dmamap_unload(&bcm2835_bus_dma_tag, bi->pagelist_map); + bus_dmamap_unload(dma_tag, bi->pagelist_map); fail4: - bus_dmamap_destroy(&bcm2835_bus_dma_tag, bi->pagelist_map); + bus_dmamap_destroy(dma_tag, bi->pagelist_map); fail3: - bus_dmamem_unmap(&bcm2835_bus_dma_tag, bi->pagelist, bi->pagelist_size); + bus_dmamem_unmap(dma_tag, bi->pagelist, bi->pagelist_size); fail2: - bus_dmamem_free(&bcm2835_bus_dma_tag, bi->pagelist_sgs, + bus_dmamem_free(dma_tag, bi->pagelist_sgs, __arraycount(bi->pagelist_sgs)); fail1: @@ -438,10 +445,10 @@ vchiq_complete_bulk(VCHIQ_BULK_T *bulk) vchiq_log_trace(vchiq_arm_log_level, "free_pagelist - %x, %d", (unsigned int)pagelist, actual); - bus_dmamap_sync(&bcm2835_bus_dma_tag, bi->pagelist_map, 0, + bus_dmamap_sync(dma_tag, bi->pagelist_map, 0, bi->pagelist_size, BUS_DMASYNC_POSTWRITE); - bus_dmamap_sync(&bcm2835_bus_dma_tag, bi->dmamap, 0, bi->size, + bus_dmamap_sync(dma_tag, bi->dmamap, 0, bi->size, pagelist->type == PAGELIST_WRITE ? BUS_DMASYNC_POSTWRITE : BUS_DMASYNC_POSTREAD); @@ -452,7 +459,7 @@ vchiq_complete_bulk(VCHIQ_BULK_T *bulk) g_fragments_size; int head_bytes, tail_bytes; - bus_dmamap_sync(&bcm2835_bus_dma_tag, dma_map, + bus_dmamap_sync(dma_tag, dma_map, (char *)fragments - g_fragments_base, g_fragments_size, BUS_DMASYNC_POSTREAD); @@ -493,16 +500,16 @@ vchiq_complete_bulk(VCHIQ_BULK_T *bulk) up(&g_free_fragments_mutex); up(&g_free_fragments_sema); } - bus_dmamap_unload(&bcm2835_bus_dma_tag, bi->dmamap); - bus_dmamap_destroy(&bcm2835_bus_dma_tag, bi->dmamap); + bus_dmamap_unload(dma_tag, bi->dmamap); + bus_dmamap_destroy(dma_tag, bi->dmamap); if (IS_USER_ADDRESS(bi->buf)) uvm_vsunlock(bi->proc->p_vmspace, bi->buf, bi->size); - bus_dmamap_unload(&bcm2835_bus_dma_tag, bi->pagelist_map); - bus_dmamap_destroy(&bcm2835_bus_dma_tag, bi->pagelist_map); - bus_dmamem_unmap(&bcm2835_bus_dma_tag, bi->pagelist, + bus_dmamap_unload(dma_tag, bi->pagelist_map); + bus_dmamap_destroy(dma_tag, bi->pagelist_map); + bus_dmamem_unmap(dma_tag, bi->pagelist, bi->pagelist_size); - bus_dmamem_free(&bcm2835_bus_dma_tag, bi->pagelist_sgs, + bus_dmamem_free(dma_tag, bi->pagelist_sgs, __arraycount(bi->pagelist_sgs)); kmem_free(bi, sizeof(*bi)); } Index: sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_kmod_netbsd.c =================================================================== RCS file: /cvsroot/src/sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_kmod_netbsd.c,v retrieving revision 1.9 diff -u -p -r1.9 vchiq_kmod_netbsd.c --- sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_kmod_netbsd.c 5 Nov 2017 09:11:43 -0000 1.9 +++ sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_kmod_netbsd.c 3 Dec 2017 12:01:17 -0000 @@ -39,10 +39,11 @@ __KERNEL_RCSID(0, "$NetBSD: vchiq_kmod_n #include #include -#include #include #include +#include + #include "vchiq_arm.h" #include "vchiq_2835.h" #include "vchiq_netbsd.h" @@ -58,6 +59,7 @@ struct vchiq_softc { void *sc_ih; int sc_intr; + int sc_phandle; }; static struct vchiq_softc *vchiq_softc = NULL; @@ -85,33 +87,41 @@ CFATTACH_DECL_NEW(vchiq, sizeof(struct v static int vchiq_match(device_t parent, cfdata_t match, void *aux) { - struct amba_attach_args *aaa = aux; - - if (strcmp(aaa->aaa_name, "bcmvchiq") != 0) - return 0; + const char * const compatible[] = { "brcm,bcm2835-vchiq", NULL }; + struct fdt_attach_args * const faa = aux; - return 1; + return of_match_compatible(faa->faa_phandle, compatible); } static void vchiq_attach(device_t parent, device_t self, void *aux) { struct vchiq_softc *sc = device_private(self); - struct amba_attach_args *aaa = aux; + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; aprint_naive("\n"); aprint_normal(": BCM2835 VCHIQ\n"); sc->sc_dev = self; - sc->sc_iot = aaa->aaa_iot; - sc->sc_intr = aaa->aaa_intr; + sc->sc_iot = faa->faa_bst; + sc->sc_phandle = phandle; + + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get register address\n"); + return; + } - if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, aaa->aaa_size, 0, - &sc->sc_ioh)) { - aprint_error_dev(self, "unable to map device\n"); + if (bus_space_map(faa->faa_bst, addr, size, 0, &sc->sc_ioh) != 0) { + aprint_error_dev(sc->sc_dev, "unable to map device\n"); return; } + vchiq_platform_attach(faa->faa_dmat); + vchiq_softc = sc; config_mountroot(self, vchiq_defer); Index: sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_netbsd.h =================================================================== RCS file: /cvsroot/src/sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_netbsd.h,v retrieving revision 1.1 diff -u -p -r1.1 vchiq_netbsd.h --- sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_netbsd.h 8 Mar 2013 12:32:31 -0000 1.1 +++ sys/external/bsd/vchiq/dist/interface/vchiq_arm/vchiq_netbsd.h 3 Dec 2017 12:01:17 -0000 @@ -36,4 +36,6 @@ struct vchiq_attach_args { const char *vaa_name; }; +void vchiq_platform_attach(bus_dma_tag_t tag); + #endif /* !_VCHIQ_NETBSD_H */