at91pdc.c revision 1.3 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