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