Author: br
Date: Sat Feb  8 19:47:59 2014
New Revision: 261639
URL: http://svnweb.freebsd.org/changeset/base/261639

Log:
  Add drivers for:
  - Enhanced Direct Memory Access Controller (eDMA)
  - Direct Memory Access Multiplexer (DMAMUX)

Added:
  head/sys/arm/freescale/vybrid/vf_dmamux.c   (contents, props changed)
  head/sys/arm/freescale/vybrid/vf_dmamux.h   (contents, props changed)
  head/sys/arm/freescale/vybrid/vf_edma.c   (contents, props changed)
  head/sys/arm/freescale/vybrid/vf_edma.h   (contents, props changed)
Modified:
  head/sys/arm/freescale/vybrid/files.vybrid
  head/sys/boot/fdt/dts/vybrid.dtsi

Modified: head/sys/arm/freescale/vybrid/files.vybrid
==============================================================================
--- head/sys/arm/freescale/vybrid/files.vybrid  Sat Feb  8 16:37:54 2014        
(r261638)
+++ head/sys/arm/freescale/vybrid/files.vybrid  Sat Feb  8 19:47:59 2014        
(r261639)
@@ -21,6 +21,8 @@ arm/freescale/vybrid/vf_anadig.c              standa
 arm/freescale/vybrid/vf_iomuxc.c               standard
 arm/freescale/vybrid/vf_mscm.c                 standard
 arm/freescale/vybrid/vf_src.c                  standard
+arm/freescale/vybrid/vf_edma.c                 standard
+arm/freescale/vybrid/vf_dmamux.c               standard
 arm/freescale/vybrid/vf_tcon.c                 optional        vt
 arm/freescale/vybrid/vf_dcu4.c                 optional        vt
 arm/freescale/vybrid/vf_nfc.c                  optional        nand

Added: head/sys/arm/freescale/vybrid/vf_dmamux.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm/freescale/vybrid/vf_dmamux.c   Sat Feb  8 19:47:59 2014        
(r261639)
@@ -0,0 +1,155 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <b...@bsdpad.com>
+ * 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 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 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.
+ */
+
+/*
+ * Vybrid Family Direct Memory Access Multiplexer (DMAMUX)
+ * Chapter 22, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_common.h>
+#include <arm/freescale/vybrid/vf_dmamux.h>
+
+#define        DMAMUX_CHCFG(n)         (0x1 * n)       /* Channels 0-15 Cfg 
Reg */
+#define        CHCFG_ENBL              (1 << 7)        /* Channel Enable */
+#define        CHCFG_TRIG              (1 << 6)        /* Channel Trigger 
Enable */
+#define        CHCFG_SOURCE_MASK       0x3f            /* Channel Source 
(Slot) */
+#define        CHCFG_SOURCE_SHIFT      0
+
+struct dmamux_softc {
+       struct resource         *res[4];
+       bus_space_tag_t         bst[4];
+       bus_space_handle_t      bsh[4];
+};
+
+struct dmamux_softc *dmamux_sc;
+
+static struct resource_spec dmamux_spec[] = {
+       { SYS_RES_MEMORY,       0,      RF_ACTIVE }, /* DMAMUX0 */
+       { SYS_RES_MEMORY,       1,      RF_ACTIVE }, /* DMAMUX1 */
+       { SYS_RES_MEMORY,       2,      RF_ACTIVE }, /* DMAMUX2 */
+       { SYS_RES_MEMORY,       3,      RF_ACTIVE }, /* DMAMUX3 */
+       { -1, 0 }
+};
+
+static int
+dmamux_probe(device_t dev)
+{
+
+       if (!ofw_bus_status_okay(dev))
+               return (ENXIO);
+
+       if (!ofw_bus_is_compatible(dev, "fsl,mvf600-dmamux"))
+               return (ENXIO);
+
+       device_set_desc(dev, "Vybrid Family Direct Memory Access Multiplexer");
+       return (BUS_PROBE_DEFAULT);
+}
+
+int
+dmamux_configure(int mux, int source, int channel, int enable)
+{
+       struct dmamux_softc *sc;
+       int reg;
+
+       sc = dmamux_sc;
+
+       MUX_WRITE1(sc, mux, DMAMUX_CHCFG(channel), 0x0);
+
+       reg = 0;
+       if (enable)
+               reg |= (CHCFG_ENBL);
+
+       reg &= ~(CHCFG_SOURCE_MASK << CHCFG_SOURCE_SHIFT);
+       reg |= (source << CHCFG_SOURCE_SHIFT);
+
+       MUX_WRITE1(sc, mux, DMAMUX_CHCFG(channel), reg);
+
+       return (0);
+}
+
+static int
+dmamux_attach(device_t dev)
+{
+       struct dmamux_softc *sc;
+       int i;
+
+       sc = device_get_softc(dev);
+
+       if (bus_alloc_resources(dev, dmamux_spec, sc->res)) {
+               device_printf(dev, "could not allocate resources\n");
+               return (ENXIO);
+       }
+
+       /* Memory interface */
+       for (i = 0; i < 4; i++) {
+               sc->bst[i] = rman_get_bustag(sc->res[i]);
+               sc->bsh[i] = rman_get_bushandle(sc->res[i]);
+       }
+
+       dmamux_sc = sc;
+
+       return (0);
+}
+
+static device_method_t dmamux_methods[] = {
+       DEVMETHOD(device_probe,         dmamux_probe),
+       DEVMETHOD(device_attach,        dmamux_attach),
+       { 0, 0 }
+};
+
+static driver_t dmamux_driver = {
+       "dmamux",
+       dmamux_methods,
+       sizeof(struct dmamux_softc),
+};
+
+static devclass_t dmamux_devclass;
+
+DRIVER_MODULE(dmamux, simplebus, dmamux_driver, dmamux_devclass, 0, 0);

