/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright © 2006, Intel Corporation.
 */
#ifndef _ADMA_H
#define _ADMA_H
#include <linux/types.h>
#include <linux/io.h>
#include <linux/platform_data/dma-iop32x.h>

/* Memory copy units */
#define DMA_CCR(chan)		(chan->mmr_base + 0x0)
#define DMA_CSR(chan)		(chan->mmr_base + 0x4)
#define DMA_DAR(chan)		(chan->mmr_base + 0xc)
#define DMA_NDAR(chan)		(chan->mmr_base + 0x10)
#define DMA_PADR(chan)		(chan->mmr_base + 0x14)
#define DMA_PUADR(chan)	(chan->mmr_base + 0x18)
#define DMA_LADR(chan)		(chan->mmr_base + 0x1c)
#define DMA_BCR(chan)		(chan->mmr_base + 0x20)
#define DMA_DCR(chan)		(chan->mmr_base + 0x24)

/* Application accelerator unit  */
#define AAU_ACR(chan)		(chan->mmr_base + 0x0)
#define AAU_ASR(chan)		(chan->mmr_base + 0x4)
#define AAU_ADAR(chan)		(chan->mmr_base + 0x8)
#define AAU_ANDAR(chan)	(chan->mmr_base + 0xc)
#define AAU_SAR(src, chan)	(chan->mmr_base + (0x10 + ((src) << 2)))
#define AAU_DAR(chan)		(chan->mmr_base + 0x20)
#define AAU_ABCR(chan)		(chan->mmr_base + 0x24)
#define AAU_ADCR(chan)		(chan->mmr_base + 0x28)
#define AAU_SAR_EDCR(src_edc)	(chan->mmr_base + (0x02c + ((src_edc-4) << 2)))
#define AAU_EDCR0_IDX	8
#define AAU_EDCR1_IDX	17
#define AAU_EDCR2_IDX	26

struct iop3xx_aau_desc_ctrl {
	unsigned int int_en:1;
	unsigned int blk1_cmd_ctrl:3;
	unsigned int blk2_cmd_ctrl:3;
	unsigned int blk3_cmd_ctrl:3;
	unsigned int blk4_cmd_ctrl:3;
	unsigned int blk5_cmd_ctrl:3;
	unsigned int blk6_cmd_ctrl:3;
	unsigned int blk7_cmd_ctrl:3;
	unsigned int blk8_cmd_ctrl:3;
	unsigned int blk_ctrl:2;
	unsigned int dual_xor_en:1;
	unsigned int tx_complete:1;
	unsigned int zero_result_err:1;
	unsigned int zero_result_en:1;
	unsigned int dest_write_en:1;
};

struct iop3xx_aau_e_desc_ctrl {
	unsigned int reserved:1;
	unsigned int blk1_cmd_ctrl:3;
	unsigned int blk2_cmd_ctrl:3;
	unsigned int blk3_cmd_ctrl:3;
	unsigned int blk4_cmd_ctrl:3;
	unsigned int blk5_cmd_ctrl:3;
	unsigned int blk6_cmd_ctrl:3;
	unsigned int blk7_cmd_ctrl:3;
	unsigned int blk8_cmd_ctrl:3;
	unsigned int reserved2:7;
};

struct iop3xx_dma_desc_ctrl {
	unsigned int pci_transaction:4;
	unsigned int int_en:1;
	unsigned int dac_cycle_en:1;
	unsigned int mem_to_mem_en:1;
	unsigned int crc_data_tx_en:1;
	unsigned int crc_gen_en:1;
	unsigned int crc_seed_dis:1;
	unsigned int reserved:21;
	unsigned int crc_tx_complete:1;
};

struct iop3xx_desc_dma {
	u32 next_desc;
	union {
		u32 pci_src_addr;
		u32 pci_dest_addr;
		u32 src_addr;
	};
	union {
		u32 upper_pci_src_addr;
		u32 upper_pci_dest_addr;
	};
	union {
		u32 local_pci_src_addr;
		u32 local_pci_dest_addr;
		u32 dest_addr;
	};
	u32 byte_count;
	union {
		u32 desc_ctrl;
		struct iop3xx_dma_desc_ctrl desc_ctrl_field;
	};
	u32 crc_addr;
};

