diff options
author | Christopher Pascoe <pascoe@cvs.openbsd.org> | 2005-04-14 23:40:35 +0000 |
---|---|---|
committer | Christopher Pascoe <pascoe@cvs.openbsd.org> | 2005-04-14 23:40:35 +0000 |
commit | a0a06583a49412e4927cd00b87a93420e8607d62 (patch) | |
tree | ce1fd500713054757ed30fe44bf1649d3b779b27 /sys/arch | |
parent | 534e452760f3e33c847df924fd461273d9cd8707 (diff) |
Add basic support for the pxa2x0 DMA controller.
ok deraadt@ dlg@ drahn@ uwe@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/arm/xscale/files.pxa2x0 | 7 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxa2x0.c | 6 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxa2x0_dma.c | 3 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxa2x0_dmac.c | 233 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxa2x0_dmac.h | 26 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxa2x0reg.h | 13 | ||||
-rw-r--r-- | sys/arch/zaurus/conf/GENERIC | 3 |
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 |