Added: head/sys/arm/freescale/vybrid/vf_dmamux.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm/freescale/vybrid/vf_dmamux.h   Sat Feb  8 19:47:59 2014        
(r261639)
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <b...@bsdpad.com>
+ * 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 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 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.
+ *
+ * $FreeBSD$
+ */
+
+int dmamux_configure(int mux, int source, int channel, int enable);
+
+enum mux_num {
+       MUX0,
+       MUX1,
+       MUX2,
+       MUX3,
+};
+
+enum mux_grp {
+       MUXGRP0, /* MUX[0,3] */
+       MUXGRP1, /* MUX[1,2] */
+};
+
+/* DMAMUX */
+#define        MUX_READ1(_sc, _mux, _reg)                              \
+       bus_space_read_1(_sc->bst[_mux], _sc->bsh[_mux], _reg)
+
+#define        MUX_WRITE1(_sc, _mux, _reg, _val)                       \
+       bus_space_write_1(_sc->bst[_mux], _sc->bsh[_mux], _reg, _val)

Added: head/sys/arm/freescale/vybrid/vf_edma.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm/freescale/vybrid/vf_edma.c     Sat Feb  8 19:47:59 2014        
(r261639)
@@ -0,0 +1,338 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <b...@bsdpad.com>
+ * 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 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 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.
+ */
+
+/*
+ * Vybrid Family Enhanced Direct Memory Access Controller (eDMA)
+ * Chapter 21, Vybrid Reference Manual, Rev. 5, 07/2013
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/freescale/vybrid/vf_edma.h>
+#include <arm/freescale/vybrid/vf_dmamux.h>
+#include <arm/freescale/vybrid/vf_common.h>
+
+struct edma_channel {
+       uint32_t        enabled;
+       uint32_t        mux_num;
+       uint32_t        mux_src;
+       uint32_t        mux_chn;
+       uint32_t        (*ih) (void *, int);
+       void            *ih_user;
+};
+
+static struct edma_channel edma_map[EDMA_NUM_CHANNELS];
+
+static struct resource_spec edma_spec[] = {
+       { SYS_RES_MEMORY,       0,      RF_ACTIVE },
+       { SYS_RES_MEMORY,       1,      RF_ACTIVE }, /* TCD */
+       { SYS_RES_IRQ,          0,      RF_ACTIVE }, /* Transfer complete */
+       { SYS_RES_IRQ,          1,      RF_ACTIVE }, /* Error Interrupt */
+       { -1, 0 }
+};
+
+static int
+edma_probe(device_t dev)
+{
+
+       if (!ofw_bus_status_okay(dev))
+               return (ENXIO);
+
+       if (!ofw_bus_is_compatible(dev, "fsl,mvf600-edma"))
+               return (ENXIO);
+
+       device_set_desc(dev, "Vybrid Family eDMA Controller");
+       return (BUS_PROBE_DEFAULT);
+}
+
+static void
+edma_transfer_complete_intr(void *arg)
+{
+       struct edma_channel *ch;
+       struct edma_softc *sc;
+       int interrupts;
+       int i;
+
+       sc = arg;
+
+       interrupts = READ4(sc, DMA_INT);
+       WRITE1(sc, DMA_CINT, CINT_CAIR);
+
+       for (i = 0; i < EDMA_NUM_CHANNELS; i++) {
+               if (interrupts & (0x1 << i)) {
+                       ch = &edma_map[i];
+                       if (ch->enabled == 1) {
+                               if (ch->ih != NULL) {
+                                       ch->ih(ch->ih_user, i);
+                               }
+                       }
+               }
+       }
+}
+
+static void
+edma_err_intr(void *arg)
+{
+       struct edma_softc *sc;
+       int reg;
+
+       sc = arg;
+
+       reg = READ4(sc, DMA_ERR);
+
+#if 0
+       device_printf(sc->dev, "DMA_ERR 0x%08x, ES 0x%08x\n",
+           reg, READ4(sc, DMA_ES));
+#endif
+
+       WRITE1(sc, DMA_CERR, CERR_CAEI);
+}
+
+static int
+channel_free(struct edma_softc *sc, int chnum)
+{
+       struct edma_channel *ch;
+
+       ch = &edma_map[chnum];
+       ch->enabled = 0;
+
+       dmamux_configure(ch->mux_num, ch->mux_src, ch->mux_chn, 0);
+
+       return (0);
+}
+
+static int
+channel_configure(struct edma_softc *sc, int mux_grp, int mux_src)
+{
+       struct edma_channel *ch;
+       int channel_first;
+       int mux_num;
+       int chnum;
+       int i;
+
+       if ((sc->device_id == 0 && mux_grp == 1) ||     \
+           (sc->device_id == 1 && mux_grp == 0)) {
+               channel_first = NCHAN_PER_MUX;
+               mux_num = (sc->device_id * 2) + 1;
+       } else {
+               channel_first = 0;
+               mux_num = sc->device_id * 2;
+       };
+
+       /* Take first unused eDMA channel */
+       ch = NULL;
+       for (i = channel_first; i < (channel_first + NCHAN_PER_MUX); i++) {
+               ch = &edma_map[i];
+               if (ch->enabled == 0) {
+                       break;
+               }
+               ch = NULL;
+       };
+
+       if (ch == NULL) {
+               /* Can't find free channel */
+               return (-1);
+       };
+
+       chnum = i;
+
+       ch->enabled = 1;
+       ch->mux_num = mux_num;
+       ch->mux_src = mux_src;
+       ch->mux_chn = (chnum - channel_first);  /* 0 to 15 */
+
+       dmamux_configure(ch->mux_num, ch->mux_src, ch->mux_chn, 1);
+
+       return (chnum);
+}
+
+static int
+dma_stop(struct edma_softc *sc, int chnum)
+{
+       int reg;
+
+       reg = READ4(sc, DMA_ERQ);
+       reg &= ~(0x1 << chnum);
+       WRITE4(sc, DMA_ERQ, reg);
+
+       return (0);
+}
+
+static int
+dma_setup(struct edma_softc *sc, struct tcd_conf *tcd)
+{
+       struct edma_channel *ch;
+       int chnum;
+       int reg;
+
+       chnum = tcd->channel;
+
+       ch = &edma_map[chnum];
+       ch->ih = tcd->ih;
+       ch->ih_user = tcd->ih_user;
+
+       TCD_WRITE4(sc, DMA_TCDn_SADDR(chnum), tcd->saddr);
+       TCD_WRITE4(sc, DMA_TCDn_DADDR(chnum), tcd->daddr);
+
+       reg = (tcd->smod << TCD_ATTR_SMOD_SHIFT);
+       reg |= (tcd->dmod << TCD_ATTR_DMOD_SHIFT);
+       reg |= (tcd->ssize << TCD_ATTR_SSIZE_SHIFT);
+       reg |= (tcd->dsize << TCD_ATTR_DSIZE_SHIFT);
+       TCD_WRITE2(sc, DMA_TCDn_ATTR(chnum), reg);
+
+       TCD_WRITE2(sc, DMA_TCDn_SOFF(chnum), tcd->soff);
+       TCD_WRITE2(sc, DMA_TCDn_DOFF(chnum), tcd->doff);
+       TCD_WRITE4(sc, DMA_TCDn_SLAST(chnum), tcd->slast);
+       TCD_WRITE4(sc, DMA_TCDn_DLASTSGA(chnum), tcd->dlast_sga);
+       TCD_WRITE4(sc, DMA_TCDn_NBYTES_MLOFFYES(chnum), tcd->nbytes);
+
+       reg = tcd->nmajor; /* Current Major Iteration Count */
+       TCD_WRITE2(sc, DMA_TCDn_CITER_ELINKNO(chnum), reg);
+       TCD_WRITE2(sc, DMA_TCDn_BITER_ELINKNO(chnum), reg);
+
+       reg = (TCD_CSR_INTMAJOR);
+       if(tcd->majorelink == 1) {
+               reg |= TCD_CSR_MAJORELINK;
+               reg |= (tcd->majorelinkch << TCD_CSR_MAJORELINKCH_SHIFT);
+       }
+       TCD_WRITE2(sc, DMA_TCDn_CSR(chnum), reg);
+
+       /* Enable requests */
+       reg = READ4(sc, DMA_ERQ);
+       reg |= (0x1 << chnum);
+       WRITE4(sc, DMA_ERQ, reg);
+
+       /* Enable error interrupts */
+       reg = READ4(sc, DMA_EEI);
+       reg |= (0x1 << chnum);
+       WRITE4(sc, DMA_EEI, reg);
+
+       return (0);
+}
+
+static int
+dma_request(struct edma_softc *sc, int chnum)
+{
+       int reg;
+
+       /* Start */
+       reg = TCD_READ2(sc, DMA_TCDn_CSR(chnum));
+       reg |= TCD_CSR_START;
+       TCD_WRITE2(sc, DMA_TCDn_CSR(chnum), reg);
+
+       return (0);
+}
+
+static int
+edma_attach(device_t dev)
+{
+       struct edma_softc *sc;
+       phandle_t node;
+       int dts_value;
+       int len;
+
+       sc = device_get_softc(dev);
+       sc->dev = dev;
+
+       if ((node = ofw_bus_get_node(sc->dev)) == -1)
+               return (ENXIO);
+
+       if ((len = OF_getproplen(node, "device-id")) <= 0)
+               return (ENXIO);
+
+       OF_getprop(node, "device-id", &dts_value, len);
+       sc->device_id = fdt32_to_cpu(dts_value);
+
+       sc->dma_stop = dma_stop;
+       sc->dma_setup = dma_setup;
+       sc->dma_request = dma_request;
+       sc->channel_configure = channel_configure;
+       sc->channel_free = channel_free;
+
+       if (bus_alloc_resources(dev, edma_spec, sc->res)) {
+               device_printf(dev, "could not allocate resources\n");
+               return (ENXIO);
+       }
+
+       /* Memory interface */
+       sc->bst = rman_get_bustag(sc->res[0]);
+       sc->bsh = rman_get_bushandle(sc->res[0]);
+       sc->bst_tcd = rman_get_bustag(sc->res[1]);
+       sc->bsh_tcd = rman_get_bushandle(sc->res[1]);
+
+       /* Setup interrupt handlers */
+       if (bus_setup_intr(dev, sc->res[2], INTR_TYPE_BIO | INTR_MPSAFE,
+               NULL, edma_transfer_complete_intr, sc, &sc->tc_ih)) {
+               device_printf(dev, "Unable to alloc DMA intr resource.\n");
+               return (ENXIO);
+       }
+
+       if (bus_setup_intr(dev, sc->res[3], INTR_TYPE_BIO | INTR_MPSAFE,
+               NULL, edma_err_intr, sc, &sc->err_ih)) {
+               device_printf(dev, "Unable to alloc DMA Err intr resource.\n");
+               return (ENXIO);
+       }
+
+       return (0);
+}
+
+static device_method_t edma_methods[] = {
+       DEVMETHOD(device_probe,         edma_probe),
+       DEVMETHOD(device_attach,        edma_attach),
+       { 0, 0 }
+};
+
+static driver_t edma_driver = {
+       "edma",
+       edma_methods,
+       sizeof(struct edma_softc),
+};
+
+static devclass_t edma_devclass;
+
+DRIVER_MODULE(edma, simplebus, edma_driver, edma_devclass, 0, 0);

