Home | History | Annotate | Line # | Download | only in at91
      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