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