struct iop3xx_desc_aau {
	u32 next_desc;
	u32 src[4];
	u32 dest_addr;
	u32 byte_count;
	union {
		u32 desc_ctrl;
		struct iop3xx_aau_desc_ctrl desc_ctrl_field;
	};
	union {
		u32 src_addr;
		u32 e_desc_ctrl;
		struct iop3xx_aau_e_desc_ctrl e_desc_ctrl_field;
	} src_edc[31];
};

struct iop3xx_aau_gfmr {
	unsigned int gfmr1:8;
	unsigned int gfmr2:8;
	unsigned int gfmr3:8;
	unsigned int gfmr4:8;
};

struct iop3xx_desc_pq_xor {
	u32 next_desc;
	u32 src[3];
	union {
		u32 data_mult1;
		struct iop3xx_aau_gfmr data_mult1_field;
	};
	u32 dest_addr;
	u32 byte_count;
	union {
		u32 desc_ctrl;
		struct iop3xx_aau_desc_ctrl desc_ctrl_field;
	};
	union {
		u32 src_addr;
		u32 e_desc_ctrl;
		struct iop3xx_aau_e_desc_ctrl e_desc_ctrl_field;
		u32 data_multiplier;
		struct iop3xx_aau_gfmr data_mult_field;
		u32 reserved;
	} src_edc_gfmr[19];
};

struct iop3xx_desc_dual_xor {
	u32 next_desc;
	u32 src0_addr;
	u32 src1_addr;
	u32 h_src_addr;
	u32 d_src_addr;
	u32 h_dest_addr;
	u32 byte_count;
	union {
		u32 desc_ctrl;
		struct iop3xx_aau_desc_ctrl desc_ctrl_field;
	};
	u32 d_dest_addr;
};

union iop3xx_desc {
	struct iop3xx_desc_aau *aau;
	struct iop3xx_desc_dma *dma;
	struct iop3xx_desc_pq_xor *pq_xor;
	struct iop3xx_desc_dual_xor *dual_xor;
	void *ptr;
};

/* No support for p+q operations */
static inline int
iop_chan_pq_slot_count(size_t len, int src_cnt, int *slots_per_op)
{
	BUG();
	return 0;
}

static inline void
iop_desc_init_pq(struct iop_adma_desc_slot *desc, int src_cnt,
		  unsigned long flags)
{
	BUG();
}

static inline void
iop_desc_set_pq_addr(struct iop_adma_desc_slot *desc, dma_addr_t *addr)
{
	BUG();
}

static inline void
iop_desc_set_pq_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
			 dma_addr_t addr, unsigned char coef)
{
	BUG();
}

static inline int
iop_chan_pq_zero_sum_slot_count(size_t len, int src_cnt, int *slots_per_op)
{
	BUG();
	return 0;
}

static inline void
iop_desc_init_pq_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
			  unsigned long flags)
{
	BUG();
}

static inline void
iop_desc_set_pq_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
{
	BUG();
}

#define iop_desc_set_pq_zero_sum_src_addr iop_desc_set_pq_src_addr

static inline void
iop_desc_set_pq_zero_sum_addr(struct iop_adma_desc_slot *desc, int pq_idx,
			      dma_addr_t *src)
{
	BUG();
}

static inline int iop_adma_get_max_xor(void)
{
	return 32;
}

static inline int iop_adma_get_max_pq(void)
{
	BUG();
	return 0;
}

static inline u32 iop_chan_get_current_descriptor(struct iop_adma_chan *chan)
{
	int id = chan->device->id;

	switch (id) {
	case DMA0_ID:
	case DMA1_ID:
		return __raw_readl(DMA_DAR(chan));
	case AAU_ID:
		return __raw_readl(AAU_ADAR(chan));
	default:
		BUG();
	}
	return 0;
}

static inline void iop_chan_set_next_descriptor(struct iop_adma_chan *chan,
						u32 next_desc_addr)
{
	int id = chan->device->id;

	switch (id) {
	case DMA0_ID:
	case DMA1_ID:
		__raw_writel(next_desc_addr, DMA_NDAR(chan));
		break;
	case AAU_ID:
		__raw_writel(next_desc_addr, AAU_ANDAR(chan));
		break;
	}

}

#define IOP_ADMA_STATUS_BUSY (1 << 10)
#define IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT (1024)
#define IOP_ADMA_XOR_MAX_BYTE_COUNT (16 * 1024 * 1024)
#define IOP_ADMA_MAX_BYTE_COUNT (16 * 1024 * 1024)

