• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/arm/include/asm/hardware/
1/*
2 * Copyright �� 2006, Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
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/* Memory copy units */
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/* Application accelerator unit  */
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/* No support for p+q operations */
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	/* num_slots will only ever be 1, 2, 4, or 8 */
306	return (desc->idx & (num_slots - 1)) ? 0 : 1;
307}
308
309/* to do: support large (i.e. > hw max) buffer sizes */
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/* to do: support large (i.e. > hw max) buffer sizes */
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, /* 01 - 04 */
328						2, 2, 2, 2, /* 05 - 08 */
329						4, 4, 4, 4, /* 09 - 12 */
330						4, 4, 4, 4, /* 13 - 16 */
331						8, 8, 8, 8, /* 17 - 20 */
332						8, 8, 8, 8, /* 21 - 24 */
333						8, 8, 8, 8, /* 25 - 28 */
334						8, 8, 8, 8, /* 29 - 32 */
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	slot_cnt += *slots_per_op;
370
371	return slot_cnt;
372}
373
374/* zero sum on iop3xx is limited to 1k at a time so it requires multiple
375 * descriptors
376 */
377static inline int iop_chan_zero_sum_slot_count(size_t len, int src_cnt,
378						int *slots_per_op)
379{
380	int slot_cnt = iop3xx_aau_xor_slot_count(len, src_cnt, slots_per_op);
381
382	if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT)
383		return slot_cnt;
384
385	len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
386	while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
387		len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
388		slot_cnt += *slots_per_op;
389	}
390
391	slot_cnt += *slots_per_op;
392
393	return slot_cnt;
394}
395
396static inline int iop_desc_is_pq(struct iop_adma_desc_slot *desc)
397{
398	return 0;
399}
400
401static inline u32 iop_desc_get_dest_addr(struct iop_adma_desc_slot *desc,
402					struct iop_adma_chan *chan)
403{
404	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
405
406	switch (chan->device->id) {
407	case DMA0_ID:
408	case DMA1_ID:
409		return hw_desc.dma->dest_addr;
410	case AAU_ID:
411		return hw_desc.aau->dest_addr;
412	default:
413		BUG();
414	}
415	return 0;
416}
417
418
419static inline u32 iop_desc_get_qdest_addr(struct iop_adma_desc_slot *desc,
420					  struct iop_adma_chan *chan)
421{
422	BUG();
423	return 0;
424}
425
426static inline u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc,
427					struct iop_adma_chan *chan)
428{
429	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
430
431	switch (chan->device->id) {
432	case DMA0_ID:
433	case DMA1_ID:
434		return hw_desc.dma->byte_count;
435	case AAU_ID:
436		return hw_desc.aau->byte_count;
437	default:
438		BUG();
439	}
440	return 0;
441}
442
443/* translate the src_idx to a descriptor word index */
444static inline int __desc_idx(int src_idx)
445{
446	static const int desc_idx_table[] = { 0, 0, 0, 0,
447					      0, 1, 2, 3,
448					      5, 6, 7, 8,
449					      9, 10, 11, 12,
450					      14, 15, 16, 17,
451					      18, 19, 20, 21,
452					      23, 24, 25, 26,
453					      27, 28, 29, 30,
454					    };
455
456	return desc_idx_table[src_idx];
457}
458
459static inline u32 iop_desc_get_src_addr(struct iop_adma_desc_slot *desc,
460					struct iop_adma_chan *chan,
461					int src_idx)
462{
463	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
464
465	switch (chan->device->id) {
466	case DMA0_ID:
467	case DMA1_ID:
468		return hw_desc.dma->src_addr;
469	case AAU_ID:
470		break;
471	default:
472		BUG();
473	}
474
475	if (src_idx < 4)
476		return hw_desc.aau->src[src_idx];
477	else
478		return hw_desc.aau->src_edc[__desc_idx(src_idx)].src_addr;
479}
480
481static inline void iop3xx_aau_desc_set_src_addr(struct iop3xx_desc_aau *hw_desc,
482					int src_idx, dma_addr_t addr)
483{
484	if (src_idx < 4)
485		hw_desc->src[src_idx] = addr;
486	else
487		hw_desc->src_edc[__desc_idx(src_idx)].src_addr = addr;
488}
489
490static inline void
491iop_desc_init_memcpy(struct iop_adma_desc_slot *desc, unsigned long flags)
492{
493	struct iop3xx_desc_dma *hw_desc = desc->hw_desc;
494	union {
495		u32 value;
496		struct iop3xx_dma_desc_ctrl field;
497	} u_desc_ctrl;
498
499	u_desc_ctrl.value = 0;
500	u_desc_ctrl.field.mem_to_mem_en = 1;
501	u_desc_ctrl.field.pci_transaction = 0xe; /* memory read block */
502	u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
503	hw_desc->desc_ctrl = u_desc_ctrl.value;
504	hw_desc->upper_pci_src_addr = 0;
505	hw_desc->crc_addr = 0;
506}
507
508static inline void
509iop_desc_init_memset(struct iop_adma_desc_slot *desc, unsigned long flags)
510{
511	struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
512	union {
513		u32 value;
514		struct iop3xx_aau_desc_ctrl field;
515	} u_desc_ctrl;
516
517	u_desc_ctrl.value = 0;
518	u_desc_ctrl.field.blk1_cmd_ctrl = 0x2; /* memory block fill */
519	u_desc_ctrl.field.dest_write_en = 1;
520	u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
521	hw_desc->desc_ctrl = u_desc_ctrl.value;
522}
523
524static inline u32
525iop3xx_desc_init_xor(struct iop3xx_desc_aau *hw_desc, int src_cnt,
526		     unsigned long flags)
527{
528	int i, shift;
529	u32 edcr;
530	union {
531		u32 value;
532		struct iop3xx_aau_desc_ctrl field;
533	} u_desc_ctrl;
534
535	u_desc_ctrl.value = 0;
536	switch (src_cnt) {
537	case 25 ... 32:
538		u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
539		edcr = 0;
540		shift = 1;
541		for (i = 24; i < src_cnt; i++) {
542			edcr |= (1 << shift);
543			shift += 3;
544		}
545		hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = edcr;
546		src_cnt = 24;
547		/* fall through */
548	case 17 ... 24:
549		if (!u_desc_ctrl.field.blk_ctrl) {
550			hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
551			u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
552		}
553		edcr = 0;
554		shift = 1;
555		for (i = 16; i < src_cnt; i++) {
556			edcr |= (1 << shift);
557			shift += 3;
558		}
559		hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = edcr;
560		src_cnt = 16;
561		/* fall through */
562	case 9 ... 16:
563		if (!u_desc_ctrl.field.blk_ctrl)
564			u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */
565		edcr = 0;
566		shift = 1;
567		for (i = 8; i < src_cnt; i++) {
568			edcr |= (1 << shift);
569			shift += 3;
570		}
571		hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = edcr;
572		src_cnt = 8;
573		/* fall through */
574	case 2 ... 8:
575		shift = 1;
576		for (i = 0; i < src_cnt; i++) {
577			u_desc_ctrl.value |= (1 << shift);
578			shift += 3;
579		}
580
581		if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4)
582			u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */
583	}
584
585	u_desc_ctrl.field.dest_write_en = 1;
586	u_desc_ctrl.field.blk1_cmd_ctrl = 0x7; /* direct fill */
587	u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
588	hw_desc->desc_ctrl = u_desc_ctrl.value;
589
590	return u_desc_ctrl.value;
591}
592
593static inline void
594iop_desc_init_xor(struct iop_adma_desc_slot *desc, int src_cnt,
595		  unsigned long flags)
596{
597	iop3xx_desc_init_xor(desc->hw_desc, src_cnt, flags);
598}
599
600/* return the number of operations */
601static inline int
602iop_desc_init_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
603		       unsigned long flags)
604{
605	int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
606	struct iop3xx_desc_aau *hw_desc, *prev_hw_desc, *iter;
607	union {
608		u32 value;
609		struct iop3xx_aau_desc_ctrl field;
610	} u_desc_ctrl;
611	int i, j;
612
613	hw_desc = desc->hw_desc;
614
615	for (i = 0, j = 0; (slot_cnt -= slots_per_op) >= 0;
616		i += slots_per_op, j++) {
617		iter = iop_hw_desc_slot_idx(hw_desc, i);
618		u_desc_ctrl.value = iop3xx_desc_init_xor(iter, src_cnt, flags);
619		u_desc_ctrl.field.dest_write_en = 0;
620		u_desc_ctrl.field.zero_result_en = 1;
621		u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
622		iter->desc_ctrl = u_desc_ctrl.value;
623
624		/* for the subsequent descriptors preserve the store queue
625		 * and chain them together
626		 */
627		if (i) {
628			prev_hw_desc =
629				iop_hw_desc_slot_idx(hw_desc, i - slots_per_op);
630			prev_hw_desc->next_desc =
631				(u32) (desc->async_tx.phys + (i << 5));
632		}
633	}
634
635	return j;
636}
637
638static inline void
639iop_desc_init_null_xor(struct iop_adma_desc_slot *desc, int src_cnt,
640		       unsigned long flags)
641{
642	struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
643	union {
644		u32 value;
645		struct iop3xx_aau_desc_ctrl field;
646	} u_desc_ctrl;
647
648	u_desc_ctrl.value = 0;
649	switch (src_cnt) {
650	case 25 ... 32:
651		u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
652		hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
653		/* fall through */
654	case 17 ... 24:
655		if (!u_desc_ctrl.field.blk_ctrl) {
656			hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
657			u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
658		}
659		hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = 0;
660		/* fall through */
661	case 9 ... 16:
662		if (!u_desc_ctrl.field.blk_ctrl)
663			u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */
664		hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = 0;
665		/* fall through */
666	case 1 ... 8:
667		if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4)
668			u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */
669	}
670
671	u_desc_ctrl.field.dest_write_en = 0;
672	u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
673	hw_desc->desc_ctrl = u_desc_ctrl.value;
674}
675
676static inline void iop_desc_set_byte_count(struct iop_adma_desc_slot *desc,
677					struct iop_adma_chan *chan,
678					u32 byte_count)
679{
680	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
681
682	switch (chan->device->id) {
683	case DMA0_ID:
684	case DMA1_ID:
685		hw_desc.dma->byte_count = byte_count;
686		break;
687	case AAU_ID:
688		hw_desc.aau->byte_count = byte_count;
689		break;
690	default:
691		BUG();
692	}
693}
694
695static inline void
696iop_desc_init_interrupt(struct iop_adma_desc_slot *desc,
697			struct iop_adma_chan *chan)
698{
699	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
700
701	switch (chan->device->id) {
702	case DMA0_ID:
703	case DMA1_ID:
704		iop_desc_init_memcpy(desc, 1);
705		hw_desc.dma->byte_count = 0;
706		hw_desc.dma->dest_addr = 0;
707		hw_desc.dma->src_addr = 0;
708		break;
709	case AAU_ID:
710		iop_desc_init_null_xor(desc, 2, 1);
711		hw_desc.aau->byte_count = 0;
712		hw_desc.aau->dest_addr = 0;
713		hw_desc.aau->src[0] = 0;
714		hw_desc.aau->src[1] = 0;
715		break;
716	default:
717		BUG();
718	}
719}
720
721static inline void
722iop_desc_set_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
723{
724	int slots_per_op = desc->slots_per_op;
725	struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
726	int i = 0;
727
728	if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
729		hw_desc->byte_count = len;
730	} else {
731		do {
732			iter = iop_hw_desc_slot_idx(hw_desc, i);
733			iter->byte_count = IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
734			len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
735			i += slots_per_op;
736		} while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT);
737
738		iter = iop_hw_desc_slot_idx(hw_desc, i);
739		iter->byte_count = len;
740	}
741}
742
743static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc,
744					struct iop_adma_chan *chan,
745					dma_addr_t addr)
746{
747	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
748
749	switch (chan->device->id) {
750	case DMA0_ID:
751	case DMA1_ID:
752		hw_desc.dma->dest_addr = addr;
753		break;
754	case AAU_ID:
755		hw_desc.aau->dest_addr = addr;
756		break;
757	default:
758		BUG();
759	}
760}
761
762static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc,
763					dma_addr_t addr)
764{
765	struct iop3xx_desc_dma *hw_desc = desc->hw_desc;
766	hw_desc->src_addr = addr;
767}
768
769static inline void
770iop_desc_set_zero_sum_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
771				dma_addr_t addr)
772{
773
774	struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
775	int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
776	int i;
777
778	for (i = 0; (slot_cnt -= slots_per_op) >= 0;
779		i += slots_per_op, addr += IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
780		iter = iop_hw_desc_slot_idx(hw_desc, i);
781		iop3xx_aau_desc_set_src_addr(iter, src_idx, addr);
782	}
783}
784
785static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc,
786					int src_idx, dma_addr_t addr)
787{
788
789	struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
790	int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
791	int i;
792
793	for (i = 0; (slot_cnt -= slots_per_op) >= 0;
794		i += slots_per_op, addr += IOP_ADMA_XOR_MAX_BYTE_COUNT) {
795		iter = iop_hw_desc_slot_idx(hw_desc, i);
796		iop3xx_aau_desc_set_src_addr(iter, src_idx, addr);
797	}
798}
799
800static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc,
801					u32 next_desc_addr)
802{
803	/* hw_desc->next_desc is the same location for all channels */
804	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
805
806	iop_paranoia(hw_desc.dma->next_desc);
807	hw_desc.dma->next_desc = next_desc_addr;
808}
809
810static inline u32 iop_desc_get_next_desc(struct iop_adma_desc_slot *desc)
811{
812	/* hw_desc->next_desc is the same location for all channels */
813	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
814	return hw_desc.dma->next_desc;
815}
816
817static inline void iop_desc_clear_next_desc(struct iop_adma_desc_slot *desc)
818{
819	/* hw_desc->next_desc is the same location for all channels */
820	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
821	hw_desc.dma->next_desc = 0;
822}
823
824static inline void iop_desc_set_block_fill_val(struct iop_adma_desc_slot *desc,
825						u32 val)
826{
827	struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
828	hw_desc->src[0] = val;
829}
830
831static inline enum sum_check_flags
832iop_desc_get_zero_result(struct iop_adma_desc_slot *desc)
833{
834	struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
835	struct iop3xx_aau_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field;
836
837	iop_paranoia(!(desc_ctrl.tx_complete && desc_ctrl.zero_result_en));
838	return desc_ctrl.zero_result_err << SUM_CHECK_P;
839}
840
841static inline void iop_chan_append(struct iop_adma_chan *chan)
842{
843	u32 dma_chan_ctrl;
844
845	dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
846	dma_chan_ctrl |= 0x2;
847	__raw_writel(dma_chan_ctrl, DMA_CCR(chan));
848}
849
850static inline u32 iop_chan_get_status(struct iop_adma_chan *chan)
851{
852	return __raw_readl(DMA_CSR(chan));
853}
854
855static inline void iop_chan_disable(struct iop_adma_chan *chan)
856{
857	u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
858	dma_chan_ctrl &= ~1;
859	__raw_writel(dma_chan_ctrl, DMA_CCR(chan));
860}
861
862static inline void iop_chan_enable(struct iop_adma_chan *chan)
863{
864	u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
865
866	dma_chan_ctrl |= 1;
867	__raw_writel(dma_chan_ctrl, DMA_CCR(chan));
868}
869
870static inline void iop_adma_device_clear_eot_status(struct iop_adma_chan *chan)
871{
872	u32 status = __raw_readl(DMA_CSR(chan));
873	status &= (1 << 9);
874	__raw_writel(status, DMA_CSR(chan));
875}
876
877static inline void iop_adma_device_clear_eoc_status(struct iop_adma_chan *chan)
878{
879	u32 status = __raw_readl(DMA_CSR(chan));
880	status &= (1 << 8);
881	__raw_writel(status, DMA_CSR(chan));
882}
883
884static inline void iop_adma_device_clear_err_status(struct iop_adma_chan *chan)
885{
886	u32 status = __raw_readl(DMA_CSR(chan));
887
888	switch (chan->device->id) {
889	case DMA0_ID:
890	case DMA1_ID:
891		status &= (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1);
892		break;
893	case AAU_ID:
894		status &= (1 << 5);
895		break;
896	default:
897		BUG();
898	}
899
900	__raw_writel(status, DMA_CSR(chan));
901}
902
903static inline int
904iop_is_err_int_parity(unsigned long status, struct iop_adma_chan *chan)
905{
906	return 0;
907}
908
909static inline int
910iop_is_err_mcu_abort(unsigned long status, struct iop_adma_chan *chan)
911{
912	return 0;
913}
914
915static inline int
916iop_is_err_int_tabort(unsigned long status, struct iop_adma_chan *chan)
917{
918	return 0;
919}
920
921static inline int
922iop_is_err_int_mabort(unsigned long status, struct iop_adma_chan *chan)
923{
924	return test_bit(5, &status);
925}
926
927static inline int
928iop_is_err_pci_tabort(unsigned long status, struct iop_adma_chan *chan)
929{
930	switch (chan->device->id) {
931	case DMA0_ID:
932	case DMA1_ID:
933		return test_bit(2, &status);
934	default:
935		return 0;
936	}
937}
938
939static inline int
940iop_is_err_pci_mabort(unsigned long status, struct iop_adma_chan *chan)
941{
942	switch (chan->device->id) {
943	case DMA0_ID:
944	case DMA1_ID:
945		return test_bit(3, &status);
946	default:
947		return 0;
948	}
949}
950
951static inline int
952iop_is_err_split_tx(unsigned long status, struct iop_adma_chan *chan)
953{
954	switch (chan->device->id) {
955	case DMA0_ID:
956	case DMA1_ID:
957		return test_bit(1, &status);
958	default:
959		return 0;
960	}
961}
962#endif /* _ADMA_H */
963