linux/arch/arm/mach-bcmring/include/mach/dma.h
<<
>>
Prefs
   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
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.