static inline int iop_chan_is_busy(struct iop_adma_chan *chan)
{
	u32 status = __raw_readl(DMA_CSR(chan));
	return (status & IOP_ADMA_STATUS_BUSY) ? 1 : 0;
}

static inline int iop_desc_is_aligned(struct iop_adma_desc_slot *desc,
					int num_slots)
{
	/* num_slots will only ever be 1, 2, 4, or 8 */
	return (desc->idx & (num_slots - 1)) ? 0 : 1;
}

/* to do: support large (i.e. > hw max) buffer sizes */
static inline int iop_chan_memcpy_slot_count(size_t len, int *slots_per_op)
{
	*slots_per_op = 1;
	return 1;
}

/* to do: support large (i.e. > hw max) buffer sizes */
static inline int iop_chan_memset_slot_count(size_t len, int *slots_per_op)
{
	*slots_per_op = 1;
	return 1;
}

static inline int iop3xx_aau_xor_slot_count(size_t len, int src_cnt,
					int *slots_per_op)
{
	static const char slot_count_table[] = {
						1, 1, 1, 1, /* 01 - 04 */
						2, 2, 2, 2, /* 05 - 08 */
						4, 4, 4, 4, /* 09 - 12 */
						4, 4, 4, 4, /* 13 - 16 */
						8, 8, 8, 8, /* 17 - 20 */
						8, 8, 8, 8, /* 21 - 24 */
						8, 8, 8, 8, /* 25 - 28 */
						8, 8, 8, 8, /* 29 - 32 */
					      };
	*slots_per_op = slot_count_table[src_cnt - 1];
	return *slots_per_op;
}

static inline int
iop_chan_interrupt_slot_count(int *slots_per_op, struct iop_adma_chan *chan)
{
	switch (chan->device->id) {
	case DMA0_ID:
	case DMA1_ID:
		return iop_chan_memcpy_slot_count(0, slots_per_op);
	case AAU_ID:
		return iop3xx_aau_xor_slot_count(0, 2, slots_per_op);
	default:
		BUG();
	}
	return 0;
}

static inline int iop_chan_xor_slot_count(size_t len, int src_cnt,
						int *slots_per_op)
{
	int slot_cnt = iop3xx_aau_xor_slot_count(len, src_cnt, slots_per_op);

	if (len <= IOP_ADMA_XOR_MAX_BYTE_COUNT)
		return slot_cnt;

	len -= IOP_ADMA_XOR_MAX_BYTE_COUNT;
	while (len > IOP_ADMA_XOR_MAX_BYTE_COUNT) {
		len -= IOP_ADMA_XOR_MAX_BYTE_COUNT;
		slot_cnt += *slots_per_op;
	}

	slot_cnt += *slots_per_op;

	return slot_cnt;
}

/* zero sum on iop3xx is limited to 1k at a time so it requires multiple
 * descriptors
 */
static inline int iop_chan_zero_sum_slot_count(size_t len, int src_cnt,
						int *slots_per_op)
{
	int slot_cnt = iop3xx_aau_xor_slot_count(len, src_cnt, slots_per_op);

	if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT)
		return slot_cnt;

	len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
	while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
		len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
		slot_cnt += *slots_per_op;
	}

	slot_cnt += *slots_per_op;

	return slot_cnt;
}

static inline u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc,
					struct iop_adma_chan *chan)
{
	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };

	switch (chan->device->id) {
	case DMA0_ID:
	case DMA1_ID:
		return hw_desc.dma->byte_count;
	case AAU_ID:
		return hw_desc.aau->byte_count;
	default:
		BUG();
	}
	return 0;
}

/* translate the src_idx to a descriptor word index */
static inline int __desc_idx(int src_idx)
{
	static const int desc_idx_table[] = { 0, 0, 0, 0,
					      0, 1, 2, 3,
					      5, 6, 7, 8,
					      9, 10, 11, 12,
					      14, 15, 16, 17,
					      18, 19, 20, 21,
					      23, 24, 25, 26,
					      27, 28, 29, 30,
					    };

	return desc_idx_table[src_idx];
}

static inline u32 iop_desc_get_src_addr(struct iop_adma_desc_slot *desc,
					struct iop_adma_chan *chan,
					int src_idx)
{
	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };

	switch (chan->device->id) {
	case DMA0_ID:
	case DMA1_ID:
		return hw_desc.dma->src_addr;
	case AAU_ID:
		break;
	default:
		BUG();
	}

	if (src_idx < 4)
		return hw_desc.aau->src[src_idx];
	else
		return hw_desc.aau->src_edc[__desc_idx(src_idx)].src_addr;
}

