Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/omap Add a driver for the Enhanced Direct Memor...
details: https://anonhg.NetBSD.org/src/rev/7533540cf32c
branches: trunk
changeset: 337447:7533540cf32c
user: bouyer <bouyer%NetBSD.org@localhost>
date: Tue Apr 14 18:37:43 2015 +0000
description:
Add a driver for the Enhanced Direct Memory Access controller found
in the AM335x SoC. Written by Jared D. McNeill, with some final debug
by me.
Supports only DMA (not QDMA) yet, and there's no support for DMA event
matrix yet (this means that only primary DMA events can be used)
diffstat:
sys/arch/arm/omap/files.omap2 | 8 +-
sys/arch/arm/omap/omap2_obio.c | 9 +-
sys/arch/arm/omap/omap2_obiovar.h | 3 +-
sys/arch/arm/omap/omap2_reg.h | 19 +-
sys/arch/arm/omap/omap_edma.c | 578 ++++++++++++++++++++++++++++++++++++++
sys/arch/arm/omap/omap_edma.h | 173 +++++++++++
6 files changed, 782 insertions(+), 8 deletions(-)
diffs (truncated from 882 to 300 lines):
diff -r 44f57f58b159 -r 7533540cf32c sys/arch/arm/omap/files.omap2
--- a/sys/arch/arm/omap/files.omap2 Tue Apr 14 18:34:29 2015 +0000
+++ b/sys/arch/arm/omap/files.omap2 Tue Apr 14 18:37:43 2015 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.omap2,v 1.29 2014/08/22 19:44:04 jakllsch Exp $
+# $NetBSD: files.omap2,v 1.30 2015/04/14 18:37:43 bouyer Exp $
#
# Configuration info for Texas Instruments OMAP2/OMAP3 CPU support
# Based on xscale/files.pxa2x0
@@ -32,7 +32,7 @@
defflag opt_omap.h TI_DM37XX: OMAP3
# OBIO just an attach point
-device obio { [addr=-1], [size=0], [intr=-1], [mult=1], [intrbase=-1], [nobyteacc=0]
+device obio { [addr=-1], [size=0], [intr=-1], [mult=1], [intrbase=-1], [nobyteacc=0], [edmabase=-1]
} : bus_space_generic
attach obio at mainbus
file arch/arm/omap/omap2_obio.c obio needs-count
@@ -170,6 +170,10 @@
attach omapdma at obio
file arch/arm/omap/omap3_sdma.c omapdma needs-flag
+device edma
+attach edma at obio
+file arch/arm/omap/omap_edma.c edma needs-flag
+
# these bus space methods are not bus-specific ...
#
file arch/arm/omap/omap_nobyteacc_space.c emifs | gpmc
diff -r 44f57f58b159 -r 7533540cf32c sys/arch/arm/omap/omap2_obio.c
--- a/sys/arch/arm/omap/omap2_obio.c Tue Apr 14 18:34:29 2015 +0000
+++ b/sys/arch/arm/omap/omap2_obio.c Tue Apr 14 18:37:43 2015 +0000
@@ -1,7 +1,7 @@
-/* $Id: omap2_obio.c,v 1.21 2013/06/15 21:58:20 matt Exp $ */
+/* $Id: omap2_obio.c,v 1.22 2015/04/14 18:37:43 bouyer Exp $ */
/* adapted from: */
-/* $NetBSD: omap2_obio.c,v 1.21 2013/06/15 21:58:20 matt Exp $ */
+/* $NetBSD: omap2_obio.c,v 1.22 2015/04/14 18:37:43 bouyer Exp $ */
/*
@@ -103,7 +103,7 @@
#include "opt_omap.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: omap2_obio.c,v 1.21 2013/06/15 21:58:20 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: omap2_obio.c,v 1.22 2015/04/14 18:37:43 bouyer Exp $");
#include "locators.h"
#include "obio.h"
@@ -284,6 +284,7 @@
oa.obio_size = cf->cf_loc[OBIOCF_SIZE];
oa.obio_intr = cf->cf_loc[OBIOCF_INTR];
oa.obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE];
+ oa.obio_edmabase = cf->cf_loc[OBIOCF_EDMABASE];
#if defined(OMAP2)
if ((oa.obio_addr >= sc->sc_base)
@@ -351,6 +352,7 @@
oa->obio_size = cf->cf_loc[OBIOCF_SIZE];
oa->obio_intr = cf->cf_loc[OBIOCF_INTR];
oa->obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE];
+ oa->obio_edmabase = cf->cf_loc[OBIOCF_EDMABASE];
return config_match(parent, cf, oa);
}
@@ -398,6 +400,7 @@
{ .name = "omapicu", .addr = 0x48200000, .required = true },
{ .name = "prcm", .addr = 0x44e00000, .required = true },
{ .name = "sitaracm", .addr = 0x44e10000, .required = true },
+ { .name = "edma", .addr = 0x49000000, .required = false },
#endif
#if defined(OMAP_3530)
{ .name = "omapdma", .addr = OMAP3530_SDMA_BASE, .required = true },
diff -r 44f57f58b159 -r 7533540cf32c sys/arch/arm/omap/omap2_obiovar.h
--- a/sys/arch/arm/omap/omap2_obiovar.h Tue Apr 14 18:34:29 2015 +0000
+++ b/sys/arch/arm/omap/omap2_obiovar.h Tue Apr 14 18:37:43 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: omap2_obiovar.h,v 1.2 2012/09/05 00:19:59 matt Exp $ */
+/* $NetBSD: omap2_obiovar.h,v 1.3 2015/04/14 18:37:43 bouyer Exp $ */
/*
* Copyright (c) 2007 Microsoft
@@ -40,6 +40,7 @@
bus_dma_tag_t obio_dmat;
unsigned int obio_mult;
unsigned int obio_intrbase;
+ int obio_edmabase;
};
struct obio_softc {
diff -r 44f57f58b159 -r 7533540cf32c sys/arch/arm/omap/omap2_reg.h
--- a/sys/arch/arm/omap/omap2_reg.h Tue Apr 14 18:34:29 2015 +0000
+++ b/sys/arch/arm/omap/omap2_reg.h Tue Apr 14 18:37:43 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: omap2_reg.h,v 1.28 2014/07/20 23:08:43 bouyer Exp $ */
+/* $NetBSD: omap2_reg.h,v 1.29 2015/04/14 18:37:43 bouyer Exp $ */
/*
* Copyright (c) 2007 Microsoft
@@ -896,5 +896,20 @@
#define SDRAM_CONFIG_EBANK __BIT(3)
#define SDRAM_CONFIG_PAGESIZE __BITS(2,0)
#endif
-
+
+/* EDMA3 */
+#define AM335X_TPCC_BASE 0x49000000
+#define AM335X_TPCC_SIZE 0x00100000
+#define AM335X_TPTC0_BASE 0x49800000
+#define AM335X_TPTC0_SIZE 0x00100000
+#define AM335X_TPTC1_BASE 0x49900000
+#define AM335X_TPTC1_SIZE 0x00100000
+#define AM335X_TPTC2_BASE 0x49a00000
+#define AM335X_TPTC2_SIZE 0x00100000
+#define AM335X_INT_EDMACOMPINT 12
+#define AM335X_INT_EDMAMPERR 13
+#define AM335X_INT_EDMAERRINT 14
+#define AM335X_INT_TCERRINT0 112
+#define AM335X_INT_TCERRINT1 113
+#define AM335X_INT_TCERRINT2 114
#endif /* _ARM_OMAP_OMAP2_REG_H_ */
diff -r 44f57f58b159 -r 7533540cf32c sys/arch/arm/omap/omap_edma.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/omap/omap_edma.c Tue Apr 14 18:37:43 2015 +0000
@@ -0,0 +1,578 @@
+/* $NetBSD: omap_edma.c,v 1.1 2015/04/14 18:37:43 bouyer Exp $ */
+
+/*-
+ * Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: omap_edma.c,v 1.1 2015/04/14 18:37:43 bouyer Exp $");
+
+#include "opt_omap.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/conf.h>
+#include <sys/intr.h>
+#include <sys/mutex.h>
+#include <sys/bus.h>
+#include <sys/bitops.h>
+
+#include <arm/omap/am335x_prcm.h>
+#include <arm/omap/omap2_prcm.h>
+#include <arm/omap/sitara_cm.h>
+#include <arm/omap/sitara_cmreg.h>
+
+#include <arm/omap/omap2_reg.h>
+#include <arm/omap/omap2_obiovar.h>
+#include <arm/omap/omap_edma.h>
+
+#ifdef TI_AM335X
+static const struct omap_module edma3cc_module =
+ { AM335X_PRCM_CM_PER, CM_PER_TPCC_CLKCTRL };
+static const struct omap_module edma3tc0_module =
+ { AM335X_PRCM_CM_PER, CM_PER_TPTC0_CLKCTRL };
+static const struct omap_module edma3tc1_module =
+ { AM335X_PRCM_CM_PER, CM_PER_TPTC1_CLKCTRL };
+static const struct omap_module edma3tc2_module =
+ { AM335X_PRCM_CM_PER, CM_PER_TPTC2_CLKCTRL };
+#endif
+
+#define NUM_DMA_CHANNELS 64
+#define NUM_PARAM_SETS 256
+#define MAX_PARAM_PER_CHANNEL 32
+
+#ifdef EDMA_DEBUG
+int edmadebug = 1;
+#define DPRINTF(n,s) do { if ((n) <= edmadebug) device_printf s; } while (0)
+#else
+#define DPRINTF(n,s) do {} while (0)
+#endif
+
+struct edma_softc;
+
+struct edma_channel {
+ struct edma_softc *ch_sc;
+ enum edma_type ch_type;
+ uint8_t ch_index;
+ void (*ch_callback)(void *);
+ void *ch_callbackarg;
+ unsigned int ch_nparams;
+};
+
+struct edma_softc {
+ device_t sc_dev;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+ kmutex_t sc_lock;
+ struct edma_channel sc_dma[NUM_DMA_CHANNELS];
+
+ void *sc_ih;
+ void *sc_mperr_ih;
+ void *sc_errint_ih;
+
+ uint32_t sc_dmamask[NUM_DMA_CHANNELS / 32];
+ uint32_t sc_parammask[NUM_PARAM_SETS / 32];
+};
+
+static int edma_match(device_t, cfdata_t, void *);
+static void edma_attach(device_t, device_t, void *);
+
+static void edma_init(struct edma_softc *);
+static int edma_intr(void *);
+static int edma_mperr_intr(void *);
+static int edma_errint_intr(void *);
+static void edma_write_param(struct edma_softc *,
+ unsigned int, const struct edma_param *);
+static bool edma_bit_isset(uint32_t *, unsigned int);
+static void edma_bit_set(uint32_t *, unsigned int);
+static void edma_bit_clr(uint32_t *, unsigned int);
+
+CFATTACH_DECL_NEW(edma, sizeof(struct edma_softc),
+ edma_match, edma_attach, NULL, NULL);
+
+#define EDMA_READ(sc, reg) \
+ bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))
+#define EDMA_WRITE(sc, reg, val) \
+ bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
+
+static int
+edma_match(device_t parent, cfdata_t match, void *aux)
+{
+ struct obio_attach_args *obio = aux;
+
+#ifdef TI_AM335X
+ if (obio->obio_addr == AM335X_TPCC_BASE &&
+ obio->obio_size == AM335X_TPCC_SIZE &&
+ obio->obio_intrbase == AM335X_INT_EDMACOMPINT)
+ return 1;
+#endif
+
+ return 0;
+}
+
+static void
+edma_attach(device_t parent, device_t self, void *aux)
+{
+ struct edma_softc *sc = device_private(self);
+ struct obio_attach_args *obio = aux;
+ int idx;
+
+ sc->sc_dev = self;
+ sc->sc_iot = obio->obio_iot;
+ mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SCHED);
+ if (bus_space_map(obio->obio_iot, obio->obio_addr, obio->obio_size,
+ 0, &sc->sc_ioh) != 0) {
+ aprint_error(": couldn't map address spcae\n");
+ return;
+ }
+
+ aprint_normal("\n");
+ aprint_naive("\n");
+
+ for (idx = 0; idx < NUM_DMA_CHANNELS; idx++) {
+ struct edma_channel *ch = &sc->sc_dma[idx];
+ ch->ch_sc = sc;
+ ch->ch_type = EDMA_TYPE_DMA;
+ ch->ch_index = idx;
+ ch->ch_callback = NULL;
+ ch->ch_callbackarg = NULL;
+ ch->ch_nparams = 0;
+ }
+
+ edma_init(sc);
+
+ sc->sc_ih = intr_establish(obio->obio_intrbase + 0,
+ IPL_SCHED, IST_LEVEL, edma_intr, sc);
+ KASSERT(sc->sc_ih != NULL);
+
+ sc->sc_mperr_ih = intr_establish(obio->obio_intrbase + 1,
+ IPL_SCHED, IST_LEVEL, edma_mperr_intr, sc);
+ sc->sc_errint_ih = intr_establish(obio->obio_intrbase + 2,
+ IPL_SCHED, IST_LEVEL, edma_errint_intr, sc);
Home |
Main Index |
Thread Index |
Old Index