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