Direct Memory Access (DMA) helpers

Data Structures

union  dma_addr_t
 A physical/virtual address pair used for DMA. More...

Defines

#define CPU_DMA_ALIGN   0
 log2 of the minimum alignment of DMA-able objects

Enumerations

enum  dma_direction { DMA_FROM_DEVICE = 0, DMA_TO_DEVICE = 1, DMA_BIDIRECTIONAL = 2 }
 

The direction of a DMA transfer.

More...

Functions

static dma_addr_t dma_addr_failure (void)
 Return an address indicating failure.
static bool dma_addr_is_failed (dma_addr_t addr)
 Test if a DMA address addr indicates failure.
static void dma_sync_for_device (dma_addr_t addr, size_t size, enum dma_direction direction)
 Synchronize a DMA buffer before transfer.
static void dma_sync_for_cpu (dma_addr_t addr, size_t size, enum dma_direction direction)
 Synchronize a DMA buffer after transfer.
static dma_addr_t dma_map_single (const void *vaddr, size_t size, enum dma_direction direction)
 Map a single contiguous buffer for DMA transfer.
static void dma_unmap_single (dma_addr_t addr, size_t size, enum dma_direction direction)
 Unmap a single contiguous buffer after a DMA transfer.

Detailed Description

Many chips supported by this framework allow certain on-chip (and in some cases, external) peripherals to transfer data to and from RAM directly without CPU intervention. This is known as Direct Memory Access, or DMA.

Depending on the chip in question, there may be various limitations imposed on the memory used in a DMA transfer:

The DMA helper functions in this module aim to make it easier to write generic code which will work on chips with any or none of these limitations without imposing any unnecessary overhead.

Note that some chips may not support DMA at all. It is still recommended, however, to follow the rules laid out in this module when writing code dealing with data transfer, as it will make it easier to port it to a different chip in the future. On such devices, utilizing the generic DMA helpers will not introduce any additional overhead.

Physical and Virtual Addresses

Most of the chips supported by this framework do not distinguish between physical addresses (i.e. addresses that appear on the bus) and virtual addresses (i.e. addresses used in CPU instructions). On these chips, the virtual address accessed by software will always appear unchanged as a physical address on the bus.

Other chips, e.g. all chips in the AVR32 AP7 family, have a Memory Management Unit which translates each address accessed by the CPU into a (possibly different) physical address before it appears on the bus. When setting up DMA transfers on these chips, care must be taken to give the physical address to the peripheral that is to perform the data transfer, as the virtual address used to access the memory may not even be a valid address on the bus.

In order to obtain a physical address corresponding to an arbitrary virtual address, the dma_map_single() function may be used. The value returned represents both the physical and virtual address of the mapped object, so it's usually a good idea to store this value as an reference to the object instead of just the virtual pointer. On platforms without MMU hardware, the value is stored as a union, so it won't take any additional space.

When the DMA transfer is finished, the object must be unmapped by calling dma_unmap_single().

Cache synchronization

The dma_map_single() and dma_unmap_single() functions described in the previous section will also ensure that any cached data is properly synchronized before returning. Sometimes, however, the same object may be used for multiple data transfers, and it is somewhat wasteful to do the address translation for each and every transfer.

The dma_sync_for_cpu() function may be used to synchronize the caches after a data transfer without unmapping the object. After the CPU is done processing the data and wants to re-use the object for another transfer, the dma_sync_for_device() may be called to resynchronize the caches before the next transfer.

In order to ensure correct operation on all supported chips, the following rules must be observed:


Define Documentation

#define CPU_DMA_ALIGN   0

log2 of the minimum alignment of DMA-able objects

Definition at line 45 of file dma.h.

Referenced by tsfs_init().


Enumeration Type Documentation

The direction of a DMA transfer.

Enumerator:
DMA_FROM_DEVICE 

From memory to peripheral.

DMA_TO_DEVICE 

From peripheral to memory.

DMA_BIDIRECTIONAL 

Both of the above.

Definition at line 133 of file dma.h.


Function Documentation

static dma_addr_t dma_addr_failure ( void   )  [inline, static]

Return an address indicating failure.

This is used primarily by the DMA allocator to indicate allocation failure.

Definition at line 71 of file dma_nommu.h.

References dma_addr_t::ptr.

static bool dma_addr_is_failed ( dma_addr_t  addr  )  [inline, static]

Test if a DMA address addr indicates failure.

Return values:
true addr indicates failure
false addr is valid

Definition at line 86 of file dma_nommu.h.

References dma_addr_t::ptr.

static dma_addr_t dma_map_single ( const void *  vaddr,
size_t  size,
enum dma_direction  direction 
) [inline, static]

Map a single contiguous buffer for DMA transfer.

After this function has been called, the device can access the buffer, but the CPU must not.

Parameters:
vaddr The virtual address of the buffer
size The length of the buffer in bytes
direction The direction of the transfer
Returns:
A physical/virtual address pair for the mapping

Definition at line 135 of file dma_nommu.h.

References dma_addr_t::ptr.

Referenced by buffer_init_rx(), and buffer_init_tx().

static void dma_sync_for_cpu ( dma_addr_t  addr,
size_t  size,
enum dma_direction  direction 
) [inline, static]

Synchronize a DMA buffer after transfer.

After this function has been called, the CPU can access the buffer, but the device must not.

Parameters:
addr The physical/virtual addresses of the buffer
size The length of the buffer in bytes
direction The direction of the transfer

Definition at line 117 of file dma_nommu.h.

static void dma_sync_for_device ( dma_addr_t  addr,
size_t  size,
enum dma_direction  direction 
) [inline, static]

Synchronize a DMA buffer before transfer.

After this function has been called, the device can access the buffer, but the CPU must not.

Parameters:
addr The physical/virtual addresses of the buffer
size The length of the buffer in bytes
direction The direction of the transfer

Definition at line 101 of file dma_nommu.h.

static void dma_unmap_single ( dma_addr_t  addr,
size_t  size,
enum dma_direction  direction 
) [inline, static]

Unmap a single contiguous buffer after a DMA transfer.

After this function has been called, the CPU can access the buffer, but the device must not.

Parameters:
addr The physical/virtual addresses of the buffer
size The length of the buffer in bytes
direction The direction of the transfer

Definition at line 153 of file dma_nommu.h.

Generated on Thu Apr 29 14:10:00 2010 for display-demo by  doxygen 1.6.3