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. | |
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.
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().
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 CPU_DMA_ALIGN 0 |
| enum dma_direction |
| 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.
| 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.
| vaddr | The virtual address of the buffer | |
| size | The length of the buffer in bytes | |
| direction | The direction of the transfer |
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.
| 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.
| 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.
| 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.
1.6.3