cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

iop-adma.h (21528B)


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