summaryrefslogtreecommitdiffstats
path: root/sys/arm/xscale
diff options
context:
space:
mode:
authorcognet <cognet@FreeBSD.org>2005-12-09 23:55:41 +0000
committercognet <cognet@FreeBSD.org>2005-12-09 23:55:41 +0000
commit854ebbd2495da6b5394408dec76d10e763243ede (patch)
tree0b4c0e5040bdcccc209403e901ce830087e592e4 /sys/arm/xscale
parent3a93af24948da1a7225e9a91cd4385d15ef64c5c (diff)
downloadFreeBSD-src-854ebbd2495da6b5394408dec76d10e763243ede.zip
FreeBSD-src-854ebbd2495da6b5394408dec76d10e763243ede.tar.gz
- Better use of the busdma API.
- Use spin locks instead of sleep locks.
Diffstat (limited to 'sys/arm/xscale')
-rw-r--r--sys/arm/xscale/i80321/i80321_aau.c54
-rw-r--r--sys/arm/xscale/i80321/i80321_dma.c62
2 files changed, 69 insertions, 47 deletions
diff --git a/sys/arm/xscale/i80321/i80321_aau.c b/sys/arm/xscale/i80321/i80321_aau.c
index 43e2c45..20b309a 100644
--- a/sys/arm/xscale/i80321/i80321_aau.c
+++ b/sys/arm/xscale/i80321/i80321_aau.c
@@ -107,23 +107,30 @@ i80321_aau_attach(device_t dev)
{
struct i80321_aau_softc *softc = device_get_softc(dev);
struct i80321_softc *sc = device_get_softc(device_get_parent(dev));
+ struct i80321_aaudesc_s *aaudescs;
- mtx_init(&softc->mtx, "AAU mtx", NULL, MTX_DEF);
+ mtx_init(&softc->mtx, "AAU mtx", NULL, MTX_SPIN);
softc->sc_st = sc->sc_st;
if (bus_space_subregion(softc->sc_st, sc->sc_sh, VERDE_AAU_BASE,
VERDE_AAU_SIZE, &softc->sc_aau_sh) != 0)
panic("%s: unable to subregion AAU registers",
device_get_name(dev));
- if (bus_dma_tag_create(NULL, 8 * sizeof(int), 0, BUS_SPACE_MAXADDR,
- BUS_SPACE_MAXADDR, NULL, NULL, sizeof(i80321_aaudesc_t),
+ if (bus_dma_tag_create(NULL, sizeof(i80321_aaudesc_t), 0,
+ BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
+ AAU_RING_SIZE * sizeof(i80321_aaudesc_t),
1, sizeof(i80321_aaudesc_t), BUS_DMA_ALLOCNOW, busdma_lock_mutex,
&Giant, &softc->dmatag))
panic("Couldn't create a dma tag");
+ if (bus_dmamem_alloc(softc->dmatag, (void **)&aaudescs,
+ BUS_DMA_NOWAIT, &softc->aauring[0].map))
+ panic("Couldn't alloc dma memory");
+
for (int i = 0; i < AAU_RING_SIZE; i++) {
- if (bus_dmamem_alloc(softc->dmatag,
- (void **)&softc->aauring[i].desc,
- BUS_DMA_NOWAIT, &softc->aauring[i].map))
- panic("Couldn't alloc dma memory");
+ if (i > 0)
+ if (bus_dmamap_create(softc->dmatag, 0,
+ &softc->aauring[i].map))
+ panic("Couldn't create dma map");
+ softc->aauring[i].desc = &aaudescs[i];
bus_dmamap_load(softc->dmatag, softc->aauring[i].map,
softc->aauring[i].desc, sizeof(i80321_aaudesc_t),
i80321_mapphys, &softc->aauring[i].phys_addr, 0);
@@ -166,19 +173,20 @@ aau_bzero(void *dst, int len, int flags)
if (!sc)
return (-1);
- mtx_lock(&sc->mtx);
+ mtx_lock_spin(&sc->mtx);
if (sc->flags & BUSY) {
- mtx_unlock(&sc->mtx);
+ mtx_unlock_spin(&sc->mtx);
return (-1);
}
sc->flags |= BUSY;
- mtx_unlock(&sc->mtx);
+ mtx_unlock_spin(&sc->mtx);
desc = sc->aauring[0].desc;
if (flags & IS_PHYSICAL) {
desc->local_addr = (vm_paddr_t)dst;
desc->count = len;
desc->descr_ctrl = 2 << 1 | 1 << 31; /* Fill, enable dest write */
- cpu_dcache_wb_range((vm_offset_t)desc, sizeof(*desc));
+ bus_dmamap_sync(sc->dmatag, sc->aauring[0].map,
+ BUS_DMASYNC_PREWRITE);
} else {
test_virt_addr(dst, len);
if ((vm_offset_t)dst & (31))
@@ -209,9 +217,9 @@ aau_bzero(void *dst, int len, int flags)
if (tmplen <= 0 && descnb > 0) {
sc->aauring[descnb - 1].desc->next_desc
= 0;
- cpu_dcache_wb_range((vm_offset_t)
- sc->aauring[descnb - 1].desc,
- sizeof(i80321_aaudesc_t));
+ bus_dmamap_sync(sc->dmatag,
+ sc->aauring[descnb - 1].map,
+ BUS_DMASYNC_PREWRITE);
}
continue;
}
@@ -224,22 +232,24 @@ aau_bzero(void *dst, int len, int flags)
} else
tmplen = 0;
if (descnb + 1 >= AAU_RING_SIZE) {
- mtx_lock(&sc->mtx);
+ mtx_lock_spin(&sc->mtx);
sc->flags &= ~BUSY;
- mtx_unlock(&sc->mtx);
+ mtx_unlock_spin(&sc->mtx);
return (-1);
}
if (tmplen > 0) {
desc->next_desc = sc->aauring[descnb + 1].
phys_addr;
- cpu_dcache_wb_range((vm_offset_t)desc
- , sizeof(*desc));
+ bus_dmamap_sync(sc->dmatag,
+ sc->aauring[descnb].map,
+ BUS_DMASYNC_PREWRITE);
desc = sc->aauring[descnb + 1].desc;
descnb++;
} else {
desc->next_desc = 0;
- cpu_dcache_wb_range((vm_offset_t)desc,
- sizeof(*desc));
+ bus_dmamap_sync(sc->dmatag,
+ sc->aauring[descnb].map,
+ BUS_DMASYNC_PREWRITE);
}
}
@@ -258,9 +268,9 @@ aau_bzero(void *dst, int len, int flags)
AAU_REG_WRITE(sc, 0x4, csr);
/* Stop the AAU. */
AAU_REG_WRITE(sc, 0, 0);
- mtx_lock(&sc->mtx);
+ mtx_lock_spin(&sc->mtx);
sc->flags &= ~BUSY;
- mtx_unlock(&sc->mtx);
+ mtx_unlock_spin(&sc->mtx);
return (ret);
}
diff --git a/sys/arm/xscale/i80321/i80321_dma.c b/sys/arm/xscale/i80321/i80321_dma.c
index 39b6a4a..3bc09d3 100644
--- a/sys/arm/xscale/i80321/i80321_dma.c
+++ b/sys/arm/xscale/i80321/i80321_dma.c
@@ -55,6 +55,7 @@ typedef struct i80321_dmadesc_s {
vm_paddr_t local_addr;
vm_size_t count;
uint32_t descr_ctrl;
+ uint64_t unused;
} __packed i80321_dmadesc_t;
typedef struct i80321_dmaring_s {
@@ -109,25 +110,31 @@ i80321_dma_attach(device_t dev)
struct i80321_dma_softc *softc = device_get_softc(dev);
struct i80321_softc *sc = device_get_softc(device_get_parent(dev));
int unit = device_get_unit(dev);
+ i80321_dmadesc_t *dmadescs;
- mtx_init(&softc->mtx, "DMA engine mtx", NULL, MTX_DEF);
+ mtx_init(&softc->mtx, "DMA engine mtx", NULL, MTX_SPIN);
softc->sc_st = sc->sc_st;
if (bus_space_subregion(softc->sc_st, sc->sc_sh, unit == 0 ?
VERDE_DMA_BASE0 : VERDE_DMA_BASE1, VERDE_DMA_SIZE,
&softc->sc_dma_sh) != 0)
panic("%s: unable to subregion DMA registers",
device_get_name(dev));
- if (bus_dma_tag_create(NULL, 8 * sizeof(int), 0, BUS_SPACE_MAXADDR,
- BUS_SPACE_MAXADDR, NULL, NULL, sizeof(i80321_dmadesc_t),
- 1, sizeof(i80321_dmadesc_t), BUS_DMA_ALLOCNOW, busdma_lock_mutex,
+ if (bus_dma_tag_create(NULL, sizeof(i80321_dmadesc_t),
+ 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
+ DMA_RING_SIZE * sizeof(i80321_dmadesc_t), 1,
+ sizeof(i80321_dmadesc_t), BUS_DMA_ALLOCNOW, busdma_lock_mutex,
&Giant, &softc->dmatag))
panic("Couldn't create a dma tag");
DMA_REG_WRITE(softc, 0, 0);
+ if (bus_dmamem_alloc(softc->dmatag, (void **)&dmadescs,
+ BUS_DMA_NOWAIT, &softc->dmaring[0].map))
+ panic("Couldn't alloc dma memory");
for (int i = 0; i < DMA_RING_SIZE; i++) {
- if (bus_dmamem_alloc(softc->dmatag,
- (void **)&softc->dmaring[i].desc,
- BUS_DMA_NOWAIT, &softc->dmaring[i].map))
- panic("Couldn't alloc dma memory");
+ if (i > 0)
+ if (bus_dmamap_create(softc->dmatag, 0,
+ &softc->dmaring[i].map))
+ panic("Couldn't alloc dmamap");
+ softc->dmaring[i].desc = &dmadescs[i];
bus_dmamap_load(softc->dmatag, softc->dmaring[i].map,
softc->dmaring[i].desc, sizeof(i80321_dmadesc_t),
i80321_mapphys, &softc->dmaring[i].phys_addr, 0);
@@ -185,10 +192,10 @@ dma_memcpy(void *dst, void *src, int len, int flags)
if (!softcs[0] || !softcs[1])
return (-1);
- mtx_lock(&softcs[0]->mtx);
+ mtx_lock_spin(&softcs[0]->mtx);
if (softcs[0]->flags & BUSY) {
- mtx_unlock(&softcs[0]->mtx);
- mtx_lock(&softcs[1]->mtx);
+ mtx_unlock_spin(&softcs[0]->mtx);
+ mtx_lock_spin(&softcs[1]->mtx);
if (softcs[1]->flags & BUSY) {
mtx_unlock(&softcs[1]->mtx);
return (-1);
@@ -197,7 +204,7 @@ dma_memcpy(void *dst, void *src, int len, int flags)
} else
sc = softcs[0];
sc->flags |= BUSY;
- mtx_unlock(&sc->mtx);
+ mtx_unlock_spin(&sc->mtx);
desc = sc->dmaring[0].desc;
if (flags & IS_PHYSICAL) {
desc->next_desc = 0;
@@ -206,13 +213,15 @@ dma_memcpy(void *dst, void *src, int len, int flags)
desc->local_addr = (vm_paddr_t)dst;
desc->count = len;
desc->descr_ctrl = 1 << 6; /* Local memory to local memory. */
- cpu_dcache_wb_range((vm_offset_t)desc, sizeof(*desc));
+ bus_dmamap_sync(sc->dmatag,
+ sc->dmaring[0].map,
+ BUS_DMASYNC_PREWRITE);
} else {
if (!virt_addr_is_valid(dst, len, 1, !(flags & DST_IS_USER)) ||
!virt_addr_is_valid(src, len, 0, !(flags & SRC_IS_USER))) {
- mtx_lock(&sc->mtx);
+ mtx_lock_spin(&sc->mtx);
sc->flags &= ~BUSY;
- mtx_unlock(&sc->mtx);
+ mtx_unlock_spin(&sc->mtx);
return (-1);
}
cpu_dcache_wb_range((vm_offset_t)src, len);
@@ -266,9 +275,9 @@ dma_memcpy(void *dst, void *src, int len, int flags)
if (tmplen <= 0 && descnb > 0) {
sc->dmaring[descnb - 1].desc->next_desc
= 0;
- cpu_dcache_wb_range((vm_offset_t)
- sc->dmaring[descnb - 1].desc,
- sizeof(i80321_dmadesc_t));
+ bus_dmamap_sync(sc->dmatag,
+ sc->dmaring[descnb - 1].map,
+ BUS_DMASYNC_PREWRITE);
}
continue;
}
@@ -284,21 +293,24 @@ dma_memcpy(void *dst, void *src, int len, int flags)
} else
tmplen = 0;
if (descnb + 1 >= DMA_RING_SIZE) {
- mtx_lock(&sc->mtx);
+ mtx_lock_spin(&sc->mtx);
sc->flags &= ~BUSY;
- mtx_unlock(&sc->mtx);
+ mtx_unlock_spin(&sc->mtx);
return (-1);
}
if (tmplen > 0) {
desc->next_desc = sc->dmaring[descnb + 1].
phys_addr;
- cpu_dcache_wb_range((vm_offset_t)desc, sizeof(*desc));
+ bus_dmamap_sync(sc->dmatag,
+ sc->dmaring[descnb].map,
+ BUS_DMASYNC_PREWRITE);
desc = sc->dmaring[descnb + 1].desc;
descnb++;
} else {
desc->next_desc = 0;
-
- cpu_dcache_wb_range((vm_offset_t)desc, sizeof(*desc));
+ bus_dmamap_sync(sc->dmatag,
+ sc->dmaring[descnb].map,
+ BUS_DMASYNC_PREWRITE);
}
}
@@ -316,9 +328,9 @@ dma_memcpy(void *dst, void *src, int len, int flags)
else
ret = 0;
DMA_REG_WRITE(sc, 0, 0);
- mtx_lock(&sc->mtx);
+ mtx_lock_spin(&sc->mtx);
sc->flags &= ~BUSY;
- mtx_unlock(&sc->mtx);
+ mtx_unlock_spin(&sc->mtx);
return (ret);
}
OpenPOWER on IntegriCloud