1*f3a72e40SRuslan Bukin /*- 2*f3a72e40SRuslan Bukin * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> 3*f3a72e40SRuslan Bukin * All rights reserved. 4*f3a72e40SRuslan Bukin * 5*f3a72e40SRuslan Bukin * Redistribution and use in source and binary forms, with or without 6*f3a72e40SRuslan Bukin * modification, are permitted provided that the following conditions 7*f3a72e40SRuslan Bukin * are met: 8*f3a72e40SRuslan Bukin * 1. Redistributions of source code must retain the above copyright 9*f3a72e40SRuslan Bukin * notice, this list of conditions and the following disclaimer. 10*f3a72e40SRuslan Bukin * 2. Redistributions in binary form must reproduce the above copyright 11*f3a72e40SRuslan Bukin * notice, this list of conditions and the following disclaimer in the 12*f3a72e40SRuslan Bukin * documentation and/or other materials provided with the distribution. 13*f3a72e40SRuslan Bukin * 14*f3a72e40SRuslan Bukin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*f3a72e40SRuslan Bukin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*f3a72e40SRuslan Bukin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*f3a72e40SRuslan Bukin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*f3a72e40SRuslan Bukin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*f3a72e40SRuslan Bukin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*f3a72e40SRuslan Bukin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*f3a72e40SRuslan Bukin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*f3a72e40SRuslan Bukin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*f3a72e40SRuslan Bukin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*f3a72e40SRuslan Bukin * SUCH DAMAGE. 25*f3a72e40SRuslan Bukin */ 26*f3a72e40SRuslan Bukin 27*f3a72e40SRuslan Bukin /* 28*f3a72e40SRuslan Bukin * Vybrid Family Direct Memory Access Multiplexer (DMAMUX) 29*f3a72e40SRuslan Bukin * Chapter 22, Vybrid Reference Manual, Rev. 5, 07/2013 30*f3a72e40SRuslan Bukin */ 31*f3a72e40SRuslan Bukin 32*f3a72e40SRuslan Bukin #include <sys/cdefs.h> 33*f3a72e40SRuslan Bukin __FBSDID("$FreeBSD$"); 34*f3a72e40SRuslan Bukin 35*f3a72e40SRuslan Bukin #include <sys/param.h> 36*f3a72e40SRuslan Bukin #include <sys/systm.h> 37*f3a72e40SRuslan Bukin #include <sys/bus.h> 38*f3a72e40SRuslan Bukin #include <sys/kernel.h> 39*f3a72e40SRuslan Bukin #include <sys/module.h> 40*f3a72e40SRuslan Bukin #include <sys/malloc.h> 41*f3a72e40SRuslan Bukin #include <sys/rman.h> 42*f3a72e40SRuslan Bukin #include <sys/timeet.h> 43*f3a72e40SRuslan Bukin #include <sys/timetc.h> 44*f3a72e40SRuslan Bukin #include <sys/watchdog.h> 45*f3a72e40SRuslan Bukin 46*f3a72e40SRuslan Bukin #include <dev/fdt/fdt_common.h> 47*f3a72e40SRuslan Bukin #include <dev/ofw/openfirm.h> 48*f3a72e40SRuslan Bukin #include <dev/ofw/ofw_bus.h> 49*f3a72e40SRuslan Bukin #include <dev/ofw/ofw_bus_subr.h> 50*f3a72e40SRuslan Bukin 51*f3a72e40SRuslan Bukin #include <machine/bus.h> 52*f3a72e40SRuslan Bukin #include <machine/fdt.h> 53*f3a72e40SRuslan Bukin #include <machine/cpu.h> 54*f3a72e40SRuslan Bukin #include <machine/intr.h> 55*f3a72e40SRuslan Bukin 56*f3a72e40SRuslan Bukin #include <arm/freescale/vybrid/vf_common.h> 57*f3a72e40SRuslan Bukin #include <arm/freescale/vybrid/vf_dmamux.h> 58*f3a72e40SRuslan Bukin 59*f3a72e40SRuslan Bukin #define DMAMUX_CHCFG(n) (0x1 * n) /* Channels 0-15 Cfg Reg */ 60*f3a72e40SRuslan Bukin #define CHCFG_ENBL (1 << 7) /* Channel Enable */ 61*f3a72e40SRuslan Bukin #define CHCFG_TRIG (1 << 6) /* Channel Trigger Enable */ 62*f3a72e40SRuslan Bukin #define CHCFG_SOURCE_MASK 0x3f /* Channel Source (Slot) */ 63*f3a72e40SRuslan Bukin #define CHCFG_SOURCE_SHIFT 0 64*f3a72e40SRuslan Bukin 65*f3a72e40SRuslan Bukin struct dmamux_softc { 66*f3a72e40SRuslan Bukin struct resource *res[4]; 67*f3a72e40SRuslan Bukin bus_space_tag_t bst[4]; 68*f3a72e40SRuslan Bukin bus_space_handle_t bsh[4]; 69*f3a72e40SRuslan Bukin }; 70*f3a72e40SRuslan Bukin 71*f3a72e40SRuslan Bukin struct dmamux_softc *dmamux_sc; 72*f3a72e40SRuslan Bukin 73*f3a72e40SRuslan Bukin static struct resource_spec dmamux_spec[] = { 74*f3a72e40SRuslan Bukin { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* DMAMUX0 */ 75*f3a72e40SRuslan Bukin { SYS_RES_MEMORY, 1, RF_ACTIVE }, /* DMAMUX1 */ 76*f3a72e40SRuslan Bukin { SYS_RES_MEMORY, 2, RF_ACTIVE }, /* DMAMUX2 */ 77*f3a72e40SRuslan Bukin { SYS_RES_MEMORY, 3, RF_ACTIVE }, /* DMAMUX3 */ 78*f3a72e40SRuslan Bukin { -1, 0 } 79*f3a72e40SRuslan Bukin }; 80*f3a72e40SRuslan Bukin 81*f3a72e40SRuslan Bukin static int 82*f3a72e40SRuslan Bukin dmamux_probe(device_t dev) 83*f3a72e40SRuslan Bukin { 84*f3a72e40SRuslan Bukin 85*f3a72e40SRuslan Bukin if (!ofw_bus_status_okay(dev)) 86*f3a72e40SRuslan Bukin return (ENXIO); 87*f3a72e40SRuslan Bukin 88*f3a72e40SRuslan Bukin if (!ofw_bus_is_compatible(dev, "fsl,mvf600-dmamux")) 89*f3a72e40SRuslan Bukin return (ENXIO); 90*f3a72e40SRuslan Bukin 91*f3a72e40SRuslan Bukin device_set_desc(dev, "Vybrid Family Direct Memory Access Multiplexer"); 92*f3a72e40SRuslan Bukin return (BUS_PROBE_DEFAULT); 93*f3a72e40SRuslan Bukin } 94*f3a72e40SRuslan Bukin 95*f3a72e40SRuslan Bukin int 96*f3a72e40SRuslan Bukin dmamux_configure(int mux, int source, int channel, int enable) 97*f3a72e40SRuslan Bukin { 98*f3a72e40SRuslan Bukin struct dmamux_softc *sc; 99*f3a72e40SRuslan Bukin int reg; 100*f3a72e40SRuslan Bukin 101*f3a72e40SRuslan Bukin sc = dmamux_sc; 102*f3a72e40SRuslan Bukin 103*f3a72e40SRuslan Bukin MUX_WRITE1(sc, mux, DMAMUX_CHCFG(channel), 0x0); 104*f3a72e40SRuslan Bukin 105*f3a72e40SRuslan Bukin reg = 0; 106*f3a72e40SRuslan Bukin if (enable) 107*f3a72e40SRuslan Bukin reg |= (CHCFG_ENBL); 108*f3a72e40SRuslan Bukin 109*f3a72e40SRuslan Bukin reg &= ~(CHCFG_SOURCE_MASK << CHCFG_SOURCE_SHIFT); 110*f3a72e40SRuslan Bukin reg |= (source << CHCFG_SOURCE_SHIFT); 111*f3a72e40SRuslan Bukin 112*f3a72e40SRuslan Bukin MUX_WRITE1(sc, mux, DMAMUX_CHCFG(channel), reg); 113*f3a72e40SRuslan Bukin 114*f3a72e40SRuslan Bukin return (0); 115*f3a72e40SRuslan Bukin } 116*f3a72e40SRuslan Bukin 117*f3a72e40SRuslan Bukin static int 118*f3a72e40SRuslan Bukin dmamux_attach(device_t dev) 119*f3a72e40SRuslan Bukin { 120*f3a72e40SRuslan Bukin struct dmamux_softc *sc; 121*f3a72e40SRuslan Bukin int i; 122*f3a72e40SRuslan Bukin 123*f3a72e40SRuslan Bukin sc = device_get_softc(dev); 124*f3a72e40SRuslan Bukin 125*f3a72e40SRuslan Bukin if (bus_alloc_resources(dev, dmamux_spec, sc->res)) { 126*f3a72e40SRuslan Bukin device_printf(dev, "could not allocate resources\n"); 127*f3a72e40SRuslan Bukin return (ENXIO); 128*f3a72e40SRuslan Bukin } 129*f3a72e40SRuslan Bukin 130*f3a72e40SRuslan Bukin /* Memory interface */ 131*f3a72e40SRuslan Bukin for (i = 0; i < 4; i++) { 132*f3a72e40SRuslan Bukin sc->bst[i] = rman_get_bustag(sc->res[i]); 133*f3a72e40SRuslan Bukin sc->bsh[i] = rman_get_bushandle(sc->res[i]); 134*f3a72e40SRuslan Bukin } 135*f3a72e40SRuslan Bukin 136*f3a72e40SRuslan Bukin dmamux_sc = sc; 137*f3a72e40SRuslan Bukin 138*f3a72e40SRuslan Bukin return (0); 139*f3a72e40SRuslan Bukin } 140*f3a72e40SRuslan Bukin 141*f3a72e40SRuslan Bukin static device_method_t dmamux_methods[] = { 142*f3a72e40SRuslan Bukin DEVMETHOD(device_probe, dmamux_probe), 143*f3a72e40SRuslan Bukin DEVMETHOD(device_attach, dmamux_attach), 144*f3a72e40SRuslan Bukin { 0, 0 } 145*f3a72e40SRuslan Bukin }; 146*f3a72e40SRuslan Bukin 147*f3a72e40SRuslan Bukin static driver_t dmamux_driver = { 148*f3a72e40SRuslan Bukin "dmamux", 149*f3a72e40SRuslan Bukin dmamux_methods, 150*f3a72e40SRuslan Bukin sizeof(struct dmamux_softc), 151*f3a72e40SRuslan Bukin }; 152*f3a72e40SRuslan Bukin 153*f3a72e40SRuslan Bukin static devclass_t dmamux_devclass; 154*f3a72e40SRuslan Bukin 155*f3a72e40SRuslan Bukin DRIVER_MODULE(dmamux, simplebus, dmamux_driver, dmamux_devclass, 0, 0); 156