Path: blob/master/arch/arm/mach-bcmring/include/mach/dma.h
10820 views
/*****************************************************************************1* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.2*3* Unless you and Broadcom execute a separate written software license4* agreement governing use of this software, this software is licensed to you5* under the terms of the GNU General Public License version 2, available at6* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").7*8* Notwithstanding the above, under no circumstances may you combine this9* software in any way with any other Broadcom software provided under a10* license other than the GPL, without Broadcom's express prior written11* consent.12*****************************************************************************/1314/****************************************************************************/15/**16* @file dma.h17*18* @brief API definitions for the linux DMA interface.19*/20/****************************************************************************/2122#if !defined(ASM_ARM_ARCH_BCMRING_DMA_H)23#define ASM_ARM_ARCH_BCMRING_DMA_H2425/* ---- Include Files ---------------------------------------------------- */2627#include <linux/kernel.h>28#include <linux/wait.h>29#include <linux/semaphore.h>30#include <csp/dmacHw.h>31#include <mach/timer.h>32#include <linux/scatterlist.h>33#include <linux/dma-mapping.h>34#include <linux/mm.h>35#include <linux/vmalloc.h>36#include <linux/pagemap.h>3738/* ---- Constants and Types ---------------------------------------------- */3940/* If DMA_DEBUG_TRACK_RESERVATION is set to a non-zero value, then the filename */41/* and line number of the reservation request will be recorded in the channel table */4243#define DMA_DEBUG_TRACK_RESERVATION 14445#define DMA_NUM_CONTROLLERS 246#define DMA_NUM_CHANNELS 8 /* per controller */4748typedef enum {49DMA_DEVICE_MEM_TO_MEM, /* For memory to memory transfers */50DMA_DEVICE_I2S0_DEV_TO_MEM,51DMA_DEVICE_I2S0_MEM_TO_DEV,52DMA_DEVICE_I2S1_DEV_TO_MEM,53DMA_DEVICE_I2S1_MEM_TO_DEV,54DMA_DEVICE_APM_CODEC_A_DEV_TO_MEM,55DMA_DEVICE_APM_CODEC_A_MEM_TO_DEV,56DMA_DEVICE_APM_CODEC_B_DEV_TO_MEM,57DMA_DEVICE_APM_CODEC_B_MEM_TO_DEV,58DMA_DEVICE_APM_CODEC_C_DEV_TO_MEM, /* Additional mic input for beam-forming */59DMA_DEVICE_APM_PCM0_DEV_TO_MEM,60DMA_DEVICE_APM_PCM0_MEM_TO_DEV,61DMA_DEVICE_APM_PCM1_DEV_TO_MEM,62DMA_DEVICE_APM_PCM1_MEM_TO_DEV,63DMA_DEVICE_SPUM_DEV_TO_MEM,64DMA_DEVICE_SPUM_MEM_TO_DEV,65DMA_DEVICE_SPIH_DEV_TO_MEM,66DMA_DEVICE_SPIH_MEM_TO_DEV,67DMA_DEVICE_UART_A_DEV_TO_MEM,68DMA_DEVICE_UART_A_MEM_TO_DEV,69DMA_DEVICE_UART_B_DEV_TO_MEM,70DMA_DEVICE_UART_B_MEM_TO_DEV,71DMA_DEVICE_PIF_MEM_TO_DEV,72DMA_DEVICE_PIF_DEV_TO_MEM,73DMA_DEVICE_ESW_DEV_TO_MEM,74DMA_DEVICE_ESW_MEM_TO_DEV,75DMA_DEVICE_VPM_MEM_TO_MEM,76DMA_DEVICE_CLCD_MEM_TO_MEM,77DMA_DEVICE_NAND_MEM_TO_MEM,78DMA_DEVICE_MEM_TO_VRAM,79DMA_DEVICE_VRAM_TO_MEM,8081/* Add new entries before this line. */8283DMA_NUM_DEVICE_ENTRIES,84DMA_DEVICE_NONE = 0xff, /* Special value to indicate that no device is currently assigned. */8586} DMA_Device_t;8788/****************************************************************************89*90* The DMA_Handle_t is the primary object used by callers of the API.91*92*****************************************************************************/9394#define DMA_INVALID_HANDLE ((DMA_Handle_t) -1)9596typedef int DMA_Handle_t;9798/****************************************************************************99*100* The DMA_DescriptorRing_t contains a ring of descriptors which is used101* to point to regions of memory.102*103*****************************************************************************/104105typedef struct {106void *virtAddr; /* Virtual Address of the descriptor ring */107dma_addr_t physAddr; /* Physical address of the descriptor ring */108int descriptorsAllocated; /* Number of descriptors allocated in the descriptor ring */109size_t bytesAllocated; /* Number of bytes allocated in the descriptor ring */110111} DMA_DescriptorRing_t;112113/****************************************************************************114*115* The DMA_MemType_t and DMA_MemMap_t are helper structures used to setup116* DMA chains from a variety of memory sources.117*118*****************************************************************************/119120#define DMA_MEM_MAP_MIN_SIZE 4096 /* Pages less than this size are better */121/* off not being DMA'd. */122123typedef enum {124DMA_MEM_TYPE_NONE, /* Not a valid setting */125DMA_MEM_TYPE_VMALLOC, /* Memory came from vmalloc call */126DMA_MEM_TYPE_KMALLOC, /* Memory came from kmalloc call */127DMA_MEM_TYPE_DMA, /* Memory came from dma_alloc_xxx call */128DMA_MEM_TYPE_USER, /* Memory came from user space. */129130} DMA_MemType_t;131132/* A segment represents a physically and virtually contiguous chunk of memory. */133/* i.e. each segment can be DMA'd */134/* A user of the DMA code will add memory regions. Each region may need to be */135/* represented by one or more segments. */136137typedef struct {138void *virtAddr; /* Virtual address used for this segment */139dma_addr_t physAddr; /* Physical address this segment maps to */140size_t numBytes; /* Size of the segment, in bytes */141142} DMA_Segment_t;143144/* A region represents a virtually contiguous chunk of memory, which may be */145/* made up of multiple segments. */146147typedef struct {148DMA_MemType_t memType;149void *virtAddr;150size_t numBytes;151152/* Each region (virtually contiguous) consists of one or more segments. Each */153/* segment is virtually and physically contiguous. */154155int numSegmentsUsed;156int numSegmentsAllocated;157DMA_Segment_t *segment;158159/* When a region corresponds to user memory, we need to lock all of the pages */160/* down before we can figure out the physical addresses. The lockedPage array contains */161/* the pages that were locked, and which subsequently need to be unlocked once the */162/* memory is unmapped. */163164unsigned numLockedPages;165struct page **lockedPages;166167} DMA_Region_t;168169typedef struct {170int inUse; /* Is this mapping currently being used? */171struct semaphore lock; /* Acquired when using this structure */172enum dma_data_direction dir; /* Direction this transfer is intended for */173174/* In the event that we're mapping user memory, we need to know which task */175/* the memory is for, so that we can obtain the correct mm locks. */176177struct task_struct *userTask;178179int numRegionsUsed;180int numRegionsAllocated;181DMA_Region_t *region;182183} DMA_MemMap_t;184185/****************************************************************************186*187* The DMA_DeviceAttribute_t contains information which describes a188* particular DMA device (or peripheral).189*190* It is anticipated that the arrary of DMA_DeviceAttribute_t's will be191* statically initialized.192*193*****************************************************************************/194195/* The device handler is called whenever a DMA operation completes. The reaon */196/* for it to be called will be a bitmask with one or more of the following bits */197/* set. */198199#define DMA_HANDLER_REASON_BLOCK_COMPLETE dmacHw_INTERRUPT_STATUS_BLOCK200#define DMA_HANDLER_REASON_TRANSFER_COMPLETE dmacHw_INTERRUPT_STATUS_TRANS201#define DMA_HANDLER_REASON_ERROR dmacHw_INTERRUPT_STATUS_ERROR202203typedef void (*DMA_DeviceHandler_t) (DMA_Device_t dev, int reason,204void *userData);205206#define DMA_DEVICE_FLAG_ON_DMA0 0x00000001207#define DMA_DEVICE_FLAG_ON_DMA1 0x00000002208#define DMA_DEVICE_FLAG_PORT_PER_DMAC 0x00000004 /* If set, it means that the port used on DMAC0 is different from the port used on DMAC1 */209#define DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST 0x00000008 /* If set, allocate from DMA1 before allocating from DMA0 */210#define DMA_DEVICE_FLAG_IS_DEDICATED 0x00000100211#define DMA_DEVICE_FLAG_NO_ISR 0x00000200212#define DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO 0x00000400213#define DMA_DEVICE_FLAG_IN_USE 0x00000800 /* If set, device is in use on a channel */214215/* Note: Some DMA devices can be used from multiple DMA Controllers. The bitmask is used to */216/* determine which DMA controllers a given device can be used from, and the interface */217/* array determeines the actual interface number to use for a given controller. */218219typedef struct {220uint32_t flags; /* Bitmask of DMA_DEVICE_FLAG_xxx constants */221uint8_t dedicatedController; /* Controller number to use if DMA_DEVICE_FLAG_IS_DEDICATED is set. */222uint8_t dedicatedChannel; /* Channel number to use if DMA_DEVICE_FLAG_IS_DEDICATED is set. */223const char *name; /* Will show up in the /proc entry */224225uint32_t dmacPort[DMA_NUM_CONTROLLERS]; /* Specifies the port number when DMA_DEVICE_FLAG_PORT_PER_DMAC flag is set */226227dmacHw_CONFIG_t config; /* Configuration to use when DMA'ing using this device */228229void *userData; /* Passed to the devHandler */230DMA_DeviceHandler_t devHandler; /* Called when DMA operations finish. */231232timer_tick_count_t transferStartTime; /* Time the current transfer was started */233234/* The following statistical information will be collected and presented in a proc entry. */235/* Note: With a contiuous bandwidth of 1 Gb/sec, it would take 584 years to overflow */236/* a 64 bit counter. */237238uint64_t numTransfers; /* Number of DMA transfers performed */239uint64_t transferTicks; /* Total time spent doing DMA transfers (measured in timer_tick_count_t's) */240uint64_t transferBytes; /* Total bytes transferred */241uint32_t timesBlocked; /* Number of times a channel was unavailable */242uint32_t numBytes; /* Last transfer size */243244/* It's not possible to free memory which is allocated for the descriptors from within */245/* the ISR. So make the presumption that a given device will tend to use the */246/* same sized buffers over and over again, and we keep them around. */247248DMA_DescriptorRing_t ring; /* Ring of descriptors allocated for this device */249250/* We stash away some of the information from the previous transfer. If back-to-back */251/* transfers are performed from the same buffer, then we don't have to keep re-initializing */252/* the descriptor buffers. */253254uint32_t prevNumBytes;255dma_addr_t prevSrcData;256dma_addr_t prevDstData;257258} DMA_DeviceAttribute_t;259260/****************************************************************************261*262* DMA_Channel_t, DMA_Controller_t, and DMA_State_t are really internal263* data structures and don't belong in this header file, but are included264* merely for discussion.265*266* By the time this is implemented, these structures will be moved out into267* the appropriate C source file instead.268*269*****************************************************************************/270271/****************************************************************************272*273* The DMA_Channel_t contains state information about each DMA channel. Some274* of the channels are dedicated. Non-dedicated channels are shared275* amongst the other devices.276*277*****************************************************************************/278279#define DMA_CHANNEL_FLAG_IN_USE 0x00000001280#define DMA_CHANNEL_FLAG_IS_DEDICATED 0x00000002281#define DMA_CHANNEL_FLAG_NO_ISR 0x00000004282#define DMA_CHANNEL_FLAG_LARGE_FIFO 0x00000008283284typedef struct {285uint32_t flags; /* bitmask of DMA_CHANNEL_FLAG_xxx constants */286DMA_Device_t devType; /* Device this channel is currently reserved for */287DMA_Device_t lastDevType; /* Device type that used this previously */288char name[20]; /* Name passed onto request_irq */289290#if (DMA_DEBUG_TRACK_RESERVATION)291const char *fileName; /* Place where channel reservation took place */292int lineNum; /* Place where channel reservation took place */293#endif294dmacHw_HANDLE_t dmacHwHandle; /* low level channel handle. */295296} DMA_Channel_t;297298/****************************************************************************299*300* The DMA_Controller_t contains state information about each DMA controller.301*302* The freeChannelQ is stored in the controller data structure rather than303* the channel data structure since several of the devices are accessible304* from multiple controllers, and there is no way to know which controller305* will become available first.306*307*****************************************************************************/308309typedef struct {310DMA_Channel_t channel[DMA_NUM_CHANNELS];311312} DMA_Controller_t;313314/****************************************************************************315*316* The DMA_Global_t contains all of the global state information used by317* the DMA code.318*319* Callers which need to allocate a shared channel will be queued up320* on the freeChannelQ until a channel becomes available.321*322*****************************************************************************/323324typedef struct {325struct semaphore lock; /* acquired when manipulating table entries */326wait_queue_head_t freeChannelQ;327328DMA_Controller_t controller[DMA_NUM_CONTROLLERS];329330} DMA_Global_t;331332/* ---- Variable Externs ------------------------------------------------- */333334extern DMA_DeviceAttribute_t DMA_gDeviceAttribute[DMA_NUM_DEVICE_ENTRIES];335336/* ---- Function Prototypes ---------------------------------------------- */337338#if defined(__KERNEL__)339340/****************************************************************************/341/**342* Initializes the DMA module.343*344* @return345* 0 - Success346* < 0 - Error347*/348/****************************************************************************/349350int dma_init(void);351352#if (DMA_DEBUG_TRACK_RESERVATION)353DMA_Handle_t dma_request_channel_dbg(DMA_Device_t dev, const char *fileName,354int lineNum);355#define dma_request_channel(dev) dma_request_channel_dbg(dev, __FILE__, __LINE__)356#else357358/****************************************************************************/359/**360* Reserves a channel for use with @a dev. If the device is setup to use361* a shared channel, then this function will block until a free channel362* becomes available.363*364* @return365* >= 0 - A valid DMA Handle.366* -EBUSY - Device is currently being used.367* -ENODEV - Device handed in is invalid.368*/369/****************************************************************************/370371DMA_Handle_t dma_request_channel(DMA_Device_t dev /* Device to use with the allocated channel. */372);373#endif374375/****************************************************************************/376/**377* Frees a previously allocated DMA Handle.378*379* @return380* 0 - DMA Handle was released successfully.381* -EINVAL - Invalid DMA handle382*/383/****************************************************************************/384385int dma_free_channel(DMA_Handle_t channel /* DMA handle. */386);387388/****************************************************************************/389/**390* Determines if a given device has been configured as using a shared391* channel.392*393* @return boolean394* 0 Device uses a dedicated channel395* non-zero Device uses a shared channel396*/397/****************************************************************************/398399int dma_device_is_channel_shared(DMA_Device_t dev /* Device to check. */400);401402/****************************************************************************/403/**404* Allocates memory to hold a descriptor ring. The descriptor ring then405* needs to be populated by making one or more calls to406* dna_add_descriptors.407*408* The returned descriptor ring will be automatically initialized.409*410* @return411* 0 Descriptor ring was allocated successfully412* -ENOMEM Unable to allocate memory for the desired number of descriptors.413*/414/****************************************************************************/415416int dma_alloc_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to populate */417int numDescriptors /* Number of descriptors that need to be allocated. */418);419420/****************************************************************************/421/**422* Releases the memory which was previously allocated for a descriptor ring.423*/424/****************************************************************************/425426void dma_free_descriptor_ring(DMA_DescriptorRing_t *ring /* Descriptor to release */427);428429/****************************************************************************/430/**431* Initializes a descriptor ring, so that descriptors can be added to it.432* Once a descriptor ring has been allocated, it may be reinitialized for433* use with additional/different regions of memory.434*435* Note that if 7 descriptors are allocated, it's perfectly acceptable to436* initialize the ring with a smaller number of descriptors. The amount437* of memory allocated for the descriptor ring will not be reduced, and438* the descriptor ring may be reinitialized later439*440* @return441* 0 Descriptor ring was initialized successfully442* -ENOMEM The descriptor which was passed in has insufficient space443* to hold the desired number of descriptors.444*/445/****************************************************************************/446447int dma_init_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to initialize */448int numDescriptors /* Number of descriptors to initialize. */449);450451/****************************************************************************/452/**453* Determines the number of descriptors which would be required for a454* transfer of the indicated memory region.455*456* This function also needs to know which DMA device this transfer will457* be destined for, so that the appropriate DMA configuration can be retrieved.458* DMA parameters such as transfer width, and whether this is a memory-to-memory459* or memory-to-peripheral, etc can all affect the actual number of descriptors460* required.461*462* @return463* > 0 Returns the number of descriptors required for the indicated transfer464* -EINVAL Invalid device type for this kind of transfer465* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)466* -ENOMEM Memory exhausted467*/468/****************************************************************************/469470int dma_calculate_descriptor_count(DMA_Device_t device, /* DMA Device that this will be associated with */471dma_addr_t srcData, /* Place to get data to write to device */472dma_addr_t dstData, /* Pointer to device data address */473size_t numBytes /* Number of bytes to transfer to the device */474);475476/****************************************************************************/477/**478* Adds a region of memory to the descriptor ring. Note that it may take479* multiple descriptors for each region of memory. It is the callers480* responsibility to allocate a sufficiently large descriptor ring.481*482* @return483* 0 Descriptors were added successfully484* -EINVAL Invalid device type for this kind of transfer485* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)486* -ENOMEM Memory exhausted487*/488/****************************************************************************/489490int dma_add_descriptors(DMA_DescriptorRing_t *ring, /* Descriptor ring to add descriptors to */491DMA_Device_t device, /* DMA Device that descriptors are for */492dma_addr_t srcData, /* Place to get data (memory or device) */493dma_addr_t dstData, /* Place to put data (memory or device) */494size_t numBytes /* Number of bytes to transfer to the device */495);496497/****************************************************************************/498/**499* Sets the descriptor ring associated with a device.500*501* Once set, the descriptor ring will be associated with the device, even502* across channel request/free calls. Passing in a NULL descriptor ring503* will release any descriptor ring currently associated with the device.504*505* Note: If you call dma_transfer, or one of the other dma_alloc_ functions506* the descriptor ring may be released and reallocated.507*508* Note: This function will release the descriptor memory for any current509* descriptor ring associated with this device.510*/511/****************************************************************************/512513int dma_set_device_descriptor_ring(DMA_Device_t device, /* Device to update the descriptor ring for. */514DMA_DescriptorRing_t *ring /* Descriptor ring to add descriptors to */515);516517/****************************************************************************/518/**519* Retrieves the descriptor ring associated with a device.520*/521/****************************************************************************/522523int dma_get_device_descriptor_ring(DMA_Device_t device, /* Device to retrieve the descriptor ring for. */524DMA_DescriptorRing_t *ring /* Place to store retrieved ring */525);526527/****************************************************************************/528/**529* Allocates buffers for the descriptors. This is normally done automatically530* but needs to be done explicitly when initiating a dma from interrupt531* context.532*533* @return534* 0 Descriptors were allocated successfully535* -EINVAL Invalid device type for this kind of transfer536* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)537* -ENOMEM Memory exhausted538*/539/****************************************************************************/540541int dma_alloc_descriptors(DMA_Handle_t handle, /* DMA Handle */542dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */543dma_addr_t srcData, /* Place to get data to write to device */544dma_addr_t dstData, /* Pointer to device data address */545size_t numBytes /* Number of bytes to transfer to the device */546);547548/****************************************************************************/549/**550* Allocates and sets up descriptors for a double buffered circular buffer.551*552* This is primarily intended to be used for things like the ingress samples553* from a microphone.554*555* @return556* > 0 Number of descriptors actually allocated.557* -EINVAL Invalid device type for this kind of transfer558* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)559* -ENOMEM Memory exhausted560*/561/****************************************************************************/562563int dma_alloc_double_dst_descriptors(DMA_Handle_t handle, /* DMA Handle */564dma_addr_t srcData, /* Physical address of source data */565dma_addr_t dstData1, /* Physical address of first destination buffer */566dma_addr_t dstData2, /* Physical address of second destination buffer */567size_t numBytes /* Number of bytes in each destination buffer */568);569570/****************************************************************************/571/**572* Initializes a DMA_MemMap_t data structure573*/574/****************************************************************************/575576int dma_init_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */577);578579/****************************************************************************/580/**581* Releases any memory currently being held by a memory mapping structure.582*/583/****************************************************************************/584585int dma_term_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */586);587588/****************************************************************************/589/**590* Looks at a memory address and categorizes it.591*592* @return One of the values from the DMA_MemType_t enumeration.593*/594/****************************************************************************/595596DMA_MemType_t dma_mem_type(void *addr);597598/****************************************************************************/599/**600* Sets the process (aka userTask) associated with a mem map. This is601* required if user-mode segments will be added to the mapping.602*/603/****************************************************************************/604605static inline void dma_mem_map_set_user_task(DMA_MemMap_t *memMap,606struct task_struct *task)607{608memMap->userTask = task;609}610611/****************************************************************************/612/**613* Looks at a memory address and determines if we support DMA'ing to/from614* that type of memory.615*616* @return boolean -617* return value != 0 means dma supported618* return value == 0 means dma not supported619*/620/****************************************************************************/621622int dma_mem_supports_dma(void *addr);623624/****************************************************************************/625/**626* Initializes a memory map for use. Since this function acquires a627* sempaphore within the memory map, it is VERY important that dma_unmap628* be called when you're finished using the map.629*/630/****************************************************************************/631632int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */633enum dma_data_direction dir /* Direction that the mapping will be going */634);635636/****************************************************************************/637/**638* Adds a segment of memory to a memory map.639*640* @return 0 on success, error code otherwise.641*/642/****************************************************************************/643644int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */645void *mem, /* Virtual address that we want to get a map of */646size_t numBytes /* Number of bytes being mapped */647);648649/****************************************************************************/650/**651* Creates a descriptor ring from a memory mapping.652*653* @return 0 on success, error code otherwise.654*/655/****************************************************************************/656657int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */658DMA_MemMap_t *memMap, /* Memory map that will be used */659dma_addr_t devPhysAddr /* Physical address of device */660);661662/****************************************************************************/663/**664* Maps in a memory region such that it can be used for performing a DMA.665*666* @return667*/668/****************************************************************************/669670int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */671void *addr, /* Virtual address that we want to get a map of */672size_t count, /* Number of bytes being mapped */673enum dma_data_direction dir /* Direction that the mapping will be going */674);675676/****************************************************************************/677/**678* Maps in a memory region such that it can be used for performing a DMA.679*680* @return681*/682/****************************************************************************/683684int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */685int dirtied /* non-zero if any of the pages were modified */686);687688/****************************************************************************/689/**690* Initiates a transfer when the descriptors have already been setup.691*692* This is a special case, and normally, the dma_transfer_xxx functions should693* be used.694*695* @return696* 0 Transfer was started successfully697* -ENODEV Invalid handle698*/699/****************************************************************************/700701int dma_start_transfer(DMA_Handle_t handle);702703/****************************************************************************/704/**705* Stops a previously started DMA transfer.706*707* @return708* 0 Transfer was stopped successfully709* -ENODEV Invalid handle710*/711/****************************************************************************/712713int dma_stop_transfer(DMA_Handle_t handle);714715/****************************************************************************/716/**717* Waits for a DMA to complete by polling. This function is only intended718* to be used for testing. Interrupts should be used for most DMA operations.719*/720/****************************************************************************/721722int dma_wait_transfer_done(DMA_Handle_t handle);723724/****************************************************************************/725/**726* Initiates a DMA transfer727*728* @return729* 0 Transfer was started successfully730* -EINVAL Invalid device type for this kind of transfer731* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)732*/733/****************************************************************************/734735int dma_transfer(DMA_Handle_t handle, /* DMA Handle */736dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */737dma_addr_t srcData, /* Place to get data to write to device */738dma_addr_t dstData, /* Pointer to device data address */739size_t numBytes /* Number of bytes to transfer to the device */740);741742/****************************************************************************/743/**744* Initiates a transfer from memory to a device.745*746* @return747* 0 Transfer was started successfully748* -EINVAL Invalid device type for this kind of transfer749* (i.e. the device is _DEV_TO_MEM and not _MEM_TO_DEV)750*/751/****************************************************************************/752753static inline int dma_transfer_to_device(DMA_Handle_t handle, /* DMA Handle */754dma_addr_t srcData, /* Place to get data to write to device (physical address) */755dma_addr_t dstData, /* Pointer to device data address (physical address) */756size_t numBytes /* Number of bytes to transfer to the device */757) {758return dma_transfer(handle,759dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,760srcData, dstData, numBytes);761}762763/****************************************************************************/764/**765* Initiates a transfer from a device to memory.766*767* @return768* 0 Transfer was started successfully769* -EINVAL Invalid device type for this kind of transfer770* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)771*/772/****************************************************************************/773774static inline int dma_transfer_from_device(DMA_Handle_t handle, /* DMA Handle */775dma_addr_t srcData, /* Pointer to the device data address (physical address) */776dma_addr_t dstData, /* Place to store data retrieved from the device (physical address) */777size_t numBytes /* Number of bytes to retrieve from the device */778) {779return dma_transfer(handle,780dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,781srcData, dstData, numBytes);782}783784/****************************************************************************/785/**786* Initiates a memory to memory transfer.787*788* @return789* 0 Transfer was started successfully790* -EINVAL Invalid device type for this kind of transfer791* (i.e. the device wasn't DMA_DEVICE_MEM_TO_MEM)792*/793/****************************************************************************/794795static inline int dma_transfer_mem_to_mem(DMA_Handle_t handle, /* DMA Handle */796dma_addr_t srcData, /* Place to transfer data from (physical address) */797dma_addr_t dstData, /* Place to transfer data to (physical address) */798size_t numBytes /* Number of bytes to transfer */799) {800return dma_transfer(handle,801dmacHw_TRANSFER_TYPE_MEM_TO_MEM,802srcData, dstData, numBytes);803}804805/****************************************************************************/806/**807* Set the callback function which will be called when a transfer completes.808* If a NULL callback function is set, then no callback will occur.809*810* @note @a devHandler will be called from IRQ context.811*812* @return813* 0 - Success814* -ENODEV - Device handed in is invalid.815*/816/****************************************************************************/817818int dma_set_device_handler(DMA_Device_t dev, /* Device to set the callback for. */819DMA_DeviceHandler_t devHandler, /* Function to call when the DMA completes */820void *userData /* Pointer which will be passed to devHandler. */821);822823#endif824825#endif /* ASM_ARM_ARCH_BCMRING_DMA_H */826827828