static inline void iop3xx_aau_desc_set_src_addr(struct iop3xx_desc_aau *hw_desc,
					int src_idx, dma_addr_t addr)
{
	if (src_idx < 4)
		hw_desc->src[src_idx] = addr;
	else
		hw_desc->src_edc[__desc_idx(src_idx)].src_addr = addr;
}

static inline void
iop_desc_init_memcpy(struct iop_adma_desc_slot *desc, unsigned long flags)
{
	struct iop3xx_desc_dma *hw_desc = desc->hw_desc;
	union {
		u32 value;
		struct iop3xx_dma_desc_ctrl field;
	} u_desc_ctrl;

	u_desc_ctrl.value = 0;
	u_desc_ctrl.field.mem_to_mem_en = 1;
	u_desc_ctrl.field.pci_transaction = 0xe; /* memory read block */
	u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
	hw_desc->desc_ctrl = u_desc_ctrl.value;
	hw_desc->upper_pci_src_addr = 0;
	hw_desc->crc_addr = 0;
}

static inline void
iop_desc_init_memset(struct iop_adma_desc_slot *desc, unsigned long flags)
{
	struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
	union {
		u32 value;
		struct iop3xx_aau_desc_ctrl field;
	} u_desc_ctrl;

	u_desc_ctrl.value = 0;
	u_desc_ctrl.field.blk1_cmd_ctrl = 0x2; /* memory block fill */
	u_desc_ctrl.field.dest_write_en = 1;
	u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
	hw_desc->desc_ctrl = u_desc_ctrl.value;
}

static inline u32
iop3xx_desc_init_xor(struct iop3xx_desc_aau *hw_desc, int src_cnt,
		     unsigned long flags)
{
	int i, shift;
	u32 edcr;
	union {
		u32 value;
		struct iop3xx_aau_desc_ctrl field;
	} u_desc_ctrl;

	u_desc_ctrl.value = 0;
	switch (src_cnt) {
	case 25 ... 32:
		u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
		edcr = 0;
		shift = 1;
		for (i = 24; i < src_cnt; i++) {
			edcr |= (1 << shift);
			shift += 3;
		}
		hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = edcr;
		src_cnt = 24;
		/* fall through */
	case 17 ... 24:
		if (!u_desc_ctrl.field.blk_ctrl) {
			hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
			u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
		}
		edcr = 0;
		shift = 1;
		for (i = 16; i < src_cnt; i++) {
			edcr |= (1 << shift);
			shift += 3;
		}
		hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = edcr;
		src_cnt = 16;
		/* fall through */
	case 9 ... 16:
		if (!u_desc_ctrl.field.blk_ctrl)
			u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */
		edcr = 0;
		shift = 1;
		for (i = 8; i < src_cnt; i++) {
			edcr |= (1 << shift);
			shift += 3;
		}
		hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = edcr;
		src_cnt = 8;
		/* fall through */
	case 2 ... 8:
		shift = 1;
		for (i = 0; i < src_cnt; i++) {
			u_desc_ctrl.value |= (1 << shift);
			shift += 3;
		}

		if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4)
			u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */
	}

	u_desc_ctrl.field.dest_write_en = 1;
	u_desc_ctrl.field.blk1_cmd_ctrl = 0x7; /* direct fill */
	u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
	hw_desc->desc_ctrl = u_desc_ctrl.value;

	return u_desc_ctrl.value;
}

static inline void
iop_desc_init_xor(struct iop_adma_desc_slot *desc, int src_cnt,
		  unsigned long flags)
{
	iop3xx_desc_init_xor(desc->hw_desc, src_cnt, flags);
}

/* return the number of operations */
static inline int
iop_desc_init_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
		       unsigned long flags)
{
	int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
	struct iop3xx_desc_aau *hw_desc, *prev_hw_desc, *iter;
	union {
		u32 value;
		struct iop3xx_aau_desc_ctrl field;
	} u_desc_ctrl;
	int i, j;

	hw_desc = desc->hw_desc;

	for (i = 0, j = 0; (slot_cnt -= slots_per_op) >= 0;
		i += slots_per_op, j++) {
		iter = iop_hw_desc_slot_idx(hw_desc, i);
		u_desc_ctrl.value = iop3xx_desc_init_xor(iter, src_cnt, flags);
		u_desc_ctrl.field.dest_write_en = 0;
		u_desc_ctrl.field.zero_result_en = 1;
		u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
		iter->desc_ctrl = u_desc_ctrl.value;

		/* for the subsequent descriptors preserve the store queue
		 * and chain them together
		 */
		if (i) {
			prev_hw_desc =
				iop_hw_desc_slot_idx(hw_desc, i - slots_per_op);
			prev_hw_desc->next_desc =
				(u32) (desc->async_tx.phys + (i << 5));
		}
	}

	return j;
}

