diff options
-rw-r--r-- | sys/arm/at91/at91.c | 75 | ||||
-rw-r--r-- | sys/arm/at91/at91_aic.c | 188 | ||||
-rw-r--r-- | sys/arm/at91/at91rm9200.c | 1 | ||||
-rw-r--r-- | sys/arm/at91/at91sam9g20.c | 1 | ||||
-rw-r--r-- | sys/arm/at91/at91sam9g20reg.h | 1 | ||||
-rw-r--r-- | sys/arm/at91/at91sam9x5.c | 1 | ||||
-rw-r--r-- | sys/arm/at91/at91sam9x5reg.h | 1 | ||||
-rw-r--r-- | sys/arm/at91/files.at91 | 1 |
8 files changed, 203 insertions, 66 deletions
diff --git a/sys/arm/at91/at91.c b/sys/arm/at91/at91.c index 384e1c1..5caa326 100644 --- a/sys/arm/at91/at91.c +++ b/sys/arm/at91/at91.c @@ -24,6 +24,8 @@ * SUCH DAMAGE. */ +#include "opt_platform.h" + #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -49,12 +51,6 @@ __FBSDID("$FreeBSD$"); #include <arm/at91/at91_pmcvar.h> #include <arm/at91/at91_aicreg.h> -static struct at91_softc *at91_softc; - -static void at91_eoi(void *); - -extern const struct arm_devmap_entry at91_devmap[]; - uint32_t at91_master_clock; static int @@ -233,6 +229,12 @@ struct bus_space at91_bs_tag = { NULL, }; +#ifndef FDT + +static struct at91_softc *at91_softc; + +static void at91_eoi(void *); + static int at91_probe(device_t dev) { @@ -264,7 +266,6 @@ static int at91_attach(device_t dev) { struct at91_softc *sc = device_get_softc(dev); - int i; arm_post_filter = at91_eoi; @@ -294,29 +295,6 @@ at91_attach(device_t dev) 0xfffffffful) != 0) panic("at91_attach: failed to set up memory rman"); - /* - * Setup the interrupt table. - */ - if (soc_info.soc_data == NULL || soc_info.soc_data->soc_irq_prio == NULL) - panic("Interrupt priority table missing\n"); - for (i = 0; i < 32; i++) { - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SVR + - i * 4, i); - /* Priority. */ - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SMR + i * 4, - soc_info.soc_data->soc_irq_prio[i]); - if (i < 8) - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_EOICR, - 1); - } - - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_SPU, 32); - /* No debug. */ - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_DCR, 0); - /* Disable and clear all interrupts. */ - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_IDCR, 0xffffffff); - bus_space_write_4(sc->sc_st, sc->sc_aic_sh, IC_ICCR, 0xffffffff); - /* * Add this device's children... */ @@ -476,42 +454,6 @@ at91_print_child(device_t dev, device_t child) return (retval); } -void -arm_mask_irq(uintptr_t nb) -{ - - bus_space_write_4(at91_softc->sc_st, - at91_softc->sc_aic_sh, IC_IDCR, 1 << nb); -} - -int -arm_get_next_irq(int last __unused) -{ - int status; - int irq; - - irq = bus_space_read_4(at91_softc->sc_st, - at91_softc->sc_aic_sh, IC_IVR); - status = bus_space_read_4(at91_softc->sc_st, - at91_softc->sc_aic_sh, IC_ISR); - if (status == 0) { - bus_space_write_4(at91_softc->sc_st, - at91_softc->sc_aic_sh, IC_EOICR, 1); - return (-1); - } - return (irq); -} - -void -arm_unmask_irq(uintptr_t nb) -{ - - bus_space_write_4(at91_softc->sc_st, - at91_softc->sc_aic_sh, IC_IECR, 1 << nb); - bus_space_write_4(at91_softc->sc_st, at91_softc->sc_aic_sh, - IC_EOICR, 0); -} - static void at91_eoi(void *unused) { @@ -588,3 +530,4 @@ static driver_t at91_driver = { static devclass_t at91_devclass; DRIVER_MODULE(atmelarm, nexus, at91_driver, at91_devclass, 0, 0); +#endif diff --git a/sys/arm/at91/at91_aic.c b/sys/arm/at91/at91_aic.c new file mode 100644 index 0000000..0f1556c --- /dev/null +++ b/sys/arm/at91/at91_aic.c @@ -0,0 +1,188 @@ +/*- + * Copyright (c) 2014 Warner Losh. 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "opt_platform.h" + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/resource.h> +#include <sys/systm.h> +#include <sys/rman.h> + +#include <machine/bus.h> +#include <machine/cpu.h> +#include <machine/cpufunc.h> +#include <machine/frame.h> +#include <machine/intr.h> +#include <machine/resource.h> + +#include <arm/at91/at91var.h> +#include <arm/at91/at91_aicreg.h> + +#ifdef FDT +#include <dev/fdt/fdt_common.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> +#endif + +static struct aic_softc { + struct resource *mem_res; /* Memory resource */ + void *intrhand; /* Interrupt handle */ + device_t sc_dev; +} *sc; + +static inline uint32_t +RD4(struct aic_softc *sc, bus_size_t off) +{ + + return (bus_read_4(sc->mem_res, off)); +} + +static inline void +WR4(struct aic_softc *sc, bus_size_t off, uint32_t val) +{ + + bus_write_4(sc->mem_res, off, val); +} + +void +arm_mask_irq(uintptr_t nb) +{ + + WR4(sc, IC_IDCR, 1 << nb); +} + +int +arm_get_next_irq(int last __unused) +{ + int status; + int irq; + + irq = RD4(sc, IC_IVR); + status = RD4(sc, IC_ISR); + if (status == 0) { + WR4(sc, IC_EOICR, 1); + return (-1); + } + return (irq); +} + +void +arm_unmask_irq(uintptr_t nb) +{ + + WR4(sc, IC_IECR, 1 << nb); + WR4(sc, IC_EOICR, 0); +} + +static int +at91_aic_probe(device_t dev) +{ +#ifdef FDT + if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-aic")) + return (ENXIO); +#endif + device_set_desc(dev, "AIC"); + return (0); +} + +static int +at91_aic_attach(device_t dev) +{ + int i, rid, err = 0; + + device_printf(dev, "Attach %d\n", bus_current_pass); + + sc = device_get_softc(dev); + sc->sc_dev = dev; + + rid = 0; + sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + + if (sc->mem_res == NULL) + panic("couldn't allocate register resources"); + + /* + * Setup the interrupt table. + */ + if (soc_info.soc_data == NULL || soc_info.soc_data->soc_irq_prio == NULL) + panic("Interrupt priority table missing\n"); + for (i = 0; i < 32; i++) { + WR4(sc, IC_SVR + i * 4, i); + /* Priority. */ + WR4(sc, IC_SMR + i * 4, soc_info.soc_data->soc_irq_prio[i]); + if (i < 8) + WR4(sc, IC_EOICR, 1); + } + + WR4(sc, IC_SPU, 32); + /* No debug. */ + WR4(sc, IC_DCR, 0); + /* Disable and clear all interrupts. */ + WR4(sc, IC_IDCR, 0xffffffff); + WR4(sc, IC_ICCR, 0xffffffff); + enable_interrupts(I32_bit | F32_bit); + + return (err); +} + +static void +at91_aic_new_pass(device_t dev) +{ + device_printf(dev, "Pass %d\n", bus_current_pass); +} + +static device_method_t at91_aic_methods[] = { + DEVMETHOD(device_probe, at91_aic_probe), + DEVMETHOD(device_attach, at91_aic_attach), + DEVMETHOD(bus_new_pass, at91_aic_new_pass), + DEVMETHOD_END +}; + +static driver_t at91_aic_driver = { + "at91_aic", + at91_aic_methods, + sizeof(struct aic_softc), +}; + +static devclass_t at91_aic_devclass; + +#ifdef FDT +DRIVER_MODULE(at91_aic, simplebus, at91_aic_driver, at91_aic_devclass, NULL, + NULL); +#else +DRIVER_MODULE(at91_aic, atmelarm, at91_aic_driver, at91_aic_devclass, NULL, + NULL); +#endif +/* not yet +EARLY_DRIVER_MODULE(at91_aic, simplebus, at91_aic_driver, at91_aic_devclass, + NULL, NULL, BUS_PASS_INTERRUPT); +*/ diff --git a/sys/arm/at91/at91rm9200.c b/sys/arm/at91/at91rm9200.c index f2ee450..2cc0c9c 100644 --- a/sys/arm/at91/at91rm9200.c +++ b/sys/arm/at91/at91rm9200.c @@ -105,6 +105,7 @@ static const uint32_t at91_pio_base[] = { static const struct cpu_devs at91_devs[] = { + DEVICE("at91_aic", AIC, 0), DEVICE("at91_pmc", PMC, 0), DEVICE("at91_st", ST, 0), DEVICE("at91_pio", PIOA, 0), diff --git a/sys/arm/at91/at91sam9g20.c b/sys/arm/at91/at91sam9g20.c index d4e6347..3c17e3a 100644 --- a/sys/arm/at91/at91sam9g20.c +++ b/sys/arm/at91/at91sam9g20.c @@ -103,6 +103,7 @@ static const uint32_t at91_pio_base[] = { static const struct cpu_devs at91_devs[] = { + DEVICE("at91_aic", AIC, 0), DEVICE("at91_pmc", PMC, 0), DEVICE("at91_wdt", WDT, 0), DEVICE("at91_rst", RSTC, 0), diff --git a/sys/arm/at91/at91sam9g20reg.h b/sys/arm/at91/at91sam9g20reg.h index 539d718..59f6099 100644 --- a/sys/arm/at91/at91sam9g20reg.h +++ b/sys/arm/at91/at91sam9g20reg.h @@ -221,6 +221,7 @@ #define AT91SAM9G20_IRQ_RSTC AT91SAM9G20_IRQ_SYSTEM #define AT91SAM9G20_IRQ_OHCI AT91SAM9G20_IRQ_UHP #define AT91SAM9G20_IRQ_NAND (-1) +#define AT91SAM9G20_IRQ_AIC (-1) #define AT91SAM9G20_AIC_BASE 0xffff000 #define AT91SAM9G20_AIC_SIZE 0x200 diff --git a/sys/arm/at91/at91sam9x5.c b/sys/arm/at91/at91sam9x5.c index 4e8c3f4..9fe7104 100644 --- a/sys/arm/at91/at91sam9x5.c +++ b/sys/arm/at91/at91sam9x5.c @@ -104,6 +104,7 @@ static const uint32_t at91_pio_base[] = { static const struct cpu_devs at91_devs[] = { + DEVICE("at91_aic", AIC, 0), DEVICE("at91_pmc", PMC, 0), DEVICE("at91_wdt", WDT, 0), DEVICE("at91_rst", RSTC, 0), diff --git a/sys/arm/at91/at91sam9x5reg.h b/sys/arm/at91/at91sam9x5reg.h index 17c43ff..82a2144 100644 --- a/sys/arm/at91/at91sam9x5reg.h +++ b/sys/arm/at91/at91sam9x5reg.h @@ -221,6 +221,7 @@ #define AT91SAM9X25_IRQ_PIOC AT91SAM9X25_IRQ_PIOCD #define AT91SAM9X25_IRQ_PIOD AT91SAM9X25_IRQ_PIOCD #define AT91SAM9X25_IRQ_NAND (-1) +#define AT91SAM9X25_IRQ_AIC (-1) #define AT91SAM9X25_AIC_BASE 0xffff000 #define AT91SAM9X25_AIC_SIZE 0x200 diff --git a/sys/arm/at91/files.at91 b/sys/arm/at91/files.at91 index 5533594..8c366ca 100644 --- a/sys/arm/at91/files.at91 +++ b/sys/arm/at91/files.at91 @@ -2,6 +2,7 @@ arm/arm/cpufunc_asm_arm9.S standard arm/arm/irq_dispatch.S standard arm/at91/at91_machdep.c standard +arm/at91/at91_aic.c standard arm/at91/at91.c standard arm/at91/at91_cfata.c optional at91_cfata arm/at91/at91_mci.c optional at91_mci |