13bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen/*
23bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen * Driver for the Synopsys DesignWare AHB DMA Controller
33bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen *
43bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen * Copyright (C) 2005-2007 Atmel Corporation
5aecb7b64dd9e2512c7a4c7e61dd781415d3dac5aViresh Kumar * Copyright (C) 2010-2011 ST Microelectronics
63bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen *
73bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen * This program is free software; you can redistribute it and/or modify
83bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen * it under the terms of the GNU General Public License version 2 as
93bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen * published by the Free Software Foundation.
103bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen */
113bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
123bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#include <linux/dw_dmac.h>
133bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
143bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DW_DMA_MAX_NR_CHANNELS	8
153bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
16a1c46016794fdd83b7993303915ec7f4a06682b7Viresh Kumar/* flow controller */
17a1c46016794fdd83b7993303915ec7f4a06682b7Viresh Kumarenum dw_dma_fc {
18a1c46016794fdd83b7993303915ec7f4a06682b7Viresh Kumar	DW_DMA_FC_D_M2M,
19a1c46016794fdd83b7993303915ec7f4a06682b7Viresh Kumar	DW_DMA_FC_D_M2P,
20a1c46016794fdd83b7993303915ec7f4a06682b7Viresh Kumar	DW_DMA_FC_D_P2M,
21a1c46016794fdd83b7993303915ec7f4a06682b7Viresh Kumar	DW_DMA_FC_D_P2P,
22a1c46016794fdd83b7993303915ec7f4a06682b7Viresh Kumar	DW_DMA_FC_P_P2M,
23a1c46016794fdd83b7993303915ec7f4a06682b7Viresh Kumar	DW_DMA_FC_SP_P2P,
24a1c46016794fdd83b7993303915ec7f4a06682b7Viresh Kumar	DW_DMA_FC_P_M2P,
25a1c46016794fdd83b7993303915ec7f4a06682b7Viresh Kumar	DW_DMA_FC_DP_P2P,
26a1c46016794fdd83b7993303915ec7f4a06682b7Viresh Kumar};
27a1c46016794fdd83b7993303915ec7f4a06682b7Viresh Kumar
283bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen/*
293bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen * Redefine this macro to handle differences between 32- and 64-bit
303bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen * addressing, big vs. little endian, etc.
313bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen */
323bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DW_REG(name)		u32 name; u32 __pad_##name
333bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
343bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen/* Hardware register definitions. */
353bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoenstruct dw_dma_chan_regs {
363bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(SAR);		/* Source Address Register */
373bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(DAR);		/* Destination Address Register */
383bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(LLP);		/* Linked List Pointer */
393bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	u32	CTL_LO;		/* Control Register Low */
403bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	u32	CTL_HI;		/* Control Register High */
413bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(SSTAT);
423bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(DSTAT);
433bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(SSTATAR);
443bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(DSTATAR);
453bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	u32	CFG_LO;		/* Configuration Register Low */
463bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	u32	CFG_HI;		/* Configuration Register High */
473bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(SGR);
483bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(DSR);
493bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen};
503bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
513bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoenstruct dw_dma_irq_regs {
523bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(XFER);
533bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(BLOCK);
543bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(SRC_TRAN);
553bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(DST_TRAN);
563bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(ERROR);
573bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen};
583bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
593bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoenstruct dw_dma_regs {
603bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	/* per-channel registers */
613bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct dw_dma_chan_regs	CHAN[DW_DMA_MAX_NR_CHANNELS];
623bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
633bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	/* irq handling */
643bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct dw_dma_irq_regs	RAW;		/* r */
653bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct dw_dma_irq_regs	STATUS;		/* r (raw & mask) */
663bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct dw_dma_irq_regs	MASK;		/* rw (set = irq enabled) */
673bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct dw_dma_irq_regs	CLEAR;		/* w (ack, affects "raw") */
683bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
693bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(STATUS_INT);			/* r */
703bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
713bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	/* software handshaking */
723bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(REQ_SRC);
733bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(REQ_DST);
743bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(SGL_REQ_SRC);
753bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(SGL_REQ_DST);
763bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(LAST_SRC);
773bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(LAST_DST);
783bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
793bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	/* miscellaneous */
803bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(CFG);
813bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(CH_EN);
823bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(ID);
833bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	DW_REG(TEST);
843bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
853bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	/* optional encoded params, 0x3c8..0x3 */
863bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen};
873bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
883bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen/* Bitfields in CTL_LO */
893bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_INT_EN		(1 << 0)	/* irqs enabled? */
903bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_DST_WIDTH(n)	((n)<<1)	/* bytes per element */
913bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_SRC_WIDTH(n)	((n)<<4)
923bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_DST_INC	(0<<7)		/* DAR update/not */
933bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_DST_DEC	(1<<7)
943bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_DST_FIX	(2<<7)
953bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_SRC_INC	(0<<7)		/* SAR update/not */
963bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_SRC_DEC	(1<<9)
973bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_SRC_FIX	(2<<9)
983bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_DST_MSIZE(n)	((n)<<11)	/* burst, #elements */
993bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_SRC_MSIZE(n)	((n)<<14)
1003bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_S_GATH_EN	(1 << 17)	/* src gather, !FIX */
1013bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_D_SCAT_EN	(1 << 18)	/* dst scatter, !FIX */
102ee66509d7f354eecb45ac99f21ea6aa8650dea7eViresh KUMAR#define DWC_CTLL_FC(n)		((n) << 20)
1033bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_FC_M2M		(0 << 20)	/* mem-to-mem */
1043bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_FC_M2P		(1 << 20)	/* mem-to-periph */
1053bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_FC_P2M		(2 << 20)	/* periph-to-mem */
1063bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_FC_P2P		(3 << 20)	/* periph-to-periph */
1073bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen/* plus 4 transfer types for peripheral-as-flow-controller */
1083bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_DMS(n)		((n)<<23)	/* dst master select */
1093bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_SMS(n)		((n)<<25)	/* src master select */
1103bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_LLP_D_EN	(1 << 27)	/* dest block chain */
1113bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLL_LLP_S_EN	(1 << 28)	/* src block chain */
1123bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1133bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen/* Bitfields in CTL_HI */
1143bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLH_DONE		0x00001000
1153bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CTLH_BLOCK_TS_MASK	0x00000fff
1163bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1173bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen/* Bitfields in CFG_LO. Platform-configurable bits are in <linux/dw_dmac.h> */
11893317e8e35b77633d589fe0e132291195757d785Viresh Kumar#define DWC_CFGL_CH_PRIOR_MASK	(0x7 << 5)	/* priority mask */
11993317e8e35b77633d589fe0e132291195757d785Viresh Kumar#define DWC_CFGL_CH_PRIOR(x)	((x) << 5)	/* priority */
1203bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CFGL_CH_SUSP	(1 << 8)	/* pause xfer */
1213bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CFGL_FIFO_EMPTY	(1 << 9)	/* pause xfer */
1223bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CFGL_HS_DST		(1 << 10)	/* handshake w/dst */
1233bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CFGL_HS_SRC		(1 << 11)	/* handshake w/src */
1243bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CFGL_MAX_BURST(x)	((x) << 20)
1253bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CFGL_RELOAD_SAR	(1 << 30)
1263bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CFGL_RELOAD_DAR	(1 << 31)
1273bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1283bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen/* Bitfields in CFG_HI. Platform-configurable bits are in <linux/dw_dmac.h> */
1293bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CFGH_DS_UPD_EN	(1 << 5)
1303bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_CFGH_SS_UPD_EN	(1 << 6)
1313bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1323bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen/* Bitfields in SGR */
1333bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_SGR_SGI(x)		((x) << 0)
1343bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_SGR_SGC(x)		((x) << 20)
1353bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1363bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen/* Bitfields in DSR */
1373bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_DSR_DSI(x)		((x) << 0)
1383bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DWC_DSR_DSC(x)		((x) << 20)
1393bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1403bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen/* Bitfields in CFG */
1413bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DW_CFG_DMA_EN		(1 << 0)
1423bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1433bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define DW_REGLEN		0x400
1443bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
145d9de451989a88a2003ca06e524aca4665c0c7f06Hans-Christian Egtvedtenum dw_dmac_flags {
146d9de451989a88a2003ca06e524aca4665c0c7f06Hans-Christian Egtvedt	DW_DMA_IS_CYCLIC = 0,
147d9de451989a88a2003ca06e524aca4665c0c7f06Hans-Christian Egtvedt};
148d9de451989a88a2003ca06e524aca4665c0c7f06Hans-Christian Egtvedt
1493bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoenstruct dw_dma_chan {
1503bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct dma_chan		chan;
1513bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	void __iomem		*ch_regs;
1523bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	u8			mask;
15393317e8e35b77633d589fe0e132291195757d785Viresh Kumar	u8			priority;
154a7c57cf7d4327c41510f8cbf45b1b970e02c34f8Linus Walleij	bool			paused;
15561e183f8306934a9f66557f69f1f0f56f18dca06Viresh Kumar	bool			initialized;
1563bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1573bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	spinlock_t		lock;
1583bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1593bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	/* these other elements are all protected by lock */
160d9de451989a88a2003ca06e524aca4665c0c7f06Hans-Christian Egtvedt	unsigned long		flags;
1613bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct list_head	active_list;
1623bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct list_head	queue;
1633bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct list_head	free_list;
164d9de451989a88a2003ca06e524aca4665c0c7f06Hans-Christian Egtvedt	struct dw_cyclic_desc	*cdesc;
1653bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1663bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	unsigned int		descs_allocated;
167327e6970258618da810f72e86cf2a8b803927e14Viresh Kumar
168327e6970258618da810f72e86cf2a8b803927e14Viresh Kumar	/* configuration passed via DMA_SLAVE_CONFIG */
169327e6970258618da810f72e86cf2a8b803927e14Viresh Kumar	struct dma_slave_config dma_sconfig;
1703bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen};
1713bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1723bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoenstatic inline struct dw_dma_chan_regs __iomem *
1733bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen__dwc_regs(struct dw_dma_chan *dwc)
1743bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen{
1753bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	return dwc->ch_regs;
1763bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen}
1773bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1783bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define channel_readl(dwc, name) \
17929782da5f0206335e2325508ba4fee0d624ddab6Viresh Kumar	readl(&(__dwc_regs(dwc)->name))
1803bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define channel_writel(dwc, name, val) \
18129782da5f0206335e2325508ba4fee0d624ddab6Viresh Kumar	writel((val), &(__dwc_regs(dwc)->name))
1823bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1833bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoenstatic inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan)
1843bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen{
1853bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	return container_of(chan, struct dw_dma_chan, chan);
1863bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen}
1873bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1883bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoenstruct dw_dma {
1893bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct dma_device	dma;
1903bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	void __iomem		*regs;
1913bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct tasklet_struct	tasklet;
1923bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct clk		*clk;
1933bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1943bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	u8			all_chan_mask;
1953bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1963bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct dw_dma_chan	chan[0];
1973bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen};
1983bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
1993bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoenstatic inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw)
2003bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen{
2013bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	return dw->regs;
2023bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen}
2033bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
2043bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define dma_readl(dw, name) \
20529782da5f0206335e2325508ba4fee0d624ddab6Viresh Kumar	readl(&(__dw_regs(dw)->name))
2063bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define dma_writel(dw, name, val) \
20729782da5f0206335e2325508ba4fee0d624ddab6Viresh Kumar	writel((val), &(__dw_regs(dw)->name))
2083bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
2093bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define channel_set_bit(dw, reg, mask) \
2103bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	dma_writel(dw, reg, ((mask) << 8) | (mask))
2113bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen#define channel_clear_bit(dw, reg, mask) \
2123bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	dma_writel(dw, reg, ((mask) << 8) | 0)
2133bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
2143bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoenstatic inline struct dw_dma *to_dw_dma(struct dma_device *ddev)
2153bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen{
2163bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	return container_of(ddev, struct dw_dma, dma);
2173bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen}
2183bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
2193bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen/* LLI == Linked List Item; a.k.a. DMA block descriptor */
2203bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoenstruct dw_lli {
2213bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	/* values that are not changed by hardware */
2223bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	dma_addr_t	sar;
2233bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	dma_addr_t	dar;
2243bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	dma_addr_t	llp;		/* chain to next lli */
2253bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	u32		ctllo;
2263bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	/* values that may get written back: */
2273bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	u32		ctlhi;
2283bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	/* sstat and dstat can snapshot peripheral register state.
2293bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	 * silicon config may discard either or both...
2303bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	 */
2313bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	u32		sstat;
2323bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	u32		dstat;
2333bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen};
2343bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
2353bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoenstruct dw_desc {
2363bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	/* FIRST values the hardware uses */
2373bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct dw_lli			lli;
2383bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
2393bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	/* THEN values for driver housekeeping */
2403bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct list_head		desc_node;
241e0bd0f8cb09cf3ccac1425f0f3a6705106c4d65cDan Williams	struct list_head		tx_list;
2423bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	struct dma_async_tx_descriptor	txd;
2433bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	size_t				len;
2443bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen};
2453bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen
2463bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoenstatic inline struct dw_desc *
2473bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoentxd_to_dw_desc(struct dma_async_tx_descriptor *txd)
2483bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen{
2493bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen	return container_of(txd, struct dw_desc, txd);
2503bfb1d20b547a5071d01344581eac5846ea84491Haavard Skinnemoen}
251