static inline void
iop_desc_init_null_xor(struct iop_adma_desc_slot *desc, int src_cnt,
		       unsigned long flags)
{
	struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
	union {
		u32 value;
		struct iop3xx_aau_desc_ctrl field;
	} u_desc_ctrl;

	u_desc_ctrl.value = 0;
	switch (src_cnt) {
	case 25 ... 32:
		u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
		hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
		/* fall through */
	case 17 ... 24:
		if (!u_desc_ctrl.field.blk_ctrl) {
			hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
			u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
		}
		hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = 0;
		/* fall through */
	case 9 ... 16:
		if (!u_desc_ctrl.field.blk_ctrl)
			u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */
		hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = 0;
		/* fall through */
	case 1 ... 8:
		if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4)
			u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */
	}

	u_desc_ctrl.field.dest_write_en = 0;
	u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
	hw_desc->desc_ctrl = u_desc_ctrl.value;
}

static inline void iop_desc_set_byte_count(struct iop_adma_desc_slot *desc,
					struct iop_adma_chan *chan,
					u32 byte_count)
{
	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };

	switch (chan->device->id) {
	case DMA0_ID:
	case DMA1_ID:
		hw_desc.dma->byte_count = byte_count;
		break;
	case AAU_ID:
		hw_desc.aau->byte_count = byte_count;
		break;
	default:
		BUG();
	}
}

static inline void
iop_desc_init_interrupt(struct iop_adma_desc_slot *desc,
			struct iop_adma_chan *chan)
{
	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };

	switch (chan->device->id) {
	case DMA0_ID:
	case DMA1_ID:
		iop_desc_init_memcpy(desc, 1);
		hw_desc.dma->byte_count = 0;
		hw_desc.dma->dest_addr = 0;
		hw_desc.dma->src_addr = 0;
		break;
	case AAU_ID:
		iop_desc_init_null_xor(desc, 2, 1);
		hw_desc.aau->byte_count = 0;
		hw_desc.aau->dest_addr = 0;
		hw_desc.aau->src[0] = 0;
		hw_desc.aau->src[1] = 0;
		break;
	default:
		BUG();
	}
}

static inline void
iop_desc_set_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
{
	int slots_per_op = desc->slots_per_op;
	struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
	int i = 0;

	if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
		hw_desc->byte_count = len;
	} else {
		do {
			iter = iop_hw_desc_slot_idx(hw_desc, i);
			iter->byte_count = IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
			len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
			i += slots_per_op;
		} while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT);

		iter = iop_hw_desc_slot_idx(hw_desc, i);
		iter->byte_count = len;
	}
}

static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc,
					struct iop_adma_chan *chan,
					dma_addr_t addr)
{
	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };

	switch (chan->device->id) {
	case DMA0_ID:
	case DMA1_ID:
		hw_desc.dma->dest_addr = addr;
		break;
	case AAU_ID:
		hw_desc.aau->dest_addr = addr;
		break;
	default:
		BUG();
	}
}

static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc,
					dma_addr_t addr)
{
	struct iop3xx_desc_dma *hw_desc = desc->hw_desc;
	hw_desc->src_addr = addr;
}

static inline void
iop_desc_set_zero_sum_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
				dma_addr_t addr)
{

	struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
	int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
	int i;

	for (i = 0; (slot_cnt -= slots_per_op) >= 0;
		i += slots_per_op, addr += IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
		iter = iop_hw_desc_slot_idx(hw_desc, i);
		iop3xx_aau_desc_set_src_addr(iter, src_idx, addr);
	}
}

static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc,
					int src_idx, dma_addr_t addr)
{

	struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
	int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
	int i;

	for (i = 0; (slot_cnt -= slots_per_op) >= 0;
		i += slots_per_op, addr += IOP_ADMA_XOR_MAX_BYTE_COUNT) {
		iter = iop_hw_desc_slot_idx(hw_desc, i);
		iop3xx_aau_desc_set_src_addr(iter, src_idx, addr);
	}
}

