1190207Srpaulo/*- 298524Sfenner * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> 398524Sfenner * All rights reserved. 498524Sfenner * 598524Sfenner * Redistribution and use in source and binary forms, with or without 698524Sfenner * modification, are permitted provided that the following conditions 798524Sfenner * are met: 898524Sfenner * 1. Redistributions of source code must retain the above copyright 998524Sfenner * notice, this list of conditions and the following disclaimer. 1098524Sfenner * 2. Redistributions in binary form must reproduce the above copyright 1198524Sfenner * notice, this list of conditions and the following disclaimer in the 1298524Sfenner * documentation and/or other materials provided with the distribution. 1398524Sfenner * 1498524Sfenner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1598524Sfenner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1698524Sfenner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1798524Sfenner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1898524Sfenner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1998524Sfenner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2098524Sfenner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2198524Sfenner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2298524Sfenner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2398524Sfenner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2498524Sfenner * SUCH DAMAGE. 2598524Sfenner */ 2698524Sfenner 2798524Sfenner/* 2898524Sfenner * Vybrid Family Direct Memory Access Multiplexer (DMAMUX) 2998524Sfenner * Chapter 22, Vybrid Reference Manual, Rev. 5, 07/2013 3098524Sfenner */ 3198524Sfenner 3298524Sfenner#include <sys/cdefs.h> 3398524Sfenner__FBSDID("$FreeBSD$"); 34127668Sbms 3598524Sfenner#include <sys/param.h> 3698524Sfenner#include <sys/systm.h> 37127668Sbms#include <sys/bus.h> 3898524Sfenner#include <sys/kernel.h> 3998524Sfenner#include <sys/module.h> 4098524Sfenner#include <sys/malloc.h> 41127668Sbms#include <sys/rman.h> 4298524Sfenner#include <sys/timeet.h> 4398524Sfenner#include <sys/timetc.h> 4498524Sfenner#include <sys/watchdog.h> 4598524Sfenner 4698524Sfenner#include <dev/fdt/fdt_common.h> 4798524Sfenner#include <dev/ofw/openfirm.h> 4898524Sfenner#include <dev/ofw/ofw_bus.h> 4998524Sfenner#include <dev/ofw/ofw_bus_subr.h> 5098524Sfenner 5198524Sfenner#include <machine/bus.h> 5298524Sfenner#include <machine/fdt.h> 5398524Sfenner#include <machine/cpu.h> 5498524Sfenner#include <machine/intr.h> 5598524Sfenner 5698524Sfenner#include <arm/freescale/vybrid/vf_common.h> 5798524Sfenner#include <arm/freescale/vybrid/vf_dmamux.h> 5898524Sfenner 5998524Sfenner#define DMAMUX_CHCFG(n) (0x1 * n) /* Channels 0-15 Cfg Reg */ 60127668Sbms#define CHCFG_ENBL (1 << 7) /* Channel Enable */ 6198524Sfenner#define CHCFG_TRIG (1 << 6) /* Channel Trigger Enable */ 6298524Sfenner#define CHCFG_SOURCE_MASK 0x3f /* Channel Source (Slot) */ 63127668Sbms#define CHCFG_SOURCE_SHIFT 0 64127668Sbms 65127668Sbmsstruct dmamux_softc { 66127668Sbms struct resource *res[4]; 6798524Sfenner bus_space_tag_t bst[4]; 6898524Sfenner bus_space_handle_t bsh[4]; 6998524Sfenner}; 7098524Sfenner 7198524Sfennerstruct dmamux_softc *dmamux_sc; 72127668Sbms 73127668Sbmsstatic struct resource_spec dmamux_spec[] = { 74127668Sbms { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* DMAMUX0 */ 7598524Sfenner { SYS_RES_MEMORY, 1, RF_ACTIVE }, /* DMAMUX1 */ 7698524Sfenner { SYS_RES_MEMORY, 2, RF_ACTIVE }, /* DMAMUX2 */ 7798524Sfenner { SYS_RES_MEMORY, 3, RF_ACTIVE }, /* DMAMUX3 */ 78127668Sbms { -1, 0 } 79127668Sbms}; 8098524Sfenner 8198524Sfennerstatic int 8298524Sfennerdmamux_probe(device_t dev) 8398524Sfenner{ 8498524Sfenner 85127668Sbms if (!ofw_bus_status_okay(dev)) 8698524Sfenner return (ENXIO); 8798524Sfenner 8898524Sfenner if (!ofw_bus_is_compatible(dev, "fsl,mvf600-dmamux")) 8998524Sfenner return (ENXIO); 90127668Sbms 91127668Sbms device_set_desc(dev, "Vybrid Family Direct Memory Access Multiplexer"); 92127668Sbms return (BUS_PROBE_DEFAULT); 9398524Sfenner} 9498524Sfenner 9598524Sfennerint 9698524Sfennerdmamux_configure(int mux, int source, int channel, int enable) 9798524Sfenner{ 9898524Sfenner struct dmamux_softc *sc; 9998524Sfenner int reg; 10098524Sfenner 10198524Sfenner sc = dmamux_sc; 10298524Sfenner 10398524Sfenner MUX_WRITE1(sc, mux, DMAMUX_CHCFG(channel), 0x0); 104127668Sbms 105127668Sbms reg = 0; 106127668Sbms if (enable) 107127668Sbms reg |= (CHCFG_ENBL); 108127668Sbms 10998524Sfenner reg &= ~(CHCFG_SOURCE_MASK << CHCFG_SOURCE_SHIFT); 11098524Sfenner reg |= (source << CHCFG_SOURCE_SHIFT); 11198524Sfenner 11298524Sfenner MUX_WRITE1(sc, mux, DMAMUX_CHCFG(channel), reg); 11398524Sfenner 114127668Sbms return (0); 11598524Sfenner} 11698524Sfenner 11798524Sfennerstatic int 11898524Sfennerdmamux_attach(device_t dev) 11998524Sfenner{ 120127668Sbms struct dmamux_softc *sc; 12198524Sfenner int i; 12298524Sfenner 12398524Sfenner sc = device_get_softc(dev); 12498524Sfenner 125127668Sbms if (bus_alloc_resources(dev, dmamux_spec, sc->res)) { 12698524Sfenner device_printf(dev, "could not allocate resources\n"); 12798524Sfenner return (ENXIO); 12898524Sfenner } 12998524Sfenner 13098524Sfenner /* Memory interface */ 131127668Sbms for (i = 0; i < 4; i++) { 13298524Sfenner sc->bst[i] = rman_get_bustag(sc->res[i]); 13398524Sfenner sc->bsh[i] = rman_get_bushandle(sc->res[i]); 13498524Sfenner } 13598524Sfenner 136127668Sbms dmamux_sc = sc; 137127668Sbms 13898524Sfenner return (0); 13998524Sfenner} 14098524Sfenner 14198524Sfennerstatic device_method_t dmamux_methods[] = { 142127668Sbms DEVMETHOD(device_probe, dmamux_probe), 143127668Sbms DEVMETHOD(device_attach, dmamux_attach), 144127668Sbms { 0, 0 } 14598524Sfenner}; 14698524Sfenner 147127668Sbmsstatic driver_t dmamux_driver = { 148127668Sbms "dmamux", 149127668Sbms dmamux_methods, 150127668Sbms sizeof(struct dmamux_softc), 15198524Sfenner}; 152127668Sbms 15398524Sfennerstatic devclass_t dmamux_devclass; 15498524Sfenner 15598524SfennerDRIVER_MODULE(dmamux, simplebus, dmamux_driver, dmamux_devclass, 0, 0); 15698524Sfenner