1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
|
#include <linux/types.h>
#define to_ppc460ex_adma_chan(chan) container_of(chan,ppc460ex_p_ch_t,common)
#define to_ppc460ex_adma_device(dev) container_of(dev,ppc460ex_p_dev_t,common)
#define tx_to_ppc460ex_adma_slot(tx) container_of(tx,ppc460ex_p_desc_t,async_tx)
#define DMA_HEXDUMP(b, l) \
print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, \
16, 1, (b), (l), false);
#define MAX_PPC460EX_DMA_CHANNELS 4
#define DCR_DMA0_BASE 0x200
#define DCR_DMA1_BASE 0x208
#define DCR_DMA2_BASE 0x210
#define DCR_DMA3_BASE 0x218
#define DCR_DMASR_BASE 0x220
#define PPC460EX_PDMA0_ID 0
#define PPC460EX_PDMA1_ID 1
#define PPC460EX_PDMA2_ID 2
#define PPC460EX_PDMA3_ID 3
#define DMA_FIFO_SIZE 0x1000
#define DMA_CDB_SIZE 64
/* DMA Registers */
#define DCR_DMA2P40_CR0 (DCR_DMA0_BASE + 0x0) /* DMA Channel Control 0 */
#define DCR_DMA2P40_CTC0 (DCR_DMA0_BASE + 0x1) /* DMA Count 0 */
#define DCR_DMA2P40_SAH0 (DCR_DMA0_BASE + 0x2) /* DMA Src Addr High 0 */
#define DCR_DMA2P40_SAL0 (DCR_DMA0_BASE + 0x3) /* DMA Src Addr Low 0 */
#define DCR_DMA2P40_DAH0 (DCR_DMA0_BASE + 0x4) /* DMA Dest Addr High 0 */
#define DCR_DMA2P40_DAL0 (DCR_DMA0_BASE + 0x5) /* DMA Dest Addr Low 0 */
#define DCR_DMA2P40_SGH0 (DCR_DMA0_BASE + 0x6) /* DMA SG Desc Addr High 0 */
#define DCR_DMA2P40_SGL0 (DCR_DMA0_BASE + 0x7) /* DMA SG Desc Addr Low 0 */
#define DCR_DMA2P40_CR1 (DCR_DMA1_BASE + 0x0) /* DMA Channel Control 1 */
#define DCR_DMA2P40_CTC1 (DCR_DMA1_BASE + 0x1) /* DMA Count 1 */
#define DCR_DMA2P40_SAH1 (DCR_DMA1_BASE + 0x2) /* DMA Src Addr High 1 */
#define DCR_DMA2P40_SAL1 (DCR_DMA1_BASE + 0x3) /* DMA Src Addr Low 1 */
#define DCR_DMA2P40_DAH1 (DCR_DMA1_BASE + 0x4) /* DMA Dest Addr High 1 */
#define DCR_DMA2P40_DAL1 (DCR_DMA1_BASE + 0x5) /* DMA Dest Addr Low 1 */
#define DCR_DMA2P40_SGH1 (DCR_DMA1_BASE + 0x6) /* DMA SG Desc Addr High 1 */
#define DCR_DMA2P40_SGL1 (DCR_DMA1_BASE + 0x7) /* DMA SG Desc Addr Low 1 */
#define DCR_DMA2P40_CR2 (DCR_DMA2_BASE + 0x0) /* DMA Channel Control 2 */
#define DCR_DMA2P40_CTC2 (DCR_DMA2_BASE + 0x1) /* DMA Count 2 */
#define DCR_DMA2P40_SAH2 (DCR_DMA2_BASE + 0x2) /* DMA Src Addr High 2 */
#define DCR_DMA2P40_SAL2 (DCR_DMA2_BASE + 0x3) /* DMA Src Addr Low 2 */
#define DCR_DMA2P40_DAH2 (DCR_DMA2_BASE + 0x4) /* DMA Dest Addr High 2 */
#define DCR_DMA2P40_DAL2 (DCR_DMA2_BASE + 0x5) /* DMA Dest Addr Low 2 */
#define DCR_DMA2P40_SGH2 (DCR_DMA2_BASE + 0x6) /* DMA SG Desc Addr High 2 */
#define DCR_DMA2P40_SGL2 (DCR_DMA2_BASE + 0x7) /* DMA SG Desc Addr Low 2 */
#define DCR_DMA2P40_CR3 (DCR_DMA3_BASE + 0x0) /* DMA Channel Control 3 */
#define DCR_DMA2P40_CTC3 (DCR_DMA3_BASE + 0x1) /* DMA Count 3 */
#define DCR_DMA2P40_SAH3 (DCR_DMA3_BASE + 0x2) /* DMA Src Addr High 3 */
#define DCR_DMA2P40_SAL3 (DCR_DMA3_BASE + 0x3) /* DMA Src Addr Low 3 */
#define DCR_DMA2P40_DAH3 (DCR_DMA3_BASE + 0x4) /* DMA Dest Addr High 3 */
#define DCR_DMA2P40_DAL3 (DCR_DMA3_BASE + 0x5) /* DMA Dest Addr Low 3 */
#define DCR_DMA2P40_SGH3 (DCR_DMA3_BASE + 0x6) /* DMA SG Desc Addr High 3 */
#define DCR_DMA2P40_SGL3 (DCR_DMA3_BASE + 0x7) /* DMA SG Desc Addr Low 3 */
#define DCR_DMA2P40_SR (DCR_DMASR_BASE + 0x0) /* DMA Status Register */
#define DCR_DMA2P40_SGC (DCR_DMASR_BASE + 0x3) /* DMA Scatter/Gather Command */
#define DCR_DMA2P40_SLP (DCR_DMASR_BASE + 0x5) /* DMA Sleep Register */
#define DCR_DMA2P40_POL (DCR_DMASR_BASE + 0x6) /* DMA Polarity Register */
/*
* Function return status codes
* These values are used to indicate whether or not the function
* call was successful, or a bad/invalid parameter was passed.
*/
#define DMA_STATUS_GOOD 0
#define DMA_STATUS_BAD_CHANNEL 1
#define DMA_STATUS_BAD_HANDLE 2
#define DMA_STATUS_BAD_MODE 3
#define DMA_STATUS_NULL_POINTER 4
#define DMA_STATUS_OUT_OF_MEMORY 5
#define DMA_STATUS_SGL_LIST_EMPTY 6
#define DMA_STATUS_GENERAL_ERROR 7
#define DMA_STATUS_CHANNEL_NOTFREE 8
#define DMA_CHANNEL_BUSY 0x80000000
/*
* These indicate status as returned from the DMA Status Register.
*/
#define DMA_STATUS_NO_ERROR 0
#define DMA_STATUS_CS 1 /* Count Status */
#define DMA_STATUS_TS 2 /* Transfer Status */
#define DMA_STATUS_DMA_ERROR 3 /* DMA Error Occurred */
#define DMA_STATUS_DMA_BUSY 4 /* The channel is busy */
/*
* DMA Channel Control Registers
*/
#ifdef CONFIG_44x
#define PPC4xx_DMA_64BIT
#define DMA_CR_OFFSET 1
#else
#define DMA_CR_OFFSET 0
#endif
#define DMA_CE_ENABLE (1<<31) /* DMA Channel Enable */
#define SET_DMA_CE_ENABLE(x) (((x)&0x1)<<31)
#define GET_DMA_CE_ENABLE(x) (((x)&DMA_CE_ENABLE)>>31)
#define DMA_CIE_ENABLE (1<<30) /* DMA Channel Interrupt Enable */
#define SET_DMA_CIE_ENABLE(x) (((x)&0x1)<<30)
#define GET_DMA_CIE_ENABLE(x) (((x)&DMA_CIE_ENABLE)>>30)
#define DMA_TD (1<<29)
#define SET_DMA_TD(x) (((x)&0x1)<<29)
#define GET_DMA_TD(x) (((x)&DMA_TD)>>29)
#define DMA_PL (1<<28) /* Peripheral Location */
#define SET_DMA_PL(x) (((x)&0x1)<<28)
#define GET_DMA_PL(x) (((x)&DMA_PL)>>28)
#define EXTERNAL_PERIPHERAL 0
#define INTERNAL_PERIPHERAL 1
#define SET_DMA_PW(x) (((x)&0x7)<<(26-DMA_CR_OFFSET)) /* Peripheral Width */
#define DMA_PW_MASK SET_DMA_PW(7)
#define PW_8 0
#define PW_16 1
#define PW_32 2
#define PW_64 3
#define PW_128 4
#define GET_DMA_PW(x) (((x)&DMA_PW_MASK)>>(26-DMA_CR_OFFSET))
#define DMA_DAI (1<<(25-DMA_CR_OFFSET)) /* Destination Address Increment */
#define SET_DMA_DAI(x) (((x)&0x1)<<(25-DMA_CR_OFFSET))
#define DMA_SAI (1<<(24-DMA_CR_OFFSET)) /* Source Address Increment */
#define SET_DMA_SAI(x) (((x)&0x1)<<(24-DMA_CR_OFFSET))
#define DMA_BEN (1<<(23-DMA_CR_OFFSET)) /* Buffer Enable */
#define SET_DMA_BEN(x) (((x)&0x1)<<(23-DMA_CR_OFFSET))
#define SET_DMA_TM(x) (((x)&0x3)<<(21-DMA_CR_OFFSET)) /* Transfer Mode */
#define DMA_TM_MASK SET_DMA_TM(3)
#define TM_PERIPHERAL 0 /* Peripheral */
#define TM_RESERVED 1 /* Reserved */
#define TM_S_MM 2 /* Memory to Memory */
#define TM_D_MM 3 /* Device Paced Memory to Memory */
#define GET_DMA_TM(x) (((x)&DMA_TM_MASK)>>(21-DMA_CR_OFFSET))
#define SET_DMA_PSC(x) (((x)&0x3)<<(19-DMA_CR_OFFSET)) /* Peripheral Setup Cycles */
#define DMA_PSC_MASK SET_DMA_PSC(3)
#define GET_DMA_PSC(x) (((x)&DMA_PSC_MASK)>>(19-DMA_CR_OFFSET))
#define SET_DMA_PWC(x) (((x)&0x3F)<<(13-DMA_CR_OFFSET)) /* Peripheral Wait Cycles */
#define DMA_PWC_MASK SET_DMA_PWC(0x3F)
#define GET_DMA_PWC(x) (((x)&DMA_PWC_MASK)>>(13-DMA_CR_OFFSET))
#define SET_DMA_PHC(x) (((x)&0x7)<<(10-DMA_CR_OFFSET)) /* Peripheral Hold Cycles */
#define DMA_PHC_MASK SET_DMA_PHC(0x7)
#define GET_DMA_PHC(x) (((x)&DMA_PHC_MASK)>>(10-DMA_CR_OFFSET))
#define DMA_ETD_OUTPUT (1<<(9-DMA_CR_OFFSET)) /* EOT pin is a TC output */
#define SET_DMA_ETD(x) (((x)&0x1)<<(9-DMA_CR_OFFSET))
#define DMA_TCE_ENABLE (1<<(8-DMA_CR_OFFSET))
#define SET_DMA_TCE(x) (((x)&0x1)<<(8-DMA_CR_OFFSET))
#define DMA_DEC (1<<(2)) /* Address Decrement */
#define SET_DMA_DEC(x) (((x)&0x1)<<2)
#define GET_DMA_DEC(x) (((x)&DMA_DEC)>>2)
/*
* Transfer Modes
* These modes are defined in a way that makes it possible to
* simply "or" in the value in the control register.
*/
#define DMA_MODE_MM (SET_DMA_TM(TM_S_MM)) /* memory to memory */
/* Device-paced memory to memory, */
/* device is at source address */
#define DMA_MODE_MM_DEVATSRC (DMA_TD | SET_DMA_TM(TM_D_MM))
/* Device-paced memory to memory, */
/* device is at destination address */
#define DMA_MODE_MM_DEVATDST (SET_DMA_TM(TM_D_MM))
#define SGL_LIST_SIZE 16384
#define DMA_PPC4xx_SIZE SGL_LIST_SIZE
#define SET_DMA_PRIORITY(x) (((x)&0x3)<<(6-DMA_CR_OFFSET)) /* DMA Channel Priority */
#define DMA_PRIORITY_MASK SET_DMA_PRIORITY(3)
#define PRIORITY_LOW 0
#define PRIORITY_MID_LOW 1
#define PRIORITY_MID_HIGH 2
#define PRIORITY_HIGH 3
#define GET_DMA_PRIORITY(x) (((x)&DMA_PRIORITY_MASK)>>(6-DMA_CR_OFFSET))
#define SET_DMA_PREFETCH(x) (((x)&0x3)<<(4-DMA_CR_OFFSET)) /* Memory Read Prefetch */
#define DMA_PREFETCH_MASK SET_DMA_PREFETCH(3)
#define PREFETCH_1 0 /* Prefetch 1 Double Word */
#define PREFETCH_2 1
#define PREFETCH_4 2
#define GET_DMA_PREFETCH(x) (((x)&DMA_PREFETCH_MASK)>>(4-DMA_CR_OFFSET))
#define DMA_PCE (1<<(3-DMA_CR_OFFSET)) /* Parity Check Enable */
#define SET_DMA_PCE(x) (((x)&0x1)<<(3-DMA_CR_OFFSET))
#define GET_DMA_PCE(x) (((x)&DMA_PCE)>>(3-DMA_CR_OFFSET))
/*
* DMA Polarity Configuration Register
*/
#define DMAReq_ActiveLow(chan) (1<<(31-(chan*3)))
#define DMAAck_ActiveLow(chan) (1<<(30-(chan*3)))
#define EOT_ActiveLow(chan) (1<<(29-(chan*3))) /* End of Transfer */
/*
* DMA Sleep Mode Register
*/
#define SLEEP_MODE_ENABLE (1<<21)
/*
* DMA Status Register
*/
#define DMA_CS0 (1<<31) /* Terminal Count has been reached */
#define DMA_CS1 (1<<30)
#define DMA_CS2 (1<<29)
#define DMA_CS3 (1<<28)
#define DMA_TS0 (1<<27) /* End of Transfer has been requested */
#define DMA_TS1 (1<<26)
#define DMA_TS2 (1<<25)
#define DMA_TS3 (1<<24)
#define DMA_CH0_ERR (1<<23) /* DMA Chanel 0 Error */
#define DMA_CH1_ERR (1<<22)
#define DMA_CH2_ERR (1<<21)
#define DMA_CH3_ERR (1<<20)
#define DMA_IN_DMA_REQ0 (1<<19) /* Internal DMA Request is pending */
#define DMA_IN_DMA_REQ1 (1<<18)
#define DMA_IN_DMA_REQ2 (1<<17)
#define DMA_IN_DMA_REQ3 (1<<16)
#define DMA_EXT_DMA_REQ0 (1<<15) /* External DMA Request is pending */
#define DMA_EXT_DMA_REQ1 (1<<14)
#define DMA_EXT_DMA_REQ2 (1<<13)
#define DMA_EXT_DMA_REQ3 (1<<12)
#define DMA_CH0_BUSY (1<<11) /* DMA Channel 0 Busy */
#define DMA_CH1_BUSY (1<<10)
#define DMA_CH2_BUSY (1<<9)
#define DMA_CH3_BUSY (1<<8)
#define DMA_SG0 (1<<7) /* DMA Channel 0 Scatter/Gather in progress */
#define DMA_SG1 (1<<6)
#define DMA_SG2 (1<<5)
#define DMA_SG3 (1<<4)
/* DMA Channel Count Register */
#define DMA_CTC_TCIE (1<<29) /* Terminal Count Interrupt Enable */
#define DMA_CTC_ETIE (1<<28) /* EOT Interupt Enable */
#define DMA_CTC_EIE (1<<27) /* Error Interrupt Enable */
#define DMA_CTC_BTEN (1<<23) /* Burst Enable/Disable bit */
#define DMA_CTC_BSIZ_MSK (3<<21) /* Mask of the Burst size bits */
#define DMA_CTC_BSIZ_2 (0)
#define DMA_CTC_BSIZ_4 (1<<21)
#define DMA_CTC_BSIZ_8 (2<<21)
#define DMA_CTC_BSIZ_16 (3<<21)
#define DMA_CTC_TC_MASK 0xFFFFF
/*
* DMA SG Command Register
*/
#define SSG_ENABLE(chan) (1<<(31-chan)) /* Start Scatter Gather */
#define SSG_MASK_ENABLE(chan) (1<<(15-chan)) /* Enable writing to SSG0 bit */
/*
* DMA Scatter/Gather Descriptor Bit fields
*/
#define SG_LINK (1<<31) /* Link */
#define SG_TCI_ENABLE (1<<29) /* Enable Terminal Count Interrupt */
#define SG_ETI_ENABLE (1<<28) /* Enable End of Transfer Interrupt */
#define SG_ERI_ENABLE (1<<27) /* Enable Error Interrupt */
#define SG_COUNT_MASK 0xFFFF /* Count Field */
#define SET_DMA_CONTROL \
(SET_DMA_CIE_ENABLE(p_init->int_enable) | /* interrupt enable */ \
SET_DMA_BEN(p_init->buffer_enable) | /* buffer enable */\
SET_DMA_ETD(p_init->etd_output) | /* end of transfer pin */ \
SET_DMA_TCE(p_init->tce_enable) | /* terminal count enable */ \
SET_DMA_PL(p_init->pl) | /* peripheral location */ \
SET_DMA_DAI(p_init->dai) | /* dest addr increment */ \
SET_DMA_SAI(p_init->sai) | /* src addr increment */ \
SET_DMA_PRIORITY(p_init->cp) | /* channel priority */ \
SET_DMA_PW(p_init->pwidth) | /* peripheral/bus width */ \
SET_DMA_PSC(p_init->psc) | /* peripheral setup cycles */ \
SET_DMA_PWC(p_init->pwc) | /* peripheral wait cycles */ \
SET_DMA_PHC(p_init->phc) | /* peripheral hold cycles */ \
SET_DMA_PREFETCH(p_init->pf) /* read prefetch */)
#define GET_DMA_POLARITY(chan) (DMAReq_ActiveLow(chan) | DMAAck_ActiveLow(chan) | EOT_ActiveLow(chan))
/**
* struct ppc460ex_dma_device - internal representation of an DMA device
* @pdev: Platform device
* @id: HW DMA Device selector
* @dma_desc_pool: base of DMA descriptor region (DMA address)
* @dma_desc_pool_virt: base of DMA descriptor region (CPU address)
* @common: embedded struct dma_device
*/
typedef struct ppc460ex_plb_dma_device {
//struct platform_device *pdev;
struct of_device *odev;
void __iomem *reg_base;
struct device *dev;
struct resource reg; /* Resource for register */
int id;
struct dma_device common;
struct ppc460ex_plb_dma_chan *chan[MAX_PPC460EX_DMA_CHANNELS];
wait_queue_head_t queue;
} ppc460ex_p_dev_t;
typedef uint32_t sgl_handle_t;
/**
* struct ppc460ex_dma_chan - internal representation of an ADMA channel
* @lock: serializes enqueue/dequeue operations to the slot pool
* @device: parent device
* @chain: device chain view of the descriptors
* @common: common dmaengine channel object members
* @all_slots: complete domain of slots usable by the channel
* @reg: Resource for register
* @pending: allows batching of hardware operations
* @completed_cookie: identifier for the most recently completed operation
* @slots_allocated: records the actual size of the descriptor slot pool
* @hw_chain_inited: h/w descriptor chain initialization flag
* @irq_tasklet: bottom half where ppc460ex_adma_slot_cleanup runs
* @needs_unmap: if buffers should not be unmapped upon final processing
*/
typedef struct ppc460ex_plb_dma_chan {
void __iomem *reg_base;
struct ppc460ex_plb_dma_device *device;
struct timer_list cleanup_watchdog;
struct list_head chain;
struct dma_chan common;
struct list_head all_slots;
struct ppc460ex_adma_desc_slot *last_used;
int pending;
dma_cookie_t completed_cookie;
int slots_allocated;
int hw_chain_inited;
void *dma_desc_pool_virt;
dma_addr_t dma_desc_pool;
struct resource reg; /* Resource for register */
unsigned int chan_id;
struct tasklet_struct irq_tasklet;
u8 needs_unmap;
sgl_handle_t *phandle;
unsigned short in_use; /* set when channel is being used, clr when
* available.
*/
/*
* Valid polarity settings:
* DMAReq_ActiveLow(n)
* DMAAck_ActiveLow(n)
* EOT_ActiveLow(n)
*
* n is 0 to max dma chans
*/
unsigned int polarity;
char buffer_enable; /* Boolean: buffer enable */
char tce_enable; /* Boolean: terminal count enable */
char etd_output; /* Boolean: eot pin is a tc output */
char pce; /* Boolean: parity check enable */
/*
* Peripheral location:
* INTERNAL_PERIPHERAL (UART0 on the 405GP)
* EXTERNAL_PERIPHERAL
*/
char pl; /* internal/external peripheral */
/*
* Valid pwidth settings:
* PW_8
* PW_16
* PW_32
* PW_64
*/
unsigned int pwidth;
char dai; /* Boolean: dst address increment */
char sai; /* Boolean: src address increment */
/*
* Valid psc settings: 0-3
*/
unsigned int psc; /* Peripheral Setup Cycles */
/*
* Valid pwc settings:
* 0-63
*/
unsigned int pwc; /* Peripheral Wait Cycles */
/*
* Valid phc settings:
* 0-7
*/
unsigned int phc; /* Peripheral Hold Cycles */
/*
* Valid cp (channel priority) settings:
* PRIORITY_LOW
* PRIORITY_MID_LOW
* PRIORITY_MID_HIGH
* PRIORITY_HIGH
*/
unsigned int cp; /* channel priority */
/*
* Valid pf (memory read prefetch) settings:
*
* PREFETCH_1
* PREFETCH_2
* PREFETCH_4
*/
unsigned int pf; /* memory read prefetch */
/*
* Boolean: channel interrupt enable
* NOTE: for sgl transfers, only the last descriptor will be setup to
* interrupt.
*/
char int_enable;
char shift; /* easy access to byte_count shift, based on */
/* the width of the channel */
uint32_t control; /* channel control word */
/* These variabled are used ONLY in single dma transfers */
unsigned int mode; /* transfer mode */
phys_addr_t addr;
char ce; /* channel enable */
char int_on_final_sg;/* for scatter/gather - only interrupt on last sg */
} ppc460ex_p_ch_t;
typedef struct ppc460ex_adma_plb_desc_slot {
dma_addr_t phys;
struct ppc460ex_adma_plb_desc_slot *group_head;
struct ppc460ex_adma_plb_desc_slot *hw_next;
struct dma_async_tx_descriptor async_tx;
struct list_head slot_node;
struct list_head chain_node;
struct list_head group_list;
unsigned int unmap_len;
void *hw_desc;
u16 stride;
u16 idx;
u16 slot_cnt;
u8 src_cnt;
u8 dst_cnt;
u8 slots_per_op;
u8 descs_per_op;
unsigned long flags;
unsigned long reverse_flags[8];
}ppc460ex_p_desc_t;
typedef struct ppc460ex_adma_plb_platform_data {
int hw_id;
dma_cap_mask_t cap_mask;
size_t pool_size;
} ppc460ex_p_aplat_t;
typedef struct dma_cdb {
u32 ctrl;
u32 cnt;
u32 src_hi;
u32 src_lo;
u32 dest_hi;
u32 dest_lo;
u32 sg_hi;
u32 sg_lo;
}dma_cdb_t;
/*
* PPC44x DMA implementations have a slightly different
* descriptor layout. Probably moved about due to the
* change to 64-bit addresses and link pointer. I don't
* know why they didn't just leave control_count after
* the dst_addr.
*/
#ifdef PPC4xx_DMA_64BIT
typedef struct {
uint32_t control;
uint32_t control_count;
phys_addr_t src_addr;
phys_addr_t dst_addr;
phys_addr_t next;
} ppc_sgl_t;
#else
typedef struct {
uint32_t control;
phys_addr_t src_addr;
phys_addr_t dst_addr;
uint32_t control_count;
uint32_t next;
} ppc_sgl_t;
#endif
typedef struct {
unsigned int ch_id;
uint32_t control; /* channel ctrl word; loaded from each descrptr */
uint32_t sgl_control; /* LK, TCI, ETI, and ERI bits in sgl descriptor */
dma_addr_t dma_addr; /* dma (physical) address of this list */
ppc_sgl_t *phead;
dma_addr_t phead_dma;
ppc_sgl_t *ptail;
dma_addr_t ptail_dma;
} sgl_list_info_t;
typedef struct {
phys_addr_t *src_addr;
phys_addr_t *dst_addr;
phys_addr_t dma_src_addr;
phys_addr_t dma_dst_addr;
} pci_alloc_desc_t;
#define PPC460EX_DMA_SGXFR_COMPLETE(id) (!((1 << (11-id)) & mfdcr(DCR_DMA2P40_SR)))
#define PPC460EX_DMA_CHAN_BUSY(id) ( (1 << (11-id)) & mfdcr(DCR_DMA2P40_SR) )
#define DMA_STATUS(id) (mfdcr(DCR_DMA2P40_SR))
#define CLEAR_DMA_STATUS(id) (mtdcr(DCR_DMA2P40_SR, 0xFFFFFFFF))
#define PPC460EX_DMA_SGSTAT_FREE(id) (!((1 << (7-id)) & mfdcr(DCR_DMA2P40_SR)) )
#define PPC460EX_DMA_TC_REACHED(id) ( (1 << (31-id)) & mfdcr(DCR_DMA2P40_SR) )
#define PPC460EX_DMA_CHAN_XFR_COMPLETE(id) ( (!PPC460EX_DMA_CHAN_BUSY(id)) && (PPC460EX_DMA_TC_REACHED(id)) )
#define PPC460EX_DMA_CHAN_SGXFR_COMPLETE(id) ( (!PPC460EX_DMA_CHAN_BUSY(id)) && PPC460EX_DMA_SGSTAT_FREE(id) )
#define PPC460EX_DMA_SG_IN_PROGRESS(id) ( (1 << (7-id)) | (1 << (11-id)) )
#define PPC460EX_DMA_SG_OP_COMPLETE(id) ( (PPC460EX_DMA_SG_IN_PROGRESS(id) & DMA_STATUS(id) ) == 0)
int ppc460ex_init_dma_channel(ppc460ex_plb_dma_dev_t *adev,
unsigned int ch_id,
ppc460ex_plb_dma_ch_t *p_init);
int ppc460ex_set_src_addr(int ch_id, phys_addr_t src_addr);
int ppc460ex_set_dst_addr(int ch_id, phys_addr_t dst_addr);
int ppc460ex_set_dma_mode(ppc460ex_plb_dma_dev_t *adev, unsigned int ch_id, unsigned int mode);
void ppc460ex_set_dma_count(ppc460ex_plb_dma_dev_t *adev, unsigned int ch_id, unsigned int count);
int ppc460ex_enable_dma_interrupt(ppc460ex_plb_dma_dev_t *adev, unsigned int ch_id);
int ppc460ex_enable_dma(ppc460ex_plb_dma_dev_t *adev, unsigned int ch_id);
int ppc460ex_get_dma_channel(void);
void ppc460ex_disable_dma(ppc460ex_plb_dma_dev_t *adev, unsigned int ch_id);
int ppc460ex_clear_dma_status(unsigned int ch_id);
#if 0
extern int test_dma_memcpy(void *src, void *dst, unsigned int length, unsigned int dma_ch);
extern int test_sgdma_memcpy(void *src, void *dst, void *src1, void *dst1,
unsigned int length, unsigned int dma_ch);
#endif
|