xref: /openbmc/linux/drivers/dma/dw/regs.h (revision ca7f2851)
1b466a37fSAndy Shevchenko /* SPDX-License-Identifier: GPL-2.0 */
29cade1a4SAndy Shevchenko /*
39cade1a4SAndy Shevchenko  * Driver for the Synopsys DesignWare AHB DMA Controller
49cade1a4SAndy Shevchenko  *
59cade1a4SAndy Shevchenko  * Copyright (C) 2005-2007 Atmel Corporation
69cade1a4SAndy Shevchenko  * Copyright (C) 2010-2011 ST Microelectronics
7a9f4d1b8SAndy Shevchenko  * Copyright (C) 2016 Intel Corporation
89cade1a4SAndy Shevchenko  */
99cade1a4SAndy Shevchenko 
102d248812SAndy Shevchenko #include <linux/bitops.h>
119cade1a4SAndy Shevchenko #include <linux/interrupt.h>
129cade1a4SAndy Shevchenko #include <linux/dmaengine.h>
139cade1a4SAndy Shevchenko 
14a9f4d1b8SAndy Shevchenko #include <linux/io-64-nonatomic-hi-lo.h>
15a9f4d1b8SAndy Shevchenko 
16bd2c6636SEugeniy Paltsev #include "internal.h"
17bd2c6636SEugeniy Paltsev 
189cade1a4SAndy Shevchenko #define DW_DMA_MAX_NR_REQUESTS	16
199cade1a4SAndy Shevchenko 
209cade1a4SAndy Shevchenko /* flow controller */
219cade1a4SAndy Shevchenko enum dw_dma_fc {
229cade1a4SAndy Shevchenko 	DW_DMA_FC_D_M2M,
239cade1a4SAndy Shevchenko 	DW_DMA_FC_D_M2P,
249cade1a4SAndy Shevchenko 	DW_DMA_FC_D_P2M,
259cade1a4SAndy Shevchenko 	DW_DMA_FC_D_P2P,
269cade1a4SAndy Shevchenko 	DW_DMA_FC_P_P2M,
279cade1a4SAndy Shevchenko 	DW_DMA_FC_SP_P2P,
289cade1a4SAndy Shevchenko 	DW_DMA_FC_P_M2P,
299cade1a4SAndy Shevchenko 	DW_DMA_FC_DP_P2P,
309cade1a4SAndy Shevchenko };
319cade1a4SAndy Shevchenko 
329cade1a4SAndy Shevchenko /*
339cade1a4SAndy Shevchenko  * Redefine this macro to handle differences between 32- and 64-bit
349cade1a4SAndy Shevchenko  * addressing, big vs. little endian, etc.
359cade1a4SAndy Shevchenko  */
369cade1a4SAndy Shevchenko #define DW_REG(name)		u32 name; u32 __pad_##name
379cade1a4SAndy Shevchenko 
389cade1a4SAndy Shevchenko /* Hardware register definitions. */
399cade1a4SAndy Shevchenko struct dw_dma_chan_regs {
409cade1a4SAndy Shevchenko 	DW_REG(SAR);		/* Source Address Register */
419cade1a4SAndy Shevchenko 	DW_REG(DAR);		/* Destination Address Register */
429cade1a4SAndy Shevchenko 	DW_REG(LLP);		/* Linked List Pointer */
439cade1a4SAndy Shevchenko 	u32	CTL_LO;		/* Control Register Low */
449cade1a4SAndy Shevchenko 	u32	CTL_HI;		/* Control Register High */
459cade1a4SAndy Shevchenko 	DW_REG(SSTAT);
469cade1a4SAndy Shevchenko 	DW_REG(DSTAT);
479cade1a4SAndy Shevchenko 	DW_REG(SSTATAR);
489cade1a4SAndy Shevchenko 	DW_REG(DSTATAR);
499cade1a4SAndy Shevchenko 	u32	CFG_LO;		/* Configuration Register Low */
509cade1a4SAndy Shevchenko 	u32	CFG_HI;		/* Configuration Register High */
519cade1a4SAndy Shevchenko 	DW_REG(SGR);
529cade1a4SAndy Shevchenko 	DW_REG(DSR);
539cade1a4SAndy Shevchenko };
549cade1a4SAndy Shevchenko 
559cade1a4SAndy Shevchenko struct dw_dma_irq_regs {
569cade1a4SAndy Shevchenko 	DW_REG(XFER);
579cade1a4SAndy Shevchenko 	DW_REG(BLOCK);
589cade1a4SAndy Shevchenko 	DW_REG(SRC_TRAN);
599cade1a4SAndy Shevchenko 	DW_REG(DST_TRAN);
609cade1a4SAndy Shevchenko 	DW_REG(ERROR);
619cade1a4SAndy Shevchenko };
629cade1a4SAndy Shevchenko 
639cade1a4SAndy Shevchenko struct dw_dma_regs {
649cade1a4SAndy Shevchenko 	/* per-channel registers */
659cade1a4SAndy Shevchenko 	struct dw_dma_chan_regs	CHAN[DW_DMA_MAX_NR_CHANNELS];
669cade1a4SAndy Shevchenko 
679cade1a4SAndy Shevchenko 	/* irq handling */
689cade1a4SAndy Shevchenko 	struct dw_dma_irq_regs	RAW;		/* r */
699cade1a4SAndy Shevchenko 	struct dw_dma_irq_regs	STATUS;		/* r (raw & mask) */
709cade1a4SAndy Shevchenko 	struct dw_dma_irq_regs	MASK;		/* rw (set = irq enabled) */
719cade1a4SAndy Shevchenko 	struct dw_dma_irq_regs	CLEAR;		/* w (ack, affects "raw") */
729cade1a4SAndy Shevchenko 
739cade1a4SAndy Shevchenko 	DW_REG(STATUS_INT);			/* r */
749cade1a4SAndy Shevchenko 
759cade1a4SAndy Shevchenko 	/* software handshaking */
769cade1a4SAndy Shevchenko 	DW_REG(REQ_SRC);
779cade1a4SAndy Shevchenko 	DW_REG(REQ_DST);
789cade1a4SAndy Shevchenko 	DW_REG(SGL_REQ_SRC);
799cade1a4SAndy Shevchenko 	DW_REG(SGL_REQ_DST);
809cade1a4SAndy Shevchenko 	DW_REG(LAST_SRC);
819cade1a4SAndy Shevchenko 	DW_REG(LAST_DST);
829cade1a4SAndy Shevchenko 
839cade1a4SAndy Shevchenko 	/* miscellaneous */
849cade1a4SAndy Shevchenko 	DW_REG(CFG);
859cade1a4SAndy Shevchenko 	DW_REG(CH_EN);
869cade1a4SAndy Shevchenko 	DW_REG(ID);
879cade1a4SAndy Shevchenko 	DW_REG(TEST);
889cade1a4SAndy Shevchenko 
89a9f4d1b8SAndy Shevchenko 	/* iDMA 32-bit support */
90a9f4d1b8SAndy Shevchenko 	DW_REG(CLASS_PRIORITY0);
91a9f4d1b8SAndy Shevchenko 	DW_REG(CLASS_PRIORITY1);
929cade1a4SAndy Shevchenko 
939cade1a4SAndy Shevchenko 	/* optional encoded params, 0x3c8..0x3f7 */
949cade1a4SAndy Shevchenko 	u32	__reserved;
959cade1a4SAndy Shevchenko 
969cade1a4SAndy Shevchenko 	/* per-channel configuration registers */
979cade1a4SAndy Shevchenko 	u32	DWC_PARAMS[DW_DMA_MAX_NR_CHANNELS];
989cade1a4SAndy Shevchenko 	u32	MULTI_BLK_TYPE;
999cade1a4SAndy Shevchenko 	u32	MAX_BLK_SIZE;
1009cade1a4SAndy Shevchenko 
1019cade1a4SAndy Shevchenko 	/* top-level parameters */
1029cade1a4SAndy Shevchenko 	u32	DW_PARAMS;
103a9f4d1b8SAndy Shevchenko 
104a9f4d1b8SAndy Shevchenko 	/* component ID */
105a9f4d1b8SAndy Shevchenko 	u32	COMP_TYPE;
106a9f4d1b8SAndy Shevchenko 	u32	COMP_VERSION;
107a9f4d1b8SAndy Shevchenko 
108a9f4d1b8SAndy Shevchenko 	/* iDMA 32-bit support */
109a9f4d1b8SAndy Shevchenko 	DW_REG(FIFO_PARTITION0);
110a9f4d1b8SAndy Shevchenko 	DW_REG(FIFO_PARTITION1);
111a9f4d1b8SAndy Shevchenko 
112a9f4d1b8SAndy Shevchenko 	DW_REG(SAI_ERR);
113a9f4d1b8SAndy Shevchenko 	DW_REG(GLOBAL_CFG);
1149cade1a4SAndy Shevchenko };
1159cade1a4SAndy Shevchenko 
1169cade1a4SAndy Shevchenko /* Bitfields in DW_PARAMS */
1179cade1a4SAndy Shevchenko #define DW_PARAMS_NR_CHAN	8		/* number of channels */
1189cade1a4SAndy Shevchenko #define DW_PARAMS_NR_MASTER	11		/* number of AHB masters */
1199cade1a4SAndy Shevchenko #define DW_PARAMS_DATA_WIDTH(n)	(15 + 2 * (n))
1209cade1a4SAndy Shevchenko #define DW_PARAMS_DATA_WIDTH1	15		/* master 1 data width */
1219cade1a4SAndy Shevchenko #define DW_PARAMS_DATA_WIDTH2	17		/* master 2 data width */
1229cade1a4SAndy Shevchenko #define DW_PARAMS_DATA_WIDTH3	19		/* master 3 data width */
1239cade1a4SAndy Shevchenko #define DW_PARAMS_DATA_WIDTH4	21		/* master 4 data width */
1249cade1a4SAndy Shevchenko #define DW_PARAMS_EN		28		/* encoded parameters */
1259cade1a4SAndy Shevchenko 
1269cade1a4SAndy Shevchenko /* Bitfields in DWC_PARAMS */
1279cade1a4SAndy Shevchenko #define DWC_PARAMS_MBLK_EN	11		/* multi block transfer */
128ef3e515aSSerge Semin #define DWC_PARAMS_HC_LLP	13		/* set LLP register to zero */
129ca7f2851SSerge Semin #define DWC_PARAMS_MSIZE	16		/* max group transaction size */
1309cade1a4SAndy Shevchenko 
13146e8c83cSAndy Shevchenko /* bursts size */
13246e8c83cSAndy Shevchenko enum dw_dma_msize {
13346e8c83cSAndy Shevchenko 	DW_DMA_MSIZE_1,
13446e8c83cSAndy Shevchenko 	DW_DMA_MSIZE_4,
13546e8c83cSAndy Shevchenko 	DW_DMA_MSIZE_8,
13646e8c83cSAndy Shevchenko 	DW_DMA_MSIZE_16,
13746e8c83cSAndy Shevchenko 	DW_DMA_MSIZE_32,
13846e8c83cSAndy Shevchenko 	DW_DMA_MSIZE_64,
13946e8c83cSAndy Shevchenko 	DW_DMA_MSIZE_128,
14046e8c83cSAndy Shevchenko 	DW_DMA_MSIZE_256,
14146e8c83cSAndy Shevchenko };
14246e8c83cSAndy Shevchenko 
1432a0fae02SMans Rullgard /* Bitfields in LLP */
1442a0fae02SMans Rullgard #define DWC_LLP_LMS(x)		((x) & 3)	/* list master select */
1452a0fae02SMans Rullgard #define DWC_LLP_LOC(x)		((x) & ~3)	/* next lli */
1462a0fae02SMans Rullgard 
1479cade1a4SAndy Shevchenko /* Bitfields in CTL_LO */
1489cade1a4SAndy Shevchenko #define DWC_CTLL_INT_EN		(1 << 0)	/* irqs enabled? */
1499cade1a4SAndy Shevchenko #define DWC_CTLL_DST_WIDTH(n)	((n)<<1)	/* bytes per element */
1509cade1a4SAndy Shevchenko #define DWC_CTLL_SRC_WIDTH(n)	((n)<<4)
1519cade1a4SAndy Shevchenko #define DWC_CTLL_DST_INC	(0<<7)		/* DAR update/not */
1529cade1a4SAndy Shevchenko #define DWC_CTLL_DST_DEC	(1<<7)
1539cade1a4SAndy Shevchenko #define DWC_CTLL_DST_FIX	(2<<7)
154c9784a46SJie Yang #define DWC_CTLL_SRC_INC	(0<<9)		/* SAR update/not */
1559cade1a4SAndy Shevchenko #define DWC_CTLL_SRC_DEC	(1<<9)
1569cade1a4SAndy Shevchenko #define DWC_CTLL_SRC_FIX	(2<<9)
1579cade1a4SAndy Shevchenko #define DWC_CTLL_DST_MSIZE(n)	((n)<<11)	/* burst, #elements */
1589cade1a4SAndy Shevchenko #define DWC_CTLL_SRC_MSIZE(n)	((n)<<14)
1599cade1a4SAndy Shevchenko #define DWC_CTLL_S_GATH_EN	(1 << 17)	/* src gather, !FIX */
1609cade1a4SAndy Shevchenko #define DWC_CTLL_D_SCAT_EN	(1 << 18)	/* dst scatter, !FIX */
1619cade1a4SAndy Shevchenko #define DWC_CTLL_FC(n)		((n) << 20)
1629cade1a4SAndy Shevchenko #define DWC_CTLL_FC_M2M		(0 << 20)	/* mem-to-mem */
1639cade1a4SAndy Shevchenko #define DWC_CTLL_FC_M2P		(1 << 20)	/* mem-to-periph */
1649cade1a4SAndy Shevchenko #define DWC_CTLL_FC_P2M		(2 << 20)	/* periph-to-mem */
1659cade1a4SAndy Shevchenko #define DWC_CTLL_FC_P2P		(3 << 20)	/* periph-to-periph */
1669cade1a4SAndy Shevchenko /* plus 4 transfer types for peripheral-as-flow-controller */
1679cade1a4SAndy Shevchenko #define DWC_CTLL_DMS(n)		((n)<<23)	/* dst master select */
1689cade1a4SAndy Shevchenko #define DWC_CTLL_SMS(n)		((n)<<25)	/* src master select */
1699cade1a4SAndy Shevchenko #define DWC_CTLL_LLP_D_EN	(1 << 27)	/* dest block chain */
1709cade1a4SAndy Shevchenko #define DWC_CTLL_LLP_S_EN	(1 << 28)	/* src block chain */
1719cade1a4SAndy Shevchenko 
1729cade1a4SAndy Shevchenko /* Bitfields in CTL_HI */
1732d248812SAndy Shevchenko #define DWC_CTLH_BLOCK_TS_MASK	GENMASK(11, 0)
1742d248812SAndy Shevchenko #define DWC_CTLH_BLOCK_TS(x)	((x) & DWC_CTLH_BLOCK_TS_MASK)
1752d248812SAndy Shevchenko #define DWC_CTLH_DONE		(1 << 12)
1769cade1a4SAndy Shevchenko 
17746e8c83cSAndy Shevchenko /* Bitfields in CFG_LO */
1789cade1a4SAndy Shevchenko #define DWC_CFGL_CH_PRIOR_MASK	(0x7 << 5)	/* priority mask */
1799cade1a4SAndy Shevchenko #define DWC_CFGL_CH_PRIOR(x)	((x) << 5)	/* priority */
1809cade1a4SAndy Shevchenko #define DWC_CFGL_CH_SUSP	(1 << 8)	/* pause xfer */
1819cade1a4SAndy Shevchenko #define DWC_CFGL_FIFO_EMPTY	(1 << 9)	/* pause xfer */
1829cade1a4SAndy Shevchenko #define DWC_CFGL_HS_DST		(1 << 10)	/* handshake w/dst */
1839cade1a4SAndy Shevchenko #define DWC_CFGL_HS_SRC		(1 << 11)	/* handshake w/src */
18446e8c83cSAndy Shevchenko #define DWC_CFGL_LOCK_CH_XFER	(0 << 12)	/* scope of LOCK_CH */
18546e8c83cSAndy Shevchenko #define DWC_CFGL_LOCK_CH_BLOCK	(1 << 12)
18646e8c83cSAndy Shevchenko #define DWC_CFGL_LOCK_CH_XACT	(2 << 12)
18746e8c83cSAndy Shevchenko #define DWC_CFGL_LOCK_BUS_XFER	(0 << 14)	/* scope of LOCK_BUS */
18846e8c83cSAndy Shevchenko #define DWC_CFGL_LOCK_BUS_BLOCK	(1 << 14)
18946e8c83cSAndy Shevchenko #define DWC_CFGL_LOCK_BUS_XACT	(2 << 14)
19046e8c83cSAndy Shevchenko #define DWC_CFGL_LOCK_CH	(1 << 15)	/* channel lockout */
19146e8c83cSAndy Shevchenko #define DWC_CFGL_LOCK_BUS	(1 << 16)	/* busmaster lockout */
19246e8c83cSAndy Shevchenko #define DWC_CFGL_HS_DST_POL	(1 << 18)	/* dst handshake active low */
19346e8c83cSAndy Shevchenko #define DWC_CFGL_HS_SRC_POL	(1 << 19)	/* src handshake active low */
1949cade1a4SAndy Shevchenko #define DWC_CFGL_MAX_BURST(x)	((x) << 20)
1959cade1a4SAndy Shevchenko #define DWC_CFGL_RELOAD_SAR	(1 << 30)
1969cade1a4SAndy Shevchenko #define DWC_CFGL_RELOAD_DAR	(1 << 31)
1979cade1a4SAndy Shevchenko 
19846e8c83cSAndy Shevchenko /* Bitfields in CFG_HI */
19946e8c83cSAndy Shevchenko #define DWC_CFGH_FCMODE		(1 << 0)
20046e8c83cSAndy Shevchenko #define DWC_CFGH_FIFO_MODE	(1 << 1)
20146e8c83cSAndy Shevchenko #define DWC_CFGH_PROTCTL(x)	((x) << 2)
2027b0c03ecSChristian Lamparter #define DWC_CFGH_PROTCTL_DATA	(0 << 2)	/* data access - always set */
2037b0c03ecSChristian Lamparter #define DWC_CFGH_PROTCTL_PRIV	(1 << 2)	/* privileged -> AHB HPROT[1] */
2047b0c03ecSChristian Lamparter #define DWC_CFGH_PROTCTL_BUFFER	(2 << 2)	/* bufferable -> AHB HPROT[2] */
2057b0c03ecSChristian Lamparter #define DWC_CFGH_PROTCTL_CACHE	(4 << 2)	/* cacheable  -> AHB HPROT[3] */
2069cade1a4SAndy Shevchenko #define DWC_CFGH_DS_UPD_EN	(1 << 5)
2079cade1a4SAndy Shevchenko #define DWC_CFGH_SS_UPD_EN	(1 << 6)
20846e8c83cSAndy Shevchenko #define DWC_CFGH_SRC_PER(x)	((x) << 7)
20946e8c83cSAndy Shevchenko #define DWC_CFGH_DST_PER(x)	((x) << 11)
2109cade1a4SAndy Shevchenko 
2119cade1a4SAndy Shevchenko /* Bitfields in SGR */
2129cade1a4SAndy Shevchenko #define DWC_SGR_SGI(x)		((x) << 0)
2139cade1a4SAndy Shevchenko #define DWC_SGR_SGC(x)		((x) << 20)
2149cade1a4SAndy Shevchenko 
2159cade1a4SAndy Shevchenko /* Bitfields in DSR */
2169cade1a4SAndy Shevchenko #define DWC_DSR_DSI(x)		((x) << 0)
2179cade1a4SAndy Shevchenko #define DWC_DSR_DSC(x)		((x) << 20)
2189cade1a4SAndy Shevchenko 
2199cade1a4SAndy Shevchenko /* Bitfields in CFG */
2209cade1a4SAndy Shevchenko #define DW_CFG_DMA_EN		(1 << 0)
2219cade1a4SAndy Shevchenko 
222a9f4d1b8SAndy Shevchenko /* iDMA 32-bit support */
223a9f4d1b8SAndy Shevchenko 
224934891b0SAndy Shevchenko /* bursts size */
225934891b0SAndy Shevchenko enum idma32_msize {
226934891b0SAndy Shevchenko 	IDMA32_MSIZE_1,
227934891b0SAndy Shevchenko 	IDMA32_MSIZE_2,
228934891b0SAndy Shevchenko 	IDMA32_MSIZE_4,
229934891b0SAndy Shevchenko 	IDMA32_MSIZE_8,
230934891b0SAndy Shevchenko 	IDMA32_MSIZE_16,
231934891b0SAndy Shevchenko 	IDMA32_MSIZE_32,
232934891b0SAndy Shevchenko };
233934891b0SAndy Shevchenko 
234a9f4d1b8SAndy Shevchenko /* Bitfields in CTL_HI */
235a9f4d1b8SAndy Shevchenko #define IDMA32C_CTLH_BLOCK_TS_MASK	GENMASK(16, 0)
236a9f4d1b8SAndy Shevchenko #define IDMA32C_CTLH_BLOCK_TS(x)	((x) & IDMA32C_CTLH_BLOCK_TS_MASK)
237a9f4d1b8SAndy Shevchenko #define IDMA32C_CTLH_DONE		(1 << 17)
238a9f4d1b8SAndy Shevchenko 
239a9f4d1b8SAndy Shevchenko /* Bitfields in CFG_LO */
240a9f4d1b8SAndy Shevchenko #define IDMA32C_CFGL_DST_BURST_ALIGN	(1 << 0)	/* dst burst align */
241a9f4d1b8SAndy Shevchenko #define IDMA32C_CFGL_SRC_BURST_ALIGN	(1 << 1)	/* src burst align */
242a9f4d1b8SAndy Shevchenko #define IDMA32C_CFGL_CH_DRAIN		(1 << 10)	/* drain FIFO */
243a9f4d1b8SAndy Shevchenko #define IDMA32C_CFGL_DST_OPT_BL		(1 << 20)	/* optimize dst burst length */
244a9f4d1b8SAndy Shevchenko #define IDMA32C_CFGL_SRC_OPT_BL		(1 << 21)	/* optimize src burst length */
245a9f4d1b8SAndy Shevchenko 
246a9f4d1b8SAndy Shevchenko /* Bitfields in CFG_HI */
247a9f4d1b8SAndy Shevchenko #define IDMA32C_CFGH_SRC_PER(x)		((x) << 0)
248a9f4d1b8SAndy Shevchenko #define IDMA32C_CFGH_DST_PER(x)		((x) << 4)
249a9f4d1b8SAndy Shevchenko #define IDMA32C_CFGH_RD_ISSUE_THD(x)	((x) << 8)
250a9f4d1b8SAndy Shevchenko #define IDMA32C_CFGH_RW_ISSUE_THD(x)	((x) << 18)
251a9f4d1b8SAndy Shevchenko #define IDMA32C_CFGH_SRC_PER_EXT(x)	((x) << 28)	/* src peripheral extension */
252a9f4d1b8SAndy Shevchenko #define IDMA32C_CFGH_DST_PER_EXT(x)	((x) << 30)	/* dst peripheral extension */
253a9f4d1b8SAndy Shevchenko 
254a9f4d1b8SAndy Shevchenko /* Bitfields in FIFO_PARTITION */
255a9f4d1b8SAndy Shevchenko #define IDMA32C_FP_PSIZE_CH0(x)		((x) << 0)
256a9f4d1b8SAndy Shevchenko #define IDMA32C_FP_PSIZE_CH1(x)		((x) << 13)
257a9f4d1b8SAndy Shevchenko #define IDMA32C_FP_UPDATE		(1 << 26)
258a9f4d1b8SAndy Shevchenko 
2599cade1a4SAndy Shevchenko enum dw_dmac_flags {
2609cade1a4SAndy Shevchenko 	DW_DMA_IS_CYCLIC = 0,
2619cade1a4SAndy Shevchenko 	DW_DMA_IS_SOFT_LLP = 1,
2625e09f98eSAndy Shevchenko 	DW_DMA_IS_PAUSED = 2,
263423f9cbfSAndy Shevchenko 	DW_DMA_IS_INITIALIZED = 3,
2649cade1a4SAndy Shevchenko };
2659cade1a4SAndy Shevchenko 
2669cade1a4SAndy Shevchenko struct dw_dma_chan {
2679cade1a4SAndy Shevchenko 	struct dma_chan			chan;
2689cade1a4SAndy Shevchenko 	void __iomem			*ch_regs;
2699cade1a4SAndy Shevchenko 	u8				mask;
2709cade1a4SAndy Shevchenko 	u8				priority;
2719cade1a4SAndy Shevchenko 	enum dma_transfer_direction	direction;
2729cade1a4SAndy Shevchenko 
2739cade1a4SAndy Shevchenko 	/* software emulation of the LLP transfers */
2749cade1a4SAndy Shevchenko 	struct list_head	*tx_node_active;
2759cade1a4SAndy Shevchenko 
2769cade1a4SAndy Shevchenko 	spinlock_t		lock;
2779cade1a4SAndy Shevchenko 
2789cade1a4SAndy Shevchenko 	/* these other elements are all protected by lock */
2799cade1a4SAndy Shevchenko 	unsigned long		flags;
2809cade1a4SAndy Shevchenko 	struct list_head	active_list;
2819cade1a4SAndy Shevchenko 	struct list_head	queue;
2829cade1a4SAndy Shevchenko 
2839cade1a4SAndy Shevchenko 	unsigned int		descs_allocated;
2849cade1a4SAndy Shevchenko 
2859cade1a4SAndy Shevchenko 	/* hardware configuration */
2869cade1a4SAndy Shevchenko 	unsigned int		block_size;
2879cade1a4SAndy Shevchenko 	bool			nollp;
288ca7f2851SSerge Semin 	u32			max_burst;
2899cade1a4SAndy Shevchenko 
2909cade1a4SAndy Shevchenko 	/* custom slave configuration */
2919217a5bfSAndy Shevchenko 	struct dw_dma_slave	dws;
2929cade1a4SAndy Shevchenko 
293295d3e10SVinod Koul 	/* configuration passed via .device_config */
2949cade1a4SAndy Shevchenko 	struct dma_slave_config dma_sconfig;
2959cade1a4SAndy Shevchenko };
2969cade1a4SAndy Shevchenko 
2979cade1a4SAndy Shevchenko static inline struct dw_dma_chan_regs __iomem *
__dwc_regs(struct dw_dma_chan * dwc)2989cade1a4SAndy Shevchenko __dwc_regs(struct dw_dma_chan *dwc)
2999cade1a4SAndy Shevchenko {
3009cade1a4SAndy Shevchenko 	return dwc->ch_regs;
3019cade1a4SAndy Shevchenko }
3029cade1a4SAndy Shevchenko 
3039cade1a4SAndy Shevchenko #define channel_readl(dwc, name) \
30414bebd01SAndy Shevchenko 	readl(&(__dwc_regs(dwc)->name))
3059cade1a4SAndy Shevchenko #define channel_writel(dwc, name, val) \
30614bebd01SAndy Shevchenko 	writel((val), &(__dwc_regs(dwc)->name))
3079cade1a4SAndy Shevchenko 
to_dw_dma_chan(struct dma_chan * chan)3089cade1a4SAndy Shevchenko static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan)
3099cade1a4SAndy Shevchenko {
3109cade1a4SAndy Shevchenko 	return container_of(chan, struct dw_dma_chan, chan);
3119cade1a4SAndy Shevchenko }
3129cade1a4SAndy Shevchenko 
3139cade1a4SAndy Shevchenko struct dw_dma {
3149cade1a4SAndy Shevchenko 	struct dma_device	dma;
31508d62f58SAndy Shevchenko 	char			name[20];
3169cade1a4SAndy Shevchenko 	void __iomem		*regs;
3179cade1a4SAndy Shevchenko 	struct dma_pool		*desc_pool;
3189cade1a4SAndy Shevchenko 	struct tasklet_struct	tasklet;
3199cade1a4SAndy Shevchenko 
320000871ceSAndy Shevchenko 	/* channels */
321000871ceSAndy Shevchenko 	struct dw_dma_chan	*chan;
3229cade1a4SAndy Shevchenko 	u8			all_chan_mask;
32399d9bf4eSAndy Shevchenko 	u8			in_use;
3249cade1a4SAndy Shevchenko 
32569da8be9SAndy Shevchenko 	/* Channel operations */
32669da8be9SAndy Shevchenko 	void	(*initialize_chan)(struct dw_dma_chan *dwc);
32769da8be9SAndy Shevchenko 	void	(*suspend_chan)(struct dw_dma_chan *dwc, bool drain);
32891f0ff88SAndy Shevchenko 	void	(*resume_chan)(struct dw_dma_chan *dwc, bool drain);
329934891b0SAndy Shevchenko 	u32	(*prepare_ctllo)(struct dw_dma_chan *dwc);
33069da8be9SAndy Shevchenko 	void	(*encode_maxburst)(struct dw_dma_chan *dwc, u32 *maxburst);
33169da8be9SAndy Shevchenko 	u32	(*bytes2block)(struct dw_dma_chan *dwc, size_t bytes,
33269da8be9SAndy Shevchenko 			       unsigned int width, size_t *len);
33369da8be9SAndy Shevchenko 	size_t	(*block2bytes)(struct dw_dma_chan *dwc, u32 block, u32 width);
33469da8be9SAndy Shevchenko 
33569da8be9SAndy Shevchenko 	/* Device operations */
33669da8be9SAndy Shevchenko 	void (*set_device_name)(struct dw_dma *dw, int id);
33769da8be9SAndy Shevchenko 	void (*disable)(struct dw_dma *dw);
33869da8be9SAndy Shevchenko 	void (*enable)(struct dw_dma *dw);
33969da8be9SAndy Shevchenko 
340161c3d04SAndy Shevchenko 	/* platform data */
341161c3d04SAndy Shevchenko 	struct dw_dma_platform_data	*pdata;
3429cade1a4SAndy Shevchenko };
3439cade1a4SAndy Shevchenko 
__dw_regs(struct dw_dma * dw)3449cade1a4SAndy Shevchenko static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw)
3459cade1a4SAndy Shevchenko {
3469cade1a4SAndy Shevchenko 	return dw->regs;
3479cade1a4SAndy Shevchenko }
3489cade1a4SAndy Shevchenko 
3499cade1a4SAndy Shevchenko #define dma_readl(dw, name) \
35014bebd01SAndy Shevchenko 	readl(&(__dw_regs(dw)->name))
3519cade1a4SAndy Shevchenko #define dma_writel(dw, name, val) \
35214bebd01SAndy Shevchenko 	writel((val), &(__dw_regs(dw)->name))
3539cade1a4SAndy Shevchenko 
354a9f4d1b8SAndy Shevchenko #define idma32_readq(dw, name)				\
355a9f4d1b8SAndy Shevchenko 	hi_lo_readq(&(__dw_regs(dw)->name))
356a9f4d1b8SAndy Shevchenko #define idma32_writeq(dw, name, val)			\
357a9f4d1b8SAndy Shevchenko 	hi_lo_writeq((val), &(__dw_regs(dw)->name))
358a9f4d1b8SAndy Shevchenko 
3599cade1a4SAndy Shevchenko #define channel_set_bit(dw, reg, mask) \
3609cade1a4SAndy Shevchenko 	dma_writel(dw, reg, ((mask) << 8) | (mask))
3619cade1a4SAndy Shevchenko #define channel_clear_bit(dw, reg, mask) \
3629cade1a4SAndy Shevchenko 	dma_writel(dw, reg, ((mask) << 8) | 0)
3639cade1a4SAndy Shevchenko 
to_dw_dma(struct dma_device * ddev)3649cade1a4SAndy Shevchenko static inline struct dw_dma *to_dw_dma(struct dma_device *ddev)
3659cade1a4SAndy Shevchenko {
3669cade1a4SAndy Shevchenko 	return container_of(ddev, struct dw_dma, dma);
3679cade1a4SAndy Shevchenko }
3689cade1a4SAndy Shevchenko 
3699cade1a4SAndy Shevchenko /* LLI == Linked List Item; a.k.a. DMA block descriptor */
3709cade1a4SAndy Shevchenko struct dw_lli {
3719cade1a4SAndy Shevchenko 	/* values that are not changed by hardware */
37214bebd01SAndy Shevchenko 	__le32		sar;
37314bebd01SAndy Shevchenko 	__le32		dar;
37414bebd01SAndy Shevchenko 	__le32		llp;		/* chain to next lli */
37514bebd01SAndy Shevchenko 	__le32		ctllo;
3769cade1a4SAndy Shevchenko 	/* values that may get written back: */
37714bebd01SAndy Shevchenko 	__le32		ctlhi;
3789cade1a4SAndy Shevchenko 	/* sstat and dstat can snapshot peripheral register state.
3799cade1a4SAndy Shevchenko 	 * silicon config may discard either or both...
3809cade1a4SAndy Shevchenko 	 */
38114bebd01SAndy Shevchenko 	__le32		sstat;
38214bebd01SAndy Shevchenko 	__le32		dstat;
3839cade1a4SAndy Shevchenko };
3849cade1a4SAndy Shevchenko 
3859cade1a4SAndy Shevchenko struct dw_desc {
3869cade1a4SAndy Shevchenko 	/* FIRST values the hardware uses */
3879cade1a4SAndy Shevchenko 	struct dw_lli			lli;
3889cade1a4SAndy Shevchenko 
389df1f3a23SMans Rullgard #define lli_set(d, reg, v)		((d)->lli.reg |= cpu_to_le32(v))
390df1f3a23SMans Rullgard #define lli_clear(d, reg, v)		((d)->lli.reg &= ~cpu_to_le32(v))
391df1f3a23SMans Rullgard #define lli_read(d, reg)		le32_to_cpu((d)->lli.reg)
392df1f3a23SMans Rullgard #define lli_write(d, reg, v)		((d)->lli.reg = cpu_to_le32(v))
393df1f3a23SMans Rullgard 
3949cade1a4SAndy Shevchenko 	/* THEN values for driver housekeeping */
3959cade1a4SAndy Shevchenko 	struct list_head		desc_node;
3969cade1a4SAndy Shevchenko 	struct list_head		tx_list;
3979cade1a4SAndy Shevchenko 	struct dma_async_tx_descriptor	txd;
3989cade1a4SAndy Shevchenko 	size_t				len;
3999cade1a4SAndy Shevchenko 	size_t				total_len;
400b68fd097SAndy Shevchenko 	u32				residue;
4019cade1a4SAndy Shevchenko };
4029cade1a4SAndy Shevchenko 
4039cade1a4SAndy Shevchenko #define to_dw_desc(h)	list_entry(h, struct dw_desc, desc_node)
4049cade1a4SAndy Shevchenko 
4059cade1a4SAndy Shevchenko static inline struct dw_desc *
txd_to_dw_desc(struct dma_async_tx_descriptor * txd)4069cade1a4SAndy Shevchenko txd_to_dw_desc(struct dma_async_tx_descriptor *txd)
4079cade1a4SAndy Shevchenko {
4089cade1a4SAndy Shevchenko 	return container_of(txd, struct dw_desc, txd);
4099cade1a4SAndy Shevchenko }
410