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 u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc,
397					struct iop_adma_chan *chan)
398{
399	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
400
401	switch (chan->device->id) {
402	case DMA0_ID:
403	case DMA1_ID:
404		return hw_desc.dma->byte_count;
405	case AAU_ID:
406		return hw_desc.aau->byte_count;
407	default:
408		BUG();
409	}
410	return 0;
411}
412
413/* translate the src_idx to a descriptor word index */
414static inline int __desc_idx(int src_idx)
415{
416	static const int desc_idx_table[] = { 0, 0, 0, 0,
417					      0, 1, 2, 3,
418					      5, 6, 7, 8,
419					      9, 10, 11, 12,
420					      14, 15, 16, 17,
421					      18, 19, 20, 21,
422					      23, 24, 25, 26,
423					      27, 28, 29, 30,
424					    };
425
426	return desc_idx_table[src_idx];
427}
428
429static inline u32 iop_desc_get_src_addr(struct iop_adma_desc_slot *desc,
430					struct iop_adma_chan *chan,
431					int src_idx)
432{
433	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
434
435	switch (chan->device->id) {
436	case DMA0_ID:
437	case DMA1_ID:
438		return hw_desc.dma->src_addr;
439	case AAU_ID:
440		break;
441	default:
442		BUG();
443	}
444
445	if (src_idx < 4)
446		return hw_desc.aau->src[src_idx];
447	else
448		return hw_desc.aau->src_edc[__desc_idx(src_idx)].src_addr;
449}
450
451static inline void iop3xx_aau_desc_set_src_addr(struct iop3xx_desc_aau *hw_desc,
452					int src_idx, dma_addr_t addr)
453{
454	if (src_idx < 4)
455		hw_desc->src[src_idx] = addr;
456	else
457		hw_desc->src_edc[__desc_idx(src_idx)].src_addr = addr;
458}
459
460static inline void
461iop_desc_init_memcpy(struct iop_adma_desc_slot *desc, unsigned long flags)
462{
463	struct iop3xx_desc_dma *hw_desc = desc->hw_desc;
464	union {
465		u32 value;
466		struct iop3xx_dma_desc_ctrl field;
467	} u_desc_ctrl;
468
469	u_desc_ctrl.value = 0;
470	u_desc_ctrl.field.mem_to_mem_en = 1;
471	u_desc_ctrl.field.pci_transaction = 0xe; /* memory read block */
472	u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
473	hw_desc->desc_ctrl = u_desc_ctrl.value;
474	hw_desc->upper_pci_src_addr = 0;
475	hw_desc->crc_addr = 0;
476}
477
478static inline void
479iop_desc_init_memset(struct iop_adma_desc_slot *desc, unsigned long flags)
480{
481	struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
482	union {
483		u32 value;
484		struct iop3xx_aau_desc_ctrl field;
485	} u_desc_ctrl;
486
487	u_desc_ctrl.value = 0;
488	u_desc_ctrl.field.blk1_cmd_ctrl = 0x2; /* memory block fill */
489	u_desc_ctrl.field.dest_write_en = 1;
490	u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
491	hw_desc->desc_ctrl = u_desc_ctrl.value;
492}
493
494static inline u32
495iop3xx_desc_init_xor(struct iop3xx_desc_aau *hw_desc, int src_cnt,
496		     unsigned long flags)
497{
498	int i, shift;
499	u32 edcr;
500	union {
501		u32 value;
502		struct iop3xx_aau_desc_ctrl field;
503	} u_desc_ctrl;
504
505	u_desc_ctrl.value = 0;
506	switch (src_cnt) {
507	case 25 ... 32:
508		u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
509		edcr = 0;
510		shift = 1;
511		for (i = 24; i < src_cnt; i++) {
512			edcr |= (1 << shift);
513			shift += 3;
514		}
515		hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = edcr;
516		src_cnt = 24;
517		/* fall through */
518	case 17 ... 24:
519		if (!u_desc_ctrl.field.blk_ctrl) {
520			hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
521			u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
522		}
523		edcr = 0;
524		shift = 1;
525		for (i = 16; i < src_cnt; i++) {
526			edcr |= (1 << shift);
527			shift += 3;
528		}
529		hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = edcr;
530		src_cnt = 16;
531		/* fall through */
532	case 9 ... 16:
533		if (!u_desc_ctrl.field.blk_ctrl)
534			u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */
535		edcr = 0;
536		shift = 1;
537		for (i = 8; i < src_cnt; i++) {
538			edcr |= (1 << shift);
539			shift += 3;
540		}
541		hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = edcr;
542		src_cnt = 8;
543		/* fall through */
544	case 2 ... 8:
545		shift = 1;
546		for (i = 0; i < src_cnt; i++) {
547			u_desc_ctrl.value |= (1 << shift);
548			shift += 3;
549		}
550
551		if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4)
552			u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */
553	}
554
555	u_desc_ctrl.field.dest_write_en = 1;
556	u_desc_ctrl.field.blk1_cmd_ctrl = 0x7; /* direct fill */
557	u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
558	hw_desc->desc_ctrl = u_desc_ctrl.value;
559
560	return u_desc_ctrl.value;
561}
562
563static inline void
564iop_desc_init_xor(struct iop_adma_desc_slot *desc, int src_cnt,
565		  unsigned long flags)
566{
567	iop3xx_desc_init_xor(desc->hw_desc, src_cnt, flags);
568}
569
570/* return the number of operations */
571static inline int
572iop_desc_init_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
573		       unsigned long flags)
574{
575	int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
576	struct iop3xx_desc_aau *hw_desc, *prev_hw_desc, *iter;
577	union {
578		u32 value;
579		struct iop3xx_aau_desc_ctrl field;
580	} u_desc_ctrl;
581	int i, j;
582
583	hw_desc = desc->hw_desc;
584
585	for (i = 0, j = 0; (slot_cnt -= slots_per_op) >= 0;
586		i += slots_per_op, j++) {
587		iter = iop_hw_desc_slot_idx(hw_desc, i);
588		u_desc_ctrl.value = iop3xx_desc_init_xor(iter, src_cnt, flags);
589		u_desc_ctrl.field.dest_write_en = 0;
590		u_desc_ctrl.field.zero_result_en = 1;
591		u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
592		iter->desc_ctrl = u_desc_ctrl.value;
593
594		/* for the subsequent descriptors preserve the store queue
595		 * and chain them together
596		 */
597		if (i) {
598			prev_hw_desc =
599				iop_hw_desc_slot_idx(hw_desc, i - slots_per_op);
600			prev_hw_desc->next_desc =
601				(u32) (desc->async_tx.phys + (i << 5));
602		}
603	}
604
605	return j;
606}
607
608static inline void
609iop_desc_init_null_xor(struct iop_adma_desc_slot *desc, int src_cnt,
610		       unsigned long flags)
611{
612	struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
613	union {
614		u32 value;
615		struct iop3xx_aau_desc_ctrl field;
616	} u_desc_ctrl;
617
618	u_desc_ctrl.value = 0;
619	switch (src_cnt) {
620	case 25 ... 32:
621		u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
622		hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
623		/* fall through */
624	case 17 ... 24:
625		if (!u_desc_ctrl.field.blk_ctrl) {
626			hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
627			u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
628		}
629		hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = 0;
630		/* fall through */
631	case 9 ... 16:
632		if (!u_desc_ctrl.field.blk_ctrl)
633			u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */
634		hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = 0;
635		/* fall through */
636	case 1 ... 8:
637		if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4)
638			u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */
639	}
640
641	u_desc_ctrl.field.dest_write_en = 0;
642	u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
643	hw_desc->desc_ctrl = u_desc_ctrl.value;
644}
645
646static inline void iop_desc_set_byte_count(struct iop_adma_desc_slot *desc,
647					struct iop_adma_chan *chan,
648					u32 byte_count)
649{
650	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
651
652	switch (chan->device->id) {
653	case DMA0_ID:
654	case DMA1_ID:
655		hw_desc.dma->byte_count = byte_count;
656		break;
657	case AAU_ID:
658		hw_desc.aau->byte_count = byte_count;
659		break;
660	default:
661		BUG();
662	}
663}
664
665static inline void
666iop_desc_init_interrupt(struct iop_adma_desc_slot *desc,
667			struct iop_adma_chan *chan)
668{
669	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
670
671	switch (chan->device->id) {
672	case DMA0_ID:
673	case DMA1_ID:
674		iop_desc_init_memcpy(desc, 1);
675		hw_desc.dma->byte_count = 0;
676		hw_desc.dma->dest_addr = 0;
677		hw_desc.dma->src_addr = 0;
678		break;
679	case AAU_ID:
680		iop_desc_init_null_xor(desc, 2, 1);
681		hw_desc.aau->byte_count = 0;
682		hw_desc.aau->dest_addr = 0;
683		hw_desc.aau->src[0] = 0;
684		hw_desc.aau->src[1] = 0;
685		break;
686	default:
687		BUG();
688	}
689}
690
691static inline void
692iop_desc_set_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
693{
694	int slots_per_op = desc->slots_per_op;
695	struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
696	int i = 0;
697
698	if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
699		hw_desc->byte_count = len;
700	} else {
701		do {
702			iter = iop_hw_desc_slot_idx(hw_desc, i);
703			iter->byte_count = IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
704			len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
705			i += slots_per_op;
706		} while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT);
707
708		iter = iop_hw_desc_slot_idx(hw_desc, i);
709		iter->byte_count = len;
710	}
711}
712
713static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc,
714					struct iop_adma_chan *chan,
715					dma_addr_t addr)
716{
717	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
718
719	switch (chan->device->id) {
720	case DMA0_ID:
721	case DMA1_ID:
722		hw_desc.dma->dest_addr = addr;
723		break;
724	case AAU_ID:
725		hw_desc.aau->dest_addr = addr;
726		break;
727	default:
728		BUG();
729	}
730}
731
732static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc,
733					dma_addr_t addr)
734{
735	struct iop3xx_desc_dma *hw_desc = desc->hw_desc;
736	hw_desc->src_addr = addr;
737}
738
739static inline void
740iop_desc_set_zero_sum_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
741				dma_addr_t addr)
742{
743
744	struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
745	int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
746	int i;
747
748	for (i = 0; (slot_cnt -= slots_per_op) >= 0;
749		i += slots_per_op, addr += IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
750		iter = iop_hw_desc_slot_idx(hw_desc, i);
751		iop3xx_aau_desc_set_src_addr(iter, src_idx, addr);
752	}
753}
754
755static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc,
756					int src_idx, dma_addr_t addr)
757{
758
759	struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
760	int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
761	int i;
762
763	for (i = 0; (slot_cnt -= slots_per_op) >= 0;
764		i += slots_per_op, addr += IOP_ADMA_XOR_MAX_BYTE_COUNT) {
765		iter = iop_hw_desc_slot_idx(hw_desc, i);
766		iop3xx_aau_desc_set_src_addr(iter, src_idx, addr);
767	}
768}
769
770static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc,
771					u32 next_desc_addr)
772{
773	/* hw_desc->next_desc is the same location for all channels */
774	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
775
776	iop_paranoia(hw_desc.dma->next_desc);
777	hw_desc.dma->next_desc = next_desc_addr;
778}
779
780static inline u32 iop_desc_get_next_desc(struct iop_adma_desc_slot *desc)
781{
782	/* hw_desc->next_desc is the same location for all channels */
783	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
784	return hw_desc.dma->next_desc;
785}
786
787static inline void iop_desc_clear_next_desc(struct iop_adma_desc_slot *desc)
788{
789	/* hw_desc->next_desc is the same location for all channels */
790	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
791	hw_desc.dma->next_desc = 0;
792}
793
794static inline void iop_desc_set_block_fill_val(struct iop_adma_desc_slot *desc,
795						u32 val)
796{
797	struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
798	hw_desc->src[0] = val;
799}
800
801static inline enum sum_check_flags
802iop_desc_get_zero_result(struct iop_adma_desc_slot *desc)
803{
804	struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
805	struct iop3xx_aau_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field;
806
807	iop_paranoia(!(desc_ctrl.tx_complete && desc_ctrl.zero_result_en));
808	return desc_ctrl.zero_result_err << SUM_CHECK_P;
809}
810
811static inline void iop_chan_append(struct iop_adma_chan *chan)
812{
813	u32 dma_chan_ctrl;
814
815	dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
816	dma_chan_ctrl |= 0x2;
817	__raw_writel(dma_chan_ctrl, DMA_CCR(chan));
818}
819
820static inline u32 iop_chan_get_status(struct iop_adma_chan *chan)
821{
822	return __raw_readl(DMA_CSR(chan));
823}
824
825static inline void iop_chan_disable(struct iop_adma_chan *chan)
826{
827	u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
828	dma_chan_ctrl &= ~1;
829	__raw_writel(dma_chan_ctrl, DMA_CCR(chan));
830}
831
832static inline void iop_chan_enable(struct iop_adma_chan *chan)
833{
834	u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
835
836	dma_chan_ctrl |= 1;
837	__raw_writel(dma_chan_ctrl, DMA_CCR(chan));
838}
839
840static inline void iop_adma_device_clear_eot_status(struct iop_adma_chan *chan)
841{
842	u32 status = __raw_readl(DMA_CSR(chan));
843	status &= (1 << 9);
844	__raw_writel(status, DMA_CSR(chan));
845}
846
847static inline void iop_adma_device_clear_eoc_status(struct iop_adma_chan *chan)
848{
849	u32 status = __raw_readl(DMA_CSR(chan));
850	status &= (1 << 8);
851	__raw_writel(status, DMA_CSR(chan));
852}
853
854static inline void iop_adma_device_clear_err_status(struct iop_adma_chan *chan)
855{
856	u32 status = __raw_readl(DMA_CSR(chan));
857
858	switch (chan->device->id) {
859	case DMA0_ID:
860	case DMA1_ID:
861		status &= (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1);
862		break;
863	case AAU_ID:
864		status &= (1 << 5);
865		break;
866	default:
867		BUG();
868	}
869
870	__raw_writel(status, DMA_CSR(chan));
871}
872
873static inline int
874iop_is_err_int_parity(unsigned long status, struct iop_adma_chan *chan)
875{
876	return 0;
877}
878
879static inline int
880iop_is_err_mcu_abort(unsigned long status, struct iop_adma_chan *chan)
881{
882	return 0;
883}
884
885static inline int
886iop_is_err_int_tabort(unsigned long status, struct iop_adma_chan *chan)
887{
888	return 0;
889}
890
891static inline int
892iop_is_err_int_mabort(unsigned long status, struct iop_adma_chan *chan)
893{
894	return test_bit(5, &status);
895}
896
897static inline int
898iop_is_err_pci_tabort(unsigned long status, struct iop_adma_chan *chan)
899{
900	switch (chan->device->id) {
901	case DMA0_ID:
902	case DMA1_ID:
903		return test_bit(2, &status);
904	default:
905		return 0;
906	}
907}
908
909static inline int
910iop_is_err_pci_mabort(unsigned long status, struct iop_adma_chan *chan)
911{
912	switch (chan->device->id) {
913	case DMA0_ID:
914	case DMA1_ID:
915		return test_bit(3, &status);
916	default:
917		return 0;
918	}
919}
920
921static inline int
922iop_is_err_split_tx(unsigned long status, struct iop_adma_chan *chan)
923{
924	switch (chan->device->id) {
925	case DMA0_ID:
926	case DMA1_ID:
927		return test_bit(1, &status);
928	default:
929		return 0;
930	}
931}
932#endif /* _ADMA_H */
933