Added: head/sys/arm/freescale/vybrid/vf_edma.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm/freescale/vybrid/vf_edma.h     Sat Feb  8 19:47:59 2014        
(r261639)
@@ -0,0 +1,186 @@
+/*-
+ * Copyright (c) 2014 Ruslan Bukin <b...@bsdpad.com>
+ * 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 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 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.
+ *
+ * $FreeBSD$
+ */
+
+#define        DMA_CR          0x000   /* Control */
+#define        DMA_ES          0x004   /* Error Status */
+#define        DMA_ERQ         0x00C   /* Enable Request */
+#define        DMA_EEI         0x014   /* Enable Error Interrupt */
+#define        DMA_CEEI        0x018   /* Clear Enable Error Interrupt */
+#define        DMA_SEEI        0x019   /* Set Enable Error Interrupt */
+#define        DMA_CERQ        0x01A   /* Clear Enable Request */
+#define        DMA_SERQ        0x01B   /* Set Enable Request */
+#define        DMA_CDNE        0x01C   /* Clear DONE Status Bit */
+#define        DMA_SSRT        0x01D   /* Set START Bit */
+#define        DMA_CERR        0x01E   /* Clear Error */
+#define         CERR_CAEI      (1 << 6) /* Clear All Error Indicators */
+#define        DMA_CINT        0x01F   /* Clear Interrupt Request */
+#define         CINT_CAIR      (1 << 6) /* Clear All Interrupt Requests */
+#define        DMA_INT         0x024   /* Interrupt Request */
+#define        DMA_ERR         0x02C   /* Error */
+#define        DMA_HRS         0x034   /* Hardware Request Status */
+#define        DMA_EARS        0x044   /* Enable Asynchronous Request in Stop 
*/
+#define        DMA_DCHPRI3     0x100   /* Channel n Priority */
+#define        DMA_DCHPRI2     0x101   /* Channel n Priority */
+#define        DMA_DCHPRI1     0x102   /* Channel n Priority */
+#define        DMA_DCHPRI0     0x103   /* Channel n Priority */
+#define        DMA_DCHPRI7     0x104   /* Channel n Priority */
+#define        DMA_DCHPRI6     0x105   /* Channel n Priority */
+#define        DMA_DCHPRI5     0x106   /* Channel n Priority */
+#define        DMA_DCHPRI4     0x107   /* Channel n Priority */
+#define        DMA_DCHPRI11    0x108   /* Channel n Priority */
+#define        DMA_DCHPRI10    0x109   /* Channel n Priority */
+#define        DMA_DCHPRI9     0x10A   /* Channel n Priority */
+#define        DMA_DCHPRI8     0x10B   /* Channel n Priority */
+#define        DMA_DCHPRI15    0x10C   /* Channel n Priority */
+#define        DMA_DCHPRI14    0x10D   /* Channel n Priority */
+#define        DMA_DCHPRI13    0x10E   /* Channel n Priority */
+#define        DMA_DCHPRI12    0x10F   /* Channel n Priority */
+#define        DMA_DCHPRI19    0x110   /* Channel n Priority */
+#define        DMA_DCHPRI18    0x111   /* Channel n Priority */
+#define        DMA_DCHPRI17    0x112   /* Channel n Priority */
+#define        DMA_DCHPRI16    0x113   /* Channel n Priority */
+#define        DMA_DCHPRI23    0x114   /* Channel n Priority */
+#define        DMA_DCHPRI22    0x115   /* Channel n Priority */
+#define        DMA_DCHPRI21    0x116   /* Channel n Priority */
+#define        DMA_DCHPRI20    0x117   /* Channel n Priority */
+#define        DMA_DCHPRI27    0x118   /* Channel n Priority */
+#define        DMA_DCHPRI26    0x119   /* Channel n Priority */
+#define        DMA_DCHPRI25    0x11A   /* Channel n Priority */
+#define        DMA_DCHPRI24    0x11B   /* Channel n Priority */
+#define        DMA_DCHPRI31    0x11C   /* Channel n Priority */
+#define        DMA_DCHPRI30    0x11D   /* Channel n Priority */
+#define        DMA_DCHPRI29    0x11E   /* Channel n Priority */
+#define        DMA_DCHPRI28    0x11F   /* Channel n Priority */
+
+#define        DMA_TCDn_SADDR(n)               (0x00 + 0x20 * n)       /* 
Source Address */
+#define        DMA_TCDn_SOFF(n)                (0x04 + 0x20 * n)       /* 
Signed Source Address Offset */
+#define        DMA_TCDn_ATTR(n)                (0x06 + 0x20 * n)       /* 
Transfer Attributes */
+#define        DMA_TCDn_NBYTES_MLNO(n)         (0x08 + 0x20 * n)       /* 
Minor Byte Count */
+#define        DMA_TCDn_NBYTES_MLOFFNO(n)      (0x08 + 0x20 * n)       /* 
Signed Minor Loop Offset */
+#define        DMA_TCDn_NBYTES_MLOFFYES(n)     (0x08 + 0x20 * n)       /* 
Signed Minor Loop Offset */
+#define        DMA_TCDn_SLAST(n)               (0x0C + 0x20 * n)       /* Last 
Source Address Adjustment */
+#define        DMA_TCDn_DADDR(n)               (0x10 + 0x20 * n)       /* 
Destination Address */
+#define        DMA_TCDn_DOFF(n)                (0x14 + 0x20 * n)       /* 
Signed Destination Address Offset */
+#define        DMA_TCDn_CITER_ELINKYES(n)      (0x16 + 0x20 * n)       /* 
Current Minor Loop Link, Major Loop Count */
+#define        DMA_TCDn_CITER_ELINKNO(n)       (0x16 + 0x20 * n)
+#define        DMA_TCDn_DLASTSGA(n)            (0x18 + 0x20 * n)       /* Last 
Dst Addr Adjustment/Scatter Gather Address */
+#define        DMA_TCDn_CSR(n)                 (0x1C + 0x20 * n)       /* 
Control and Status */
+#define        DMA_TCDn_BITER_ELINKYES(n)      (0x1E + 0x20 * n)       /* 
Beginning Minor Loop Link, Major Loop Count */
+#define        DMA_TCDn_BITER_ELINKNO(n)       (0x1E + 0x20 * n)       /* 
Beginning Minor Loop Link, Major Loop Count */
+
+#define TCD_CSR_START                  (1 << 0)
+#define        TCD_CSR_INTMAJOR                (1 << 1)
+#define        TCD_CSR_INTHALF                 (1 << 2)
+#define        TCD_CSR_DREQ                    (1 << 3)
+#define        TCD_CSR_ESG                     (1 << 4)
+#define        TCD_CSR_MAJORELINK              (1 << 5)
+#define        TCD_CSR_ACTIVE                  (1 << 6)
+#define        TCD_CSR_DONE                    (1 << 7)
+#define        TCD_CSR_MAJORELINKCH_SHIFT      8
+
+#define        TCD_ATTR_SMOD_SHIFT             11      /* Source Address 
Modulo */
+#define        TCD_ATTR_SSIZE_SHIFT            8       /* Source Data Transfer 
Size */
+#define        TCD_ATTR_DMOD_SHIFT             3       /* Dst Address Modulo */
+#define        TCD_ATTR_DSIZE_SHIFT            0       /* Dst Data Transfer 
Size */
+
+#define        TCD_READ4(_sc, _reg)            \
+       bus_space_read_4(_sc->bst_tcd, _sc->bsh_tcd, _reg)
+#define        TCD_WRITE4(_sc, _reg, _val)     \
+       bus_space_write_4(_sc->bst_tcd, _sc->bsh_tcd, _reg, _val)
+#define        TCD_READ2(_sc, _reg)            \
+       bus_space_read_2(_sc->bst_tcd, _sc->bsh_tcd, _reg)
+#define        TCD_WRITE2(_sc, _reg, _val)     \
+       bus_space_write_2(_sc->bst_tcd, _sc->bsh_tcd, _reg, _val)
+#define        TCD_READ1(_sc, _reg)            \
+       bus_space_read_1(_sc->bst_tcd, _sc->bsh_tcd, _reg)
+#define        TCD_WRITE1(_sc, _reg, _val)     \
+       bus_space_write_1(_sc->bst_tcd, _sc->bsh_tcd, _reg, _val)
+
+#define        EDMA_NUM_DEVICES        2
+#define        EDMA_NUM_CHANNELS       32
+#define        NCHAN_PER_MUX           16
+
+struct tcd_conf {
+       bus_addr_t      saddr;
+       bus_addr_t      daddr;
+       uint32_t        nbytes;
+       uint32_t        nmajor;
+       uint32_t        majorelink;
+       uint32_t        majorelinkch;
+       uint32_t        esg;
+       uint32_t        smod;
+       uint32_t        dmod;
+       uint32_t        soff;
+       uint32_t        doff;
+       uint32_t        ssize;
+       uint32_t        dsize;
+       uint32_t        slast;
+       uint32_t        dlast_sga;
+       uint32_t        channel;
+       uint32_t        (*ih)(void *, int);
+       void            *ih_user;
+};
+
+/*
+ * TCD struct is described at
+ * Vybrid Reference Manual, Rev. 5, 07/2013
+ *
+ * Should be used for Scatter/Gathering feature.
+ */
+
+struct TCD {
+       uint32_t        saddr;
+       uint16_t        attr;
+       uint16_t        soff;
+       uint32_t        nbytes;
+       uint32_t        slast;
+       uint32_t        daddr;
+       uint16_t        citer;
+       uint16_t        doff;
+       uint32_t        dlast_sga;
+       uint16_t        biter;
+       uint16_t        csr;
+} __packed;
+
+struct edma_softc {
+       device_t                dev;
+       struct resource         *res[4];
+       bus_space_tag_t         bst;
+       bus_space_handle_t      bsh;
+       bus_space_tag_t         bst_tcd;
+       bus_space_handle_t      bsh_tcd;
+       void                    *tc_ih;
+       void                    *err_ih;
+       uint32_t                device_id;
+
+       int     (*channel_configure) (struct edma_softc *, int, int);
+       int     (*channel_free) (struct edma_softc *, int);
+       int     (*dma_request) (struct edma_softc *, int);
+       int     (*dma_setup) (struct edma_softc *, struct tcd_conf *);
+       int     (*dma_stop) (struct edma_softc *, int);
+};

Modified: head/sys/boot/fdt/dts/vybrid.dtsi
==============================================================================
--- head/sys/boot/fdt/dts/vybrid.dtsi   Sat Feb  8 16:37:54 2014        
(r261638)
+++ head/sys/boot/fdt/dts/vybrid.dtsi   Sat Feb  8 19:47:59 2014        
(r261639)
@@ -111,6 +111,7 @@
                              <0x40019000 0x1000>; /* TCD */
                        interrupts = < 40 41 >;
                        interrupt-parent = <&GIC>;
+                       device-id = < 0 >;
                        status = "disabled";
                };
 
@@ -120,6 +121,7 @@
                              <0x40099000 0x1000>; /* TCD */
                        interrupts = < 42 43 >;
                        interrupt-parent = <&GIC>;
+                       device-id = < 1 >;
                        status = "disabled";
                };
 
@@ -308,6 +310,7 @@
                        interrupts = < 119 >;
                        interrupt-parent = <&GIC>;
                        status = "disabled";
+                       edma-controller = <&edma1>;
                        clock_names = "sai3", "cko1";
                        iomux_config = < 16 0x2
                                         19 0x2
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to