summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Pascoe <pascoe@cvs.openbsd.org>2005-04-14 23:40:35 +0000
committerChristopher Pascoe <pascoe@cvs.openbsd.org>2005-04-14 23:40:35 +0000
commita0a06583a49412e4927cd00b87a93420e8607d62 (patch)
treece1fd500713054757ed30fe44bf1649d3b779b27
parent534e452760f3e33c847df924fd461273d9cd8707 (diff)
Add basic support for the pxa2x0 DMA controller.
ok deraadt@ dlg@ drahn@ uwe@
-rw-r--r--sys/arch/arm/xscale/files.pxa2x07
-rw-r--r--sys/arch/arm/xscale/pxa2x0.c6
-rw-r--r--sys/arch/arm/xscale/pxa2x0_dma.c3
-rw-r--r--sys/arch/arm/xscale/pxa2x0_dmac.c233
-rw-r--r--sys/arch/arm/xscale/pxa2x0_dmac.h26
-rw-r--r--sys/arch/arm/xscale/pxa2x0reg.h13
-rw-r--r--sys/arch/zaurus/conf/GENERIC3
7 files changed, 278 insertions, 13 deletions
diff --git a/sys/arch/arm/xscale/files.pxa2x0 b/sys/arch/arm/xscale/files.pxa2x0
index e066256c77b..0947ef7e9ac 100644
--- a/sys/arch/arm/xscale/files.pxa2x0
+++ b/sys/arch/arm/xscale/files.pxa2x0
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pxa2x0,v 1.10 2005/03/08 20:00:23 tdeval Exp $
+# $OpenBSD: files.pxa2x0,v 1.11 2005/04/14 23:40:34 pascoe Exp $
# $NetBSD: files.pxa2x0,v 1.6 2004/05/01 19:09:14 thorpej Exp $
#
# Configuration info for Intel PXA2[51]0 CPU support
@@ -30,6 +30,11 @@ device pxagpio
attach pxagpio at pxaip
file arch/arm/xscale/pxa2x0_gpio.c pxagpio needs-flag
+# DMA controller
+device pxadmac
+attach pxadmac at pxaip
+file arch/arm/xscale/pxa2x0_dmac.c pxadmac needs-flag
+
# clock device
# PXA2x0's built-in timer is compatible to SA-1110.
device saost
diff --git a/sys/arch/arm/xscale/pxa2x0.c b/sys/arch/arm/xscale/pxa2x0.c
index 9556121a798..5ded6690269 100644
--- a/sys/arch/arm/xscale/pxa2x0.c
+++ b/sys/arch/arm/xscale/pxa2x0.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pxa2x0.c,v 1.6 2005/02/28 13:21:17 uwe Exp $ */
+/* $OpenBSD: pxa2x0.c,v 1.7 2005/04/14 23:40:34 pascoe Exp $ */
/* $NetBSD: pxa2x0.c,v 1.5 2003/12/12 16:42:44 thorpej Exp $ */
/*
@@ -101,9 +101,7 @@ __KERNEL_RCSID(0, "$NetBSD: pxa2x0.c,v 1.5 2003/12/12 16:42:44 thorpej Exp $");
#include "pxaintc.h"
#include "pxagpio.h"
-#if 0
-#include "pxadmac.h" /* Not yet */
-#endif
+#include "pxadmac.h"
#include <sys/param.h>
#include <sys/systm.h>
diff --git a/sys/arch/arm/xscale/pxa2x0_dma.c b/sys/arch/arm/xscale/pxa2x0_dma.c
index 9013edaa720..c1500fa8348 100644
--- a/sys/arch/arm/xscale/pxa2x0_dma.c
+++ b/sys/arch/arm/xscale/pxa2x0_dma.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pxa2x0_dma.c,v 1.2 2005/01/02 19:52:36 drahn Exp $ */
+/* $OpenBSD: pxa2x0_dma.c,v 1.3 2005/04/14 23:40:34 pascoe Exp $ */
/* $NetBSD: pxa2x0_dma.c,v 1.3 2003/08/07 16:58:35 bsh Exp $ */
/*
@@ -36,7 +36,6 @@
/*
* bus dma tag for PXA2[15]0 processor.
- * (Currently used only for LCD frame buffer)
*/
#include <sys/cdefs.h>
diff --git a/sys/arch/arm/xscale/pxa2x0_dmac.c b/sys/arch/arm/xscale/pxa2x0_dmac.c
new file mode 100644
index 00000000000..a05aebe97eb
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_dmac.c
@@ -0,0 +1,233 @@
+/* $OpenBSD: pxa2x0_dmac.c,v 1.1 2005/04/14 23:40:34 pascoe Exp $ */
+
+/*
+ * Copyright (c) 2005 Christopher Pascoe <pascoe@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DMA Controller Handler for the Intel PXA2X0 processor.
+ */
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/evcount.h>
+#include <uvm/uvm_extern.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+#include <machine/lock.h>
+
+#include <arm/xscale/pxa2x0reg.h>
+#include <arm/xscale/pxa2x0var.h>
+#include <arm/xscale/pxa2x0_dmac.h>
+
+typedef void (*pxadmac_intrhandler)(void *);
+
+struct pxadmac_softc {
+ struct device sc_dev;
+ bus_space_tag_t sc_bust;
+ bus_space_handle_t sc_bush;
+ void *sc_ih;
+ int sc_nchan;
+ int sc_npri;
+ pxadmac_intrhandler sc_intrhandlers[DMAC_N_CHANNELS_PXA27X];
+ void *sc_intrargs[DMAC_N_CHANNELS_PXA27X];
+};
+
+int pxadmac_intr(void *);
+
+/*
+ * DMAC autoconf glue
+ */
+int pxadmac_match(struct device *, void *, void *);
+void pxadmac_attach(struct device *, struct device *, void *);
+
+struct cfattach pxadmac_ca = {
+ sizeof(struct pxadmac_softc), pxadmac_match, pxadmac_attach
+};
+
+struct cfdriver pxadmac_cd = {
+ NULL, "pxadmac", DV_DULL
+};
+
+static struct pxadmac_softc *pxadmac_softc = NULL;
+
+int
+pxadmac_match(struct device *parent, void *cf, void *aux)
+{
+ struct pxaip_attach_args *pxa = aux;
+
+ if (pxadmac_softc != NULL || pxa->pxa_addr != PXA2X0_DMAC_BASE)
+ return (0);
+
+ return (1);
+}
+
+void
+pxadmac_attach(struct device *parent, struct device *self, void *args)
+{
+ struct pxadmac_softc *sc = (struct pxadmac_softc *)self;
+ struct pxaip_attach_args *pxa = args;
+ bus_size_t bus_size;
+
+ sc->sc_bust = pxa->pxa_iot;
+
+ printf(": DMA Controller\n");
+
+ if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X) {
+ sc->sc_nchan = DMAC_N_CHANNELS_PXA27X;
+ sc->sc_npri = DMAC_N_PRIORITIES_PXA27X;
+ bus_size = PXA27X_DMAC_SIZE;
+ } else {
+ sc->sc_nchan = DMAC_N_CHANNELS;
+ sc->sc_npri = DMAC_N_PRIORITIES;
+ bus_size = PXA2X0_DMAC_SIZE;
+ }
+
+ if (bus_space_map(sc->sc_bust, pxa->pxa_addr, bus_size, 0,
+ &sc->sc_bush)) {
+ printf("%s: Can't map registers!\n", sc->sc_dev.dv_xname);
+ return;
+ }
+
+ sc->sc_ih = pxa2x0_intr_establish(pxa->pxa_intr, IPL_BIO,
+ pxadmac_intr, sc, "pxadmac");
+ if (sc->sc_ih == NULL) {
+ printf(": unable to establish interrupt\n");
+ bus_space_unmap(sc->sc_bust, sc->sc_bush, bus_size);
+ return;
+ }
+
+ pxadmac_softc = sc;
+}
+
+/* Perform non-descriptor based DMA to a FIFO */
+int
+pxa2x0_dma_to_fifo(int periph, int chan, bus_addr_t fifo_addr, int width,
+ int burstsize, bus_addr_t src_addr, int length, void (*intr)(void *),
+ void *intrarg)
+{
+ struct pxadmac_softc *sc = pxadmac_softc;
+ uint32_t cmd;
+
+ if (periph < 0 || periph > 63 || periph == 23) {
+ printf("pxa2x0_dma_to_fifo: bogus peripheral %d", periph);
+ return EINVAL;
+ }
+
+ if (chan < 0 || chan >= sc->sc_nchan) {
+ printf("pxa2x0_dma_to_fifo: bogus dma channel %d", chan);
+ return EINVAL;
+ }
+
+ if (length < 0 || length > DCMD_LENGTH_MASK) {
+ printf("pxa2x0_dma_to_fifo: bogus length %d", length);
+ return EINVAL;
+ }
+
+ cmd = (length & DCMD_LENGTH_MASK) | DCMD_INCSRCADDR | DCMD_FLOWTRG
+ | DCMD_ENDIRQEN;
+
+ switch (width) {
+ case 1:
+ cmd |= DCMD_WIDTH_1;
+ break;
+ case 4:
+ cmd |= DCMD_WIDTH_4;
+ break;
+ default:
+ printf("pxa2x0_dma_to_fifo: bogus width %d", width);
+ return EINVAL;
+ }
+
+ switch (burstsize) {
+ case 8:
+ cmd |= DCMD_SIZE_8;
+ break;
+ case 16:
+ cmd |= DCMD_SIZE_16;
+ break;
+ case 32:
+ cmd |= DCMD_SIZE_32;
+ break;
+ default:
+ printf("pxa2x0_dma_to_fifo: bogus burstsize %d", burstsize);
+ return EINVAL;
+ }
+
+ /* Save handler for interrupt-on-completion. */
+ sc->sc_intrhandlers[chan] = intr;
+ sc->sc_intrargs[chan] = intrarg;
+
+ /* XXX: abort anything already in progress, hopefully nothing. */
+ bus_space_write_4(sc->sc_bust, sc->sc_bush, DMAC_DCSR(chan),
+ DCSR_NODESCFETCH);
+
+ /* Map peripheral to channel for flow control setup. */
+ bus_space_write_4(sc->sc_bust, sc->sc_bush, DMAC_DRCMR(periph),
+ chan | DRCMR_MAPVLD);
+
+ /* Setup transfer addresses. */
+ bus_space_write_4(sc->sc_bust, sc->sc_bush, DMAC_DDADR(chan),
+ DDADR_STOP);
+ bus_space_write_4(sc->sc_bust, sc->sc_bush, DMAC_DSADR(chan),
+ src_addr);
+ bus_space_write_4(sc->sc_bust, sc->sc_bush, DMAC_DTADR(chan),
+ fifo_addr);
+ bus_space_write_4(sc->sc_bust, sc->sc_bush, DMAC_DCMD(chan),
+ cmd);
+
+ /* Start the transfer. */
+ bus_space_write_4(sc->sc_bust, sc->sc_bush, DMAC_DCSR(chan),
+ DCSR_RUN | DCSR_NODESCFETCH);
+
+ return 0;
+}
+
+int
+pxadmac_intr(void *v)
+{
+ struct pxadmac_softc *sc = v;
+ u_int32_t dint, dcsr;
+ int chan;
+
+ /* Interrupt for us? */
+ dint = bus_space_read_4(sc->sc_bust, sc->sc_bush, DMAC_DINT);
+ if (!dint)
+ return 0;
+
+ /* Process individual channels and run handlers. */
+ /* XXX: this does not respect priority order for channels. */
+ for (chan = 0; dint != 0 && chan < 32; chan++) {
+ /* Don't ack channels that weren't ready at call time. */
+ if ((dint & (1 << chan)) == 0)
+ continue;
+ dint &= ~(1 << chan);
+
+ /* Acknowledge individual channel interrupt. */
+ dcsr = bus_space_read_4(sc->sc_bust, sc->sc_bush,
+ DMAC_DCSR(chan));
+ bus_space_write_4(sc->sc_bust, sc->sc_bush, DMAC_DCSR(chan),
+ dcsr & 0x7C80021F);
+
+ /* Call the registered handler. */
+ if (sc->sc_intrhandlers[chan])
+ sc->sc_intrhandlers[chan](sc->sc_intrargs[chan]);
+ }
+
+ return 1;
+}
diff --git a/sys/arch/arm/xscale/pxa2x0_dmac.h b/sys/arch/arm/xscale/pxa2x0_dmac.h
new file mode 100644
index 00000000000..48619e944e7
--- /dev/null
+++ b/sys/arch/arm/xscale/pxa2x0_dmac.h
@@ -0,0 +1,26 @@
+/* $OpenBSD: pxa2x0_dmac.h,v 1.1 2005/04/14 23:40:34 pascoe Exp $ */
+
+/*
+ * Copyright (c) 2005 Christopher Pascoe <pascoe@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _PXA2X0_DMAC_H
+#define _PXA2X0_DMAC_H
+
+int pxa2x0_dma_to_fifo(int periph, int chan, bus_addr_t fifo_addr, int width,
+ int burstsize, bus_addr_t src_addr, int length, void (*intr)(void *),
+ void *intrarg);
+
+#endif /* _PXA2X0_DMAC_H */
diff --git a/sys/arch/arm/xscale/pxa2x0reg.h b/sys/arch/arm/xscale/pxa2x0reg.h
index 27f6df99e86..99c90d41bef 100644
--- a/sys/arch/arm/xscale/pxa2x0reg.h
+++ b/sys/arch/arm/xscale/pxa2x0reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pxa2x0reg.h,v 1.19 2005/04/12 09:13:13 dlg Exp $ */
+/* $OpenBSD: pxa2x0reg.h,v 1.20 2005/04/14 23:40:34 pascoe Exp $ */
/* $NetBSD: pxa2x0reg.h,v 1.4 2003/06/11 20:43:01 scw Exp $ */
/*
@@ -85,6 +85,7 @@
#define PXA2X0_DMAC_BASE 0x40000000
#define PXA2X0_DMAC_SIZE 0x300
+#define PXA27X_DMAC_SIZE 0x0400
#define PXA2X0_FFUART_BASE 0x40100000 /* Full Function UART */
#define PXA2X0_BTUART_BASE 0x40200000 /* Bluetooth UART */
#define PXA2X0_I2C_BASE 0x40300000 /* I2C Bus Interface Unit */
@@ -164,8 +165,10 @@
#define ICCR_DIM (1<<0)
/* DMAC */
-#define DMAC_N_CHANNELS 16
-#define DMAC_N_PRIORITIES 3
+#define DMAC_N_CHANNELS 16
+#define DMAC_N_CHANNELS_PXA27X 32
+#define DMAC_N_PRIORITIES 3
+#define DMAC_N_PRIORITIES_PXA27X 4
#define DMAC_DCSR(n) ((n)*4)
#define DCSR_BUSERRINTR (1<<0) /* bus error interrupt */
@@ -176,7 +179,7 @@
#define DCSR_STOPIRQEN (1<<29) /* stop interrupt enable */
#define DCSR_NODESCFETCH (1<<30) /* no-descriptor fetch mode */
#define DCSR_RUN (1<<31)
-#define DMAC_DINT 0x00f0 /* DAM interrupt */
+#define DMAC_DINT 0x00f0 /* DMA interrupt */
#define DMAC_DINT_MASK 0xffffu
#define DMAC_DRCMR(n) (0x100+(n)*4) /* Channel map register */
#define DRCMR_CHLNUM 0x0f /* channel number */
@@ -196,7 +199,7 @@
#define DCMD_SIZE_8 (1<<DCMD_SIZE_SHIFT)
#define DCMD_SIZE_16 (2<<DCMD_SIZE_SHIFT)
#define DCMD_SIZE_32 (3<<DCMD_SIZE_SHIFT)
-#define DCMD_LITTLE_ENDIEN (0<<18)
+#define DCMD_LITTLE_ENDIAN (0<<18)
#define DCMD_ENDIRQEN (1<<21)
#define DCMD_STARTIRQEN (1<<22)
#define DCMD_FLOWTRG (1<<28) /* flow control by target */
diff --git a/sys/arch/zaurus/conf/GENERIC b/sys/arch/zaurus/conf/GENERIC
index 023bb44f496..bc0248518c4 100644
--- a/sys/arch/zaurus/conf/GENERIC
+++ b/sys/arch/zaurus/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.31 2005/03/31 12:35:45 dlg Exp $
+# $OpenBSD: GENERIC,v 1.32 2005/04/14 23:40:34 pascoe Exp $
#
# GENERIC machine description file
#
@@ -62,6 +62,7 @@ pxaip0 at mainbus?
pxaintc0 at pxaip? # interrupt controller
pxagpio0 at pxaip? # GPIO
+pxadmac0 at pxaip? # DMA controller
scoop0 at pxaip?
scoop1 at pxaip?
saost0 at pxaip? addr 0x40a00000 size 0x20