1/***************************************************************************** 2* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. 3* 4* Unless you and Broadcom execute a separate written software license 5* agreement governing use of this software, this software is licensed to you 6* under the terms of the GNU General Public License version 2, available at 7* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). 8* 9* Notwithstanding the above, under no circumstances may you combine this 10* software in any way with any other Broadcom software provided under a 11* license other than the GPL, without Broadcom's express prior written 12* consent. 13*****************************************************************************/ 14 15/****************************************************************************/ 16/** 17* @file dma.h 18* 19* @brief API definitions for the linux DMA interface. 20*/ 21/****************************************************************************/ 22 23#if !defined(ASM_ARM_ARCH_BCMRING_DMA_H) 24#define ASM_ARM_ARCH_BCMRING_DMA_H 25 26/* ---- Include Files ---------------------------------------------------- */ 27 28#include <linux/kernel.h> 29#include <linux/wait.h> 30#include <linux/semaphore.h> 31#include <csp/dmacHw.h> 32#include <mach/timer.h> 33#include <linux/scatterlist.h> 34#include <linux/dma-mapping.h> 35#include <linux/mm.h> 36#include <linux/vmalloc.h> 37#include <linux/pagemap.h> 38 39/* ---- Constants and Types ---------------------------------------------- */ 40 41/* If DMA_DEBUG_TRACK_RESERVATION is set to a non-zero value, then the filename */ 42/* and line number of the reservation request will be recorded in the channel table */ 43 44#define DMA_DEBUG_TRACK_RESERVATION 1 45 46#define DMA_NUM_CONTROLLERS 2 47#define DMA_NUM_CHANNELS 8 /* per controller */ 48 49typedef enum { 50 DMA_DEVICE_MEM_TO_MEM, /* For memory to memory transfers */ 51 DMA_DEVICE_I2S0_DEV_TO_MEM, 52 DMA_DEVICE_I2S0_MEM_TO_DEV, 53 DMA_DEVICE_I2S1_DEV_TO_MEM, 54 DMA_DEVICE_I2S1_MEM_TO_DEV, 55 DMA_DEVICE_APM_CODEC_A_DEV_TO_MEM, 56 DMA_DEVICE_APM_CODEC_A_MEM_TO_DEV, 57 DMA_DEVICE_APM_CODEC_B_DEV_TO_MEM, 58 DMA_DEVICE_APM_CODEC_B_MEM_TO_DEV, 59 DMA_DEVICE_APM_CODEC_C_DEV_TO_MEM, /* Additional mic input for beam-forming */ 60 DMA_DEVICE_APM_PCM0_DEV_TO_MEM, 61 DMA_DEVICE_APM_PCM0_MEM_TO_DEV, 62 DMA_DEVICE_APM_PCM1_DEV_TO_MEM, 63 DMA_DEVICE_APM_PCM1_MEM_TO_DEV, 64 DMA_DEVICE_SPUM_DEV_TO_MEM, 65 DMA_DEVICE_SPUM_MEM_TO_DEV, 66 DMA_DEVICE_SPIH_DEV_TO_MEM, 67 DMA_DEVICE_SPIH_MEM_TO_DEV, 68 DMA_DEVICE_UART_A_DEV_TO_MEM, 69 DMA_DEVICE_UART_A_MEM_TO_DEV, 70 DMA_DEVICE_UART_B_DEV_TO_MEM, 71 DMA_DEVICE_UART_B_MEM_TO_DEV, 72 DMA_DEVICE_PIF_MEM_TO_DEV, 73 DMA_DEVICE_PIF_DEV_TO_MEM, 74 DMA_DEVICE_ESW_DEV_TO_MEM, 75 DMA_DEVICE_ESW_MEM_TO_DEV, 76 DMA_DEVICE_VPM_MEM_TO_MEM, 77 DMA_DEVICE_CLCD_MEM_TO_MEM, 78 DMA_DEVICE_NAND_MEM_TO_MEM, 79 DMA_DEVICE_MEM_TO_VRAM, 80 DMA_DEVICE_VRAM_TO_MEM, 81 82 /* Add new entries before this line. */ 83 84 DMA_NUM_DEVICE_ENTRIES, 85 DMA_DEVICE_NONE = 0xff, /* Special value to indicate that no device is currently assigned. */ 86 87} DMA_Device_t; 88 89/**************************************************************************** 90* 91* The DMA_Handle_t is the primary object used by callers of the API. 92* 93*****************************************************************************/ 94 95#define DMA_INVALID_HANDLE ((DMA_Handle_t) -1) 96 97typedef int DMA_Handle_t; 98 99/**************************************************************************** 100* 101* The DMA_DescriptorRing_t contains a ring of descriptors which is used 102* to point to regions of memory. 103* 104*****************************************************************************/ 105 106typedef struct { 107 void *virtAddr; /* Virtual Address of the descriptor ring */ 108 dma_addr_t physAddr; /* Physical address of the descriptor ring */ 109 int descriptorsAllocated; /* Number of descriptors allocated in the descriptor ring */ 110 size_t bytesAllocated; /* Number of bytes allocated in the descriptor ring */ 111 112} DMA_DescriptorRing_t; 113 114/**************************************************************************** 115* 116* The DMA_MemType_t and DMA_MemMap_t are helper structures used to setup 117* DMA chains from a variety of memory sources. 118* 119*****************************************************************************/ 120 121#define DMA_MEM_MAP_MIN_SIZE 4096 /* Pages less than this size are better */ 122 /* off not being DMA'd. */ 123 124typedef enum { 125 DMA_MEM_TYPE_NONE, /* Not a valid setting */ 126 DMA_MEM_TYPE_VMALLOC, /* Memory came from vmalloc call */ 127 DMA_MEM_TYPE_KMALLOC, /* Memory came from kmalloc call */ 128 DMA_MEM_TYPE_DMA, /* Memory came from dma_alloc_xxx call */ 129 DMA_MEM_TYPE_USER, /* Memory came from user space. */ 130 131} DMA_MemType_t; 132 133/* A segment represents a physically and virtually contiguous chunk of memory. */ 134/* i.e. each segment can be DMA'd */ 135/* A user of the DMA code will add memory regions. Each region may need to be */ 136/* represented by one or more segments. */ 137 138typedef struct { 139 void *virtAddr; /* Virtual address used for this segment */ 140 dma_addr_t physAddr; /* Physical address this segment maps to */ 141 size_t numBytes; /* Size of the segment, in bytes */ 142 143} DMA_Segment_t; 144 145/* A region represents a virtually contiguous chunk of memory, which may be */ 146/* made up of multiple segments. */ 147 148typedef struct { 149 DMA_MemType_t memType; 150 void *virtAddr; 151 size_t numBytes; 152 153 /* Each region (virtually contiguous) consists of one or more segments. Each */ 154 /* segment is virtually and physically contiguous. */ 155 156 int numSegmentsUsed; 157 int numSegmentsAllocated; 158 DMA_Segment_t *segment; 159 160 /* When a region corresponds to user memory, we need to lock all of the pages */ 161 /* down before we can figure out the physical addresses. The lockedPage array contains */ 162 /* the pages that were locked, and which subsequently need to be unlocked once the */ 163 /* memory is unmapped. */ 164 165 unsigned numLockedPages; 166 struct page **lockedPages; 167 168} DMA_Region_t; 169 170typedef struct { 171 int inUse; /* Is this mapping currently being used? */ 172 struct semaphore lock; /* Acquired when using this structure */ 173 enum dma_data_direction dir; /* Direction this transfer is intended for */ 174 175 /* In the event that we're mapping user memory, we need to know which task */ 176 /* the memory is for, so that we can obtain the correct mm locks. */ 177 178 struct task_struct *userTask; 179 180 int numRegionsUsed; 181 int numRegionsAllocated; 182 DMA_Region_t *region; 183 184} DMA_MemMap_t; 185 186/**************************************************************************** 187* 188* The DMA_DeviceAttribute_t contains information which describes a 189* particular DMA device (or peripheral). 190* 191* It is anticipated that the arrary of DMA_DeviceAttribute_t's will be 192* statically initialized. 193* 194*****************************************************************************/ 195 196/* The device handler is called whenever a DMA operation completes. The reaon */ 197/* for it to be called will be a bitmask with one or more of the following bits */ 198/* set. */ 199 200#define DMA_HANDLER_REASON_BLOCK_COMPLETE dmacHw_INTERRUPT_STATUS_BLOCK 201#define DMA_HANDLER_REASON_TRANSFER_COMPLETE dmacHw_INTERRUPT_STATUS_TRANS 202#define DMA_HANDLER_REASON_ERROR dmacHw_INTERRUPT_STATUS_ERROR 203 204typedef void (*DMA_DeviceHandler_t) (DMA_Device_t dev, int reason, 205 void *userData); 206 207#define DMA_DEVICE_FLAG_ON_DMA0 0x00000001 208#define DMA_DEVICE_FLAG_ON_DMA1 0x00000002 209#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 */ 210#define DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST 0x00000008 /* If set, allocate from DMA1 before allocating from DMA0 */ 211#define DMA_DEVICE_FLAG_IS_DEDICATED 0x00000100 212#define DMA_DEVICE_FLAG_NO_ISR 0x00000200 213#define DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO 0x00000400 214#define DMA_DEVICE_FLAG_IN_USE 0x00000800 /* If set, device is in use on a channel */ 215 216/* Note: Some DMA devices can be used from multiple DMA Controllers. The bitmask is used to */ 217/* determine which DMA controllers a given device can be used from, and the interface */ 218/* array determeines the actual interface number to use for a given controller. */ 219 220typedef struct { 221 uint32_t flags; /* Bitmask of DMA_DEVICE_FLAG_xxx constants */ 222 uint8_t dedicatedController; /* Controller number to use if DMA_DEVICE_FLAG_IS_DEDICATED is set. */ 223 uint8_t dedicatedChannel; /* Channel number to use if DMA_DEVICE_FLAG_IS_DEDICATED is set. */ 224 const char *name; /* Will show up in the /proc entry */ 225 226 uint32_t dmacPort[DMA_NUM_CONTROLLERS]; /* Specifies the port number when DMA_DEVICE_FLAG_PORT_PER_DMAC flag is set */ 227 228 dmacHw_CONFIG_t config; /* Configuration to use when DMA'ing using this device */ 229 230 void *userData; /* Passed to the devHandler */ 231 DMA_DeviceHandler_t devHandler; /* Called when DMA operations finish. */ 232 233 timer_tick_count_t transferStartTime; /* Time the current transfer was started */ 234 235 /* The following statistical information will be collected and presented in a proc entry. */ 236 /* Note: With a contiuous bandwidth of 1 Gb/sec, it would take 584 years to overflow */ 237 /* a 64 bit counter. */ 238 239 uint64_t numTransfers; /* Number of DMA transfers performed */ 240 uint64_t transferTicks; /* Total time spent doing DMA transfers (measured in timer_tick_count_t's) */ 241 uint64_t transferBytes; /* Total bytes transferred */ 242 uint32_t timesBlocked; /* Number of times a channel was unavailable */ 243 uint32_t numBytes; /* Last transfer size */ 244 245 /* It's not possible to free memory which is allocated for the descriptors from within */ 246 /* the ISR. So make the presumption that a given device will tend to use the */ 247 /* same sized buffers over and over again, and we keep them around. */ 248 249 DMA_DescriptorRing_t ring; /* Ring of descriptors allocated for this device */ 250 251 /* We stash away some of the information from the previous transfer. If back-to-back */ 252 /* transfers are performed from the same buffer, then we don't have to keep re-initializing */ 253 /* the descriptor buffers. */ 254 255 uint32_t prevNumBytes; 256 dma_addr_t prevSrcData; 257 dma_addr_t prevDstData; 258 259} DMA_DeviceAttribute_t; 260 261/**************************************************************************** 262* 263* DMA_Channel_t, DMA_Controller_t, and DMA_State_t are really internal 264* data structures and don't belong in this header file, but are included 265* merely for discussion. 266* 267* By the time this is implemented, these structures will be moved out into 268* the appropriate C source file instead. 269* 270*****************************************************************************/ 271 272/**************************************************************************** 273* 274* The DMA_Channel_t contains state information about each DMA channel. Some 275* of the channels are dedicated. Non-dedicated channels are shared 276* amongst the other devices. 277* 278*****************************************************************************/ 279 280#define DMA_CHANNEL_FLAG_IN_USE 0x00000001 281#define DMA_CHANNEL_FLAG_IS_DEDICATED 0x00000002 282#define DMA_CHANNEL_FLAG_NO_ISR 0x00000004 283#define DMA_CHANNEL_FLAG_LARGE_FIFO 0x00000008 284 285typedef struct { 286 uint32_t flags; /* bitmask of DMA_CHANNEL_FLAG_xxx constants */ 287 DMA_Device_t devType; /* Device this channel is currently reserved for */ 288 DMA_Device_t lastDevType; /* Device type that used this previously */ 289 char name[20]; /* Name passed onto request_irq */ 290 291#if (DMA_DEBUG_TRACK_RESERVATION) 292 const char *fileName; /* Place where channel reservation took place */ 293 int lineNum; /* Place where channel reservation took place */ 294#endif 295 dmacHw_HANDLE_t dmacHwHandle; /* low level channel handle. */ 296 297} DMA_Channel_t; 298 299/**************************************************************************** 300* 301* The DMA_Controller_t contains state information about each DMA controller. 302* 303* The freeChannelQ is stored in the controller data structure rather than 304* the channel data structure since several of the devices are accessible 305* from multiple controllers, and there is no way to know which controller 306* will become available first. 307* 308*****************************************************************************/ 309 310typedef struct { 311 DMA_Channel_t channel[DMA_NUM_CHANNELS]; 312 313} DMA_Controller_t; 314 315/**************************************************************************** 316* 317* The DMA_Global_t contains all of the global state information used by 318* the DMA code. 319* 320* Callers which need to allocate a shared channel will be queued up 321* on the freeChannelQ until a channel becomes available. 322* 323*****************************************************************************/ 324 325typedef struct { 326 struct semaphore lock; /* acquired when manipulating table entries */ 327 wait_queue_head_t freeChannelQ; 328 329 DMA_Controller_t controller[DMA_NUM_CONTROLLERS]; 330 331} DMA_Global_t; 332 333/* ---- Variable Externs ------------------------------------------------- */ 334 335extern DMA_DeviceAttribute_t DMA_gDeviceAttribute[DMA_NUM_DEVICE_ENTRIES]; 336 337/* ---- Function Prototypes ---------------------------------------------- */ 338 339#if defined(__KERNEL__) 340 341/****************************************************************************/ 342/** 343* Initializes the DMA module. 344* 345* @return 346* 0 - Success 347* < 0 - Error 348*/ 349/****************************************************************************/ 350 351int dma_init(void); 352 353#if (DMA_DEBUG_TRACK_RESERVATION) 354DMA_Handle_t dma_request_channel_dbg(DMA_Device_t dev, const char *fileName, 355 int lineNum); 356#define dma_request_channel(dev) dma_request_channel_dbg(dev, __FILE__, __LINE__) 357#else 358 359/****************************************************************************/ 360/** 361* Reserves a channel for use with @a dev. If the device is setup to use 362* a shared channel, then this function will block until a free channel 363* becomes available. 364* 365* @return 366* >= 0 - A valid DMA Handle. 367* -EBUSY - Device is currently being used. 368* -ENODEV - Device handed in is invalid. 369*/ 370/****************************************************************************/ 371 372DMA_Handle_t dma_request_channel(DMA_Device_t dev /* Device to use with the allocated channel. */ 373 ); 374#endif 375 376/****************************************************************************/ 377/** 378* Frees a previously allocated DMA Handle. 379* 380* @return 381* 0 - DMA Handle was released successfully. 382* -EINVAL - Invalid DMA handle 383*/ 384/****************************************************************************/ 385 386int dma_free_channel(DMA_Handle_t channel /* DMA handle. */ 387 ); 388 389/****************************************************************************/ 390/** 391* Determines if a given device has been configured as using a shared 392* channel. 393* 394* @return boolean 395* 0 Device uses a dedicated channel 396* non-zero Device uses a shared channel 397*/ 398/****************************************************************************/ 399 400int dma_device_is_channel_shared(DMA_Device_t dev /* Device to check. */ 401 ); 402 403/****************************************************************************/ 404/** 405* Allocates memory to hold a descriptor ring. The descriptor ring then 406* needs to be populated by making one or more calls to 407* dna_add_descriptors. 408* 409* The returned descriptor ring will be automatically initialized. 410* 411* @return 412* 0 Descriptor ring was allocated successfully 413* -ENOMEM Unable to allocate memory for the desired number of descriptors. 414*/ 415/****************************************************************************/ 416 417int dma_alloc_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to populate */ 418 int numDescriptors /* Number of descriptors that need to be allocated. */ 419 ); 420 421/****************************************************************************/ 422/** 423* Releases the memory which was previously allocated for a descriptor ring. 424*/ 425/****************************************************************************/ 426 427void dma_free_descriptor_ring(DMA_DescriptorRing_t *ring /* Descriptor to release */ 428 ); 429 430/****************************************************************************/ 431/** 432* Initializes a descriptor ring, so that descriptors can be added to it. 433* Once a descriptor ring has been allocated, it may be reinitialized for 434* use with additional/different regions of memory. 435* 436* Note that if 7 descriptors are allocated, it's perfectly acceptable to 437* initialize the ring with a smaller number of descriptors. The amount 438* of memory allocated for the descriptor ring will not be reduced, and 439* the descriptor ring may be reinitialized later 440* 441* @return 442* 0 Descriptor ring was initialized successfully 443* -ENOMEM The descriptor which was passed in has insufficient space 444* to hold the desired number of descriptors. 445*/ 446/****************************************************************************/ 447 448int dma_init_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to initialize */ 449 int numDescriptors /* Number of descriptors to initialize. */ 450 ); 451 452/****************************************************************************/ 453/** 454* Determines the number of descriptors which would be required for a 455* transfer of the indicated memory region. 456* 457* This function also needs to know which DMA device this transfer will 458* be destined for, so that the appropriate DMA configuration can be retrieved. 459* DMA parameters such as transfer width, and whether this is a memory-to-memory 460* or memory-to-peripheral, etc can all affect the actual number of descriptors 461* required. 462* 463* @return 464* > 0 Returns the number of descriptors required for the indicated transfer 465* -EINVAL Invalid device type for this kind of transfer 466* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM) 467* -ENOMEM Memory exhausted 468*/ 469/****************************************************************************/ 470 471int dma_calculate_descriptor_count(DMA_Device_t device, /* DMA Device that this will be associated with */ 472 dma_addr_t srcData, /* Place to get data to write to device */ 473 dma_addr_t dstData, /* Pointer to device data address */ 474 size_t numBytes /* Number of bytes to transfer to the device */ 475 ); 476 477/****************************************************************************/ 478/** 479* Adds a region of memory to the descriptor ring. Note that it may take 480* multiple descriptors for each region of memory. It is the callers 481* responsibility to allocate a sufficiently large descriptor ring. 482* 483* @return 484* 0 Descriptors were added successfully 485* -EINVAL Invalid device type for this kind of transfer 486* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM) 487* -ENOMEM Memory exhausted 488*/ 489/****************************************************************************/ 490 491int dma_add_descriptors(DMA_DescriptorRing_t *ring, /* Descriptor ring to add descriptors to */ 492 DMA_Device_t device, /* DMA Device that descriptors are for */ 493 dma_addr_t srcData, /* Place to get data (memory or device) */ 494 dma_addr_t dstData, /* Place to put data (memory or device) */ 495 size_t numBytes /* Number of bytes to transfer to the device */ 496 ); 497 498/****************************************************************************/ 499/** 500* Sets the descriptor ring associated with a device. 501* 502* Once set, the descriptor ring will be associated with the device, even 503* across channel request/free calls. Passing in a NULL descriptor ring 504* will release any descriptor ring currently associated with the device. 505* 506* Note: If you call dma_transfer, or one of the other dma_alloc_ functions 507* the descriptor ring may be released and reallocated. 508* 509* Note: This function will release the descriptor memory for any current 510* descriptor ring associated with this device. 511*/ 512/****************************************************************************/ 513 514int dma_set_device_descriptor_ring(DMA_Device_t device, /* Device to update the descriptor ring for. */ 515 DMA_DescriptorRing_t *ring /* Descriptor ring to add descriptors to */ 516 ); 517 518/****************************************************************************/ 519/** 520* Retrieves the descriptor ring associated with a device. 521*/ 522/****************************************************************************/ 523 524int dma_get_device_descriptor_ring(DMA_Device_t device, /* Device to retrieve the descriptor ring for. */ 525 DMA_DescriptorRing_t *ring /* Place to store retrieved ring */ 526 ); 527 528/****************************************************************************/ 529/** 530* Allocates buffers for the descriptors. This is normally done automatically 531* but needs to be done explicitly when initiating a dma from interrupt 532* context. 533* 534* @return 535* 0 Descriptors were allocated successfully 536* -EINVAL Invalid device type for this kind of transfer 537* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM) 538* -ENOMEM Memory exhausted 539*/ 540/****************************************************************************/ 541 542int dma_alloc_descriptors(DMA_Handle_t handle, /* DMA Handle */ 543 dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */ 544 dma_addr_t srcData, /* Place to get data to write to device */ 545 dma_addr_t dstData, /* Pointer to device data address */ 546 size_t numBytes /* Number of bytes to transfer to the device */ 547 ); 548 549/****************************************************************************/ 550/** 551* Allocates and sets up descriptors for a double buffered circular buffer. 552* 553* This is primarily intended to be used for things like the ingress samples 554* from a microphone. 555* 556* @return 557* > 0 Number of descriptors actually allocated. 558* -EINVAL Invalid device type for this kind of transfer 559* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM) 560* -ENOMEM Memory exhausted 561*/ 562/****************************************************************************/ 563 564int dma_alloc_double_dst_descriptors(DMA_Handle_t handle, /* DMA Handle */ 565 dma_addr_t srcData, /* Physical address of source data */ 566 dma_addr_t dstData1, /* Physical address of first destination buffer */ 567 dma_addr_t dstData2, /* Physical address of second destination buffer */ 568 size_t numBytes /* Number of bytes in each destination buffer */ 569 ); 570 571/****************************************************************************/ 572/** 573* Initializes a DMA_MemMap_t data structure 574*/ 575/****************************************************************************/ 576 577int dma_init_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */ 578 ); 579 580/****************************************************************************/ 581/** 582* Releases any memory currently being held by a memory mapping structure. 583*/ 584/****************************************************************************/ 585 586int dma_term_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */ 587 ); 588 589/****************************************************************************/ 590/** 591* Looks at a memory address and categorizes it. 592* 593* @return One of the values from the DMA_MemType_t enumeration. 594*/ 595/****************************************************************************/ 596 597DMA_MemType_t dma_mem_type(void *addr); 598 599/****************************************************************************/ 600/** 601* Sets the process (aka userTask) associated with a mem map. This is 602* required if user-mode segments will be added to the mapping. 603*/ 604/****************************************************************************/ 605 606static inline void dma_mem_map_set_user_task(DMA_MemMap_t *memMap, 607 struct task_struct *task) 608{ 609 memMap->userTask = task; 610} 611 612/****************************************************************************/ 613/** 614* Looks at a memory address and determines if we support DMA'ing to/from 615* that type of memory. 616* 617* @return boolean - 618* return value != 0 means dma supported 619* return value == 0 means dma not supported 620*/ 621/****************************************************************************/ 622 623int dma_mem_supports_dma(void *addr); 624 625/****************************************************************************/ 626/** 627* Initializes a memory map for use. Since this function acquires a 628* sempaphore within the memory map, it is VERY important that dma_unmap 629* be called when you're finished using the map. 630*/ 631/****************************************************************************/ 632 633int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */ 634 enum dma_data_direction dir /* Direction that the mapping will be going */ 635 ); 636 637/****************************************************************************/ 638/** 639* Adds a segment of memory to a memory map. 640* 641* @return 0 on success, error code otherwise. 642*/ 643/****************************************************************************/ 644 645int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */ 646 void *mem, /* Virtual address that we want to get a map of */ 647 size_t numBytes /* Number of bytes being mapped */ 648 ); 649 650/****************************************************************************/ 651/** 652* Creates a descriptor ring from a memory mapping. 653* 654* @return 0 on success, error code otherwise. 655*/ 656/****************************************************************************/ 657 658int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */ 659 DMA_MemMap_t *memMap, /* Memory map that will be used */ 660 dma_addr_t devPhysAddr /* Physical address of device */ 661 ); 662 663/****************************************************************************/ 664/** 665* Maps in a memory region such that it can be used for performing a DMA. 666* 667* @return 668*/ 669/****************************************************************************/ 670 671int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */ 672 void *addr, /* Virtual address that we want to get a map of */ 673 size_t count, /* Number of bytes being mapped */ 674 enum dma_data_direction dir /* Direction that the mapping will be going */ 675 ); 676 677/****************************************************************************/ 678/** 679* Maps in a memory region such that it can be used for performing a DMA. 680* 681* @return 682*/ 683/****************************************************************************/ 684 685int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */ 686 int dirtied /* non-zero if any of the pages were modified */ 687 ); 688 689/****************************************************************************/ 690/** 691* Initiates a transfer when the descriptors have already been setup. 692* 693* This is a special case, and normally, the dma_transfer_xxx functions should 694* be used. 695* 696* @return 697* 0 Transfer was started successfully 698* -ENODEV Invalid handle 699*/ 700/****************************************************************************/ 701 702int dma_start_transfer(DMA_Handle_t handle); 703 704/****************************************************************************/ 705/** 706* Stops a previously started DMA transfer. 707* 708* @return 709* 0 Transfer was stopped successfully 710* -ENODEV Invalid handle 711*/ 712/****************************************************************************/ 713 714int dma_stop_transfer(DMA_Handle_t handle); 715 716/****************************************************************************/ 717/** 718* Waits for a DMA to complete by polling. This function is only intended 719* to be used for testing. Interrupts should be used for most DMA operations. 720*/ 721/****************************************************************************/ 722 723int dma_wait_transfer_done(DMA_Handle_t handle); 724 725/****************************************************************************/ 726/** 727* Initiates a DMA transfer 728* 729* @return 730* 0 Transfer was started successfully 731* -EINVAL Invalid device type for this kind of transfer 732* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM) 733*/ 734/****************************************************************************/ 735 736int dma_transfer(DMA_Handle_t handle, /* DMA Handle */ 737 dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */ 738 dma_addr_t srcData, /* Place to get data to write to device */ 739 dma_addr_t dstData, /* Pointer to device data address */ 740 size_t numBytes /* Number of bytes to transfer to the device */ 741 ); 742 743/****************************************************************************/ 744/** 745* Initiates a transfer from memory to a device. 746* 747* @return 748* 0 Transfer was started successfully 749* -EINVAL Invalid device type for this kind of transfer 750* (i.e. the device is _DEV_TO_MEM and not _MEM_TO_DEV) 751*/ 752/****************************************************************************/ 753 754static inline int dma_transfer_to_device(DMA_Handle_t handle, /* DMA Handle */ 755 dma_addr_t srcData, /* Place to get data to write to device (physical address) */ 756 dma_addr_t dstData, /* Pointer to device data address (physical address) */ 757 size_t numBytes /* Number of bytes to transfer to the device */ 758 ) { 759 return dma_transfer(handle, 760 dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, 761 srcData, dstData, numBytes); 762} 763 764/****************************************************************************/ 765/** 766* Initiates a transfer from a device to memory. 767* 768* @return 769* 0 Transfer was started successfully 770* -EINVAL Invalid device type for this kind of transfer 771* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM) 772*/ 773/****************************************************************************/ 774 775static inline int dma_transfer_from_device(DMA_Handle_t handle, /* DMA Handle */ 776 dma_addr_t srcData, /* Pointer to the device data address (physical address) */ 777 dma_addr_t dstData, /* Place to store data retrieved from the device (physical address) */ 778 size_t numBytes /* Number of bytes to retrieve from the device */ 779 ) { 780 return dma_transfer(handle, 781 dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, 782 srcData, dstData, numBytes); 783} 784 785/****************************************************************************/ 786/** 787* Initiates a memory to memory transfer. 788* 789* @return 790* 0 Transfer was started successfully 791* -EINVAL Invalid device type for this kind of transfer 792* (i.e. the device wasn't DMA_DEVICE_MEM_TO_MEM) 793*/ 794/****************************************************************************/ 795 796static inline int dma_transfer_mem_to_mem(DMA_Handle_t handle, /* DMA Handle */ 797 dma_addr_t srcData, /* Place to transfer data from (physical address) */ 798 dma_addr_t dstData, /* Place to transfer data to (physical address) */ 799 size_t numBytes /* Number of bytes to transfer */ 800 ) { 801 return dma_transfer(handle, 802 dmacHw_TRANSFER_TYPE_MEM_TO_MEM, 803 srcData, dstData, numBytes); 804} 805 806/****************************************************************************/ 807/** 808* Set the callback function which will be called when a transfer completes. 809* If a NULL callback function is set, then no callback will occur. 810* 811* @note @a devHandler will be called from IRQ context. 812* 813* @return 814* 0 - Success 815* -ENODEV - Device handed in is invalid. 816*/ 817/****************************************************************************/ 818 819int dma_set_device_handler(DMA_Device_t dev, /* Device to set the callback for. */ 820 DMA_DeviceHandler_t devHandler, /* Function to call when the DMA completes */ 821 void *userData /* Pointer which will be passed to devHandler. */ 822 ); 823 824#endif 825 826#endif /* ASM_ARM_ARCH_BCMRING_DMA_H */ 827

