1 1.3 dyoung /* $Id: at91pdc.c,v 1.3 2011/07/01 19:31:17 dyoung Exp $ */ 2 1.2 matt 3 1.2 matt #include <sys/types.h> 4 1.3 dyoung #include <sys/bus.h> 5 1.2 matt #include <arm/at91/at91pdcvar.h> 6 1.2 matt 7 1.2 matt int at91pdc_alloc_fifo(bus_dma_tag_t dmat, at91pdc_fifo_t *fifo, int size, 8 1.2 matt int flags) 9 1.2 matt { 10 1.2 matt bus_dma_segment_t segs; 11 1.2 matt int rsegs; 12 1.2 matt int err; 13 1.2 matt int f; 14 1.2 matt 15 1.2 matt memset(fifo, 0, sizeof(*fifo)); 16 1.2 matt 17 1.2 matt /* allocate map: */ 18 1.2 matt f = flags & (BUS_DMA_BUS1 | BUS_DMA_BUS2 | BUS_DMA_BUS3 | BUS_DMA_BUS4); 19 1.2 matt err = bus_dmamap_create(dmat, size, 1, size, 0, 20 1.2 matt BUS_DMA_WAITOK | f, 21 1.2 matt &fifo->f_dmamap); 22 1.2 matt if (err) 23 1.2 matt goto fail_0; 24 1.2 matt 25 1.2 matt /* allocate DMA safe memory: */ 26 1.2 matt f |= flags & BUS_DMA_STREAMING; 27 1.2 matt err = bus_dmamem_alloc(dmat, size, 0, size, &segs, 1, &rsegs, 28 1.2 matt BUS_DMA_WAITOK | f); 29 1.2 matt if (err) 30 1.2 matt goto fail_1; 31 1.2 matt 32 1.2 matt /* allocate virtual memory: */ 33 1.2 matt f |= flags & (BUS_DMA_COHERENT | BUS_DMA_NOCACHE); 34 1.2 matt err = bus_dmamem_map(dmat, &segs, 1, size, &fifo->f_buf, 35 1.2 matt BUS_DMA_WAITOK | f); 36 1.2 matt if (err) 37 1.2 matt goto fail_2; 38 1.2 matt 39 1.2 matt /* connect physical to virtual memory: */ 40 1.2 matt f |= flags & (BUS_DMA_READ | BUS_DMA_WRITE); 41 1.2 matt f &= ~(BUS_DMA_COHERENT | BUS_DMA_NOCACHE); 42 1.2 matt err = bus_dmamap_load(dmat, fifo->f_dmamap, fifo->f_buf, size, NULL, 43 1.2 matt BUS_DMA_NOWAIT | f); 44 1.2 matt if (err) 45 1.2 matt goto fail_3; 46 1.2 matt 47 1.2 matt /* initialize rest of the structure: */ 48 1.2 matt fifo->f_buf_size = size; 49 1.2 matt fifo->f_ndx = fifo->f_length = 0; 50 1.2 matt 51 1.2 matt fifo->f_buf_addr = fifo->f_dmamap->dm_segs[0].ds_addr; 52 1.2 matt fifo->f_pdc_rd_ndx = fifo->f_pdc_wr_ndx = 0; 53 1.2 matt fifo->f_pdc_space = fifo->f_buf_size; 54 1.2 matt 55 1.2 matt return 0; 56 1.2 matt fail_3: 57 1.2 matt bus_dmamem_unmap(dmat, fifo->f_buf, size); 58 1.2 matt fail_2: 59 1.2 matt bus_dmamem_free(dmat, &segs, rsegs); 60 1.2 matt fail_1: 61 1.2 matt bus_dmamap_destroy(dmat, fifo->f_dmamap); 62 1.2 matt fail_0: 63 1.2 matt return err; 64 1.2 matt } 65