diff options
author | cognet <cognet@FreeBSD.org> | 2005-12-09 23:55:41 +0000 |
---|---|---|
committer | cognet <cognet@FreeBSD.org> | 2005-12-09 23:55:41 +0000 |
commit | 854ebbd2495da6b5394408dec76d10e763243ede (patch) | |
tree | 0b4c0e5040bdcccc209403e901ce830087e592e4 | |
parent | 3a93af24948da1a7225e9a91cd4385d15ef64c5c (diff) | |
download | FreeBSD-src-854ebbd2495da6b5394408dec76d10e763243ede.zip FreeBSD-src-854ebbd2495da6b5394408dec76d10e763243ede.tar.gz |
- Better use of the busdma API.
- Use spin locks instead of sleep locks.
-rw-r--r-- | sys/arm/xscale/i80321/i80321_aau.c | 54 | ||||
-rw-r--r-- | sys/arm/xscale/i80321/i80321_dma.c | 62 |
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); } |