1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#ifndef _ADMA_H
19#define _ADMA_H
20#include <linux/types.h>
21#include <linux/io.h>
22#include <mach/hardware.h>
23#include <asm/hardware/iop_adma.h>
24
25
26#define DMA_CCR(chan) (chan->mmr_base + 0x0)
27#define DMA_CSR(chan) (chan->mmr_base + 0x4)
28#define DMA_DAR(chan) (chan->mmr_base + 0xc)
29#define DMA_NDAR(chan) (chan->mmr_base + 0x10)
30#define DMA_PADR(chan) (chan->mmr_base + 0x14)
31#define DMA_PUADR(chan) (chan->mmr_base + 0x18)
32#define DMA_LADR(chan) (chan->mmr_base + 0x1c)
33#define DMA_BCR(chan) (chan->mmr_base + 0x20)
34#define DMA_DCR(chan) (chan->mmr_base + 0x24)
35
36
37#define AAU_ACR(chan) (chan->mmr_base + 0x0)
38#define AAU_ASR(chan) (chan->mmr_base + 0x4)
39#define AAU_ADAR(chan) (chan->mmr_base + 0x8)
40#define AAU_ANDAR(chan) (chan->mmr_base + 0xc)
41#define AAU_SAR(src, chan) (chan->mmr_base + (0x10 + ((src) << 2)))
42#define AAU_DAR(chan) (chan->mmr_base + 0x20)
43#define AAU_ABCR(chan) (chan->mmr_base + 0x24)
44#define AAU_ADCR(chan) (chan->mmr_base + 0x28)
45#define AAU_SAR_EDCR(src_edc) (chan->mmr_base + (0x02c + ((src_edc-4) << 2)))
46#define AAU_EDCR0_IDX 8
47#define AAU_EDCR1_IDX 17
48#define AAU_EDCR2_IDX 26
49
50#define DMA0_ID 0
51#define DMA1_ID 1
52#define AAU_ID 2
53
54struct iop3xx_aau_desc_ctrl {
55 unsigned int int_en:1;
56 unsigned int blk1_cmd_ctrl:3;
57 unsigned int blk2_cmd_ctrl:3;
58 unsigned int blk3_cmd_ctrl:3;
59 unsigned int blk4_cmd_ctrl:3;
60 unsigned int blk5_cmd_ctrl:3;
61 unsigned int blk6_cmd_ctrl:3;
62 unsigned int blk7_cmd_ctrl:3;
63 unsigned int blk8_cmd_ctrl:3;
64 unsigned int blk_ctrl:2;
65 unsigned int dual_xor_en:1;
66 unsigned int tx_complete:1;
67 unsigned int zero_result_err:1;
68 unsigned int zero_result_en:1;
69 unsigned int dest_write_en:1;
70};
71
72struct iop3xx_aau_e_desc_ctrl {
73 unsigned int reserved:1;
74 unsigned int blk1_cmd_ctrl:3;
75 unsigned int blk2_cmd_ctrl:3;
76 unsigned int blk3_cmd_ctrl:3;
77 unsigned int blk4_cmd_ctrl:3;
78 unsigned int blk5_cmd_ctrl:3;
79 unsigned int blk6_cmd_ctrl:3;
80 unsigned int blk7_cmd_ctrl:3;
81 unsigned int blk8_cmd_ctrl:3;
82 unsigned int reserved2:7;
83};
84
85struct iop3xx_dma_desc_ctrl {
86 unsigned int pci_transaction:4;
87 unsigned int int_en:1;
88 unsigned int dac_cycle_en:1;
89 unsigned int mem_to_mem_en:1;
90 unsigned int crc_data_tx_en:1;
91 unsigned int crc_gen_en:1;
92 unsigned int crc_seed_dis:1;
93 unsigned int reserved:21;
94 unsigned int crc_tx_complete:1;
95};
96
97struct iop3xx_desc_dma {
98 u32 next_desc;
99 union {
100 u32 pci_src_addr;
101 u32 pci_dest_addr;
102 u32 src_addr;
103 };
104 union {
105 u32 upper_pci_src_addr;
106 u32 upper_pci_dest_addr;
107 };
108 union {
109 u32 local_pci_src_addr;
110 u32 local_pci_dest_addr;
111 u32 dest_addr;
112 };
113 u32 byte_count;
114 union {
115 u32 desc_ctrl;
116 struct iop3xx_dma_desc_ctrl desc_ctrl_field;
117 };
118 u32 crc_addr;
119};
120
121struct iop3xx_desc_aau {
122 u32 next_desc;
123 u32 src[4];
124 u32 dest_addr;
125 u32 byte_count;
126 union {
127 u32 desc_ctrl;
128 struct iop3xx_aau_desc_ctrl desc_ctrl_field;
129 };
130 union {
131 u32 src_addr;
132 u32 e_desc_ctrl;
133 struct iop3xx_aau_e_desc_ctrl e_desc_ctrl_field;
134 } src_edc[31];
135};
136
137struct iop3xx_aau_gfmr {
138 unsigned int gfmr1:8;
139 unsigned int gfmr2:8;
140 unsigned int gfmr3:8;
141 unsigned int gfmr4:8;
142};
143
144struct iop3xx_desc_pq_xor {
145 u32 next_desc;
146 u32 src[3];
147 union {
148 u32 data_mult1;
149 struct iop3xx_aau_gfmr data_mult1_field;
150 };
151 u32 dest_addr;
152 u32 byte_count;
153 union {
154 u32 desc_ctrl;
155 struct iop3xx_aau_desc_ctrl desc_ctrl_field;
156 };
157 union {
158 u32 src_addr;
159 u32 e_desc_ctrl;
160 struct iop3xx_aau_e_desc_ctrl e_desc_ctrl_field;
161 u32 data_multiplier;
162 struct iop3xx_aau_gfmr data_mult_field;
163 u32 reserved;
164 } src_edc_gfmr[19];
165};
166
167struct iop3xx_desc_dual_xor {
168 u32 next_desc;
169 u32 src0_addr;
170 u32 src1_addr;
171 u32 h_src_addr;
172 u32 d_src_addr;
173 u32 h_dest_addr;
174 u32 byte_count;
175 union {
176 u32 desc_ctrl;
177 struct iop3xx_aau_desc_ctrl desc_ctrl_field;
178 };
179 u32 d_dest_addr;
180};
181
182union iop3xx_desc {
183 struct iop3xx_desc_aau *aau;
184 struct iop3xx_desc_dma *dma;
185 struct iop3xx_desc_pq_xor *pq_xor;
186 struct iop3xx_desc_dual_xor *dual_xor;
187 void *ptr;
188};
189
190
191static inline int
192iop_chan_pq_slot_count(size_t len, int src_cnt, int *slots_per_op)
193{
194 BUG();
195 return 0;
196}
197
198static inline void
199iop_desc_init_pq(struct iop_adma_desc_slot *desc, int src_cnt,
200 unsigned long flags)
201{
202 BUG();
203}
204
205static inline void
206iop_desc_set_pq_addr(struct iop_adma_desc_slot *desc, dma_addr_t *addr)
207{
208 BUG();
209}
210
211static inline void
212iop_desc_set_pq_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
213 dma_addr_t addr, unsigned char coef)
214{
215 BUG();
216}
217
218static inline int
219iop_chan_pq_zero_sum_slot_count(size_t len, int src_cnt, int *slots_per_op)
220{
221 BUG();
222 return 0;
223}
224
225static inline void
226iop_desc_init_pq_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
227 unsigned long flags)
228{
229 BUG();
230}
231
232static inline void
233iop_desc_set_pq_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
234{
235 BUG();
236}
237
238#define iop_desc_set_pq_zero_sum_src_addr iop_desc_set_pq_src_addr
239
240static inline void
241iop_desc_set_pq_zero_sum_addr(struct iop_adma_desc_slot *desc, int pq_idx,
242 dma_addr_t *src)
243{
244 BUG();
245}
246
247static inline int iop_adma_get_max_xor(void)
248{
249 return 32;
250}
251
252static inline int iop_adma_get_max_pq(void)
253{
254 BUG();
255 return 0;
256}
257
258static inline u32 iop_chan_get_current_descriptor(struct iop_adma_chan *chan)
259{
260 int id = chan->device->id;
261
262 switch (id) {
263 case DMA0_ID:
264 case DMA1_ID:
265 return __raw_readl(DMA_DAR(chan));
266 case AAU_ID:
267 return __raw_readl(AAU_ADAR(chan));
268 default:
269 BUG();
270 }
271 return 0;
272}
273
274static inline void iop_chan_set_next_descriptor(struct iop_adma_chan *chan,
275 u32 next_desc_addr)
276{
277 int id = chan->device->id;
278
279 switch (id) {
280 case DMA0_ID:
281 case DMA1_ID:
282 __raw_writel(next_desc_addr, DMA_NDAR(chan));
283 break;
284 case AAU_ID:
285 __raw_writel(next_desc_addr, AAU_ANDAR(chan));
286 break;
287 }
288
289}
290
291#define IOP_ADMA_STATUS_BUSY (1 << 10)
292#define IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT (1024)
293#define IOP_ADMA_XOR_MAX_BYTE_COUNT (16 * 1024 * 1024)
294#define IOP_ADMA_MAX_BYTE_COUNT (16 * 1024 * 1024)
295
296static inline int iop_chan_is_busy(struct iop_adma_chan *chan)
297{
298 u32 status = __raw_readl(DMA_CSR(chan));
299 return (status & IOP_ADMA_STATUS_BUSY) ? 1 : 0;
300}
301
302static inline int iop_desc_is_aligned(struct iop_adma_desc_slot *desc,
303 int num_slots)
304{
305
306 return (desc->idx & (num_slots - 1)) ? 0 : 1;
307}
308
309
310static inline int iop_chan_memcpy_slot_count(size_t len, int *slots_per_op)
311{
312 *slots_per_op = 1;
313 return 1;
314}
315
316
317static inline int iop_chan_memset_slot_count(size_t len, int *slots_per_op)
318{
319 *slots_per_op = 1;
320 return 1;
321}
322
323static inline int iop3xx_aau_xor_slot_count(size_t len, int src_cnt,
324 int *slots_per_op)
325{
326 static const char slot_count_table[] = {
327 1, 1, 1, 1,
328 2, 2, 2, 2,
329 4, 4, 4, 4,
330 4, 4, 4, 4,
331 8, 8, 8, 8,
332 8, 8, 8, 8,
333 8, 8, 8, 8,
334 8, 8, 8, 8,
335 };
336 *slots_per_op = slot_count_table[src_cnt - 1];
337 return *slots_per_op;
338}
339
340static inline int
341iop_chan_interrupt_slot_count(int *slots_per_op, struct iop_adma_chan *chan)
342{
343 switch (chan->device->id) {
344 case DMA0_ID:
345 case DMA1_ID:
346 return iop_chan_memcpy_slot_count(0, slots_per_op);
347 case AAU_ID:
348 return iop3xx_aau_xor_slot_count(0, 2, slots_per_op);
349 default:
350 BUG();
351 }
352 return 0;
353}
354
355static inline int iop_chan_xor_slot_count(size_t len, int src_cnt,
356 int *slots_per_op)
357{
358 int slot_cnt = iop3xx_aau_xor_slot_count(len, src_cnt, slots_per_op);
359
360 if (len <= IOP_ADMA_XOR_MAX_BYTE_COUNT)
361 return slot_cnt;
362
363 len -= IOP_ADMA_XOR_MAX_BYTE_COUNT;
364 while (len > IOP_ADMA_XOR_MAX_BYTE_COUNT) {
365 len -= IOP_ADMA_XOR_MAX_BYTE_COUNT;
366 slot_cnt += *slots_per_op;
367 }
368
369 if (len)
370 slot_cnt += *slots_per_op;
371
372 return slot_cnt;
373}
374
375
376
377
378static inline int iop_chan_zero_sum_slot_count(size_t len, int src_cnt,
379 int *slots_per_op)
380{
381 int slot_cnt = iop3xx_aau_xor_slot_count(len, src_cnt, slots_per_op);
382
383 if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT)
384 return slot_cnt;
385
386 len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
387 while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
388 len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
389 slot_cnt += *slots_per_op;
390 }
391
392 if (len)
393 slot_cnt += *slots_per_op;
394
395 return slot_cnt;
396}
397
398static inline int iop_desc_is_pq(struct iop_adma_desc_slot *desc)
399{
400 return 0;
401}
402
403static inline u32 iop_desc_get_dest_addr(struct iop_adma_desc_slot *desc,
404 struct iop_adma_chan *chan)
405{
406 union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
407
408 switch (chan->device->id) {
409 case DMA0_ID:
410 case DMA1_ID:
411 return hw_desc.dma->dest_addr;
412 case AAU_ID:
413 return hw_desc.aau->dest_addr;
414 default:
415 BUG();
416 }
417 return 0;
418}
419
420
421static inline u32 iop_desc_get_qdest_addr(struct iop_adma_desc_slot *desc,
422 struct iop_adma_chan *chan)
423{
424 BUG();
425 return 0;
426}
427
428static inline u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc,
429 struct iop_adma_chan *chan)
430{
431 union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
432
433 switch (chan->device->id) {
434 case DMA0_ID:
435 case DMA1_ID:
436 return hw_desc.dma->byte_count;
437 case AAU_ID:
438 return hw_desc.aau->byte_count;
439 default:
440 BUG();
441 }
442 return 0;
443}
444
445
446static inline int __desc_idx(int src_idx)
447{
448 static const int desc_idx_table[] = { 0, 0, 0, 0,
449 0, 1, 2, 3,
450 5, 6, 7, 8,
451 9, 10, 11, 12,
452 14, 15, 16, 17,
453 18, 19, 20, 21,
454 23, 24, 25, 26,
455 27, 28, 29, 30,
456 };
457
458 return desc_idx_table[src_idx];
459}
460
461static inline u32 iop_desc_get_src_addr(struct iop_adma_desc_slot *desc,
462 struct iop_adma_chan *chan,
463 int src_idx)
464{
465 union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
466
467 switch (chan->device->id) {
468 case DMA0_ID:
469 case DMA1_ID:
470 return hw_desc.dma->src_addr;
471 case AAU_ID:
472 break;
473 default:
474 BUG();
475 }
476
477 if (src_idx < 4)
478 return hw_desc.aau->src[src_idx];
479 else
480 return hw_desc.aau->src_edc[__desc_idx(src_idx)].src_addr;
481}
482
483static inline void iop3xx_aau_desc_set_src_addr(struct iop3xx_desc_aau *hw_desc,
484 int src_idx, dma_addr_t addr)
485{
486 if (src_idx < 4)
487 hw_desc->src[src_idx] = addr;
488 else
489 hw_desc->src_edc[__desc_idx(src_idx)].src_addr = addr;
490}
491
492static inline void
493iop_desc_init_memcpy(struct iop_adma_desc_slot *desc, unsigned long flags)
494{
495 struct iop3xx_desc_dma *hw_desc = desc->hw_desc;
496 union {
497 u32 value;
498 struct iop3xx_dma_desc_ctrl field;
499 } u_desc_ctrl;
500
501 u_desc_ctrl.value = 0;
502 u_desc_ctrl.field.mem_to_mem_en = 1;
503 u_desc_ctrl.field.pci_transaction = 0xe;
504 u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
505 hw_desc->desc_ctrl = u_desc_ctrl.value;
506 hw_desc->upper_pci_src_addr = 0;
507 hw_desc->crc_addr = 0;
508}
509
510static inline void
511iop_desc_init_memset(struct iop_adma_desc_slot *desc, unsigned long flags)
512{
513 struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
514 union {
515 u32 value;
516 struct iop3xx_aau_desc_ctrl field;
517 } u_desc_ctrl;
518
519 u_desc_ctrl.value = 0;
520 u_desc_ctrl.field.blk1_cmd_ctrl = 0x2;
521 u_desc_ctrl.field.dest_write_en = 1;
522 u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
523 hw_desc->desc_ctrl = u_desc_ctrl.value;
524}
525
526static inline u32
527iop3xx_desc_init_xor(struct iop3xx_desc_aau *hw_desc, int src_cnt,
528 unsigned long flags)
529{
530 int i, shift;
531 u32 edcr;
532 union {
533 u32 value;
534 struct iop3xx_aau_desc_ctrl field;
535 } u_desc_ctrl;
536
537 u_desc_ctrl.value = 0;
538 switch (src_cnt) {
539 case 25 ... 32:
540 u_desc_ctrl.field.blk_ctrl = 0x3;
541 edcr = 0;
542 shift = 1;
543 for (i = 24; i < src_cnt; i++) {
544 edcr |= (1 << shift);
545 shift += 3;
546 }
547 hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = edcr;
548 src_cnt = 24;
549
550 case 17 ... 24:
551 if (!u_desc_ctrl.field.blk_ctrl) {
552 hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
553 u_desc_ctrl.field.blk_ctrl = 0x3;
554 }
555 edcr = 0;
556 shift = 1;
557 for (i = 16; i < src_cnt; i++) {
558 edcr |= (1 << shift);
559 shift += 3;
560 }
561 hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = edcr;
562 src_cnt = 16;
563
564 case 9 ... 16:
565 if (!u_desc_ctrl.field.blk_ctrl)
566 u_desc_ctrl.field.blk_ctrl = 0x2;
567 edcr = 0;
568 shift = 1;
569 for (i = 8; i < src_cnt; i++) {
570 edcr |= (1 << shift);
571 shift += 3;
572 }
573 hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = edcr;
574 src_cnt = 8;
575
576 case 2 ... 8:
577 shift = 1;
578 for (i = 0; i < src_cnt; i++) {
579 u_desc_ctrl.value |= (1 << shift);
580 shift += 3;
581 }
582
583 if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4)
584 u_desc_ctrl.field.blk_ctrl = 0x1;
585 }
586
587 u_desc_ctrl.field.dest_write_en = 1;
588 u_desc_ctrl.field.blk1_cmd_ctrl = 0x7;
589 u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
590 hw_desc->desc_ctrl = u_desc_ctrl.value;
591
592 return u_desc_ctrl.value;
593}
594
595static inline void
596iop_desc_init_xor(struct iop_adma_desc_slot *desc, int src_cnt,
597 unsigned long flags)
598{
599 iop3xx_desc_init_xor(desc->hw_desc, src_cnt, flags);
600}
601
602
603static inline int
604iop_desc_init_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
605 unsigned long flags)
606{
607 int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
608 struct iop3xx_desc_aau *hw_desc, *prev_hw_desc, *iter;
609 union {
610 u32 value;
611 struct iop3xx_aau_desc_ctrl field;
612 } u_desc_ctrl;
613 int i, j;
614
615 hw_desc = desc->hw_desc;
616
617 for (i = 0, j = 0; (slot_cnt -= slots_per_op) >= 0;
618 i += slots_per_op, j++) {
619 iter = iop_hw_desc_slot_idx(hw_desc, i);
620 u_desc_ctrl.value = iop3xx_desc_init_xor(iter, src_cnt, flags);
621 u_desc_ctrl.field.dest_write_en = 0;
622 u_desc_ctrl.field.zero_result_en = 1;
623 u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
624 iter->desc_ctrl = u_desc_ctrl.value;
625
626
627
628
629 if (i) {
630 prev_hw_desc =
631 iop_hw_desc_slot_idx(hw_desc, i - slots_per_op);
632 prev_hw_desc->next_desc =
633 (u32) (desc->async_tx.phys + (i << 5));
634 }
635 }
636
637 return j;
638}
639
640static inline void
641iop_desc_init_null_xor(struct iop_adma_desc_slot *desc, int src_cnt,
642 unsigned long flags)
643{
644 struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
645 union {
646 u32 value;
647 struct iop3xx_aau_desc_ctrl field;
648 } u_desc_ctrl;
649
650 u_desc_ctrl.value = 0;
651 switch (src_cnt) {
652 case 25 ... 32:
653 u_desc_ctrl.field.blk_ctrl = 0x3;
654 hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
655
656 case 17 ... 24:
657 if (!u_desc_ctrl.field.blk_ctrl) {
658 hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
659 u_desc_ctrl.field.blk_ctrl = 0x3;
660 }
661 hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = 0;
662
663 case 9 ... 16:
664 if (!u_desc_ctrl.field.blk_ctrl)
665 u_desc_ctrl.field.blk_ctrl = 0x2;
666 hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = 0;
667
668 case 1 ... 8:
669 if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4)
670 u_desc_ctrl.field.blk_ctrl = 0x1;
671 }
672
673 u_desc_ctrl.field.dest_write_en = 0;
674 u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
675 hw_desc->desc_ctrl = u_desc_ctrl.value;
676}
677
678static inline void iop_desc_set_byte_count(struct iop_adma_desc_slot *desc,
679 struct iop_adma_chan *chan,
680 u32 byte_count)
681{
682 union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
683
684 switch (chan->device->id) {
685 case DMA0_ID:
686 case DMA1_ID:
687 hw_desc.dma->byte_count = byte_count;
688 break;
689 case AAU_ID:
690 hw_desc.aau->byte_count = byte_count;
691 break;
692 default:
693 BUG();
694 }
695}
696
697static inline void
698iop_desc_init_interrupt(struct iop_adma_desc_slot *desc,
699 struct iop_adma_chan *chan)
700{
701 union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
702
703 switch (chan->device->id) {
704 case DMA0_ID:
705 case DMA1_ID:
706 iop_desc_init_memcpy(desc, 1);
707 hw_desc.dma->byte_count = 0;
708 hw_desc.dma->dest_addr = 0;
709 hw_desc.dma->src_addr = 0;
710 break;
711 case AAU_ID:
712 iop_desc_init_null_xor(desc, 2, 1);
713 hw_desc.aau->byte_count = 0;
714 hw_desc.aau->dest_addr = 0;
715 hw_desc.aau->src[0] = 0;
716 hw_desc.aau->src[1] = 0;
717 break;
718 default:
719 BUG();
720 }
721}
722
723static inline void
724iop_desc_set_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
725{
726 int slots_per_op = desc->slots_per_op;
727 struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
728 int i = 0;
729
730 if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
731 hw_desc->byte_count = len;
732 } else {
733 do {
734 iter = iop_hw_desc_slot_idx(hw_desc, i);
735 iter->byte_count = IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
736 len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
737 i += slots_per_op;
738 } while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT);
739
740 if (len) {
741 iter = iop_hw_desc_slot_idx(hw_desc, i);
742 iter->byte_count = len;
743 }
744 }
745}
746
747static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc,
748 struct iop_adma_chan *chan,
749 dma_addr_t addr)
750{
751 union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
752
753 switch (chan->device->id) {
754 case DMA0_ID:
755 case DMA1_ID:
756 hw_desc.dma->dest_addr = addr;
757 break;
758 case AAU_ID:
759 hw_desc.aau->dest_addr = addr;
760 break;
761 default:
762 BUG();
763 }
764}
765
766static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc,
767 dma_addr_t addr)
768{
769 struct iop3xx_desc_dma *hw_desc = desc->hw_desc;
770 hw_desc->src_addr = addr;
771}
772
773static inline void
774iop_desc_set_zero_sum_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
775 dma_addr_t addr)
776{
777
778 struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
779 int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
780 int i;
781
782 for (i = 0; (slot_cnt -= slots_per_op) >= 0;
783 i += slots_per_op, addr += IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
784 iter = iop_hw_desc_slot_idx(hw_desc, i);
785 iop3xx_aau_desc_set_src_addr(iter, src_idx, addr);
786 }
787}
788
789static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc,
790 int src_idx, dma_addr_t addr)
791{
792
793 struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
794 int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
795 int i;
796
797 for (i = 0; (slot_cnt -= slots_per_op) >= 0;
798 i += slots_per_op, addr += IOP_ADMA_XOR_MAX_BYTE_COUNT) {
799 iter = iop_hw_desc_slot_idx(hw_desc, i);
800 iop3xx_aau_desc_set_src_addr(iter, src_idx, addr);
801 }
802}
803
804static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc,
805 u32 next_desc_addr)
806{
807
808 union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
809
810 iop_paranoia(hw_desc.dma->next_desc);
811 hw_desc.dma->next_desc = next_desc_addr;
812}
813
814static inline u32 iop_desc_get_next_desc(struct iop_adma_desc_slot *desc)
815{
816
817 union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
818 return hw_desc.dma->next_desc;
819}
820
821static inline void iop_desc_clear_next_desc(struct iop_adma_desc_slot *desc)
822{
823
824 union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
825 hw_desc.dma->next_desc = 0;
826}
827
828static inline void iop_desc_set_block_fill_val(struct iop_adma_desc_slot *desc,
829 u32 val)
830{
831 struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
832 hw_desc->src[0] = val;
833}
834
835static inline enum sum_check_flags
836iop_desc_get_zero_result(struct iop_adma_desc_slot *desc)
837{
838 struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
839 struct iop3xx_aau_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field;
840
841 iop_paranoia(!(desc_ctrl.tx_complete && desc_ctrl.zero_result_en));
842 return desc_ctrl.zero_result_err << SUM_CHECK_P;
843}
844
845static inline void iop_chan_append(struct iop_adma_chan *chan)
846{
847 u32 dma_chan_ctrl;
848
849 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
850 dma_chan_ctrl |= 0x2;
851 __raw_writel(dma_chan_ctrl, DMA_CCR(chan));
852}
853
854static inline u32 iop_chan_get_status(struct iop_adma_chan *chan)
855{
856 return __raw_readl(DMA_CSR(chan));
857}
858
859static inline void iop_chan_disable(struct iop_adma_chan *chan)
860{
861 u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
862 dma_chan_ctrl &= ~1;
863 __raw_writel(dma_chan_ctrl, DMA_CCR(chan));
864}
865
866static inline void iop_chan_enable(struct iop_adma_chan *chan)
867{
868 u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
869
870 dma_chan_ctrl |= 1;
871 __raw_writel(dma_chan_ctrl, DMA_CCR(chan));
872}
873
874static inline void iop_adma_device_clear_eot_status(struct iop_adma_chan *chan)
875{
876 u32 status = __raw_readl(DMA_CSR(chan));
877 status &= (1 << 9);
878 __raw_writel(status, DMA_CSR(chan));
879}
880
881static inline void iop_adma_device_clear_eoc_status(struct iop_adma_chan *chan)
882{
883 u32 status = __raw_readl(DMA_CSR(chan));
884 status &= (1 << 8);
885 __raw_writel(status, DMA_CSR(chan));
886}
887
888static inline void iop_adma_device_clear_err_status(struct iop_adma_chan *chan)
889{
890 u32 status = __raw_readl(DMA_CSR(chan));
891
892 switch (chan->device->id) {
893 case DMA0_ID:
894 case DMA1_ID:
895 status &= (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1);
896 break;
897 case AAU_ID:
898 status &= (1 << 5);
899 break;
900 default:
901 BUG();
902 }
903
904 __raw_writel(status, DMA_CSR(chan));
905}
906
907static inline int
908iop_is_err_int_parity(unsigned long status, struct iop_adma_chan *chan)
909{
910 return 0;
911}
912
913static inline int
914iop_is_err_mcu_abort(unsigned long status, struct iop_adma_chan *chan)
915{
916 return 0;
917}
918
919static inline int
920iop_is_err_int_tabort(unsigned long status, struct iop_adma_chan *chan)
921{
922 return 0;
923}
924
925static inline int
926iop_is_err_int_mabort(unsigned long status, struct iop_adma_chan *chan)
927{
928 return test_bit(5, &status);
929}
930
931static inline int
932iop_is_err_pci_tabort(unsigned long status, struct iop_adma_chan *chan)
933{
934 switch (chan->device->id) {
935 case DMA0_ID:
936 case DMA1_ID:
937 return test_bit(2, &status);
938 default:
939 return 0;
940 }
941}
942
943static inline int
944iop_is_err_pci_mabort(unsigned long status, struct iop_adma_chan *chan)
945{
946 switch (chan->device->id) {
947 case DMA0_ID:
948 case DMA1_ID:
949 return test_bit(3, &status);
950 default:
951 return 0;
952 }
953}
954
955static inline int
956iop_is_err_split_tx(unsigned long status, struct iop_adma_chan *chan)
957{
958 switch (chan->device->id) {
959 case DMA0_ID:
960 case DMA1_ID:
961 return test_bit(1, &status);
962 default:
963 return 0;
964 }
965}
966#endif
967