static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc,
					u32 next_desc_addr)
{
	/* hw_desc->next_desc is the same location for all channels */
	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };

	iop_paranoia(hw_desc.dma->next_desc);
	hw_desc.dma->next_desc = next_desc_addr;
}

static inline u32 iop_desc_get_next_desc(struct iop_adma_desc_slot *desc)
{
	/* hw_desc->next_desc is the same location for all channels */
	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
	return hw_desc.dma->next_desc;
}

static inline void iop_desc_clear_next_desc(struct iop_adma_desc_slot *desc)
{
	/* hw_desc->next_desc is the same location for all channels */
	union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
	hw_desc.dma->next_desc = 0;
}

static inline void iop_desc_set_block_fill_val(struct iop_adma_desc_slot *desc,
						u32 val)
{
	struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
	hw_desc->src[0] = val;
}

static inline enum sum_check_flags
iop_desc_get_zero_result(struct iop_adma_desc_slot *desc)
{
	struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
	struct iop3xx_aau_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field;

	iop_paranoia(!(desc_ctrl.tx_complete && desc_ctrl.zero_result_en));
	return desc_ctrl.zero_result_err << SUM_CHECK_P;
}

static inline void iop_chan_append(struct iop_adma_chan *chan)
{
	u32 dma_chan_ctrl;

	dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
	dma_chan_ctrl |= 0x2;
	__raw_writel(dma_chan_ctrl, DMA_CCR(chan));
}

static inline u32 iop_chan_get_status(struct iop_adma_chan *chan)
{
	return __raw_readl(DMA_CSR(chan));
}

static inline void iop_chan_disable(struct iop_adma_chan *chan)
{
	u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
	dma_chan_ctrl &= ~1;
	__raw_writel(dma_chan_ctrl, DMA_CCR(chan));
}

static inline void iop_chan_enable(struct iop_adma_chan *chan)
{
	u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));

	dma_chan_ctrl |= 1;
	__raw_writel(dma_chan_ctrl, DMA_CCR(chan));
}

static inline void iop_adma_device_clear_eot_status(struct iop_adma_chan *chan)
{
	u32 status = __raw_readl(DMA_CSR(chan));
	status &= (1 << 9);
	__raw_writel(status, DMA_CSR(chan));
}

static inline void iop_adma_device_clear_eoc_status(struct iop_adma_chan *chan)
{
	u32 status = __raw_readl(DMA_CSR(chan));
	status &= (1 << 8);
	__raw_writel(status, DMA_CSR(chan));
}

static inline void iop_adma_device_clear_err_status(struct iop_adma_chan *chan)
{
	u32 status = __raw_readl(DMA_CSR(chan));

	switch (chan->device->id) {
	case DMA0_ID:
	case DMA1_ID:
		status &= (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1);
		break;
	case AAU_ID:
		status &= (1 << 5);
		break;
	default:
		BUG();
	}

	__raw_writel(status, DMA_CSR(chan));
}

static inline int
iop_is_err_int_parity(unsigned long status, struct iop_adma_chan *chan)
{
	return 0;
}

static inline int
iop_is_err_mcu_abort(unsigned long status, struct iop_adma_chan *chan)
{
	return 0;
}

static inline int
iop_is_err_int_tabort(unsigned long status, struct iop_adma_chan *chan)
{
	return 0;
}

static inline int
iop_is_err_int_mabort(unsigned long status, struct iop_adma_chan *chan)
{
	return test_bit(5, &status);
}

static inline int
iop_is_err_pci_tabort(unsigned long status, struct iop_adma_chan *chan)
{
	switch (chan->device->id) {
	case DMA0_ID:
	case DMA1_ID:
		return test_bit(2, &status);
	default:
		return 0;
	}
}

static inline int
iop_is_err_pci_mabort(unsigned long status, struct iop_adma_chan *chan)
{
	switch (chan->device->id) {
	case DMA0_ID:
	case DMA1_ID:
		return test_bit(3, &status);
	default:
		return 0;
	}
}

static inline int
iop_is_err_split_tx(unsigned long status, struct iop_adma_chan *chan)
{
	switch (chan->device->id) {
	case DMA0_ID:
	case DMA1_ID:
		return test_bit(1, &status);
	default:
		return 0;
	}
}
#endif /* _ADMA_H */
