Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-bcmring/include/mach/dma.h
10820 views
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
49
typedef 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
97
typedef 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
106
typedef 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
124
typedef 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
138
typedef 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
148
typedef 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
170
typedef 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
204
typedef 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
220
typedef 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
285
typedef 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
310
typedef 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
325
typedef 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
335
extern 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
351
int dma_init(void);
352
353
#if (DMA_DEBUG_TRACK_RESERVATION)
354
DMA_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
372
DMA_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
386
int 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
400
int 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
417
int 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
427
void 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
448
int 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
471
int 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
491
int 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
514
int 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
524
int 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
542
int 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
564
int 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
577
int 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
586
int 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
597
DMA_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
606
static 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
623
int 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
633
int 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
645
int 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
658
int 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
671
int 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
685
int 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
702
int 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
714
int 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
723
int 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
736
int 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
754
static 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
775
static 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
796
static 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
819
int 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
828