xref: /openbmc/linux/drivers/dma/at_hdmac.c (revision 897500c7)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2dc78baa2SNicolas Ferre /*
3dc78baa2SNicolas Ferre  * Driver for the Atmel AHB DMA Controller (aka HDMA or DMAC on AT91 systems)
4dc78baa2SNicolas Ferre  *
5dc78baa2SNicolas Ferre  * Copyright (C) 2008 Atmel Corporation
6ac803b56STudor Ambarus  * Copyright (C) 2022 Microchip Technology, Inc. and its subsidiaries
7dc78baa2SNicolas Ferre  *
89102d871SNicolas Ferre  * This supports the Atmel AHB DMA Controller found in several Atmel SoCs.
99102d871SNicolas Ferre  * The only Atmel DMA Controller that is not covered by this driver is the one
109102d871SNicolas Ferre  * found on AT91SAM9263.
11dc78baa2SNicolas Ferre  */
12dc78baa2SNicolas Ferre 
1362971b29SLudovic Desroches #include <dt-bindings/dma/at91.h>
14d8840a7eSTudor Ambarus #include <linux/bitfield.h>
15dc78baa2SNicolas Ferre #include <linux/clk.h>
16dc78baa2SNicolas Ferre #include <linux/dmaengine.h>
17dc78baa2SNicolas Ferre #include <linux/dmapool.h>
18e3e672b8STudor Ambarus #include <linux/dma-mapping.h>
19dc78baa2SNicolas Ferre #include <linux/interrupt.h>
20dc78baa2SNicolas Ferre #include <linux/module.h>
21c5115953SNicolas Ferre #include <linux/of.h>
225f1d429bSTudor Ambarus #include <linux/overflow.h>
23*897500c7SRob Herring #include <linux/of_platform.h>
24bbe89c8eSLudovic Desroches #include <linux/of_dma.h>
25e3e672b8STudor Ambarus #include <linux/platform_device.h>
26e3e672b8STudor Ambarus #include <linux/slab.h>
27dc78baa2SNicolas Ferre 
28d2ebfb33SRussell King - ARM Linux #include "dmaengine.h"
29ac803b56STudor Ambarus #include "virt-dma.h"
30dc78baa2SNicolas Ferre 
31dc78baa2SNicolas Ferre /*
32dc78baa2SNicolas Ferre  * Glossary
33dc78baa2SNicolas Ferre  * --------
34dc78baa2SNicolas Ferre  *
35dc78baa2SNicolas Ferre  * at_hdmac		: Name of the ATmel AHB DMA Controller
36dc78baa2SNicolas Ferre  * at_dma_ / atdma	: ATmel DMA controller entity related
37dc78baa2SNicolas Ferre  * atc_	/ atchan	: ATmel DMA Channel entity related
38dc78baa2SNicolas Ferre  */
39dc78baa2SNicolas Ferre 
405cecadc3STudor Ambarus #define	AT_DMA_MAX_NR_CHANNELS	8
415cecadc3STudor Ambarus 
42d8840a7eSTudor Ambarus /* Global Configuration Register */
43d8840a7eSTudor Ambarus #define AT_DMA_GCFG		0x00
44d8840a7eSTudor Ambarus #define AT_DMA_IF_BIGEND(i)	BIT((i))	/* AHB-Lite Interface i in Big-endian mode */
45d8840a7eSTudor Ambarus #define AT_DMA_ARB_CFG		BIT(4)		/* Arbiter mode. */
465cecadc3STudor Ambarus 
47d8840a7eSTudor Ambarus /* Controller Enable Register */
48d8840a7eSTudor Ambarus #define AT_DMA_EN		0x04
49d8840a7eSTudor Ambarus #define AT_DMA_ENABLE		BIT(0)
505cecadc3STudor Ambarus 
51d8840a7eSTudor Ambarus /* Software Single Request Register */
52d8840a7eSTudor Ambarus #define AT_DMA_SREQ		0x08
53d8840a7eSTudor Ambarus #define AT_DMA_SSREQ(x)		BIT((x) << 1)		/* Request a source single transfer on channel x */
54d8840a7eSTudor Ambarus #define AT_DMA_DSREQ(x)		BIT(1 + ((x) << 1))	/* Request a destination single transfer on channel x */
555cecadc3STudor Ambarus 
56d8840a7eSTudor Ambarus /* Software Chunk Transfer Request Register */
57d8840a7eSTudor Ambarus #define AT_DMA_CREQ		0x0c
58d8840a7eSTudor Ambarus #define AT_DMA_SCREQ(x)		BIT((x) << 1)		/* Request a source chunk transfer on channel x */
59d8840a7eSTudor Ambarus #define AT_DMA_DCREQ(x)		BIT(1 + ((x) << 1))	/* Request a destination chunk transfer on channel x */
605cecadc3STudor Ambarus 
61d8840a7eSTudor Ambarus /* Software Last Transfer Flag Register */
62d8840a7eSTudor Ambarus #define AT_DMA_LAST		0x10
63d8840a7eSTudor Ambarus #define AT_DMA_SLAST(x)		BIT((x) << 1)		/* This src rq is last tx of buffer on channel x */
64d8840a7eSTudor Ambarus #define AT_DMA_DLAST(x)		BIT(1 + ((x) << 1))	/* This dst rq is last tx of buffer on channel x */
655cecadc3STudor Ambarus 
66d8840a7eSTudor Ambarus /* Request Synchronization Register */
67d8840a7eSTudor Ambarus #define AT_DMA_SYNC		0x14
68d8840a7eSTudor Ambarus #define AT_DMA_SYR(h)		BIT((h))		/* Synchronize handshake line h */
695cecadc3STudor Ambarus 
705cecadc3STudor Ambarus /* Error, Chained Buffer transfer completed and Buffer transfer completed Interrupt registers */
715cecadc3STudor Ambarus #define AT_DMA_EBCIER		0x18			/* Enable register */
72d8840a7eSTudor Ambarus #define AT_DMA_EBCIDR		0x1c			/* Disable register */
735cecadc3STudor Ambarus #define AT_DMA_EBCIMR		0x20			/* Mask Register */
745cecadc3STudor Ambarus #define AT_DMA_EBCISR		0x24			/* Status Register */
755cecadc3STudor Ambarus #define AT_DMA_CBTC_OFFSET	8
765cecadc3STudor Ambarus #define AT_DMA_ERR_OFFSET	16
77d8840a7eSTudor Ambarus #define AT_DMA_BTC(x)		BIT((x))
78d8840a7eSTudor Ambarus #define AT_DMA_CBTC(x)		BIT(AT_DMA_CBTC_OFFSET + (x))
79d8840a7eSTudor Ambarus #define AT_DMA_ERR(x)		BIT(AT_DMA_ERR_OFFSET + (x))
805cecadc3STudor Ambarus 
81d8840a7eSTudor Ambarus /* Channel Handler Enable Register */
82d8840a7eSTudor Ambarus #define AT_DMA_CHER		0x28
83d8840a7eSTudor Ambarus #define AT_DMA_ENA(x)		BIT((x))
84d8840a7eSTudor Ambarus #define AT_DMA_SUSP(x)		BIT(8 + (x))
85d8840a7eSTudor Ambarus #define AT_DMA_KEEP(x)		BIT(24 + (x))
865cecadc3STudor Ambarus 
87d8840a7eSTudor Ambarus /* Channel Handler Disable Register */
88d8840a7eSTudor Ambarus #define AT_DMA_CHDR		0x2c
89d8840a7eSTudor Ambarus #define AT_DMA_DIS(x)		BIT(x)
90d8840a7eSTudor Ambarus #define AT_DMA_RES(x)		BIT(8 + (x))
915cecadc3STudor Ambarus 
92d8840a7eSTudor Ambarus /* Channel Handler Status Register */
93d8840a7eSTudor Ambarus #define AT_DMA_CHSR		0x30
94d8840a7eSTudor Ambarus #define AT_DMA_EMPT(x)		BIT(16 + (x))
95d8840a7eSTudor Ambarus #define AT_DMA_STAL(x)		BIT(24 + (x))
965cecadc3STudor Ambarus 
97d8840a7eSTudor Ambarus /* Channel registers base address */
98d8840a7eSTudor Ambarus #define AT_DMA_CH_REGS_BASE	0x3c
995cecadc3STudor Ambarus #define ch_regs(x)		(AT_DMA_CH_REGS_BASE + (x) * 0x28) /* Channel x base addr */
1005cecadc3STudor Ambarus 
1015cecadc3STudor Ambarus /* Hardware register offset for each channel */
1025cecadc3STudor Ambarus #define ATC_SADDR_OFFSET	0x00	/* Source Address Register */
1035cecadc3STudor Ambarus #define ATC_DADDR_OFFSET	0x04	/* Destination Address Register */
1045cecadc3STudor Ambarus #define ATC_DSCR_OFFSET		0x08	/* Descriptor Address Register */
105d8840a7eSTudor Ambarus #define ATC_CTRLA_OFFSET	0x0c	/* Control A Register */
1065cecadc3STudor Ambarus #define ATC_CTRLB_OFFSET	0x10	/* Control B Register */
1075cecadc3STudor Ambarus #define ATC_CFG_OFFSET		0x14	/* Configuration Register */
1085cecadc3STudor Ambarus #define ATC_SPIP_OFFSET		0x18	/* Src PIP Configuration Register */
109d8840a7eSTudor Ambarus #define ATC_DPIP_OFFSET		0x1c	/* Dst PIP Configuration Register */
1105cecadc3STudor Ambarus 
1115cecadc3STudor Ambarus 
1125cecadc3STudor Ambarus /* Bitfield definitions */
1135cecadc3STudor Ambarus 
1145cecadc3STudor Ambarus /* Bitfields in DSCR */
115d8840a7eSTudor Ambarus #define ATC_DSCR_IF		GENMASK(1, 0)	/* Dsc feched via AHB-Lite Interface */
1165cecadc3STudor Ambarus 
1175cecadc3STudor Ambarus /* Bitfields in CTRLA */
118d8840a7eSTudor Ambarus #define ATC_BTSIZE_MAX		GENMASK(15, 0)	/* Maximum Buffer Transfer Size */
119d8840a7eSTudor Ambarus #define ATC_BTSIZE		GENMASK(15, 0)	/* Buffer Transfer Size */
120d8840a7eSTudor Ambarus #define ATC_SCSIZE		GENMASK(18, 16)	/* Source Chunk Transfer Size */
121d8840a7eSTudor Ambarus #define ATC_DCSIZE		GENMASK(22, 20)	/* Destination Chunk Transfer Size */
122d8840a7eSTudor Ambarus #define ATC_SRC_WIDTH		GENMASK(25, 24)	/* Source Single Transfer Size */
123d8840a7eSTudor Ambarus #define ATC_DST_WIDTH		GENMASK(29, 28)	/* Destination Single Transfer Size */
124d8840a7eSTudor Ambarus #define ATC_DONE		BIT(31)	/* Tx Done (only written back in descriptor) */
1255cecadc3STudor Ambarus 
1265cecadc3STudor Ambarus /* Bitfields in CTRLB */
127d8840a7eSTudor Ambarus #define ATC_SIF			GENMASK(1, 0)	/* Src tx done via AHB-Lite Interface i */
128d8840a7eSTudor Ambarus #define ATC_DIF			GENMASK(5, 4)	/* Dst tx done via AHB-Lite Interface i */
129d8840a7eSTudor Ambarus #define AT_DMA_MEM_IF		0x0		/* interface 0 as memory interface */
130d8840a7eSTudor Ambarus #define AT_DMA_PER_IF		0x1		/* interface 1 as peripheral interface */
131d8840a7eSTudor Ambarus #define ATC_SRC_PIP		BIT(8)		/* Source Picture-in-Picture enabled */
132d8840a7eSTudor Ambarus #define ATC_DST_PIP		BIT(12)		/* Destination Picture-in-Picture enabled */
133d8840a7eSTudor Ambarus #define ATC_SRC_DSCR_DIS	BIT(16)		/* Src Descriptor fetch disable */
134d8840a7eSTudor Ambarus #define ATC_DST_DSCR_DIS	BIT(20)		/* Dst Descriptor fetch disable */
135e14fd2afSPeter Rosin #define ATC_FC			GENMASK(23, 21)	/* Choose Flow Controller */
136d8840a7eSTudor Ambarus #define ATC_FC_MEM2MEM		0x0		/* Mem-to-Mem (DMA) */
137d8840a7eSTudor Ambarus #define ATC_FC_MEM2PER		0x1		/* Mem-to-Periph (DMA) */
138d8840a7eSTudor Ambarus #define ATC_FC_PER2MEM		0x2		/* Periph-to-Mem (DMA) */
139d8840a7eSTudor Ambarus #define ATC_FC_PER2PER		0x3		/* Periph-to-Periph (DMA) */
140d8840a7eSTudor Ambarus #define ATC_FC_PER2MEM_PER	0x4		/* Periph-to-Mem (Peripheral) */
141d8840a7eSTudor Ambarus #define ATC_FC_MEM2PER_PER	0x5		/* Mem-to-Periph (Peripheral) */
142d8840a7eSTudor Ambarus #define ATC_FC_PER2PER_SRCPER	0x6		/* Periph-to-Periph (Src Peripheral) */
143d8840a7eSTudor Ambarus #define ATC_FC_PER2PER_DSTPER	0x7		/* Periph-to-Periph (Dst Peripheral) */
144d8840a7eSTudor Ambarus #define ATC_SRC_ADDR_MODE	GENMASK(25, 24)
145d8840a7eSTudor Ambarus #define ATC_SRC_ADDR_MODE_INCR	0x0		/* Incrementing Mode */
146d8840a7eSTudor Ambarus #define ATC_SRC_ADDR_MODE_DECR	0x1		/* Decrementing Mode */
147d8840a7eSTudor Ambarus #define ATC_SRC_ADDR_MODE_FIXED	0x2		/* Fixed Mode */
148d8840a7eSTudor Ambarus #define ATC_DST_ADDR_MODE	GENMASK(29, 28)
149d8840a7eSTudor Ambarus #define ATC_DST_ADDR_MODE_INCR	0x0		/* Incrementing Mode */
150d8840a7eSTudor Ambarus #define ATC_DST_ADDR_MODE_DECR	0x1		/* Decrementing Mode */
151d8840a7eSTudor Ambarus #define ATC_DST_ADDR_MODE_FIXED	0x2		/* Fixed Mode */
152d8840a7eSTudor Ambarus #define ATC_IEN			BIT(30)		/* BTC interrupt enable (active low) */
153d8840a7eSTudor Ambarus #define ATC_AUTO		BIT(31)		/* Auto multiple buffer tx enable */
1545cecadc3STudor Ambarus 
1555cecadc3STudor Ambarus /* Bitfields in CFG */
156d8840a7eSTudor Ambarus #define ATC_SRC_PER		GENMASK(3, 0)	/* Channel src rq associated with periph handshaking ifc h */
157d8840a7eSTudor Ambarus #define ATC_DST_PER		GENMASK(7, 4)	/* Channel dst rq associated with periph handshaking ifc h */
158d8840a7eSTudor Ambarus #define ATC_SRC_REP		BIT(8)		/* Source Replay Mod */
159d8840a7eSTudor Ambarus #define ATC_SRC_H2SEL		BIT(9)		/* Source Handshaking Mod */
160d8840a7eSTudor Ambarus #define ATC_SRC_PER_MSB		GENMASK(11, 10)	/* Channel src rq (most significant bits) */
161d8840a7eSTudor Ambarus #define ATC_DST_REP		BIT(12)		/* Destination Replay Mod */
162d8840a7eSTudor Ambarus #define ATC_DST_H2SEL		BIT(13)		/* Destination Handshaking Mod */
163d8840a7eSTudor Ambarus #define ATC_DST_PER_MSB		GENMASK(15, 14)	/* Channel dst rq (most significant bits) */
164d8840a7eSTudor Ambarus #define ATC_SOD			BIT(16)		/* Stop On Done */
165d8840a7eSTudor Ambarus #define ATC_LOCK_IF		BIT(20)		/* Interface Lock */
166d8840a7eSTudor Ambarus #define ATC_LOCK_B		BIT(21)		/* AHB Bus Lock */
167d8840a7eSTudor Ambarus #define ATC_LOCK_IF_L		BIT(22)		/* Master Interface Arbiter Lock */
168d8840a7eSTudor Ambarus #define ATC_AHB_PROT		GENMASK(26, 24)	/* AHB Protection */
169d8840a7eSTudor Ambarus #define ATC_FIFOCFG		GENMASK(29, 28)	/* FIFO Request Configuration */
170d8840a7eSTudor Ambarus #define ATC_FIFOCFG_LARGESTBURST	0x0
171d8840a7eSTudor Ambarus #define ATC_FIFOCFG_HALFFIFO		0x1
172d8840a7eSTudor Ambarus #define ATC_FIFOCFG_ENOUGHSPACE		0x2
1735cecadc3STudor Ambarus 
1745cecadc3STudor Ambarus /* Bitfields in SPIP */
175d8840a7eSTudor Ambarus #define ATC_SPIP_HOLE		GENMASK(15, 0)
176d8840a7eSTudor Ambarus #define ATC_SPIP_BOUNDARY	GENMASK(25, 16)
1775cecadc3STudor Ambarus 
1785cecadc3STudor Ambarus /* Bitfields in DPIP */
179d8840a7eSTudor Ambarus #define ATC_DPIP_HOLE		GENMASK(15, 0)
180d8840a7eSTudor Ambarus #define ATC_DPIP_BOUNDARY	GENMASK(25, 16)
181d8840a7eSTudor Ambarus 
1822a6c7e8cSPeter Rosin #define ATC_PER_MSB		GENMASK(5, 4)	/* Extract MSBs of a handshaking identifier */
1832a6c7e8cSPeter Rosin #define ATC_SRC_PER_ID(id)					       \
1842a6c7e8cSPeter Rosin 	({ typeof(id) _id = (id);				       \
1852a6c7e8cSPeter Rosin 	   FIELD_PREP(ATC_SRC_PER_MSB, FIELD_GET(ATC_PER_MSB, _id)) |  \
1862a6c7e8cSPeter Rosin 	   FIELD_PREP(ATC_SRC_PER, _id); })
1872a6c7e8cSPeter Rosin #define ATC_DST_PER_ID(id)					       \
1882a6c7e8cSPeter Rosin 	({ typeof(id) _id = (id);				       \
1892a6c7e8cSPeter Rosin 	   FIELD_PREP(ATC_DST_PER_MSB, FIELD_GET(ATC_PER_MSB, _id)) |  \
1902a6c7e8cSPeter Rosin 	   FIELD_PREP(ATC_DST_PER, _id); })
191d8840a7eSTudor Ambarus 
1925cecadc3STudor Ambarus 
1935cecadc3STudor Ambarus 
1945cecadc3STudor Ambarus /*--  descriptors  -----------------------------------------------------*/
1955cecadc3STudor Ambarus 
1965cecadc3STudor Ambarus /* LLI == Linked List Item; aka DMA buffer descriptor */
1975cecadc3STudor Ambarus struct at_lli {
1985cecadc3STudor Ambarus 	/* values that are not changed by hardware */
1995cecadc3STudor Ambarus 	u32 saddr;
2005cecadc3STudor Ambarus 	u32 daddr;
2015cecadc3STudor Ambarus 	/* value that may get written back: */
2025cecadc3STudor Ambarus 	u32 ctrla;
2035cecadc3STudor Ambarus 	/* more values that are not changed by hardware */
2045cecadc3STudor Ambarus 	u32 ctrlb;
2055cecadc3STudor Ambarus 	u32 dscr;	/* chain to next lli */
2065cecadc3STudor Ambarus };
2075cecadc3STudor Ambarus 
2085cecadc3STudor Ambarus /**
209ac803b56STudor Ambarus  * struct atdma_sg - atdma scatter gather entry
210ac803b56STudor Ambarus  * @len: length of the current Linked List Item.
211ac803b56STudor Ambarus  * @lli: linked list item that is passed to the DMA controller
212ac803b56STudor Ambarus  * @lli_phys: physical address of the LLI.
213ac803b56STudor Ambarus  */
214ac803b56STudor Ambarus struct atdma_sg {
215ac803b56STudor Ambarus 	unsigned int len;
216ac803b56STudor Ambarus 	struct at_lli *lli;
217ac803b56STudor Ambarus 	dma_addr_t lli_phys;
218ac803b56STudor Ambarus };
219ac803b56STudor Ambarus 
220ac803b56STudor Ambarus /**
2215cecadc3STudor Ambarus  * struct at_desc - software descriptor
222ac803b56STudor Ambarus  * @vd: pointer to the virtual dma descriptor.
223ac803b56STudor Ambarus  * @atchan: pointer to the atmel dma channel.
2245cecadc3STudor Ambarus  * @total_len: total transaction byte count
225ac803b56STudor Ambarus  * @sg_len: number of sg entries.
226ac803b56STudor Ambarus  * @sg: array of sgs.
2275cecadc3STudor Ambarus  */
2285cecadc3STudor Ambarus struct at_desc {
229ac803b56STudor Ambarus 	struct				virt_dma_desc vd;
230ac803b56STudor Ambarus 	struct				at_dma_chan *atchan;
2315cecadc3STudor Ambarus 	size_t				total_len;
232ac803b56STudor Ambarus 	unsigned int			sglen;
2335cecadc3STudor Ambarus 	/* Interleaved data */
2345cecadc3STudor Ambarus 	size_t				boundary;
2355cecadc3STudor Ambarus 	size_t				dst_hole;
2365cecadc3STudor Ambarus 	size_t				src_hole;
2375cecadc3STudor Ambarus 
2385cecadc3STudor Ambarus 	/* Memset temporary buffer */
2395cecadc3STudor Ambarus 	bool				memset_buffer;
2405cecadc3STudor Ambarus 	dma_addr_t			memset_paddr;
2415cecadc3STudor Ambarus 	int				*memset_vaddr;
242ac803b56STudor Ambarus 	struct atdma_sg			sg[];
2435cecadc3STudor Ambarus };
2445cecadc3STudor Ambarus 
2455cecadc3STudor Ambarus /*--  Channels  --------------------------------------------------------*/
2465cecadc3STudor Ambarus 
2475cecadc3STudor Ambarus /**
2485cecadc3STudor Ambarus  * atc_status - information bits stored in channel status flag
2495cecadc3STudor Ambarus  *
2505cecadc3STudor Ambarus  * Manipulated with atomic operations.
2515cecadc3STudor Ambarus  */
2525cecadc3STudor Ambarus enum atc_status {
2535cecadc3STudor Ambarus 	ATC_IS_PAUSED = 1,
2545cecadc3STudor Ambarus 	ATC_IS_CYCLIC = 24,
2555cecadc3STudor Ambarus };
2565cecadc3STudor Ambarus 
2575cecadc3STudor Ambarus /**
2585cecadc3STudor Ambarus  * struct at_dma_chan - internal representation of an Atmel HDMAC channel
259ac803b56STudor Ambarus  * @vc: virtual dma channel entry.
260ac803b56STudor Ambarus  * @atdma: pointer to the driver data.
2615cecadc3STudor Ambarus  * @ch_regs: memory mapped register base
2625cecadc3STudor Ambarus  * @mask: channel index in a mask
2635cecadc3STudor Ambarus  * @per_if: peripheral interface
2645cecadc3STudor Ambarus  * @mem_if: memory interface
2655cecadc3STudor Ambarus  * @status: transmit status information from irq/prep* functions
2665cecadc3STudor Ambarus  *                to tasklet (use atomic operations)
2675cecadc3STudor Ambarus  * @save_cfg: configuration register that is saved on suspend/resume cycle
2685cecadc3STudor Ambarus  * @save_dscr: for cyclic operations, preserve next descriptor address in
2695cecadc3STudor Ambarus  *             the cyclic list on suspend/resume cycle
2705cecadc3STudor Ambarus  * @dma_sconfig: configuration for slave transfers, passed via
2715cecadc3STudor Ambarus  * .device_config
272ac803b56STudor Ambarus  * @desc: pointer to the atmel dma descriptor.
2735cecadc3STudor Ambarus  */
2745cecadc3STudor Ambarus struct at_dma_chan {
275ac803b56STudor Ambarus 	struct virt_dma_chan	vc;
276ac803b56STudor Ambarus 	struct at_dma		*atdma;
2775cecadc3STudor Ambarus 	void __iomem		*ch_regs;
2785cecadc3STudor Ambarus 	u8			mask;
2795cecadc3STudor Ambarus 	u8			per_if;
2805cecadc3STudor Ambarus 	u8			mem_if;
2815cecadc3STudor Ambarus 	unsigned long		status;
2825cecadc3STudor Ambarus 	u32			save_cfg;
2835cecadc3STudor Ambarus 	u32			save_dscr;
2845cecadc3STudor Ambarus 	struct dma_slave_config	dma_sconfig;
285ac803b56STudor Ambarus 	bool			cyclic;
286ac803b56STudor Ambarus 	struct at_desc		*desc;
2875cecadc3STudor Ambarus };
2885cecadc3STudor Ambarus 
2895cecadc3STudor Ambarus #define	channel_readl(atchan, name) \
2905cecadc3STudor Ambarus 	__raw_readl((atchan)->ch_regs + ATC_##name##_OFFSET)
2915cecadc3STudor Ambarus 
2925cecadc3STudor Ambarus #define	channel_writel(atchan, name, val) \
2935cecadc3STudor Ambarus 	__raw_writel((val), (atchan)->ch_regs + ATC_##name##_OFFSET)
2945cecadc3STudor Ambarus 
2955cecadc3STudor Ambarus /*
2965cecadc3STudor Ambarus  * Fix sconfig's burst size according to at_hdmac. We need to convert them as:
2975cecadc3STudor Ambarus  * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3, 32 -> 4, 64 -> 5, 128 -> 6, 256 -> 7.
2985cecadc3STudor Ambarus  *
2995cecadc3STudor Ambarus  * This can be done by finding most significant bit set.
3005cecadc3STudor Ambarus  */
convert_burst(u32 * maxburst)3015cecadc3STudor Ambarus static inline void convert_burst(u32 *maxburst)
3025cecadc3STudor Ambarus {
3035cecadc3STudor Ambarus 	if (*maxburst > 1)
3045cecadc3STudor Ambarus 		*maxburst = fls(*maxburst) - 2;
3055cecadc3STudor Ambarus 	else
3065cecadc3STudor Ambarus 		*maxburst = 0;
3075cecadc3STudor Ambarus }
3085cecadc3STudor Ambarus 
3095cecadc3STudor Ambarus /*
3105cecadc3STudor Ambarus  * Fix sconfig's bus width according to at_hdmac.
3115cecadc3STudor Ambarus  * 1 byte -> 0, 2 bytes -> 1, 4 bytes -> 2.
3125cecadc3STudor Ambarus  */
convert_buswidth(enum dma_slave_buswidth addr_width)3135cecadc3STudor Ambarus static inline u8 convert_buswidth(enum dma_slave_buswidth addr_width)
3145cecadc3STudor Ambarus {
3155cecadc3STudor Ambarus 	switch (addr_width) {
3165cecadc3STudor Ambarus 	case DMA_SLAVE_BUSWIDTH_2_BYTES:
3175cecadc3STudor Ambarus 		return 1;
3185cecadc3STudor Ambarus 	case DMA_SLAVE_BUSWIDTH_4_BYTES:
3195cecadc3STudor Ambarus 		return 2;
3205cecadc3STudor Ambarus 	default:
3215cecadc3STudor Ambarus 		/* For 1 byte width or fallback */
3225cecadc3STudor Ambarus 		return 0;
3235cecadc3STudor Ambarus 	}
3245cecadc3STudor Ambarus }
3255cecadc3STudor Ambarus 
3265cecadc3STudor Ambarus /*--  Controller  ------------------------------------------------------*/
3275cecadc3STudor Ambarus 
3285cecadc3STudor Ambarus /**
3295cecadc3STudor Ambarus  * struct at_dma - internal representation of an Atmel HDMA Controller
3301c1114d8STudor Ambarus  * @dma_device: dmaengine dma_device object members
3315cecadc3STudor Ambarus  * @atdma_devtype: identifier of DMA controller compatibility
3325cecadc3STudor Ambarus  * @ch_regs: memory mapped register base
3335cecadc3STudor Ambarus  * @clk: dma controller clock
3345cecadc3STudor Ambarus  * @save_imr: interrupt mask register that is saved on suspend/resume cycle
3355cecadc3STudor Ambarus  * @all_chan_mask: all channels availlable in a mask
336ac803b56STudor Ambarus  * @lli_pool: hw lli table
3375cecadc3STudor Ambarus  * @chan: channels table to store at_dma_chan structures
3385cecadc3STudor Ambarus  */
3395cecadc3STudor Ambarus struct at_dma {
3401c1114d8STudor Ambarus 	struct dma_device	dma_device;
3415cecadc3STudor Ambarus 	void __iomem		*regs;
3425cecadc3STudor Ambarus 	struct clk		*clk;
3435cecadc3STudor Ambarus 	u32			save_imr;
3445cecadc3STudor Ambarus 
3455cecadc3STudor Ambarus 	u8			all_chan_mask;
3465cecadc3STudor Ambarus 
347ac803b56STudor Ambarus 	struct dma_pool		*lli_pool;
3485cecadc3STudor Ambarus 	struct dma_pool		*memset_pool;
3495cecadc3STudor Ambarus 	/* AT THE END channels table */
3505cecadc3STudor Ambarus 	struct at_dma_chan	chan[];
3515cecadc3STudor Ambarus };
3525cecadc3STudor Ambarus 
3535cecadc3STudor Ambarus #define	dma_readl(atdma, name) \
3545cecadc3STudor Ambarus 	__raw_readl((atdma)->regs + AT_DMA_##name)
3555cecadc3STudor Ambarus #define	dma_writel(atdma, name, val) \
3565cecadc3STudor Ambarus 	__raw_writel((val), (atdma)->regs + AT_DMA_##name)
3575cecadc3STudor Ambarus 
to_atdma_desc(struct dma_async_tx_descriptor * t)358ac803b56STudor Ambarus static inline struct at_desc *to_atdma_desc(struct dma_async_tx_descriptor *t)
359ac803b56STudor Ambarus {
360ac803b56STudor Ambarus 	return container_of(t, struct at_desc, vd.tx);
361ac803b56STudor Ambarus }
362ac803b56STudor Ambarus 
to_at_dma_chan(struct dma_chan * chan)363ac803b56STudor Ambarus static inline struct at_dma_chan *to_at_dma_chan(struct dma_chan *chan)
364ac803b56STudor Ambarus {
365ac803b56STudor Ambarus 	return container_of(chan, struct at_dma_chan, vc.chan);
366ac803b56STudor Ambarus }
367ac803b56STudor Ambarus 
to_at_dma(struct dma_device * ddev)3685cecadc3STudor Ambarus static inline struct at_dma *to_at_dma(struct dma_device *ddev)
3695cecadc3STudor Ambarus {
3701c1114d8STudor Ambarus 	return container_of(ddev, struct at_dma, dma_device);
3715cecadc3STudor Ambarus }
3725cecadc3STudor Ambarus 
3735cecadc3STudor Ambarus 
3745cecadc3STudor Ambarus /*--  Helper functions  ------------------------------------------------*/
3755cecadc3STudor Ambarus 
chan2dev(struct dma_chan * chan)3765cecadc3STudor Ambarus static struct device *chan2dev(struct dma_chan *chan)
3775cecadc3STudor Ambarus {
3785cecadc3STudor Ambarus 	return &chan->dev->device;
3795cecadc3STudor Ambarus }
3805cecadc3STudor Ambarus 
3815cecadc3STudor Ambarus #if defined(VERBOSE_DEBUG)
vdbg_dump_regs(struct at_dma_chan * atchan)3825cecadc3STudor Ambarus static void vdbg_dump_regs(struct at_dma_chan *atchan)
3835cecadc3STudor Ambarus {
384ac803b56STudor Ambarus 	struct at_dma	*atdma = to_at_dma(atchan->vc.chan.device);
3855cecadc3STudor Ambarus 
386ac803b56STudor Ambarus 	dev_err(chan2dev(&atchan->vc.chan),
3875cecadc3STudor Ambarus 		"  channel %d : imr = 0x%x, chsr = 0x%x\n",
388ac803b56STudor Ambarus 		atchan->vc.chan.chan_id,
3895cecadc3STudor Ambarus 		dma_readl(atdma, EBCIMR),
3905cecadc3STudor Ambarus 		dma_readl(atdma, CHSR));
3915cecadc3STudor Ambarus 
392ac803b56STudor Ambarus 	dev_err(chan2dev(&atchan->vc.chan),
3935cecadc3STudor Ambarus 		"  channel: s0x%x d0x%x ctrl0x%x:0x%x cfg0x%x l0x%x\n",
3945cecadc3STudor Ambarus 		channel_readl(atchan, SADDR),
3955cecadc3STudor Ambarus 		channel_readl(atchan, DADDR),
3965cecadc3STudor Ambarus 		channel_readl(atchan, CTRLA),
3975cecadc3STudor Ambarus 		channel_readl(atchan, CTRLB),
3985cecadc3STudor Ambarus 		channel_readl(atchan, CFG),
3995cecadc3STudor Ambarus 		channel_readl(atchan, DSCR));
4005cecadc3STudor Ambarus }
4015cecadc3STudor Ambarus #else
vdbg_dump_regs(struct at_dma_chan * atchan)4025cecadc3STudor Ambarus static void vdbg_dump_regs(struct at_dma_chan *atchan) {}
4035cecadc3STudor Ambarus #endif
4045cecadc3STudor Ambarus 
atc_dump_lli(struct at_dma_chan * atchan,struct at_lli * lli)4055cecadc3STudor Ambarus static void atc_dump_lli(struct at_dma_chan *atchan, struct at_lli *lli)
4065cecadc3STudor Ambarus {
407ac803b56STudor Ambarus 	dev_crit(chan2dev(&atchan->vc.chan),
4085cecadc3STudor Ambarus 		 "desc: s%pad d%pad ctrl0x%x:0x%x l%pad\n",
4095cecadc3STudor Ambarus 		 &lli->saddr, &lli->daddr,
4105cecadc3STudor Ambarus 		 lli->ctrla, lli->ctrlb, &lli->dscr);
4115cecadc3STudor Ambarus }
4125cecadc3STudor Ambarus 
4135cecadc3STudor Ambarus 
atc_setup_irq(struct at_dma * atdma,int chan_id,int on)4145cecadc3STudor Ambarus static void atc_setup_irq(struct at_dma *atdma, int chan_id, int on)
4155cecadc3STudor Ambarus {
4165cecadc3STudor Ambarus 	u32 ebci;
4175cecadc3STudor Ambarus 
4185cecadc3STudor Ambarus 	/* enable interrupts on buffer transfer completion & error */
4195cecadc3STudor Ambarus 	ebci =    AT_DMA_BTC(chan_id)
4205cecadc3STudor Ambarus 		| AT_DMA_ERR(chan_id);
4215cecadc3STudor Ambarus 	if (on)
4225cecadc3STudor Ambarus 		dma_writel(atdma, EBCIER, ebci);
4235cecadc3STudor Ambarus 	else
4245cecadc3STudor Ambarus 		dma_writel(atdma, EBCIDR, ebci);
4255cecadc3STudor Ambarus }
4265cecadc3STudor Ambarus 
atc_enable_chan_irq(struct at_dma * atdma,int chan_id)4275cecadc3STudor Ambarus static void atc_enable_chan_irq(struct at_dma *atdma, int chan_id)
4285cecadc3STudor Ambarus {
4295cecadc3STudor Ambarus 	atc_setup_irq(atdma, chan_id, 1);
4305cecadc3STudor Ambarus }
4315cecadc3STudor Ambarus 
atc_disable_chan_irq(struct at_dma * atdma,int chan_id)4325cecadc3STudor Ambarus static void atc_disable_chan_irq(struct at_dma *atdma, int chan_id)
4335cecadc3STudor Ambarus {
4345cecadc3STudor Ambarus 	atc_setup_irq(atdma, chan_id, 0);
4355cecadc3STudor Ambarus }
4365cecadc3STudor Ambarus 
4375cecadc3STudor Ambarus 
4385cecadc3STudor Ambarus /**
4395cecadc3STudor Ambarus  * atc_chan_is_enabled - test if given channel is enabled
4405cecadc3STudor Ambarus  * @atchan: channel we want to test status
4415cecadc3STudor Ambarus  */
atc_chan_is_enabled(struct at_dma_chan * atchan)4425cecadc3STudor Ambarus static inline int atc_chan_is_enabled(struct at_dma_chan *atchan)
4435cecadc3STudor Ambarus {
444ac803b56STudor Ambarus 	struct at_dma *atdma = to_at_dma(atchan->vc.chan.device);
4455cecadc3STudor Ambarus 
4465cecadc3STudor Ambarus 	return !!(dma_readl(atdma, CHSR) & atchan->mask);
4475cecadc3STudor Ambarus }
4485cecadc3STudor Ambarus 
4495cecadc3STudor Ambarus /**
4505cecadc3STudor Ambarus  * atc_chan_is_paused - test channel pause/resume status
4515cecadc3STudor Ambarus  * @atchan: channel we want to test status
4525cecadc3STudor Ambarus  */
atc_chan_is_paused(struct at_dma_chan * atchan)4535cecadc3STudor Ambarus static inline int atc_chan_is_paused(struct at_dma_chan *atchan)
4545cecadc3STudor Ambarus {
4555cecadc3STudor Ambarus 	return test_bit(ATC_IS_PAUSED, &atchan->status);
4565cecadc3STudor Ambarus }
4575cecadc3STudor Ambarus 
4585cecadc3STudor Ambarus /**
4595cecadc3STudor Ambarus  * atc_chan_is_cyclic - test if given channel has cyclic property set
4605cecadc3STudor Ambarus  * @atchan: channel we want to test status
4615cecadc3STudor Ambarus  */
atc_chan_is_cyclic(struct at_dma_chan * atchan)4625cecadc3STudor Ambarus static inline int atc_chan_is_cyclic(struct at_dma_chan *atchan)
4635cecadc3STudor Ambarus {
4645cecadc3STudor Ambarus 	return test_bit(ATC_IS_CYCLIC, &atchan->status);
4655cecadc3STudor Ambarus }
4665cecadc3STudor Ambarus 
4675cecadc3STudor Ambarus /**
468ac803b56STudor Ambarus  * set_lli_eol - set end-of-link to descriptor so it will end transfer
4695cecadc3STudor Ambarus  * @desc: descriptor, signle or at the end of a chain, to end chain on
470ac803b56STudor Ambarus  * @i: index of the atmel scatter gather entry that is at the end of the chain.
4715cecadc3STudor Ambarus  */
set_lli_eol(struct at_desc * desc,unsigned int i)472ac803b56STudor Ambarus static void set_lli_eol(struct at_desc *desc, unsigned int i)
4735cecadc3STudor Ambarus {
474ac803b56STudor Ambarus 	u32 ctrlb = desc->sg[i].lli->ctrlb;
4755cecadc3STudor Ambarus 
4765cecadc3STudor Ambarus 	ctrlb &= ~ATC_IEN;
4775cecadc3STudor Ambarus 	ctrlb |= ATC_SRC_DSCR_DIS | ATC_DST_DSCR_DIS;
4785cecadc3STudor Ambarus 
479ac803b56STudor Ambarus 	desc->sg[i].lli->ctrlb = ctrlb;
480ac803b56STudor Ambarus 	desc->sg[i].lli->dscr = 0;
4815cecadc3STudor Ambarus }
4825cecadc3STudor Ambarus 
483d8840a7eSTudor Ambarus #define	ATC_DEFAULT_CFG		FIELD_PREP(ATC_FIFOCFG, ATC_FIFOCFG_HALFFIFO)
484d8840a7eSTudor Ambarus #define	ATC_DEFAULT_CTRLB	(FIELD_PREP(ATC_SIF, AT_DMA_MEM_IF) | \
485d8840a7eSTudor Ambarus 				 FIELD_PREP(ATC_DIF, AT_DMA_MEM_IF))
486816070edSLudovic Desroches #define ATC_DMA_BUSWIDTHS\
487816070edSLudovic Desroches 	(BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) |\
488816070edSLudovic Desroches 	BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |\
489816070edSLudovic Desroches 	BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |\
490816070edSLudovic Desroches 	BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
491dc78baa2SNicolas Ferre 
49293dce3a6SCyrille Pitchen #define ATC_MAX_DSCR_TRIALS	10
49393dce3a6SCyrille Pitchen 
494dc78baa2SNicolas Ferre /*
495dc78baa2SNicolas Ferre  * Initial number of descriptors to allocate for each channel. This could
496dc78baa2SNicolas Ferre  * be increased during dma usage.
497dc78baa2SNicolas Ferre  */
498dc78baa2SNicolas Ferre static unsigned int init_nr_desc_per_channel = 64;
499dc78baa2SNicolas Ferre module_param(init_nr_desc_per_channel, uint, 0644);
500dc78baa2SNicolas Ferre MODULE_PARM_DESC(init_nr_desc_per_channel,
501dc78baa2SNicolas Ferre 		 "initial descriptors per channel (default: 64)");
502dc78baa2SNicolas Ferre 
50333cb6d1eSAlexandre Belloni /**
50433cb6d1eSAlexandre Belloni  * struct at_dma_platform_data - Controller configuration parameters
50533cb6d1eSAlexandre Belloni  * @nr_channels: Number of channels supported by hardware (max 8)
50633cb6d1eSAlexandre Belloni  * @cap_mask: dma_capability flags supported by the platform
50733cb6d1eSAlexandre Belloni  */
50833cb6d1eSAlexandre Belloni struct at_dma_platform_data {
50933cb6d1eSAlexandre Belloni 	unsigned int	nr_channels;
51033cb6d1eSAlexandre Belloni 	dma_cap_mask_t  cap_mask;
51133cb6d1eSAlexandre Belloni };
51233cb6d1eSAlexandre Belloni 
51333cb6d1eSAlexandre Belloni /**
51433cb6d1eSAlexandre Belloni  * struct at_dma_slave - Controller-specific information about a slave
51533cb6d1eSAlexandre Belloni  * @dma_dev: required DMA master device
51633cb6d1eSAlexandre Belloni  * @cfg: Platform-specific initializer for the CFG register
51733cb6d1eSAlexandre Belloni  */
51833cb6d1eSAlexandre Belloni struct at_dma_slave {
51933cb6d1eSAlexandre Belloni 	struct device		*dma_dev;
52033cb6d1eSAlexandre Belloni 	u32			cfg;
52133cb6d1eSAlexandre Belloni };
522dc78baa2SNicolas Ferre 
atc_get_xfer_width(dma_addr_t src,dma_addr_t dst,size_t len)523265567fbSTorsten Fleischer static inline unsigned int atc_get_xfer_width(dma_addr_t src, dma_addr_t dst,
524265567fbSTorsten Fleischer 						size_t len)
525265567fbSTorsten Fleischer {
526265567fbSTorsten Fleischer 	unsigned int width;
527265567fbSTorsten Fleischer 
528265567fbSTorsten Fleischer 	if (!((src | dst  | len) & 3))
529265567fbSTorsten Fleischer 		width = 2;
530265567fbSTorsten Fleischer 	else if (!((src | dst | len) & 1))
531265567fbSTorsten Fleischer 		width = 1;
532265567fbSTorsten Fleischer 	else
533265567fbSTorsten Fleischer 		width = 0;
534265567fbSTorsten Fleischer 
535265567fbSTorsten Fleischer 	return width;
536265567fbSTorsten Fleischer }
537265567fbSTorsten Fleischer 
atdma_lli_chain(struct at_desc * desc,unsigned int i)538ac803b56STudor Ambarus static void atdma_lli_chain(struct at_desc *desc, unsigned int i)
539dc78baa2SNicolas Ferre {
540ac803b56STudor Ambarus 	struct atdma_sg *atdma_sg = &desc->sg[i];
541dc78baa2SNicolas Ferre 
542ac803b56STudor Ambarus 	if (i)
543ac803b56STudor Ambarus 		desc->sg[i - 1].lli->dscr = atdma_sg->lli_phys;
54453830cc7SNicolas Ferre }
54553830cc7SNicolas Ferre 
54653830cc7SNicolas Ferre /**
547dc78baa2SNicolas Ferre  * atc_dostart - starts the DMA engine for real
548dc78baa2SNicolas Ferre  * @atchan: the channel we want to start
549dc78baa2SNicolas Ferre  */
atc_dostart(struct at_dma_chan * atchan)550ac803b56STudor Ambarus static void atc_dostart(struct at_dma_chan *atchan)
551dc78baa2SNicolas Ferre {
552ac803b56STudor Ambarus 	struct virt_dma_desc *vd = vchan_next_desc(&atchan->vc);
553ac803b56STudor Ambarus 	struct at_desc *desc;
554dc78baa2SNicolas Ferre 
555ac803b56STudor Ambarus 	if (!vd) {
556ac803b56STudor Ambarus 		atchan->desc = NULL;
557dc78baa2SNicolas Ferre 		return;
558dc78baa2SNicolas Ferre 	}
559dc78baa2SNicolas Ferre 
560dc78baa2SNicolas Ferre 	vdbg_dump_regs(atchan);
561dc78baa2SNicolas Ferre 
562ac803b56STudor Ambarus 	list_del(&vd->node);
563ac803b56STudor Ambarus 	atchan->desc = desc = to_atdma_desc(&vd->tx);
564ac803b56STudor Ambarus 
565dc78baa2SNicolas Ferre 	channel_writel(atchan, SADDR, 0);
566dc78baa2SNicolas Ferre 	channel_writel(atchan, DADDR, 0);
567dc78baa2SNicolas Ferre 	channel_writel(atchan, CTRLA, 0);
568dc78baa2SNicolas Ferre 	channel_writel(atchan, CTRLB, 0);
569ac803b56STudor Ambarus 	channel_writel(atchan, DSCR, desc->sg[0].lli_phys);
570ac803b56STudor Ambarus 	channel_writel(atchan, SPIP,
571ac803b56STudor Ambarus 		       FIELD_PREP(ATC_SPIP_HOLE, desc->src_hole) |
572ac803b56STudor Ambarus 		       FIELD_PREP(ATC_SPIP_BOUNDARY, desc->boundary));
573ac803b56STudor Ambarus 	channel_writel(atchan, DPIP,
574ac803b56STudor Ambarus 		       FIELD_PREP(ATC_DPIP_HOLE, desc->dst_hole) |
575ac803b56STudor Ambarus 		       FIELD_PREP(ATC_DPIP_BOUNDARY, desc->boundary));
576ac803b56STudor Ambarus 
577580ee844STudor Ambarus 	/* Don't allow CPU to reorder channel enable. */
578580ee844STudor Ambarus 	wmb();
579ac803b56STudor Ambarus 	dma_writel(atchan->atdma, CHER, atchan->mask);
580dc78baa2SNicolas Ferre 
581dc78baa2SNicolas Ferre 	vdbg_dump_regs(atchan);
582dc78baa2SNicolas Ferre }
583dc78baa2SNicolas Ferre 
atdma_desc_free(struct virt_dma_desc * vd)584ac803b56STudor Ambarus static void atdma_desc_free(struct virt_dma_desc *vd)
585d48de6f1SElen Song {
586ac803b56STudor Ambarus 	struct at_dma *atdma = to_at_dma(vd->tx.chan->device);
587ac803b56STudor Ambarus 	struct at_desc *desc = to_atdma_desc(&vd->tx);
588ac803b56STudor Ambarus 	unsigned int i;
589bdf6c792STorsten Fleischer 
590ac803b56STudor Ambarus 	for (i = 0; i < desc->sglen; i++) {
591ac803b56STudor Ambarus 		if (desc->sg[i].lli)
592ac803b56STudor Ambarus 			dma_pool_free(atdma->lli_pool, desc->sg[i].lli,
593ac803b56STudor Ambarus 				      desc->sg[i].lli_phys);
594bdf6c792STorsten Fleischer 	}
595d48de6f1SElen Song 
596ac803b56STudor Ambarus 	/* If the transfer was a memset, free our temporary buffer */
597ac803b56STudor Ambarus 	if (desc->memset_buffer) {
598ac803b56STudor Ambarus 		dma_pool_free(atdma->memset_pool, desc->memset_vaddr,
599ac803b56STudor Ambarus 			      desc->memset_paddr);
600ac803b56STudor Ambarus 		desc->memset_buffer = false;
601d48de6f1SElen Song 	}
602d48de6f1SElen Song 
603ac803b56STudor Ambarus 	kfree(desc);
604d48de6f1SElen Song }
605d48de6f1SElen Song 
606bdf6c792STorsten Fleischer /**
607bdf6c792STorsten Fleischer  * atc_calc_bytes_left - calculates the number of bytes left according to the
608bdf6c792STorsten Fleischer  * value read from CTRLA.
609bdf6c792STorsten Fleischer  *
610bdf6c792STorsten Fleischer  * @current_len: the number of bytes left before reading CTRLA
611bdf6c792STorsten Fleischer  * @ctrla: the value of CTRLA
612d48de6f1SElen Song  */
atc_calc_bytes_left(u32 current_len,u32 ctrla)613f5d79afaSTudor Ambarus static inline u32 atc_calc_bytes_left(u32 current_len, u32 ctrla)
614bdf6c792STorsten Fleischer {
615d8840a7eSTudor Ambarus 	u32 btsize = FIELD_GET(ATC_BTSIZE, ctrla);
616d8840a7eSTudor Ambarus 	u32 src_width = FIELD_GET(ATC_SRC_WIDTH, ctrla);
617bdf6c792STorsten Fleischer 
61893dce3a6SCyrille Pitchen 	/*
61993dce3a6SCyrille Pitchen 	 * According to the datasheet, when reading the Control A Register
62093dce3a6SCyrille Pitchen 	 * (ctrla), the Buffer Transfer Size (btsize) bitfield refers to the
62193dce3a6SCyrille Pitchen 	 * number of transfers completed on the Source Interface.
62293dce3a6SCyrille Pitchen 	 * So btsize is always a number of source width transfers.
623bdf6c792STorsten Fleischer 	 */
62493dce3a6SCyrille Pitchen 	return current_len - (btsize << src_width);
625bdf6c792STorsten Fleischer }
626bdf6c792STorsten Fleischer 
627bdf6c792STorsten Fleischer /**
628b50cf4bdSTudor Ambarus  * atc_get_llis_residue - Get residue for a hardware linked list transfer
629b50cf4bdSTudor Ambarus  *
630ac803b56STudor Ambarus  * Calculate the residue by removing the length of the Linked List Item (LLI)
631ac803b56STudor Ambarus  * already transferred from the total length. To get the current LLI we can use
632ac803b56STudor Ambarus  * the value of the channel's DSCR register and compare it against the DSCR
633ac803b56STudor Ambarus  * value of each LLI.
634b50cf4bdSTudor Ambarus  *
635b50cf4bdSTudor Ambarus  * The CTRLA register provides us with the amount of data already read from the
636ac803b56STudor Ambarus  * source for the LLI. So we can compute a more accurate residue by also
637ac803b56STudor Ambarus  * removing the number of bytes corresponding to this amount of data.
638b50cf4bdSTudor Ambarus  *
639b50cf4bdSTudor Ambarus  * However, the DSCR and CTRLA registers cannot be read both atomically. Hence a
640ac803b56STudor Ambarus  * race condition may occur: the first read register may refer to one LLI
641ac803b56STudor Ambarus  * whereas the second read may refer to a later LLI in the list because of the
642ac803b56STudor Ambarus  * DMA transfer progression inbetween the two reads.
643b50cf4bdSTudor Ambarus  *
644b50cf4bdSTudor Ambarus  * One solution could have been to pause the DMA transfer, read the DSCR and
645b50cf4bdSTudor Ambarus  * CTRLA then resume the DMA transfer. Nonetheless, this approach presents some
646b50cf4bdSTudor Ambarus  * drawbacks:
647b50cf4bdSTudor Ambarus  * - If the DMA transfer is paused, RX overruns or TX underruns are more likey
648b50cf4bdSTudor Ambarus  *   to occur depending on the system latency. Taking the USART driver as an
649b50cf4bdSTudor Ambarus  *   example, it uses a cyclic DMA transfer to read data from the Receive
650b50cf4bdSTudor Ambarus  *   Holding Register (RHR) to avoid RX overruns since the RHR is not protected
651b50cf4bdSTudor Ambarus  *   by any FIFO on most Atmel SoCs. So pausing the DMA transfer to compute the
652b50cf4bdSTudor Ambarus  *   residue would break the USART driver design.
653b50cf4bdSTudor Ambarus  * - The atc_pause() function masks interrupts but we'd rather avoid to do so
654b50cf4bdSTudor Ambarus  * for system latency purpose.
655b50cf4bdSTudor Ambarus  *
656b50cf4bdSTudor Ambarus  * Then we'd rather use another solution: the DSCR is read a first time, the
657b50cf4bdSTudor Ambarus  * CTRLA is read in turn, next the DSCR is read a second time. If the two
658b50cf4bdSTudor Ambarus  * consecutive read values of the DSCR are the same then we assume both refers
659ac803b56STudor Ambarus  * to the very same LLI as well as the CTRLA value read inbetween does. For
660ac803b56STudor Ambarus  * cyclic tranfers, the assumption is that a full loop is "not so fast". If the
661ac803b56STudor Ambarus  * two DSCR values are different, we read again the CTRLA then the DSCR till two
662ac803b56STudor Ambarus  * consecutive read values from DSCR are equal or till the maximum trials is
663ac803b56STudor Ambarus  * reach. This algorithm is very unlikely not to find a stable value for DSCR.
664b50cf4bdSTudor Ambarus  * @atchan: pointer to an atmel hdmac channel.
665b50cf4bdSTudor Ambarus  * @desc: pointer to the descriptor for which the residue is calculated.
666b50cf4bdSTudor Ambarus  * @residue: residue to be set to dma_tx_state.
667b50cf4bdSTudor Ambarus  * Returns 0 on success, -errno otherwise.
668b50cf4bdSTudor Ambarus  */
atc_get_llis_residue(struct at_dma_chan * atchan,struct at_desc * desc,u32 * residue)669b50cf4bdSTudor Ambarus static int atc_get_llis_residue(struct at_dma_chan *atchan,
670b50cf4bdSTudor Ambarus 				struct at_desc *desc, u32 *residue)
671b50cf4bdSTudor Ambarus {
672b50cf4bdSTudor Ambarus 	u32 len, ctrla, dscr;
673b50cf4bdSTudor Ambarus 	unsigned int i;
674b50cf4bdSTudor Ambarus 
675b50cf4bdSTudor Ambarus 	len = desc->total_len;
676b50cf4bdSTudor Ambarus 	dscr = channel_readl(atchan, DSCR);
677b50cf4bdSTudor Ambarus 	rmb(); /* ensure DSCR is read before CTRLA */
678b50cf4bdSTudor Ambarus 	ctrla = channel_readl(atchan, CTRLA);
679b50cf4bdSTudor Ambarus 	for (i = 0; i < ATC_MAX_DSCR_TRIALS; ++i) {
680b50cf4bdSTudor Ambarus 		u32 new_dscr;
681b50cf4bdSTudor Ambarus 
682b50cf4bdSTudor Ambarus 		rmb(); /* ensure DSCR is read after CTRLA */
683b50cf4bdSTudor Ambarus 		new_dscr = channel_readl(atchan, DSCR);
684b50cf4bdSTudor Ambarus 
685b50cf4bdSTudor Ambarus 		/*
686b50cf4bdSTudor Ambarus 		 * If the DSCR register value has not changed inside the DMA
687b50cf4bdSTudor Ambarus 		 * controller since the previous read, we assume that both the
688b50cf4bdSTudor Ambarus 		 * dscr and ctrla values refers to the very same descriptor.
689b50cf4bdSTudor Ambarus 		 */
690b50cf4bdSTudor Ambarus 		if (likely(new_dscr == dscr))
691b50cf4bdSTudor Ambarus 			break;
692b50cf4bdSTudor Ambarus 
693b50cf4bdSTudor Ambarus 		/*
694b50cf4bdSTudor Ambarus 		 * DSCR has changed inside the DMA controller, so the previouly
695b50cf4bdSTudor Ambarus 		 * read value of CTRLA may refer to an already processed
696b50cf4bdSTudor Ambarus 		 * descriptor hence could be outdated. We need to update ctrla
697b50cf4bdSTudor Ambarus 		 * to match the current descriptor.
698b50cf4bdSTudor Ambarus 		 */
699b50cf4bdSTudor Ambarus 		dscr = new_dscr;
700b50cf4bdSTudor Ambarus 		rmb(); /* ensure DSCR is read before CTRLA */
701b50cf4bdSTudor Ambarus 		ctrla = channel_readl(atchan, CTRLA);
702b50cf4bdSTudor Ambarus 	}
703b50cf4bdSTudor Ambarus 	if (unlikely(i == ATC_MAX_DSCR_TRIALS))
704b50cf4bdSTudor Ambarus 		return -ETIMEDOUT;
705b50cf4bdSTudor Ambarus 
706b50cf4bdSTudor Ambarus 	/* For the first descriptor we can be more accurate. */
707ac803b56STudor Ambarus 	if (desc->sg[0].lli->dscr == dscr) {
708b50cf4bdSTudor Ambarus 		*residue = atc_calc_bytes_left(len, ctrla);
709b50cf4bdSTudor Ambarus 		return 0;
710b50cf4bdSTudor Ambarus 	}
711ac803b56STudor Ambarus 	len -= desc->sg[0].len;
712b50cf4bdSTudor Ambarus 
713ac803b56STudor Ambarus 	for (i = 1; i < desc->sglen; i++) {
714ac803b56STudor Ambarus 		if (desc->sg[i].lli && desc->sg[i].lli->dscr == dscr)
715b50cf4bdSTudor Ambarus 			break;
716ac803b56STudor Ambarus 		len -= desc->sg[i].len;
717b50cf4bdSTudor Ambarus 	}
718b50cf4bdSTudor Ambarus 
719b50cf4bdSTudor Ambarus 	/*
720ac803b56STudor Ambarus 	 * For the current LLI in the chain we can calculate the remaining bytes
721ac803b56STudor Ambarus 	 * using the channel's CTRLA register.
722b50cf4bdSTudor Ambarus 	 */
723b50cf4bdSTudor Ambarus 	*residue = atc_calc_bytes_left(len, ctrla);
724b50cf4bdSTudor Ambarus 	return 0;
725ac803b56STudor Ambarus 
726b50cf4bdSTudor Ambarus }
727b50cf4bdSTudor Ambarus 
728b50cf4bdSTudor Ambarus /**
72991617bf6STudor Ambarus  * atc_get_residue - get the number of bytes residue for a cookie.
730f5d79afaSTudor Ambarus  * The residue is passed by address and updated on success.
731bdf6c792STorsten Fleischer  * @chan: DMA channel
732bdf6c792STorsten Fleischer  * @cookie: transaction identifier to check status of
733f5d79afaSTudor Ambarus  * @residue: residue to be updated.
734f5d79afaSTudor Ambarus  * Return 0 on success, -errono otherwise.
735bdf6c792STorsten Fleischer  */
atc_get_residue(struct dma_chan * chan,dma_cookie_t cookie,u32 * residue)73691617bf6STudor Ambarus static int atc_get_residue(struct dma_chan *chan, dma_cookie_t cookie,
737f5d79afaSTudor Ambarus 			   u32 *residue)
738d48de6f1SElen Song {
739d48de6f1SElen Song 	struct at_dma_chan *atchan = to_at_dma_chan(chan);
740ac803b56STudor Ambarus 	struct virt_dma_desc *vd;
741ac803b56STudor Ambarus 	struct at_desc *desc = NULL;
742b50cf4bdSTudor Ambarus 	u32 len, ctrla;
743d48de6f1SElen Song 
744ac803b56STudor Ambarus 	vd = vchan_find_desc(&atchan->vc, cookie);
745ac803b56STudor Ambarus 	if (vd)
746ac803b56STudor Ambarus 		desc = to_atdma_desc(&vd->tx);
747ac803b56STudor Ambarus 	else if (atchan->desc && atchan->desc->vd.tx.cookie == cookie)
748ac803b56STudor Ambarus 		desc = atchan->desc;
749bdf6c792STorsten Fleischer 
750ac803b56STudor Ambarus 	if (!desc)
751ac803b56STudor Ambarus 		return -EINVAL;
752ac803b56STudor Ambarus 
753ac803b56STudor Ambarus 	if (desc->sg[0].lli->dscr)
754bdf6c792STorsten Fleischer 		/* hardware linked list transfer */
755ac803b56STudor Ambarus 		return atc_get_llis_residue(atchan, desc, residue);
756d48de6f1SElen Song 
757bdf6c792STorsten Fleischer 	/* single transfer */
758ac803b56STudor Ambarus 	len = desc->total_len;
75993dce3a6SCyrille Pitchen 	ctrla = channel_readl(atchan, CTRLA);
760f5d79afaSTudor Ambarus 	*residue = atc_calc_bytes_left(len, ctrla);
761f5d79afaSTudor Ambarus 	return 0;
762d48de6f1SElen Song }
763d48de6f1SElen Song 
764dc78baa2SNicolas Ferre /**
765dc78baa2SNicolas Ferre  * atc_handle_error - handle errors reported by DMA controller
766ac803b56STudor Ambarus  * @atchan: channel where error occurs.
767ac803b56STudor Ambarus  * @i: channel index
768dc78baa2SNicolas Ferre  */
atc_handle_error(struct at_dma_chan * atchan,unsigned int i)769ac803b56STudor Ambarus static void atc_handle_error(struct at_dma_chan *atchan, unsigned int i)
770dc78baa2SNicolas Ferre {
771ac803b56STudor Ambarus 	struct at_desc *desc = atchan->desc;
772dc78baa2SNicolas Ferre 
773ac803b56STudor Ambarus 	/* Disable channel on AHB error */
774ac803b56STudor Ambarus 	dma_writel(atchan->atdma, CHDR, AT_DMA_RES(i) | atchan->mask);
7754c2e9ba0STudor Ambarus 
776dc78baa2SNicolas Ferre 	/*
777dc78baa2SNicolas Ferre 	 * KERN_CRITICAL may seem harsh, but since this only happens
778dc78baa2SNicolas Ferre 	 * when someone submits a bad physical address in a
779dc78baa2SNicolas Ferre 	 * descriptor, we should consider ourselves lucky that the
780dc78baa2SNicolas Ferre 	 * controller flagged an error instead of scribbling over
781dc78baa2SNicolas Ferre 	 * random memory locations.
782dc78baa2SNicolas Ferre 	 */
783ac803b56STudor Ambarus 	dev_crit(chan2dev(&atchan->vc.chan), "Bad descriptor submitted for DMA!\n");
784ac803b56STudor Ambarus 	dev_crit(chan2dev(&atchan->vc.chan), "cookie: %d\n",
785ac803b56STudor Ambarus 		 desc->vd.tx.cookie);
786ac803b56STudor Ambarus 	for (i = 0; i < desc->sglen; i++)
787ac803b56STudor Ambarus 		atc_dump_lli(atchan, desc->sg[i].lli);
788ac803b56STudor Ambarus }
789dc78baa2SNicolas Ferre 
atdma_handle_chan_done(struct at_dma_chan * atchan,u32 pending,unsigned int i)790ac803b56STudor Ambarus static void atdma_handle_chan_done(struct at_dma_chan *atchan, u32 pending,
791ac803b56STudor Ambarus 				   unsigned int i)
792ac803b56STudor Ambarus {
793ac803b56STudor Ambarus 	struct at_desc *desc;
794ac803b56STudor Ambarus 
795ac803b56STudor Ambarus 	spin_lock(&atchan->vc.lock);
796ac803b56STudor Ambarus 	desc = atchan->desc;
797ac803b56STudor Ambarus 
798ac803b56STudor Ambarus 	if (desc) {
799ac803b56STudor Ambarus 		if (pending & AT_DMA_ERR(i)) {
800ac803b56STudor Ambarus 			atc_handle_error(atchan, i);
801dc78baa2SNicolas Ferre 			/* Pretend the descriptor completed successfully */
802dc78baa2SNicolas Ferre 		}
803dc78baa2SNicolas Ferre 
804ac803b56STudor Ambarus 		if (atc_chan_is_cyclic(atchan)) {
805ac803b56STudor Ambarus 			vchan_cyclic_callback(&desc->vd);
806ac803b56STudor Ambarus 		} else {
807ac803b56STudor Ambarus 			vchan_cookie_complete(&desc->vd);
808ac803b56STudor Ambarus 			atchan->desc = NULL;
809ac803b56STudor Ambarus 			if (!(atc_chan_is_enabled(atchan)))
810ac803b56STudor Ambarus 				atc_dostart(atchan);
81153830cc7SNicolas Ferre 		}
812ac803b56STudor Ambarus 	}
813ac803b56STudor Ambarus 	spin_unlock(&atchan->vc.lock);
814dc78baa2SNicolas Ferre }
815dc78baa2SNicolas Ferre 
at_dma_interrupt(int irq,void * dev_id)816dc78baa2SNicolas Ferre static irqreturn_t at_dma_interrupt(int irq, void *dev_id)
817dc78baa2SNicolas Ferre {
8180e75c28cSTudor Ambarus 	struct at_dma		*atdma = dev_id;
819dc78baa2SNicolas Ferre 	struct at_dma_chan	*atchan;
820dc78baa2SNicolas Ferre 	int			i;
821dc78baa2SNicolas Ferre 	u32			status, pending, imr;
822dc78baa2SNicolas Ferre 	int			ret = IRQ_NONE;
823dc78baa2SNicolas Ferre 
824dc78baa2SNicolas Ferre 	do {
825dc78baa2SNicolas Ferre 		imr = dma_readl(atdma, EBCIMR);
826dc78baa2SNicolas Ferre 		status = dma_readl(atdma, EBCISR);
827dc78baa2SNicolas Ferre 		pending = status & imr;
828dc78baa2SNicolas Ferre 
829dc78baa2SNicolas Ferre 		if (!pending)
830dc78baa2SNicolas Ferre 			break;
831dc78baa2SNicolas Ferre 
8321c1114d8STudor Ambarus 		dev_vdbg(atdma->dma_device.dev,
833dc78baa2SNicolas Ferre 			"interrupt: status = 0x%08x, 0x%08x, 0x%08x\n",
834dc78baa2SNicolas Ferre 			 status, imr, pending);
835dc78baa2SNicolas Ferre 
8361c1114d8STudor Ambarus 		for (i = 0; i < atdma->dma_device.chancnt; i++) {
837dc78baa2SNicolas Ferre 			atchan = &atdma->chan[i];
838ac803b56STudor Ambarus 			if (!(pending & (AT_DMA_BTC(i) | AT_DMA_ERR(i))))
839ac803b56STudor Ambarus 				continue;
840ac803b56STudor Ambarus 			atdma_handle_chan_done(atchan, pending, i);
841dc78baa2SNicolas Ferre 			ret = IRQ_HANDLED;
842dc78baa2SNicolas Ferre 		}
843dc78baa2SNicolas Ferre 
844dc78baa2SNicolas Ferre 	} while (pending);
845dc78baa2SNicolas Ferre 
846dc78baa2SNicolas Ferre 	return ret;
847dc78baa2SNicolas Ferre }
848dc78baa2SNicolas Ferre 
849dc78baa2SNicolas Ferre /*--  DMA Engine API  --------------------------------------------------*/
850dc78baa2SNicolas Ferre /**
8515abecfa5SMaxime Ripard  * atc_prep_dma_interleaved - prepare memory to memory interleaved operation
8525abecfa5SMaxime Ripard  * @chan: the channel to prepare operation on
8535abecfa5SMaxime Ripard  * @xt: Interleaved transfer template
8545abecfa5SMaxime Ripard  * @flags: tx descriptor status flags
8555abecfa5SMaxime Ripard  */
8565abecfa5SMaxime Ripard static struct dma_async_tx_descriptor *
atc_prep_dma_interleaved(struct dma_chan * chan,struct dma_interleaved_template * xt,unsigned long flags)8575abecfa5SMaxime Ripard atc_prep_dma_interleaved(struct dma_chan *chan,
8585abecfa5SMaxime Ripard 			 struct dma_interleaved_template *xt,
8595abecfa5SMaxime Ripard 			 unsigned long flags)
8605abecfa5SMaxime Ripard {
861ac803b56STudor Ambarus 	struct at_dma		*atdma = to_at_dma(chan->device);
8625abecfa5SMaxime Ripard 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
86362a277d4SGustavo A. R. Silva 	struct data_chunk	*first;
864ac803b56STudor Ambarus 	struct atdma_sg		*atdma_sg;
865ac803b56STudor Ambarus 	struct at_desc		*desc;
866ac803b56STudor Ambarus 	struct at_lli		*lli;
8675abecfa5SMaxime Ripard 	size_t			xfer_count;
8685abecfa5SMaxime Ripard 	unsigned int		dwidth;
8695abecfa5SMaxime Ripard 	u32			ctrla;
8705abecfa5SMaxime Ripard 	u32			ctrlb;
8715abecfa5SMaxime Ripard 	size_t			len = 0;
8725abecfa5SMaxime Ripard 	int			i;
8735abecfa5SMaxime Ripard 
8744483320eSManinder Singh 	if (unlikely(!xt || xt->numf != 1 || !xt->frame_size))
8754483320eSManinder Singh 		return NULL;
8764483320eSManinder Singh 
87762a277d4SGustavo A. R. Silva 	first = xt->sgl;
87862a277d4SGustavo A. R. Silva 
8795abecfa5SMaxime Ripard 	dev_info(chan2dev(chan),
8802c5d7407SArnd Bergmann 		 "%s: src=%pad, dest=%pad, numf=%d, frame_size=%d, flags=0x%lx\n",
8812c5d7407SArnd Bergmann 		__func__, &xt->src_start, &xt->dst_start, xt->numf,
8825abecfa5SMaxime Ripard 		xt->frame_size, flags);
8835abecfa5SMaxime Ripard 
8845abecfa5SMaxime Ripard 	/*
8855abecfa5SMaxime Ripard 	 * The controller can only "skip" X bytes every Y bytes, so we
8865abecfa5SMaxime Ripard 	 * need to make sure we are given a template that fit that
8875abecfa5SMaxime Ripard 	 * description, ie a template with chunks that always have the
8885abecfa5SMaxime Ripard 	 * same size, with the same ICGs.
8895abecfa5SMaxime Ripard 	 */
8905abecfa5SMaxime Ripard 	for (i = 0; i < xt->frame_size; i++) {
8915abecfa5SMaxime Ripard 		struct data_chunk *chunk = xt->sgl + i;
8925abecfa5SMaxime Ripard 
8935abecfa5SMaxime Ripard 		if ((chunk->size != xt->sgl->size) ||
8945abecfa5SMaxime Ripard 		    (dmaengine_get_dst_icg(xt, chunk) != dmaengine_get_dst_icg(xt, first)) ||
8955abecfa5SMaxime Ripard 		    (dmaengine_get_src_icg(xt, chunk) != dmaengine_get_src_icg(xt, first))) {
8965abecfa5SMaxime Ripard 			dev_err(chan2dev(chan),
8975abecfa5SMaxime Ripard 				"%s: the controller can transfer only identical chunks\n",
8985abecfa5SMaxime Ripard 				__func__);
8995abecfa5SMaxime Ripard 			return NULL;
9005abecfa5SMaxime Ripard 		}
9015abecfa5SMaxime Ripard 
9025abecfa5SMaxime Ripard 		len += chunk->size;
9035abecfa5SMaxime Ripard 	}
9045abecfa5SMaxime Ripard 
905ac803b56STudor Ambarus 	dwidth = atc_get_xfer_width(xt->src_start, xt->dst_start, len);
9065abecfa5SMaxime Ripard 
9075abecfa5SMaxime Ripard 	xfer_count = len >> dwidth;
9085abecfa5SMaxime Ripard 	if (xfer_count > ATC_BTSIZE_MAX) {
9095abecfa5SMaxime Ripard 		dev_err(chan2dev(chan), "%s: buffer is too big\n", __func__);
9105abecfa5SMaxime Ripard 		return NULL;
9115abecfa5SMaxime Ripard 	}
9125abecfa5SMaxime Ripard 
913d8840a7eSTudor Ambarus 	ctrla = FIELD_PREP(ATC_SRC_WIDTH, dwidth) |
914d8840a7eSTudor Ambarus 		FIELD_PREP(ATC_DST_WIDTH, dwidth);
9155abecfa5SMaxime Ripard 
916d8840a7eSTudor Ambarus 	ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN |
917d8840a7eSTudor Ambarus 		FIELD_PREP(ATC_SRC_ADDR_MODE, ATC_SRC_ADDR_MODE_INCR) |
918d8840a7eSTudor Ambarus 		FIELD_PREP(ATC_DST_ADDR_MODE, ATC_DST_ADDR_MODE_INCR) |
919d8840a7eSTudor Ambarus 		ATC_SRC_PIP | ATC_DST_PIP |
920d8840a7eSTudor Ambarus 		FIELD_PREP(ATC_FC, ATC_FC_MEM2MEM);
9215abecfa5SMaxime Ripard 
922ac803b56STudor Ambarus 	desc = kzalloc(struct_size(desc, sg, 1), GFP_ATOMIC);
923ac803b56STudor Ambarus 	if (!desc)
924ac803b56STudor Ambarus 		return NULL;
925ac803b56STudor Ambarus 	desc->sglen = 1;
926ac803b56STudor Ambarus 
927ac803b56STudor Ambarus 	atdma_sg = desc->sg;
928ac803b56STudor Ambarus 	atdma_sg->lli = dma_pool_alloc(atdma->lli_pool, GFP_NOWAIT,
929ac803b56STudor Ambarus 				       &atdma_sg->lli_phys);
930ac803b56STudor Ambarus 	if (!atdma_sg->lli) {
931ac803b56STudor Ambarus 		kfree(desc);
9325abecfa5SMaxime Ripard 		return NULL;
9335abecfa5SMaxime Ripard 	}
934ac803b56STudor Ambarus 	lli = atdma_sg->lli;
9355abecfa5SMaxime Ripard 
936ac803b56STudor Ambarus 	lli->saddr = xt->src_start;
937ac803b56STudor Ambarus 	lli->daddr = xt->dst_start;
938ac803b56STudor Ambarus 	lli->ctrla = ctrla | xfer_count;
939ac803b56STudor Ambarus 	lli->ctrlb = ctrlb;
9405abecfa5SMaxime Ripard 
9415abecfa5SMaxime Ripard 	desc->boundary = first->size >> dwidth;
9425abecfa5SMaxime Ripard 	desc->dst_hole = (dmaengine_get_dst_icg(xt, first) >> dwidth) + 1;
9435abecfa5SMaxime Ripard 	desc->src_hole = (dmaengine_get_src_icg(xt, first) >> dwidth) + 1;
9445abecfa5SMaxime Ripard 
945ac803b56STudor Ambarus 	atdma_sg->len = len;
946ac803b56STudor Ambarus 	desc->total_len = len;
9475abecfa5SMaxime Ripard 
948ac803b56STudor Ambarus 	set_lli_eol(desc, 0);
949ac803b56STudor Ambarus 	return vchan_tx_prep(&atchan->vc, &desc->vd, flags);
9505abecfa5SMaxime Ripard }
9515abecfa5SMaxime Ripard 
9525abecfa5SMaxime Ripard /**
953dc78baa2SNicolas Ferre  * atc_prep_dma_memcpy - prepare a memcpy operation
954dc78baa2SNicolas Ferre  * @chan: the channel to prepare operation on
955dc78baa2SNicolas Ferre  * @dest: operation virtual destination address
956dc78baa2SNicolas Ferre  * @src: operation virtual source address
957dc78baa2SNicolas Ferre  * @len: operation length
958dc78baa2SNicolas Ferre  * @flags: tx descriptor status flags
959dc78baa2SNicolas Ferre  */
960dc78baa2SNicolas Ferre static struct dma_async_tx_descriptor *
atc_prep_dma_memcpy(struct dma_chan * chan,dma_addr_t dest,dma_addr_t src,size_t len,unsigned long flags)961dc78baa2SNicolas Ferre atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
962dc78baa2SNicolas Ferre 		size_t len, unsigned long flags)
963dc78baa2SNicolas Ferre {
964ac803b56STudor Ambarus 	struct at_dma		*atdma = to_at_dma(chan->device);
965dc78baa2SNicolas Ferre 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
966dc78baa2SNicolas Ferre 	struct at_desc		*desc = NULL;
967dc78baa2SNicolas Ferre 	size_t			xfer_count;
968dc78baa2SNicolas Ferre 	size_t			offset;
969ac803b56STudor Ambarus 	size_t			sg_len;
970dc78baa2SNicolas Ferre 	unsigned int		src_width;
971dc78baa2SNicolas Ferre 	unsigned int		dst_width;
972ac803b56STudor Ambarus 	unsigned int		i;
973dc78baa2SNicolas Ferre 	u32			ctrla;
974dc78baa2SNicolas Ferre 	u32			ctrlb;
975dc78baa2SNicolas Ferre 
976ac803b56STudor Ambarus 	dev_dbg(chan2dev(chan), "prep_dma_memcpy: d%pad s%pad l0x%zx f0x%lx\n",
9772c5d7407SArnd Bergmann 		&dest, &src, len, flags);
978dc78baa2SNicolas Ferre 
979dc78baa2SNicolas Ferre 	if (unlikely(!len)) {
980ac803b56STudor Ambarus 		dev_err(chan2dev(chan), "prep_dma_memcpy: length is zero!\n");
981dc78baa2SNicolas Ferre 		return NULL;
982dc78baa2SNicolas Ferre 	}
983dc78baa2SNicolas Ferre 
984ac803b56STudor Ambarus 	sg_len = DIV_ROUND_UP(len, ATC_BTSIZE_MAX);
985ac803b56STudor Ambarus 	desc = kzalloc(struct_size(desc, sg, sg_len), GFP_ATOMIC);
986ac803b56STudor Ambarus 	if (!desc)
987ac803b56STudor Ambarus 		return NULL;
988ac803b56STudor Ambarus 	desc->sglen = sg_len;
989ac803b56STudor Ambarus 
990d8840a7eSTudor Ambarus 	ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN |
991d8840a7eSTudor Ambarus 		FIELD_PREP(ATC_SRC_ADDR_MODE, ATC_SRC_ADDR_MODE_INCR) |
992d8840a7eSTudor Ambarus 		FIELD_PREP(ATC_DST_ADDR_MODE, ATC_DST_ADDR_MODE_INCR) |
993d8840a7eSTudor Ambarus 		FIELD_PREP(ATC_FC, ATC_FC_MEM2MEM);
994dc78baa2SNicolas Ferre 
995dc78baa2SNicolas Ferre 	/*
996dc78baa2SNicolas Ferre 	 * We can be a lot more clever here, but this should take care
997dc78baa2SNicolas Ferre 	 * of the most common optimization.
998dc78baa2SNicolas Ferre 	 */
999265567fbSTorsten Fleischer 	src_width = dst_width = atc_get_xfer_width(src, dest, len);
1000265567fbSTorsten Fleischer 
1001d8840a7eSTudor Ambarus 	ctrla = FIELD_PREP(ATC_SRC_WIDTH, src_width) |
1002d8840a7eSTudor Ambarus 		FIELD_PREP(ATC_DST_WIDTH, dst_width);
1003dc78baa2SNicolas Ferre 
1004ac803b56STudor Ambarus 	for (offset = 0, i = 0; offset < len;
1005ac803b56STudor Ambarus 	     offset += xfer_count << src_width, i++) {
1006ac803b56STudor Ambarus 		struct atdma_sg *atdma_sg = &desc->sg[i];
1007ac803b56STudor Ambarus 		struct at_lli *lli;
1008ac803b56STudor Ambarus 
1009ac803b56STudor Ambarus 		atdma_sg->lli = dma_pool_alloc(atdma->lli_pool, GFP_NOWAIT,
1010ac803b56STudor Ambarus 					       &atdma_sg->lli_phys);
1011ac803b56STudor Ambarus 		if (!atdma_sg->lli)
1012ac803b56STudor Ambarus 			goto err_desc_get;
1013ac803b56STudor Ambarus 		lli = atdma_sg->lli;
1014ac803b56STudor Ambarus 
1015dc78baa2SNicolas Ferre 		xfer_count = min_t(size_t, (len - offset) >> src_width,
1016dc78baa2SNicolas Ferre 				   ATC_BTSIZE_MAX);
1017dc78baa2SNicolas Ferre 
1018ac803b56STudor Ambarus 		lli->saddr = src + offset;
1019ac803b56STudor Ambarus 		lli->daddr = dest + offset;
1020ac803b56STudor Ambarus 		lli->ctrla = ctrla | xfer_count;
1021ac803b56STudor Ambarus 		lli->ctrlb = ctrlb;
1022dc78baa2SNicolas Ferre 
1023ac803b56STudor Ambarus 		desc->sg[i].len = xfer_count << src_width;
1024dc78baa2SNicolas Ferre 
1025ac803b56STudor Ambarus 		atdma_lli_chain(desc, i);
1026dc78baa2SNicolas Ferre 	}
1027dc78baa2SNicolas Ferre 
1028ac803b56STudor Ambarus 	desc->total_len = len;
1029bdf6c792STorsten Fleischer 
1030dc78baa2SNicolas Ferre 	/* set end-of-link to the last link descriptor of list*/
1031ac803b56STudor Ambarus 	set_lli_eol(desc, i - 1);
1032dc78baa2SNicolas Ferre 
1033ac803b56STudor Ambarus 	return vchan_tx_prep(&atchan->vc, &desc->vd, flags);
1034dc78baa2SNicolas Ferre 
1035dc78baa2SNicolas Ferre err_desc_get:
1036ac803b56STudor Ambarus 	atdma_desc_free(&desc->vd);
1037dc78baa2SNicolas Ferre 	return NULL;
1038dc78baa2SNicolas Ferre }
1039dc78baa2SNicolas Ferre 
atdma_create_memset_lli(struct dma_chan * chan,struct atdma_sg * atdma_sg,dma_addr_t psrc,dma_addr_t pdst,size_t len)1040ac803b56STudor Ambarus static int atdma_create_memset_lli(struct dma_chan *chan,
1041ac803b56STudor Ambarus 				   struct atdma_sg *atdma_sg,
1042ac803b56STudor Ambarus 				   dma_addr_t psrc, dma_addr_t pdst, size_t len)
1043ce2a673dSMaxime Ripard {
1044ac803b56STudor Ambarus 	struct at_dma *atdma = to_at_dma(chan->device);
1045ac803b56STudor Ambarus 	struct at_lli *lli;
1046ce2a673dSMaxime Ripard 	size_t xfer_count;
1047d8840a7eSTudor Ambarus 	u32 ctrla = FIELD_PREP(ATC_SRC_WIDTH, 2) | FIELD_PREP(ATC_DST_WIDTH, 2);
1048ce2a673dSMaxime Ripard 	u32 ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN |
1049d8840a7eSTudor Ambarus 		    FIELD_PREP(ATC_SRC_ADDR_MODE, ATC_SRC_ADDR_MODE_FIXED) |
1050d8840a7eSTudor Ambarus 		    FIELD_PREP(ATC_DST_ADDR_MODE, ATC_DST_ADDR_MODE_INCR) |
1051d8840a7eSTudor Ambarus 		    FIELD_PREP(ATC_FC, ATC_FC_MEM2MEM);
1052ce2a673dSMaxime Ripard 
1053ce2a673dSMaxime Ripard 	xfer_count = len >> 2;
1054ce2a673dSMaxime Ripard 	if (xfer_count > ATC_BTSIZE_MAX) {
1055ac803b56STudor Ambarus 		dev_err(chan2dev(chan), "%s: buffer is too big\n", __func__);
1056ac803b56STudor Ambarus 		return -EINVAL;
1057ce2a673dSMaxime Ripard 	}
1058ce2a673dSMaxime Ripard 
1059ac803b56STudor Ambarus 	atdma_sg->lli = dma_pool_alloc(atdma->lli_pool, GFP_NOWAIT,
1060ac803b56STudor Ambarus 				       &atdma_sg->lli_phys);
1061ac803b56STudor Ambarus 	if (!atdma_sg->lli)
1062ac803b56STudor Ambarus 		return -ENOMEM;
1063ac803b56STudor Ambarus 	lli = atdma_sg->lli;
1064ce2a673dSMaxime Ripard 
1065ac803b56STudor Ambarus 	lli->saddr = psrc;
1066ac803b56STudor Ambarus 	lli->daddr = pdst;
1067ac803b56STudor Ambarus 	lli->ctrla = ctrla | xfer_count;
1068ac803b56STudor Ambarus 	lli->ctrlb = ctrlb;
1069ce2a673dSMaxime Ripard 
1070ac803b56STudor Ambarus 	atdma_sg->len = len;
1071ce2a673dSMaxime Ripard 
1072ac803b56STudor Ambarus 	return 0;
1073ce2a673dSMaxime Ripard }
1074ce2a673dSMaxime Ripard 
10754d112426SMaxime Ripard /**
10764d112426SMaxime Ripard  * atc_prep_dma_memset - prepare a memcpy operation
10774d112426SMaxime Ripard  * @chan: the channel to prepare operation on
10784d112426SMaxime Ripard  * @dest: operation virtual destination address
10794d112426SMaxime Ripard  * @value: value to set memory buffer to
10804d112426SMaxime Ripard  * @len: operation length
10814d112426SMaxime Ripard  * @flags: tx descriptor status flags
10824d112426SMaxime Ripard  */
10834d112426SMaxime Ripard static struct dma_async_tx_descriptor *
atc_prep_dma_memset(struct dma_chan * chan,dma_addr_t dest,int value,size_t len,unsigned long flags)10844d112426SMaxime Ripard atc_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value,
10854d112426SMaxime Ripard 		    size_t len, unsigned long flags)
10864d112426SMaxime Ripard {
1087ac803b56STudor Ambarus 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
10884d112426SMaxime Ripard 	struct at_dma		*atdma = to_at_dma(chan->device);
1089ce2a673dSMaxime Ripard 	struct at_desc		*desc;
1090ce2a673dSMaxime Ripard 	void __iomem		*vaddr;
1091ce2a673dSMaxime Ripard 	dma_addr_t		paddr;
1092ceabe10cSBen Walker 	char			fill_pattern;
1093ac803b56STudor Ambarus 	int			ret;
10944d112426SMaxime Ripard 
10952c5d7407SArnd Bergmann 	dev_vdbg(chan2dev(chan), "%s: d%pad v0x%x l0x%zx f0x%lx\n", __func__,
10962c5d7407SArnd Bergmann 		&dest, value, len, flags);
10974d112426SMaxime Ripard 
10984d112426SMaxime Ripard 	if (unlikely(!len)) {
10994d112426SMaxime Ripard 		dev_dbg(chan2dev(chan), "%s: length is zero!\n", __func__);
11004d112426SMaxime Ripard 		return NULL;
11014d112426SMaxime Ripard 	}
11024d112426SMaxime Ripard 
11034d112426SMaxime Ripard 	if (!is_dma_fill_aligned(chan->device, dest, 0, len)) {
11044d112426SMaxime Ripard 		dev_dbg(chan2dev(chan), "%s: buffer is not aligned\n",
11054d112426SMaxime Ripard 			__func__);
11064d112426SMaxime Ripard 		return NULL;
11074d112426SMaxime Ripard 	}
11084d112426SMaxime Ripard 
1109247b4d83STudor Ambarus 	vaddr = dma_pool_alloc(atdma->memset_pool, GFP_NOWAIT, &paddr);
1110ce2a673dSMaxime Ripard 	if (!vaddr) {
11114d112426SMaxime Ripard 		dev_err(chan2dev(chan), "%s: couldn't allocate buffer\n",
11124d112426SMaxime Ripard 			__func__);
1113ce2a673dSMaxime Ripard 		return NULL;
1114ce2a673dSMaxime Ripard 	}
1115ceabe10cSBen Walker 
1116ceabe10cSBen Walker 	/* Only the first byte of value is to be used according to dmaengine */
1117ceabe10cSBen Walker 	fill_pattern = (char)value;
1118ceabe10cSBen Walker 
1119ceabe10cSBen Walker 	*(u32*)vaddr = (fill_pattern << 24) |
1120ceabe10cSBen Walker 		       (fill_pattern << 16) |
1121ceabe10cSBen Walker 		       (fill_pattern << 8) |
1122ceabe10cSBen Walker 		       fill_pattern;
1123ce2a673dSMaxime Ripard 
1124ac803b56STudor Ambarus 	desc = kzalloc(struct_size(desc, sg, 1), GFP_ATOMIC);
1125ac803b56STudor Ambarus 	if (!desc)
1126ce2a673dSMaxime Ripard 		goto err_free_buffer;
1127ac803b56STudor Ambarus 	desc->sglen = 1;
1128ac803b56STudor Ambarus 
1129ac803b56STudor Ambarus 	ret = atdma_create_memset_lli(chan, desc->sg, paddr, dest, len);
1130ac803b56STudor Ambarus 	if (ret)
1131ac803b56STudor Ambarus 		goto err_free_desc;
11324d112426SMaxime Ripard 
1133ce2a673dSMaxime Ripard 	desc->memset_paddr = paddr;
1134ce2a673dSMaxime Ripard 	desc->memset_vaddr = vaddr;
1135ce2a673dSMaxime Ripard 	desc->memset_buffer = true;
11364d112426SMaxime Ripard 
11374d112426SMaxime Ripard 	desc->total_len = len;
11384d112426SMaxime Ripard 
11394d112426SMaxime Ripard 	/* set end-of-link on the descriptor */
1140ac803b56STudor Ambarus 	set_lli_eol(desc, 0);
11414d112426SMaxime Ripard 
1142ac803b56STudor Ambarus 	return vchan_tx_prep(&atchan->vc, &desc->vd, flags);
11434d112426SMaxime Ripard 
1144ac803b56STudor Ambarus err_free_desc:
1145ac803b56STudor Ambarus 	kfree(desc);
1146ce2a673dSMaxime Ripard err_free_buffer:
1147ce2a673dSMaxime Ripard 	dma_pool_free(atdma->memset_pool, vaddr, paddr);
11484d112426SMaxime Ripard 	return NULL;
11494d112426SMaxime Ripard }
11504d112426SMaxime Ripard 
115167d25f0dSMaxime Ripard static struct dma_async_tx_descriptor *
atc_prep_dma_memset_sg(struct dma_chan * chan,struct scatterlist * sgl,unsigned int sg_len,int value,unsigned long flags)115267d25f0dSMaxime Ripard atc_prep_dma_memset_sg(struct dma_chan *chan,
115367d25f0dSMaxime Ripard 		       struct scatterlist *sgl,
115467d25f0dSMaxime Ripard 		       unsigned int sg_len, int value,
115567d25f0dSMaxime Ripard 		       unsigned long flags)
115667d25f0dSMaxime Ripard {
115767d25f0dSMaxime Ripard 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
115867d25f0dSMaxime Ripard 	struct at_dma		*atdma = to_at_dma(chan->device);
1159ac803b56STudor Ambarus 	struct at_desc		*desc;
116067d25f0dSMaxime Ripard 	struct scatterlist	*sg;
116167d25f0dSMaxime Ripard 	void __iomem		*vaddr;
116267d25f0dSMaxime Ripard 	dma_addr_t		paddr;
116367d25f0dSMaxime Ripard 	size_t			total_len = 0;
116467d25f0dSMaxime Ripard 	int			i;
1165ac803b56STudor Ambarus 	int			ret;
116667d25f0dSMaxime Ripard 
116767d25f0dSMaxime Ripard 	dev_vdbg(chan2dev(chan), "%s: v0x%x l0x%zx f0x%lx\n", __func__,
116867d25f0dSMaxime Ripard 		 value, sg_len, flags);
116967d25f0dSMaxime Ripard 
117067d25f0dSMaxime Ripard 	if (unlikely(!sgl || !sg_len)) {
117167d25f0dSMaxime Ripard 		dev_dbg(chan2dev(chan), "%s: scatterlist is empty!\n",
117267d25f0dSMaxime Ripard 			__func__);
117367d25f0dSMaxime Ripard 		return NULL;
117467d25f0dSMaxime Ripard 	}
117567d25f0dSMaxime Ripard 
1176247b4d83STudor Ambarus 	vaddr = dma_pool_alloc(atdma->memset_pool, GFP_NOWAIT, &paddr);
117767d25f0dSMaxime Ripard 	if (!vaddr) {
117867d25f0dSMaxime Ripard 		dev_err(chan2dev(chan), "%s: couldn't allocate buffer\n",
117967d25f0dSMaxime Ripard 			__func__);
118067d25f0dSMaxime Ripard 		return NULL;
118167d25f0dSMaxime Ripard 	}
118267d25f0dSMaxime Ripard 	*(u32*)vaddr = value;
118367d25f0dSMaxime Ripard 
1184ac803b56STudor Ambarus 	desc = kzalloc(struct_size(desc, sg, sg_len), GFP_ATOMIC);
1185ac803b56STudor Ambarus 	if (!desc)
1186ac803b56STudor Ambarus 		goto err_free_dma_buf;
1187ac803b56STudor Ambarus 	desc->sglen = sg_len;
1188ac803b56STudor Ambarus 
118967d25f0dSMaxime Ripard 	for_each_sg(sgl, sg, sg_len, i) {
119067d25f0dSMaxime Ripard 		dma_addr_t dest = sg_dma_address(sg);
119167d25f0dSMaxime Ripard 		size_t len = sg_dma_len(sg);
119267d25f0dSMaxime Ripard 
11932c5d7407SArnd Bergmann 		dev_vdbg(chan2dev(chan), "%s: d%pad, l0x%zx\n",
11942c5d7407SArnd Bergmann 			 __func__, &dest, len);
119567d25f0dSMaxime Ripard 
119667d25f0dSMaxime Ripard 		if (!is_dma_fill_aligned(chan->device, dest, 0, len)) {
119767d25f0dSMaxime Ripard 			dev_err(chan2dev(chan), "%s: buffer is not aligned\n",
119867d25f0dSMaxime Ripard 				__func__);
1199ac803b56STudor Ambarus 			goto err_free_desc;
120067d25f0dSMaxime Ripard 		}
120167d25f0dSMaxime Ripard 
1202ac803b56STudor Ambarus 		ret = atdma_create_memset_lli(chan, &desc->sg[i], paddr, dest,
1203ac803b56STudor Ambarus 					      len);
1204ac803b56STudor Ambarus 		if (ret)
1205ac803b56STudor Ambarus 			goto err_free_desc;
120667d25f0dSMaxime Ripard 
1207ac803b56STudor Ambarus 		atdma_lli_chain(desc, i);
120867d25f0dSMaxime Ripard 		total_len += len;
120967d25f0dSMaxime Ripard 	}
121067d25f0dSMaxime Ripard 
121167d25f0dSMaxime Ripard 	desc->memset_paddr = paddr;
121267d25f0dSMaxime Ripard 	desc->memset_vaddr = vaddr;
121367d25f0dSMaxime Ripard 	desc->memset_buffer = true;
121467d25f0dSMaxime Ripard 
1215ac803b56STudor Ambarus 	desc->total_len = total_len;
121667d25f0dSMaxime Ripard 
121767d25f0dSMaxime Ripard 	/* set end-of-link on the descriptor */
1218ac803b56STudor Ambarus 	set_lli_eol(desc, i - 1);
121967d25f0dSMaxime Ripard 
1220ac803b56STudor Ambarus 	return vchan_tx_prep(&atchan->vc, &desc->vd, flags);
122167d25f0dSMaxime Ripard 
1222ac803b56STudor Ambarus err_free_desc:
1223ac803b56STudor Ambarus 	atdma_desc_free(&desc->vd);
1224ac803b56STudor Ambarus err_free_dma_buf:
1225ac803b56STudor Ambarus 	dma_pool_free(atdma->memset_pool, vaddr, paddr);
122667d25f0dSMaxime Ripard 	return NULL;
122767d25f0dSMaxime Ripard }
122867d25f0dSMaxime Ripard 
1229808347f6SNicolas Ferre /**
1230808347f6SNicolas Ferre  * atc_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction
1231808347f6SNicolas Ferre  * @chan: DMA channel
1232808347f6SNicolas Ferre  * @sgl: scatterlist to transfer to/from
1233808347f6SNicolas Ferre  * @sg_len: number of entries in @scatterlist
1234808347f6SNicolas Ferre  * @direction: DMA direction
1235808347f6SNicolas Ferre  * @flags: tx descriptor status flags
1236185ecb5fSAlexandre Bounine  * @context: transaction context (ignored)
1237808347f6SNicolas Ferre  */
1238808347f6SNicolas Ferre static struct dma_async_tx_descriptor *
atc_prep_slave_sg(struct dma_chan * chan,struct scatterlist * sgl,unsigned int sg_len,enum dma_transfer_direction direction,unsigned long flags,void * context)1239808347f6SNicolas Ferre atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
1240db8196dfSVinod Koul 		unsigned int sg_len, enum dma_transfer_direction direction,
1241185ecb5fSAlexandre Bounine 		unsigned long flags, void *context)
1242808347f6SNicolas Ferre {
1243ac803b56STudor Ambarus 	struct at_dma		*atdma = to_at_dma(chan->device);
1244808347f6SNicolas Ferre 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
1245808347f6SNicolas Ferre 	struct at_dma_slave	*atslave = chan->private;
1246beeaa103SNicolas Ferre 	struct dma_slave_config	*sconfig = &atchan->dma_sconfig;
1247ac803b56STudor Ambarus 	struct at_desc		*desc;
1248808347f6SNicolas Ferre 	u32			ctrla;
1249808347f6SNicolas Ferre 	u32			ctrlb;
1250808347f6SNicolas Ferre 	dma_addr_t		reg;
1251808347f6SNicolas Ferre 	unsigned int		reg_width;
1252808347f6SNicolas Ferre 	unsigned int		mem_width;
1253808347f6SNicolas Ferre 	unsigned int		i;
1254808347f6SNicolas Ferre 	struct scatterlist	*sg;
1255808347f6SNicolas Ferre 	size_t			total_len = 0;
1256808347f6SNicolas Ferre 
1257cc52a10aSNicolas Ferre 	dev_vdbg(chan2dev(chan), "prep_slave_sg (%d): %s f0x%lx\n",
1258cc52a10aSNicolas Ferre 			sg_len,
1259db8196dfSVinod Koul 			direction == DMA_MEM_TO_DEV ? "TO DEVICE" : "FROM DEVICE",
1260808347f6SNicolas Ferre 			flags);
1261808347f6SNicolas Ferre 
1262808347f6SNicolas Ferre 	if (unlikely(!atslave || !sg_len)) {
1263c618a9beSNicolas Ferre 		dev_dbg(chan2dev(chan), "prep_slave_sg: sg length is zero!\n");
1264808347f6SNicolas Ferre 		return NULL;
1265808347f6SNicolas Ferre 	}
1266808347f6SNicolas Ferre 
1267ac803b56STudor Ambarus 	desc = kzalloc(struct_size(desc, sg, sg_len), GFP_ATOMIC);
1268ac803b56STudor Ambarus 	if (!desc)
1269ac803b56STudor Ambarus 		return NULL;
1270ac803b56STudor Ambarus 	desc->sglen = sg_len;
1271ac803b56STudor Ambarus 
1272d8840a7eSTudor Ambarus 	ctrla = FIELD_PREP(ATC_SCSIZE, sconfig->src_maxburst) |
1273d8840a7eSTudor Ambarus 		FIELD_PREP(ATC_DCSIZE, sconfig->dst_maxburst);
1274ae14d4b5SNicolas Ferre 	ctrlb = ATC_IEN;
1275808347f6SNicolas Ferre 
1276808347f6SNicolas Ferre 	switch (direction) {
1277db8196dfSVinod Koul 	case DMA_MEM_TO_DEV:
1278beeaa103SNicolas Ferre 		reg_width = convert_buswidth(sconfig->dst_addr_width);
1279d8840a7eSTudor Ambarus 		ctrla |= FIELD_PREP(ATC_DST_WIDTH, reg_width);
1280d8840a7eSTudor Ambarus 		ctrlb |= FIELD_PREP(ATC_DST_ADDR_MODE,
1281d8840a7eSTudor Ambarus 				    ATC_DST_ADDR_MODE_FIXED) |
1282d8840a7eSTudor Ambarus 			 FIELD_PREP(ATC_SRC_ADDR_MODE, ATC_SRC_ADDR_MODE_INCR) |
1283d8840a7eSTudor Ambarus 			 FIELD_PREP(ATC_FC, ATC_FC_MEM2PER) |
1284d8840a7eSTudor Ambarus 			 FIELD_PREP(ATC_SIF, atchan->mem_if) |
1285d8840a7eSTudor Ambarus 			 FIELD_PREP(ATC_DIF, atchan->per_if);
1286beeaa103SNicolas Ferre 		reg = sconfig->dst_addr;
1287808347f6SNicolas Ferre 		for_each_sg(sgl, sg, sg_len, i) {
1288ac803b56STudor Ambarus 			struct atdma_sg *atdma_sg = &desc->sg[i];
1289ac803b56STudor Ambarus 			struct at_lli *lli;
1290808347f6SNicolas Ferre 			u32		len;
1291808347f6SNicolas Ferre 			u32		mem;
1292808347f6SNicolas Ferre 
1293ac803b56STudor Ambarus 			atdma_sg->lli = dma_pool_alloc(atdma->lli_pool,
1294ac803b56STudor Ambarus 						       GFP_NOWAIT,
1295ac803b56STudor Ambarus 						       &atdma_sg->lli_phys);
1296ac803b56STudor Ambarus 			if (!atdma_sg->lli)
1297808347f6SNicolas Ferre 				goto err_desc_get;
1298ac803b56STudor Ambarus 			lli = atdma_sg->lli;
1299808347f6SNicolas Ferre 
13000f70e8ceSNicolas Ferre 			mem = sg_dma_address(sg);
1301808347f6SNicolas Ferre 			len = sg_dma_len(sg);
1302c4567976SNicolas Ferre 			if (unlikely(!len)) {
1303c4567976SNicolas Ferre 				dev_dbg(chan2dev(chan),
1304c4567976SNicolas Ferre 					"prep_slave_sg: sg(%d) data length is zero\n", i);
1305c4567976SNicolas Ferre 				goto err;
1306c4567976SNicolas Ferre 			}
1307808347f6SNicolas Ferre 			mem_width = 2;
1308808347f6SNicolas Ferre 			if (unlikely(mem & 3 || len & 3))
1309808347f6SNicolas Ferre 				mem_width = 0;
1310808347f6SNicolas Ferre 
1311ac803b56STudor Ambarus 			lli->saddr = mem;
1312ac803b56STudor Ambarus 			lli->daddr = reg;
1313ac803b56STudor Ambarus 			lli->ctrla = ctrla |
1314d8840a7eSTudor Ambarus 				     FIELD_PREP(ATC_SRC_WIDTH, mem_width) |
1315d8840a7eSTudor Ambarus 				     len >> mem_width;
1316ac803b56STudor Ambarus 			lli->ctrlb = ctrlb;
1317808347f6SNicolas Ferre 
1318ac803b56STudor Ambarus 			atdma_sg->len = len;
1319808347f6SNicolas Ferre 			total_len += len;
1320ac803b56STudor Ambarus 
1321ac803b56STudor Ambarus 			desc->sg[i].len = len;
1322ac803b56STudor Ambarus 			atdma_lli_chain(desc, i);
1323808347f6SNicolas Ferre 		}
1324808347f6SNicolas Ferre 		break;
1325db8196dfSVinod Koul 	case DMA_DEV_TO_MEM:
1326beeaa103SNicolas Ferre 		reg_width = convert_buswidth(sconfig->src_addr_width);
1327d8840a7eSTudor Ambarus 		ctrla |= FIELD_PREP(ATC_SRC_WIDTH, reg_width);
1328d8840a7eSTudor Ambarus 		ctrlb |= FIELD_PREP(ATC_DST_ADDR_MODE, ATC_DST_ADDR_MODE_INCR) |
1329d8840a7eSTudor Ambarus 			 FIELD_PREP(ATC_SRC_ADDR_MODE,
1330d8840a7eSTudor Ambarus 				    ATC_SRC_ADDR_MODE_FIXED) |
1331d8840a7eSTudor Ambarus 			 FIELD_PREP(ATC_FC, ATC_FC_PER2MEM) |
1332d8840a7eSTudor Ambarus 			 FIELD_PREP(ATC_SIF, atchan->per_if) |
1333d8840a7eSTudor Ambarus 			 FIELD_PREP(ATC_DIF, atchan->mem_if);
1334808347f6SNicolas Ferre 
1335beeaa103SNicolas Ferre 		reg = sconfig->src_addr;
1336808347f6SNicolas Ferre 		for_each_sg(sgl, sg, sg_len, i) {
1337ac803b56STudor Ambarus 			struct atdma_sg *atdma_sg = &desc->sg[i];
1338ac803b56STudor Ambarus 			struct at_lli *lli;
1339808347f6SNicolas Ferre 			u32		len;
1340808347f6SNicolas Ferre 			u32		mem;
1341808347f6SNicolas Ferre 
1342ac803b56STudor Ambarus 			atdma_sg->lli = dma_pool_alloc(atdma->lli_pool,
1343ac803b56STudor Ambarus 						       GFP_NOWAIT,
1344ac803b56STudor Ambarus 						       &atdma_sg->lli_phys);
1345ac803b56STudor Ambarus 			if (!atdma_sg->lli)
1346808347f6SNicolas Ferre 				goto err_desc_get;
1347ac803b56STudor Ambarus 			lli = atdma_sg->lli;
1348808347f6SNicolas Ferre 
13490f70e8ceSNicolas Ferre 			mem = sg_dma_address(sg);
1350808347f6SNicolas Ferre 			len = sg_dma_len(sg);
1351c4567976SNicolas Ferre 			if (unlikely(!len)) {
1352c4567976SNicolas Ferre 				dev_dbg(chan2dev(chan),
1353c4567976SNicolas Ferre 					"prep_slave_sg: sg(%d) data length is zero\n", i);
1354c4567976SNicolas Ferre 				goto err;
1355c4567976SNicolas Ferre 			}
1356808347f6SNicolas Ferre 			mem_width = 2;
1357808347f6SNicolas Ferre 			if (unlikely(mem & 3 || len & 3))
1358808347f6SNicolas Ferre 				mem_width = 0;
1359808347f6SNicolas Ferre 
1360ac803b56STudor Ambarus 			lli->saddr = reg;
1361ac803b56STudor Ambarus 			lli->daddr = mem;
1362ac803b56STudor Ambarus 			lli->ctrla = ctrla |
1363d8840a7eSTudor Ambarus 				     FIELD_PREP(ATC_DST_WIDTH, mem_width) |
1364d8840a7eSTudor Ambarus 				     len >> reg_width;
1365ac803b56STudor Ambarus 			lli->ctrlb = ctrlb;
1366808347f6SNicolas Ferre 
1367ac803b56STudor Ambarus 			desc->sg[i].len = len;
1368808347f6SNicolas Ferre 			total_len += len;
1369ac803b56STudor Ambarus 
1370ac803b56STudor Ambarus 			atdma_lli_chain(desc, i);
1371808347f6SNicolas Ferre 		}
1372808347f6SNicolas Ferre 		break;
1373808347f6SNicolas Ferre 	default:
1374808347f6SNicolas Ferre 		return NULL;
1375808347f6SNicolas Ferre 	}
1376808347f6SNicolas Ferre 
1377808347f6SNicolas Ferre 	/* set end-of-link to the last link descriptor of list*/
1378ac803b56STudor Ambarus 	set_lli_eol(desc, i - 1);
1379808347f6SNicolas Ferre 
1380ac803b56STudor Ambarus 	desc->total_len = total_len;
1381bdf6c792STorsten Fleischer 
1382ac803b56STudor Ambarus 	return vchan_tx_prep(&atchan->vc, &desc->vd, flags);
1383808347f6SNicolas Ferre 
1384808347f6SNicolas Ferre err_desc_get:
1385808347f6SNicolas Ferre 	dev_err(chan2dev(chan), "not enough descriptors available\n");
1386c4567976SNicolas Ferre err:
1387ac803b56STudor Ambarus 	atdma_desc_free(&desc->vd);
1388808347f6SNicolas Ferre 	return NULL;
1389808347f6SNicolas Ferre }
1390808347f6SNicolas Ferre 
139121e3cdb0SLee Jones /*
139253830cc7SNicolas Ferre  * atc_dma_cyclic_check_values
139353830cc7SNicolas Ferre  * Check for too big/unaligned periods and unaligned DMA buffer
139453830cc7SNicolas Ferre  */
139553830cc7SNicolas Ferre static int
atc_dma_cyclic_check_values(unsigned int reg_width,dma_addr_t buf_addr,size_t period_len)139653830cc7SNicolas Ferre atc_dma_cyclic_check_values(unsigned int reg_width, dma_addr_t buf_addr,
13970e7264ccSAndy Shevchenko 		size_t period_len)
139853830cc7SNicolas Ferre {
139953830cc7SNicolas Ferre 	if (period_len > (ATC_BTSIZE_MAX << reg_width))
140053830cc7SNicolas Ferre 		goto err_out;
140153830cc7SNicolas Ferre 	if (unlikely(period_len & ((1 << reg_width) - 1)))
140253830cc7SNicolas Ferre 		goto err_out;
140353830cc7SNicolas Ferre 	if (unlikely(buf_addr & ((1 << reg_width) - 1)))
140453830cc7SNicolas Ferre 		goto err_out;
140553830cc7SNicolas Ferre 
140653830cc7SNicolas Ferre 	return 0;
140753830cc7SNicolas Ferre 
140853830cc7SNicolas Ferre err_out:
140953830cc7SNicolas Ferre 	return -EINVAL;
141053830cc7SNicolas Ferre }
141153830cc7SNicolas Ferre 
141221e3cdb0SLee Jones /*
1413d73111c6SMasanari Iida  * atc_dma_cyclic_fill_desc - Fill one period descriptor
141453830cc7SNicolas Ferre  */
141553830cc7SNicolas Ferre static int
atc_dma_cyclic_fill_desc(struct dma_chan * chan,struct at_desc * desc,unsigned int i,dma_addr_t buf_addr,unsigned int reg_width,size_t period_len,enum dma_transfer_direction direction)1416beeaa103SNicolas Ferre atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc,
1417ac803b56STudor Ambarus 		unsigned int i, dma_addr_t buf_addr,
1418beeaa103SNicolas Ferre 		unsigned int reg_width, size_t period_len,
1419beeaa103SNicolas Ferre 		enum dma_transfer_direction direction)
142053830cc7SNicolas Ferre {
1421ac803b56STudor Ambarus 	struct at_dma		*atdma = to_at_dma(chan->device);
1422beeaa103SNicolas Ferre 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
1423beeaa103SNicolas Ferre 	struct dma_slave_config	*sconfig = &atchan->dma_sconfig;
1424ac803b56STudor Ambarus 	struct atdma_sg		*atdma_sg = &desc->sg[i];
1425ac803b56STudor Ambarus 	struct at_lli		*lli;
142653830cc7SNicolas Ferre 
1427ac803b56STudor Ambarus 	atdma_sg->lli = dma_pool_alloc(atdma->lli_pool, GFP_ATOMIC,
1428ac803b56STudor Ambarus 				       &atdma_sg->lli_phys);
1429ac803b56STudor Ambarus 	if (!atdma_sg->lli)
1430ac803b56STudor Ambarus 		return -ENOMEM;
1431ac803b56STudor Ambarus 	lli = atdma_sg->lli;
143253830cc7SNicolas Ferre 
143353830cc7SNicolas Ferre 	switch (direction) {
1434db8196dfSVinod Koul 	case DMA_MEM_TO_DEV:
1435ac803b56STudor Ambarus 		lli->saddr = buf_addr + (period_len * i);
1436ac803b56STudor Ambarus 		lli->daddr = sconfig->dst_addr;
1437ac803b56STudor Ambarus 		lli->ctrlb = FIELD_PREP(ATC_DST_ADDR_MODE,
1438d8840a7eSTudor Ambarus 					ATC_DST_ADDR_MODE_FIXED) |
1439d8840a7eSTudor Ambarus 			     FIELD_PREP(ATC_SRC_ADDR_MODE,
1440d8840a7eSTudor Ambarus 					ATC_SRC_ADDR_MODE_INCR) |
1441d8840a7eSTudor Ambarus 			     FIELD_PREP(ATC_FC, ATC_FC_MEM2PER) |
1442d8840a7eSTudor Ambarus 			     FIELD_PREP(ATC_SIF, atchan->mem_if) |
1443d8840a7eSTudor Ambarus 			     FIELD_PREP(ATC_DIF, atchan->per_if);
1444ac803b56STudor Ambarus 
144553830cc7SNicolas Ferre 		break;
144653830cc7SNicolas Ferre 
1447db8196dfSVinod Koul 	case DMA_DEV_TO_MEM:
1448ac803b56STudor Ambarus 		lli->saddr = sconfig->src_addr;
1449ac803b56STudor Ambarus 		lli->daddr = buf_addr + (period_len * i);
1450ac803b56STudor Ambarus 		lli->ctrlb = FIELD_PREP(ATC_DST_ADDR_MODE,
1451d8840a7eSTudor Ambarus 					ATC_DST_ADDR_MODE_INCR) |
1452d8840a7eSTudor Ambarus 			     FIELD_PREP(ATC_SRC_ADDR_MODE,
1453d8840a7eSTudor Ambarus 					ATC_SRC_ADDR_MODE_FIXED) |
1454d8840a7eSTudor Ambarus 			     FIELD_PREP(ATC_FC, ATC_FC_PER2MEM) |
1455d8840a7eSTudor Ambarus 			     FIELD_PREP(ATC_SIF, atchan->per_if) |
1456d8840a7eSTudor Ambarus 			     FIELD_PREP(ATC_DIF, atchan->mem_if);
145753830cc7SNicolas Ferre 		break;
145853830cc7SNicolas Ferre 
145953830cc7SNicolas Ferre 	default:
146053830cc7SNicolas Ferre 		return -EINVAL;
146153830cc7SNicolas Ferre 	}
146253830cc7SNicolas Ferre 
1463ac803b56STudor Ambarus 	lli->ctrla = FIELD_PREP(ATC_SCSIZE, sconfig->src_maxburst) |
1464ac803b56STudor Ambarus 		     FIELD_PREP(ATC_DCSIZE, sconfig->dst_maxburst) |
1465ac803b56STudor Ambarus 		     FIELD_PREP(ATC_DST_WIDTH, reg_width) |
1466ac803b56STudor Ambarus 		     FIELD_PREP(ATC_SRC_WIDTH, reg_width) |
1467ac803b56STudor Ambarus 		     period_len >> reg_width;
1468ac803b56STudor Ambarus 	desc->sg[i].len = period_len;
1469ac803b56STudor Ambarus 
147053830cc7SNicolas Ferre 	return 0;
147153830cc7SNicolas Ferre }
147253830cc7SNicolas Ferre 
147353830cc7SNicolas Ferre /**
147453830cc7SNicolas Ferre  * atc_prep_dma_cyclic - prepare the cyclic DMA transfer
147553830cc7SNicolas Ferre  * @chan: the DMA channel to prepare
147653830cc7SNicolas Ferre  * @buf_addr: physical DMA address where the buffer starts
147753830cc7SNicolas Ferre  * @buf_len: total number of bytes for the entire buffer
147853830cc7SNicolas Ferre  * @period_len: number of bytes for each period
147953830cc7SNicolas Ferre  * @direction: transfer direction, to or from device
1480ec8b5e48SPeter Ujfalusi  * @flags: tx descriptor status flags
148153830cc7SNicolas Ferre  */
148253830cc7SNicolas Ferre static struct dma_async_tx_descriptor *
atc_prep_dma_cyclic(struct dma_chan * chan,dma_addr_t buf_addr,size_t buf_len,size_t period_len,enum dma_transfer_direction direction,unsigned long flags)148353830cc7SNicolas Ferre atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
1484185ecb5fSAlexandre Bounine 		size_t period_len, enum dma_transfer_direction direction,
148531c1e5a1SLaurent Pinchart 		unsigned long flags)
148653830cc7SNicolas Ferre {
148753830cc7SNicolas Ferre 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
148853830cc7SNicolas Ferre 	struct at_dma_slave	*atslave = chan->private;
1489beeaa103SNicolas Ferre 	struct dma_slave_config	*sconfig = &atchan->dma_sconfig;
1490ac803b56STudor Ambarus 	struct at_desc		*desc;
149153830cc7SNicolas Ferre 	unsigned long		was_cyclic;
1492beeaa103SNicolas Ferre 	unsigned int		reg_width;
149353830cc7SNicolas Ferre 	unsigned int		periods = buf_len / period_len;
149453830cc7SNicolas Ferre 	unsigned int		i;
149553830cc7SNicolas Ferre 
14962c5d7407SArnd Bergmann 	dev_vdbg(chan2dev(chan), "prep_dma_cyclic: %s buf@%pad - %d (%d/%d)\n",
1497db8196dfSVinod Koul 			direction == DMA_MEM_TO_DEV ? "TO DEVICE" : "FROM DEVICE",
14982c5d7407SArnd Bergmann 			&buf_addr,
149953830cc7SNicolas Ferre 			periods, buf_len, period_len);
150053830cc7SNicolas Ferre 
150153830cc7SNicolas Ferre 	if (unlikely(!atslave || !buf_len || !period_len)) {
150253830cc7SNicolas Ferre 		dev_dbg(chan2dev(chan), "prep_dma_cyclic: length is zero!\n");
150353830cc7SNicolas Ferre 		return NULL;
150453830cc7SNicolas Ferre 	}
150553830cc7SNicolas Ferre 
150653830cc7SNicolas Ferre 	was_cyclic = test_and_set_bit(ATC_IS_CYCLIC, &atchan->status);
150753830cc7SNicolas Ferre 	if (was_cyclic) {
150853830cc7SNicolas Ferre 		dev_dbg(chan2dev(chan), "prep_dma_cyclic: channel in use!\n");
150953830cc7SNicolas Ferre 		return NULL;
151053830cc7SNicolas Ferre 	}
151153830cc7SNicolas Ferre 
15120e7264ccSAndy Shevchenko 	if (unlikely(!is_slave_direction(direction)))
15130e7264ccSAndy Shevchenko 		goto err_out;
15140e7264ccSAndy Shevchenko 
151562355887SVinod Koul 	if (direction == DMA_MEM_TO_DEV)
1516beeaa103SNicolas Ferre 		reg_width = convert_buswidth(sconfig->dst_addr_width);
1517beeaa103SNicolas Ferre 	else
1518beeaa103SNicolas Ferre 		reg_width = convert_buswidth(sconfig->src_addr_width);
1519beeaa103SNicolas Ferre 
152053830cc7SNicolas Ferre 	/* Check for too big/unaligned periods and unaligned DMA buffer */
15210e7264ccSAndy Shevchenko 	if (atc_dma_cyclic_check_values(reg_width, buf_addr, period_len))
152253830cc7SNicolas Ferre 		goto err_out;
152353830cc7SNicolas Ferre 
1524ac803b56STudor Ambarus 	desc = kzalloc(struct_size(desc, sg, periods), GFP_ATOMIC);
1525ac803b56STudor Ambarus 	if (!desc)
1526ac803b56STudor Ambarus 		goto err_out;
1527ac803b56STudor Ambarus 	desc->sglen = periods;
1528ac803b56STudor Ambarus 
152953830cc7SNicolas Ferre 	/* build cyclic linked list */
153053830cc7SNicolas Ferre 	for (i = 0; i < periods; i++) {
1531beeaa103SNicolas Ferre 		if (atc_dma_cyclic_fill_desc(chan, desc, i, buf_addr,
1532beeaa103SNicolas Ferre 					     reg_width, period_len, direction))
1533ac803b56STudor Ambarus 			goto err_fill_desc;
1534ac803b56STudor Ambarus 		atdma_lli_chain(desc, i);
153553830cc7SNicolas Ferre 	}
1536ac803b56STudor Ambarus 	desc->total_len = buf_len;
153753830cc7SNicolas Ferre 	/* lets make a cyclic list */
1538ac803b56STudor Ambarus 	desc->sg[i - 1].lli->dscr = desc->sg[0].lli_phys;
153953830cc7SNicolas Ferre 
1540ac803b56STudor Ambarus 	return vchan_tx_prep(&atchan->vc, &desc->vd, flags);
154153830cc7SNicolas Ferre 
1542ac803b56STudor Ambarus err_fill_desc:
1543ac803b56STudor Ambarus 	atdma_desc_free(&desc->vd);
154453830cc7SNicolas Ferre err_out:
154553830cc7SNicolas Ferre 	clear_bit(ATC_IS_CYCLIC, &atchan->status);
154653830cc7SNicolas Ferre 	return NULL;
154753830cc7SNicolas Ferre }
154853830cc7SNicolas Ferre 
atc_config(struct dma_chan * chan,struct dma_slave_config * sconfig)15494facfe7fSMaxime Ripard static int atc_config(struct dma_chan *chan,
1550beeaa103SNicolas Ferre 		      struct dma_slave_config *sconfig)
1551beeaa103SNicolas Ferre {
1552beeaa103SNicolas Ferre 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
1553beeaa103SNicolas Ferre 
15544facfe7fSMaxime Ripard 	dev_vdbg(chan2dev(chan), "%s\n", __func__);
15554facfe7fSMaxime Ripard 
1556beeaa103SNicolas Ferre 	/* Check if it is chan is configured for slave transfers */
1557beeaa103SNicolas Ferre 	if (!chan->private)
1558beeaa103SNicolas Ferre 		return -EINVAL;
1559beeaa103SNicolas Ferre 
1560beeaa103SNicolas Ferre 	memcpy(&atchan->dma_sconfig, sconfig, sizeof(*sconfig));
1561beeaa103SNicolas Ferre 
1562beeaa103SNicolas Ferre 	convert_burst(&atchan->dma_sconfig.src_maxburst);
1563beeaa103SNicolas Ferre 	convert_burst(&atchan->dma_sconfig.dst_maxburst);
1564beeaa103SNicolas Ferre 
1565beeaa103SNicolas Ferre 	return 0;
1566beeaa103SNicolas Ferre }
1567beeaa103SNicolas Ferre 
atc_pause(struct dma_chan * chan)15684facfe7fSMaxime Ripard static int atc_pause(struct dma_chan *chan)
1569808347f6SNicolas Ferre {
1570808347f6SNicolas Ferre 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
1571808347f6SNicolas Ferre 	struct at_dma		*atdma = to_at_dma(chan->device);
1572ac803b56STudor Ambarus 	int			chan_id = atchan->vc.chan.chan_id;
1573d8cb04b0SNicolas Ferre 	unsigned long		flags;
157423b5e3adSNicolas Ferre 
15754facfe7fSMaxime Ripard 	dev_vdbg(chan2dev(chan), "%s\n", __func__);
1576c3635c78SLinus Walleij 
1577ac803b56STudor Ambarus 	spin_lock_irqsave(&atchan->vc.lock, flags);
157823b5e3adSNicolas Ferre 
157923b5e3adSNicolas Ferre 	dma_writel(atdma, CHER, AT_DMA_SUSP(chan_id));
158023b5e3adSNicolas Ferre 	set_bit(ATC_IS_PAUSED, &atchan->status);
158123b5e3adSNicolas Ferre 
1582ac803b56STudor Ambarus 	spin_unlock_irqrestore(&atchan->vc.lock, flags);
15834facfe7fSMaxime Ripard 
15844facfe7fSMaxime Ripard 	return 0;
15854facfe7fSMaxime Ripard }
15864facfe7fSMaxime Ripard 
atc_resume(struct dma_chan * chan)15874facfe7fSMaxime Ripard static int atc_resume(struct dma_chan *chan)
15884facfe7fSMaxime Ripard {
15894facfe7fSMaxime Ripard 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
15904facfe7fSMaxime Ripard 	struct at_dma		*atdma = to_at_dma(chan->device);
1591ac803b56STudor Ambarus 	int			chan_id = atchan->vc.chan.chan_id;
15924facfe7fSMaxime Ripard 	unsigned long		flags;
15934facfe7fSMaxime Ripard 
15944facfe7fSMaxime Ripard 	dev_vdbg(chan2dev(chan), "%s\n", __func__);
15954facfe7fSMaxime Ripard 
15963c477482SNicolas Ferre 	if (!atc_chan_is_paused(atchan))
159723b5e3adSNicolas Ferre 		return 0;
159823b5e3adSNicolas Ferre 
1599ac803b56STudor Ambarus 	spin_lock_irqsave(&atchan->vc.lock, flags);
160023b5e3adSNicolas Ferre 
160123b5e3adSNicolas Ferre 	dma_writel(atdma, CHDR, AT_DMA_RES(chan_id));
160223b5e3adSNicolas Ferre 	clear_bit(ATC_IS_PAUSED, &atchan->status);
160323b5e3adSNicolas Ferre 
1604ac803b56STudor Ambarus 	spin_unlock_irqrestore(&atchan->vc.lock, flags);
16054facfe7fSMaxime Ripard 
16064facfe7fSMaxime Ripard 	return 0;
16074facfe7fSMaxime Ripard }
16084facfe7fSMaxime Ripard 
atc_terminate_all(struct dma_chan * chan)16094facfe7fSMaxime Ripard static int atc_terminate_all(struct dma_chan *chan)
16104facfe7fSMaxime Ripard {
16114facfe7fSMaxime Ripard 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
16124facfe7fSMaxime Ripard 	struct at_dma		*atdma = to_at_dma(chan->device);
1613ac803b56STudor Ambarus 	int			chan_id = atchan->vc.chan.chan_id;
16144facfe7fSMaxime Ripard 	unsigned long		flags;
16154facfe7fSMaxime Ripard 
1616ac803b56STudor Ambarus 	LIST_HEAD(list);
1617ac803b56STudor Ambarus 
16184facfe7fSMaxime Ripard 	dev_vdbg(chan2dev(chan), "%s\n", __func__);
16194facfe7fSMaxime Ripard 
1620808347f6SNicolas Ferre 	/*
1621808347f6SNicolas Ferre 	 * This is only called when something went wrong elsewhere, so
1622808347f6SNicolas Ferre 	 * we don't really care about the data. Just disable the
1623808347f6SNicolas Ferre 	 * channel. We still have to poll the channel enable bit due
1624808347f6SNicolas Ferre 	 * to AHB/HSB limitations.
1625808347f6SNicolas Ferre 	 */
1626ac803b56STudor Ambarus 	spin_lock_irqsave(&atchan->vc.lock, flags);
1627808347f6SNicolas Ferre 
162823b5e3adSNicolas Ferre 	/* disabling channel: must also remove suspend state */
162923b5e3adSNicolas Ferre 	dma_writel(atdma, CHDR, AT_DMA_RES(chan_id) | atchan->mask);
1630808347f6SNicolas Ferre 
1631808347f6SNicolas Ferre 	/* confirm that this channel is disabled */
1632808347f6SNicolas Ferre 	while (dma_readl(atdma, CHSR) & atchan->mask)
1633808347f6SNicolas Ferre 		cpu_relax();
1634808347f6SNicolas Ferre 
1635ac803b56STudor Ambarus 	if (atchan->desc) {
1636ac803b56STudor Ambarus 		vchan_terminate_vdesc(&atchan->desc->vd);
1637ac803b56STudor Ambarus 		atchan->desc = NULL;
1638ac803b56STudor Ambarus 	}
1639ac803b56STudor Ambarus 
1640ac803b56STudor Ambarus 	vchan_get_all_descriptors(&atchan->vc, &list);
1641808347f6SNicolas Ferre 
164223b5e3adSNicolas Ferre 	clear_bit(ATC_IS_PAUSED, &atchan->status);
164353830cc7SNicolas Ferre 	/* if channel dedicated to cyclic operations, free it */
164453830cc7SNicolas Ferre 	clear_bit(ATC_IS_CYCLIC, &atchan->status);
164553830cc7SNicolas Ferre 
1646ac803b56STudor Ambarus 	spin_unlock_irqrestore(&atchan->vc.lock, flags);
1647ac803b56STudor Ambarus 
1648ac803b56STudor Ambarus 	vchan_dma_desc_free_list(&atchan->vc, &list);
16496e5ad28dSTudor Ambarus 
1650c3635c78SLinus Walleij 	return 0;
1651808347f6SNicolas Ferre }
1652808347f6SNicolas Ferre 
1653dc78baa2SNicolas Ferre /**
165407934481SLinus Walleij  * atc_tx_status - poll for transaction completion
1655dc78baa2SNicolas Ferre  * @chan: DMA channel
1656dc78baa2SNicolas Ferre  * @cookie: transaction identifier to check status of
165707934481SLinus Walleij  * @txstate: if not %NULL updated with transaction state
1658dc78baa2SNicolas Ferre  *
165907934481SLinus Walleij  * If @txstate is passed in, upon return it reflect the driver
1660dc78baa2SNicolas Ferre  * internal state and can be used with dma_async_is_complete() to check
1661dc78baa2SNicolas Ferre  * the status of multiple cookies without re-checking hardware state.
1662dc78baa2SNicolas Ferre  */
1663dc78baa2SNicolas Ferre static enum dma_status
atc_tx_status(struct dma_chan * chan,dma_cookie_t cookie,struct dma_tx_state * txstate)166407934481SLinus Walleij atc_tx_status(struct dma_chan *chan,
1665dc78baa2SNicolas Ferre 		dma_cookie_t cookie,
166607934481SLinus Walleij 		struct dma_tx_state *txstate)
1667dc78baa2SNicolas Ferre {
1668dc78baa2SNicolas Ferre 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
1669d8cb04b0SNicolas Ferre 	unsigned long		flags;
1670f5d79afaSTudor Ambarus 	enum dma_status		dma_status;
1671f5d79afaSTudor Ambarus 	u32 residue;
1672f5d79afaSTudor Ambarus 	int ret;
1673d48de6f1SElen Song 
1674f5d79afaSTudor Ambarus 	dma_status = dma_cookie_status(chan, cookie, txstate);
1675f5d79afaSTudor Ambarus 	if (dma_status == DMA_COMPLETE || !txstate)
1676f5d79afaSTudor Ambarus 		return dma_status;
1677dc78baa2SNicolas Ferre 
1678ac803b56STudor Ambarus 	spin_lock_irqsave(&atchan->vc.lock, flags);
1679ac803b56STudor Ambarus 	/*  Get number of bytes left in the active transactions */
168091617bf6STudor Ambarus 	ret = atc_get_residue(chan, cookie, &residue);
1681ac803b56STudor Ambarus 	spin_unlock_irqrestore(&atchan->vc.lock, flags);
1682dc78baa2SNicolas Ferre 
1683f5d79afaSTudor Ambarus 	if (unlikely(ret < 0)) {
1684d48de6f1SElen Song 		dev_vdbg(chan2dev(chan), "get residual bytes error\n");
1685d48de6f1SElen Song 		return DMA_ERROR;
1686c3dbc60cSNicolas Ferre 	} else {
1687f5d79afaSTudor Ambarus 		dma_set_residue(txstate, residue);
1688c3dbc60cSNicolas Ferre 	}
1689543aabc7SNicolas Ferre 
1690f5d79afaSTudor Ambarus 	dev_vdbg(chan2dev(chan), "tx_status %d: cookie = %d residue = %u\n",
1691f5d79afaSTudor Ambarus 		 dma_status, cookie, residue);
1692dc78baa2SNicolas Ferre 
1693f5d79afaSTudor Ambarus 	return dma_status;
1694dc78baa2SNicolas Ferre }
1695dc78baa2SNicolas Ferre 
atc_issue_pending(struct dma_chan * chan)1696dc78baa2SNicolas Ferre static void atc_issue_pending(struct dma_chan *chan)
1697dc78baa2SNicolas Ferre {
1698dc78baa2SNicolas Ferre 	struct at_dma_chan *atchan = to_at_dma_chan(chan);
1699fcd37565STudor Ambarus 	unsigned long flags;
1700dc78baa2SNicolas Ferre 
1701ac803b56STudor Ambarus 	spin_lock_irqsave(&atchan->vc.lock, flags);
1702ac803b56STudor Ambarus 	if (vchan_issue_pending(&atchan->vc) && !atchan->desc) {
1703ac803b56STudor Ambarus 		if (!(atc_chan_is_enabled(atchan)))
1704ac803b56STudor Ambarus 			atc_dostart(atchan);
1705ac803b56STudor Ambarus 	}
1706ac803b56STudor Ambarus 	spin_unlock_irqrestore(&atchan->vc.lock, flags);
1707dc78baa2SNicolas Ferre }
1708dc78baa2SNicolas Ferre 
1709dc78baa2SNicolas Ferre /**
1710dc78baa2SNicolas Ferre  * atc_alloc_chan_resources - allocate resources for DMA channel
1711dc78baa2SNicolas Ferre  * @chan: allocate descriptor resources for this channel
1712dc78baa2SNicolas Ferre  *
1713dc78baa2SNicolas Ferre  * return - the number of allocated descriptors
1714dc78baa2SNicolas Ferre  */
atc_alloc_chan_resources(struct dma_chan * chan)1715dc78baa2SNicolas Ferre static int atc_alloc_chan_resources(struct dma_chan *chan)
1716dc78baa2SNicolas Ferre {
1717dc78baa2SNicolas Ferre 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
1718dc78baa2SNicolas Ferre 	struct at_dma		*atdma = to_at_dma(chan->device);
1719808347f6SNicolas Ferre 	struct at_dma_slave	*atslave;
1720808347f6SNicolas Ferre 	u32			cfg;
1721dc78baa2SNicolas Ferre 
1722dc78baa2SNicolas Ferre 	dev_vdbg(chan2dev(chan), "alloc_chan_resources\n");
1723dc78baa2SNicolas Ferre 
1724dc78baa2SNicolas Ferre 	/* ASSERT:  channel is idle */
1725dc78baa2SNicolas Ferre 	if (atc_chan_is_enabled(atchan)) {
1726dc78baa2SNicolas Ferre 		dev_dbg(chan2dev(chan), "DMA channel not idle ?\n");
1727dc78baa2SNicolas Ferre 		return -EIO;
1728dc78baa2SNicolas Ferre 	}
1729dc78baa2SNicolas Ferre 
1730808347f6SNicolas Ferre 	cfg = ATC_DEFAULT_CFG;
1731808347f6SNicolas Ferre 
1732808347f6SNicolas Ferre 	atslave = chan->private;
1733808347f6SNicolas Ferre 	if (atslave) {
1734808347f6SNicolas Ferre 		/*
1735808347f6SNicolas Ferre 		 * We need controller-specific data to set up slave
1736808347f6SNicolas Ferre 		 * transfers.
1737808347f6SNicolas Ferre 		 */
17381c1114d8STudor Ambarus 		BUG_ON(!atslave->dma_dev || atslave->dma_dev != atdma->dma_device.dev);
1739808347f6SNicolas Ferre 
1740ea7e7906SNicolas Ferre 		/* if cfg configuration specified take it instead of default */
1741808347f6SNicolas Ferre 		if (atslave->cfg)
1742808347f6SNicolas Ferre 			cfg = atslave->cfg;
1743808347f6SNicolas Ferre 	}
1744808347f6SNicolas Ferre 
1745dc78baa2SNicolas Ferre 	/* channel parameters */
1746808347f6SNicolas Ferre 	channel_writel(atchan, CFG, cfg);
1747dc78baa2SNicolas Ferre 
1748ac803b56STudor Ambarus 	return 0;
1749dc78baa2SNicolas Ferre }
1750dc78baa2SNicolas Ferre 
1751dc78baa2SNicolas Ferre /**
1752dc78baa2SNicolas Ferre  * atc_free_chan_resources - free all channel resources
1753dc78baa2SNicolas Ferre  * @chan: DMA channel
1754dc78baa2SNicolas Ferre  */
atc_free_chan_resources(struct dma_chan * chan)1755dc78baa2SNicolas Ferre static void atc_free_chan_resources(struct dma_chan *chan)
1756dc78baa2SNicolas Ferre {
1757dc78baa2SNicolas Ferre 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
1758dc78baa2SNicolas Ferre 
1759dc78baa2SNicolas Ferre 	BUG_ON(atc_chan_is_enabled(atchan));
1760dc78baa2SNicolas Ferre 
1761ac803b56STudor Ambarus 	vchan_free_chan_resources(to_virt_chan(chan));
176253830cc7SNicolas Ferre 	atchan->status = 0;
1763dc78baa2SNicolas Ferre 
176498f5f932SRichard Genoud 	/*
176598f5f932SRichard Genoud 	 * Free atslave allocated in at_dma_xlate()
176698f5f932SRichard Genoud 	 */
176798f5f932SRichard Genoud 	kfree(chan->private);
176898f5f932SRichard Genoud 	chan->private = NULL;
176998f5f932SRichard Genoud 
1770dc78baa2SNicolas Ferre 	dev_vdbg(chan2dev(chan), "free_chan_resources: done\n");
1771dc78baa2SNicolas Ferre }
1772dc78baa2SNicolas Ferre 
1773bbe89c8eSLudovic Desroches #ifdef CONFIG_OF
at_dma_filter(struct dma_chan * chan,void * slave)1774bbe89c8eSLudovic Desroches static bool at_dma_filter(struct dma_chan *chan, void *slave)
1775bbe89c8eSLudovic Desroches {
1776bbe89c8eSLudovic Desroches 	struct at_dma_slave *atslave = slave;
1777bbe89c8eSLudovic Desroches 
1778bbe89c8eSLudovic Desroches 	if (atslave->dma_dev == chan->device->dev) {
1779bbe89c8eSLudovic Desroches 		chan->private = atslave;
1780bbe89c8eSLudovic Desroches 		return true;
1781bbe89c8eSLudovic Desroches 	} else {
1782bbe89c8eSLudovic Desroches 		return false;
1783bbe89c8eSLudovic Desroches 	}
1784bbe89c8eSLudovic Desroches }
1785bbe89c8eSLudovic Desroches 
at_dma_xlate(struct of_phandle_args * dma_spec,struct of_dma * of_dma)1786bbe89c8eSLudovic Desroches static struct dma_chan *at_dma_xlate(struct of_phandle_args *dma_spec,
1787bbe89c8eSLudovic Desroches 				     struct of_dma *of_dma)
1788bbe89c8eSLudovic Desroches {
1789bbe89c8eSLudovic Desroches 	struct dma_chan *chan;
1790bbe89c8eSLudovic Desroches 	struct at_dma_chan *atchan;
1791bbe89c8eSLudovic Desroches 	struct at_dma_slave *atslave;
1792bbe89c8eSLudovic Desroches 	dma_cap_mask_t mask;
1793bbe89c8eSLudovic Desroches 	unsigned int per_id;
1794bbe89c8eSLudovic Desroches 	struct platform_device *dmac_pdev;
1795bbe89c8eSLudovic Desroches 
1796bbe89c8eSLudovic Desroches 	if (dma_spec->args_count != 2)
1797bbe89c8eSLudovic Desroches 		return NULL;
1798bbe89c8eSLudovic Desroches 
1799bbe89c8eSLudovic Desroches 	dmac_pdev = of_find_device_by_node(dma_spec->np);
18000cef8e2cSYu Kuai 	if (!dmac_pdev)
18010cef8e2cSYu Kuai 		return NULL;
1802bbe89c8eSLudovic Desroches 
1803bbe89c8eSLudovic Desroches 	dma_cap_zero(mask);
1804bbe89c8eSLudovic Desroches 	dma_cap_set(DMA_SLAVE, mask);
1805bbe89c8eSLudovic Desroches 
1806a6e7f19cSTudor Ambarus 	atslave = kmalloc(sizeof(*atslave), GFP_KERNEL);
18073832b78bSYu Kuai 	if (!atslave) {
18083832b78bSYu Kuai 		put_device(&dmac_pdev->dev);
1809bbe89c8eSLudovic Desroches 		return NULL;
18103832b78bSYu Kuai 	}
181162971b29SLudovic Desroches 
1812d8840a7eSTudor Ambarus 	atslave->cfg = ATC_DST_H2SEL | ATC_SRC_H2SEL;
1813bbe89c8eSLudovic Desroches 	/*
1814bbe89c8eSLudovic Desroches 	 * We can fill both SRC_PER and DST_PER, one of these fields will be
1815bbe89c8eSLudovic Desroches 	 * ignored depending on DMA transfer direction.
1816bbe89c8eSLudovic Desroches 	 */
181762971b29SLudovic Desroches 	per_id = dma_spec->args[1] & AT91_DMA_CFG_PER_ID_MASK;
1818d8840a7eSTudor Ambarus 	atslave->cfg |= ATC_DST_PER_ID(per_id) |  ATC_SRC_PER_ID(per_id);
181962971b29SLudovic Desroches 	/*
182062971b29SLudovic Desroches 	 * We have to translate the value we get from the device tree since
182162971b29SLudovic Desroches 	 * the half FIFO configuration value had to be 0 to keep backward
182262971b29SLudovic Desroches 	 * compatibility.
182362971b29SLudovic Desroches 	 */
182462971b29SLudovic Desroches 	switch (dma_spec->args[1] & AT91_DMA_CFG_FIFOCFG_MASK) {
182562971b29SLudovic Desroches 	case AT91_DMA_CFG_FIFOCFG_ALAP:
1826d8840a7eSTudor Ambarus 		atslave->cfg |= FIELD_PREP(ATC_FIFOCFG,
1827d8840a7eSTudor Ambarus 					   ATC_FIFOCFG_LARGESTBURST);
182862971b29SLudovic Desroches 		break;
182962971b29SLudovic Desroches 	case AT91_DMA_CFG_FIFOCFG_ASAP:
1830d8840a7eSTudor Ambarus 		atslave->cfg |= FIELD_PREP(ATC_FIFOCFG,
1831d8840a7eSTudor Ambarus 					   ATC_FIFOCFG_ENOUGHSPACE);
183262971b29SLudovic Desroches 		break;
183362971b29SLudovic Desroches 	case AT91_DMA_CFG_FIFOCFG_HALF:
183462971b29SLudovic Desroches 	default:
1835d8840a7eSTudor Ambarus 		atslave->cfg |= FIELD_PREP(ATC_FIFOCFG, ATC_FIFOCFG_HALFFIFO);
183662971b29SLudovic Desroches 	}
1837bbe89c8eSLudovic Desroches 	atslave->dma_dev = &dmac_pdev->dev;
1838bbe89c8eSLudovic Desroches 
1839bbe89c8eSLudovic Desroches 	chan = dma_request_channel(mask, at_dma_filter, atslave);
18403832b78bSYu Kuai 	if (!chan) {
18413832b78bSYu Kuai 		put_device(&dmac_pdev->dev);
1842e097eb74SYu Kuai 		kfree(atslave);
1843bbe89c8eSLudovic Desroches 		return NULL;
18443832b78bSYu Kuai 	}
1845bbe89c8eSLudovic Desroches 
1846bbe89c8eSLudovic Desroches 	atchan = to_at_dma_chan(chan);
1847bbe89c8eSLudovic Desroches 	atchan->per_if = dma_spec->args[0] & 0xff;
1848bbe89c8eSLudovic Desroches 	atchan->mem_if = (dma_spec->args[0] >> 16) & 0xff;
1849bbe89c8eSLudovic Desroches 
1850bbe89c8eSLudovic Desroches 	return chan;
1851bbe89c8eSLudovic Desroches }
1852bbe89c8eSLudovic Desroches #else
at_dma_xlate(struct of_phandle_args * dma_spec,struct of_dma * of_dma)1853bbe89c8eSLudovic Desroches static struct dma_chan *at_dma_xlate(struct of_phandle_args *dma_spec,
1854bbe89c8eSLudovic Desroches 				     struct of_dma *of_dma)
1855bbe89c8eSLudovic Desroches {
1856bbe89c8eSLudovic Desroches 	return NULL;
1857bbe89c8eSLudovic Desroches }
1858bbe89c8eSLudovic Desroches #endif
1859dc78baa2SNicolas Ferre 
1860dc78baa2SNicolas Ferre /*--  Module Management  -----------------------------------------------*/
1861dc78baa2SNicolas Ferre 
186202f88be9SNicolas Ferre /* cap_mask is a multi-u32 bitfield, fill it with proper C code. */
186302f88be9SNicolas Ferre static struct at_dma_platform_data at91sam9rl_config = {
186402f88be9SNicolas Ferre 	.nr_channels = 2,
186502f88be9SNicolas Ferre };
186602f88be9SNicolas Ferre static struct at_dma_platform_data at91sam9g45_config = {
186702f88be9SNicolas Ferre 	.nr_channels = 8,
186802f88be9SNicolas Ferre };
186902f88be9SNicolas Ferre 
1870c5115953SNicolas Ferre #if defined(CONFIG_OF)
1871c5115953SNicolas Ferre static const struct of_device_id atmel_dma_dt_ids[] = {
1872c5115953SNicolas Ferre 	{
1873c5115953SNicolas Ferre 		.compatible = "atmel,at91sam9rl-dma",
187402f88be9SNicolas Ferre 		.data = &at91sam9rl_config,
1875c5115953SNicolas Ferre 	}, {
1876c5115953SNicolas Ferre 		.compatible = "atmel,at91sam9g45-dma",
187702f88be9SNicolas Ferre 		.data = &at91sam9g45_config,
1878dcc81734SNicolas Ferre 	}, {
1879dcc81734SNicolas Ferre 		/* sentinel */
1880dcc81734SNicolas Ferre 	}
1881c5115953SNicolas Ferre };
1882c5115953SNicolas Ferre 
1883c5115953SNicolas Ferre MODULE_DEVICE_TABLE(of, atmel_dma_dt_ids);
1884c5115953SNicolas Ferre #endif
1885c5115953SNicolas Ferre 
18860ab88a01SNicolas Ferre static const struct platform_device_id atdma_devtypes[] = {
188767348450SNicolas Ferre 	{
188867348450SNicolas Ferre 		.name = "at91sam9rl_dma",
188902f88be9SNicolas Ferre 		.driver_data = (unsigned long) &at91sam9rl_config,
189067348450SNicolas Ferre 	}, {
189167348450SNicolas Ferre 		.name = "at91sam9g45_dma",
189202f88be9SNicolas Ferre 		.driver_data = (unsigned long) &at91sam9g45_config,
189367348450SNicolas Ferre 	}, {
189467348450SNicolas Ferre 		/* sentinel */
189567348450SNicolas Ferre 	}
189667348450SNicolas Ferre };
189767348450SNicolas Ferre 
at_dma_get_driver_data(struct platform_device * pdev)18987fd63ccdSUwe Kleine-König static inline const struct at_dma_platform_data * __init at_dma_get_driver_data(
1899c5115953SNicolas Ferre 						struct platform_device *pdev)
1900c5115953SNicolas Ferre {
1901c5115953SNicolas Ferre 	if (pdev->dev.of_node) {
1902c5115953SNicolas Ferre 		const struct of_device_id *match;
1903c5115953SNicolas Ferre 		match = of_match_node(atmel_dma_dt_ids, pdev->dev.of_node);
1904c5115953SNicolas Ferre 		if (match == NULL)
190502f88be9SNicolas Ferre 			return NULL;
190602f88be9SNicolas Ferre 		return match->data;
1907c5115953SNicolas Ferre 	}
190802f88be9SNicolas Ferre 	return (struct at_dma_platform_data *)
190902f88be9SNicolas Ferre 			platform_get_device_id(pdev)->driver_data;
1910c5115953SNicolas Ferre }
1911c5115953SNicolas Ferre 
1912dc78baa2SNicolas Ferre /**
1913dc78baa2SNicolas Ferre  * at_dma_off - disable DMA controller
1914dc78baa2SNicolas Ferre  * @atdma: the Atmel HDAMC device
1915dc78baa2SNicolas Ferre  */
at_dma_off(struct at_dma * atdma)1916dc78baa2SNicolas Ferre static void at_dma_off(struct at_dma *atdma)
1917dc78baa2SNicolas Ferre {
1918dc78baa2SNicolas Ferre 	dma_writel(atdma, EN, 0);
1919dc78baa2SNicolas Ferre 
1920dc78baa2SNicolas Ferre 	/* disable all interrupts */
1921dc78baa2SNicolas Ferre 	dma_writel(atdma, EBCIDR, -1L);
1922dc78baa2SNicolas Ferre 
1923dc78baa2SNicolas Ferre 	/* confirm that all channels are disabled */
1924dc78baa2SNicolas Ferre 	while (dma_readl(atdma, CHSR) & atdma->all_chan_mask)
1925dc78baa2SNicolas Ferre 		cpu_relax();
1926dc78baa2SNicolas Ferre }
1927dc78baa2SNicolas Ferre 
at_dma_probe(struct platform_device * pdev)1928dc78baa2SNicolas Ferre static int __init at_dma_probe(struct platform_device *pdev)
1929dc78baa2SNicolas Ferre {
1930dc78baa2SNicolas Ferre 	struct at_dma		*atdma;
1931dc78baa2SNicolas Ferre 	int			irq;
1932dc78baa2SNicolas Ferre 	int			err;
1933dc78baa2SNicolas Ferre 	int			i;
19347fd63ccdSUwe Kleine-König 	const struct at_dma_platform_data *plat_dat;
1935dc78baa2SNicolas Ferre 
193602f88be9SNicolas Ferre 	/* setup platform data for each SoC */
193702f88be9SNicolas Ferre 	dma_cap_set(DMA_MEMCPY, at91sam9rl_config.cap_mask);
19385abecfa5SMaxime Ripard 	dma_cap_set(DMA_INTERLEAVE, at91sam9g45_config.cap_mask);
193902f88be9SNicolas Ferre 	dma_cap_set(DMA_MEMCPY, at91sam9g45_config.cap_mask);
19404d112426SMaxime Ripard 	dma_cap_set(DMA_MEMSET, at91sam9g45_config.cap_mask);
194167d25f0dSMaxime Ripard 	dma_cap_set(DMA_MEMSET_SG, at91sam9g45_config.cap_mask);
19424d112426SMaxime Ripard 	dma_cap_set(DMA_PRIVATE, at91sam9g45_config.cap_mask);
194302f88be9SNicolas Ferre 	dma_cap_set(DMA_SLAVE, at91sam9g45_config.cap_mask);
194467348450SNicolas Ferre 
194567348450SNicolas Ferre 	/* get DMA parameters from controller type */
194602f88be9SNicolas Ferre 	plat_dat = at_dma_get_driver_data(pdev);
194702f88be9SNicolas Ferre 	if (!plat_dat)
194802f88be9SNicolas Ferre 		return -ENODEV;
1949dc78baa2SNicolas Ferre 
19505f1d429bSTudor Ambarus 	atdma = devm_kzalloc(&pdev->dev,
19515f1d429bSTudor Ambarus 			     struct_size(atdma, chan, plat_dat->nr_channels),
19525f1d429bSTudor Ambarus 			     GFP_KERNEL);
19535f1d429bSTudor Ambarus 	if (!atdma)
19545f1d429bSTudor Ambarus 		return -ENOMEM;
19555f1d429bSTudor Ambarus 
19568bfe4a61STudor Ambarus 	atdma->regs = devm_platform_ioremap_resource(pdev, 0);
19578bfe4a61STudor Ambarus 	if (IS_ERR(atdma->regs))
19588bfe4a61STudor Ambarus 		return PTR_ERR(atdma->regs);
1959dc78baa2SNicolas Ferre 
1960dc78baa2SNicolas Ferre 	irq = platform_get_irq(pdev, 0);
1961dc78baa2SNicolas Ferre 	if (irq < 0)
1962dc78baa2SNicolas Ferre 		return irq;
1963dc78baa2SNicolas Ferre 
196467348450SNicolas Ferre 	/* discover transaction capabilities */
19651c1114d8STudor Ambarus 	atdma->dma_device.cap_mask = plat_dat->cap_mask;
196602f88be9SNicolas Ferre 	atdma->all_chan_mask = (1 << plat_dat->nr_channels) - 1;
1967dc78baa2SNicolas Ferre 
19684c15a4c7STudor Ambarus 	atdma->clk = devm_clk_get(&pdev->dev, "dma_clk");
19698bfe4a61STudor Ambarus 	if (IS_ERR(atdma->clk))
19708bfe4a61STudor Ambarus 		return PTR_ERR(atdma->clk);
19718bfe4a61STudor Ambarus 
1972f784d9c9SBoris BREZILLON 	err = clk_prepare_enable(atdma->clk);
1973f784d9c9SBoris BREZILLON 	if (err)
19744c15a4c7STudor Ambarus 		return err;
1975dc78baa2SNicolas Ferre 
1976dc78baa2SNicolas Ferre 	/* force dma off, just in case */
1977dc78baa2SNicolas Ferre 	at_dma_off(atdma);
1978dc78baa2SNicolas Ferre 
1979dc78baa2SNicolas Ferre 	err = request_irq(irq, at_dma_interrupt, 0, "at_hdmac", atdma);
1980dc78baa2SNicolas Ferre 	if (err)
1981dc78baa2SNicolas Ferre 		goto err_irq;
1982dc78baa2SNicolas Ferre 
1983dc78baa2SNicolas Ferre 	platform_set_drvdata(pdev, atdma);
1984dc78baa2SNicolas Ferre 
1985dc78baa2SNicolas Ferre 	/* create a pool of consistent memory blocks for hardware descriptors */
1986ac803b56STudor Ambarus 	atdma->lli_pool = dma_pool_create("at_hdmac_lli_pool",
1987ac803b56STudor Ambarus 					  &pdev->dev, sizeof(struct at_lli),
1988dc78baa2SNicolas Ferre 					  4 /* word alignment */, 0);
1989ac803b56STudor Ambarus 	if (!atdma->lli_pool) {
1990ac803b56STudor Ambarus 		dev_err(&pdev->dev, "Unable to allocate DMA LLI descriptor pool\n");
1991dc78baa2SNicolas Ferre 		err = -ENOMEM;
19924d112426SMaxime Ripard 		goto err_desc_pool_create;
19934d112426SMaxime Ripard 	}
19944d112426SMaxime Ripard 
19954d112426SMaxime Ripard 	/* create a pool of consistent memory blocks for memset blocks */
19964d112426SMaxime Ripard 	atdma->memset_pool = dma_pool_create("at_hdmac_memset_pool",
19974d112426SMaxime Ripard 					     &pdev->dev, sizeof(int), 4, 0);
19984d112426SMaxime Ripard 	if (!atdma->memset_pool) {
19994d112426SMaxime Ripard 		dev_err(&pdev->dev, "No memory for memset dma pool\n");
20004d112426SMaxime Ripard 		err = -ENOMEM;
20014d112426SMaxime Ripard 		goto err_memset_pool_create;
2002dc78baa2SNicolas Ferre 	}
2003dc78baa2SNicolas Ferre 
2004dc78baa2SNicolas Ferre 	/* clear any pending interrupt */
2005dc78baa2SNicolas Ferre 	while (dma_readl(atdma, EBCISR))
2006dc78baa2SNicolas Ferre 		cpu_relax();
2007dc78baa2SNicolas Ferre 
2008dc78baa2SNicolas Ferre 	/* initialize channels related values */
20091c1114d8STudor Ambarus 	INIT_LIST_HEAD(&atdma->dma_device.channels);
201002f88be9SNicolas Ferre 	for (i = 0; i < plat_dat->nr_channels; i++) {
2011dc78baa2SNicolas Ferre 		struct at_dma_chan	*atchan = &atdma->chan[i];
2012dc78baa2SNicolas Ferre 
2013bbe89c8eSLudovic Desroches 		atchan->mem_if = AT_DMA_MEM_IF;
2014bbe89c8eSLudovic Desroches 		atchan->per_if = AT_DMA_PER_IF;
2015dc78baa2SNicolas Ferre 
2016dc78baa2SNicolas Ferre 		atchan->ch_regs = atdma->regs + ch_regs(i);
2017dc78baa2SNicolas Ferre 		atchan->mask = 1 << i;
2018dc78baa2SNicolas Ferre 
2019ac803b56STudor Ambarus 		atchan->atdma = atdma;
2020ac803b56STudor Ambarus 		atchan->vc.desc_free = atdma_desc_free;
2021ac803b56STudor Ambarus 		vchan_init(&atchan->vc, &atdma->dma_device);
2022bda3a47cSNikolaus Voss 		atc_enable_chan_irq(atdma, i);
2023dc78baa2SNicolas Ferre 	}
2024dc78baa2SNicolas Ferre 
2025dc78baa2SNicolas Ferre 	/* set base routines */
20261c1114d8STudor Ambarus 	atdma->dma_device.device_alloc_chan_resources = atc_alloc_chan_resources;
20271c1114d8STudor Ambarus 	atdma->dma_device.device_free_chan_resources = atc_free_chan_resources;
20281c1114d8STudor Ambarus 	atdma->dma_device.device_tx_status = atc_tx_status;
20291c1114d8STudor Ambarus 	atdma->dma_device.device_issue_pending = atc_issue_pending;
20301c1114d8STudor Ambarus 	atdma->dma_device.dev = &pdev->dev;
2031dc78baa2SNicolas Ferre 
2032dc78baa2SNicolas Ferre 	/* set prep routines based on capability */
20331c1114d8STudor Ambarus 	if (dma_has_cap(DMA_INTERLEAVE, atdma->dma_device.cap_mask))
20341c1114d8STudor Ambarus 		atdma->dma_device.device_prep_interleaved_dma = atc_prep_dma_interleaved;
20355abecfa5SMaxime Ripard 
20361c1114d8STudor Ambarus 	if (dma_has_cap(DMA_MEMCPY, atdma->dma_device.cap_mask))
20371c1114d8STudor Ambarus 		atdma->dma_device.device_prep_dma_memcpy = atc_prep_dma_memcpy;
2038dc78baa2SNicolas Ferre 
20391c1114d8STudor Ambarus 	if (dma_has_cap(DMA_MEMSET, atdma->dma_device.cap_mask)) {
20401c1114d8STudor Ambarus 		atdma->dma_device.device_prep_dma_memset = atc_prep_dma_memset;
20411c1114d8STudor Ambarus 		atdma->dma_device.device_prep_dma_memset_sg = atc_prep_dma_memset_sg;
20421c1114d8STudor Ambarus 		atdma->dma_device.fill_align = DMAENGINE_ALIGN_4_BYTES;
20434d112426SMaxime Ripard 	}
20444d112426SMaxime Ripard 
20451c1114d8STudor Ambarus 	if (dma_has_cap(DMA_SLAVE, atdma->dma_device.cap_mask)) {
20461c1114d8STudor Ambarus 		atdma->dma_device.device_prep_slave_sg = atc_prep_slave_sg;
2047d7db8080SNicolas Ferre 		/* controller can do slave DMA: can trigger cyclic transfers */
20481c1114d8STudor Ambarus 		dma_cap_set(DMA_CYCLIC, atdma->dma_device.cap_mask);
20491c1114d8STudor Ambarus 		atdma->dma_device.device_prep_dma_cyclic = atc_prep_dma_cyclic;
20501c1114d8STudor Ambarus 		atdma->dma_device.device_config = atc_config;
20511c1114d8STudor Ambarus 		atdma->dma_device.device_pause = atc_pause;
20521c1114d8STudor Ambarus 		atdma->dma_device.device_resume = atc_resume;
20531c1114d8STudor Ambarus 		atdma->dma_device.device_terminate_all = atc_terminate_all;
20541c1114d8STudor Ambarus 		atdma->dma_device.src_addr_widths = ATC_DMA_BUSWIDTHS;
20551c1114d8STudor Ambarus 		atdma->dma_device.dst_addr_widths = ATC_DMA_BUSWIDTHS;
20561c1114d8STudor Ambarus 		atdma->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
20571c1114d8STudor Ambarus 		atdma->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
2058d7db8080SNicolas Ferre 	}
2059808347f6SNicolas Ferre 
2060dc78baa2SNicolas Ferre 	dma_writel(atdma, EN, AT_DMA_ENABLE);
2061dc78baa2SNicolas Ferre 
2062c678fa66SDave Jiang 	dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s%s), %d channels\n",
20631c1114d8STudor Ambarus 	  dma_has_cap(DMA_MEMCPY, atdma->dma_device.cap_mask) ? "cpy " : "",
20641c1114d8STudor Ambarus 	  dma_has_cap(DMA_MEMSET, atdma->dma_device.cap_mask) ? "set " : "",
20651c1114d8STudor Ambarus 	  dma_has_cap(DMA_SLAVE, atdma->dma_device.cap_mask)  ? "slave " : "",
206602f88be9SNicolas Ferre 	  plat_dat->nr_channels);
2067dc78baa2SNicolas Ferre 
20681c1114d8STudor Ambarus 	err = dma_async_device_register(&atdma->dma_device);
2069c47e6403STudor Ambarus 	if (err) {
2070c47e6403STudor Ambarus 		dev_err(&pdev->dev, "Unable to register: %d.\n", err);
2071c47e6403STudor Ambarus 		goto err_dma_async_device_register;
2072c47e6403STudor Ambarus 	}
2073dc78baa2SNicolas Ferre 
2074bbe89c8eSLudovic Desroches 	/*
2075bbe89c8eSLudovic Desroches 	 * Do not return an error if the dmac node is not present in order to
2076bbe89c8eSLudovic Desroches 	 * not break the existing way of requesting channel with
2077bbe89c8eSLudovic Desroches 	 * dma_request_channel().
2078bbe89c8eSLudovic Desroches 	 */
2079bbe89c8eSLudovic Desroches 	if (pdev->dev.of_node) {
2080bbe89c8eSLudovic Desroches 		err = of_dma_controller_register(pdev->dev.of_node,
2081bbe89c8eSLudovic Desroches 						 at_dma_xlate, atdma);
2082bbe89c8eSLudovic Desroches 		if (err) {
2083bbe89c8eSLudovic Desroches 			dev_err(&pdev->dev, "could not register of_dma_controller\n");
2084bbe89c8eSLudovic Desroches 			goto err_of_dma_controller_register;
2085bbe89c8eSLudovic Desroches 		}
2086bbe89c8eSLudovic Desroches 	}
2087bbe89c8eSLudovic Desroches 
2088dc78baa2SNicolas Ferre 	return 0;
2089dc78baa2SNicolas Ferre 
2090bbe89c8eSLudovic Desroches err_of_dma_controller_register:
20911c1114d8STudor Ambarus 	dma_async_device_unregister(&atdma->dma_device);
2092c47e6403STudor Ambarus err_dma_async_device_register:
20934d112426SMaxime Ripard 	dma_pool_destroy(atdma->memset_pool);
20944d112426SMaxime Ripard err_memset_pool_create:
2095ac803b56STudor Ambarus 	dma_pool_destroy(atdma->lli_pool);
20964d112426SMaxime Ripard err_desc_pool_create:
2097dc78baa2SNicolas Ferre 	free_irq(platform_get_irq(pdev, 0), atdma);
2098dc78baa2SNicolas Ferre err_irq:
2099f784d9c9SBoris BREZILLON 	clk_disable_unprepare(atdma->clk);
2100dc78baa2SNicolas Ferre 	return err;
2101dc78baa2SNicolas Ferre }
2102dc78baa2SNicolas Ferre 
at_dma_remove(struct platform_device * pdev)21031d1bbd30SMaxin B. John static int at_dma_remove(struct platform_device *pdev)
2104dc78baa2SNicolas Ferre {
2105dc78baa2SNicolas Ferre 	struct at_dma		*atdma = platform_get_drvdata(pdev);
2106dc78baa2SNicolas Ferre 	struct dma_chan		*chan, *_chan;
2107dc78baa2SNicolas Ferre 
2108dc78baa2SNicolas Ferre 	at_dma_off(atdma);
210977e75fdaSRichard Genoud 	if (pdev->dev.of_node)
211077e75fdaSRichard Genoud 		of_dma_controller_free(pdev->dev.of_node);
21111c1114d8STudor Ambarus 	dma_async_device_unregister(&atdma->dma_device);
2112dc78baa2SNicolas Ferre 
21134d112426SMaxime Ripard 	dma_pool_destroy(atdma->memset_pool);
2114ac803b56STudor Ambarus 	dma_pool_destroy(atdma->lli_pool);
2115dc78baa2SNicolas Ferre 	free_irq(platform_get_irq(pdev, 0), atdma);
2116dc78baa2SNicolas Ferre 
21171c1114d8STudor Ambarus 	list_for_each_entry_safe(chan, _chan, &atdma->dma_device.channels,
2118dc78baa2SNicolas Ferre 			device_node) {
2119dc78baa2SNicolas Ferre 		/* Disable interrupts */
2120bda3a47cSNikolaus Voss 		atc_disable_chan_irq(atdma, chan->chan_id);
2121dc78baa2SNicolas Ferre 		list_del(&chan->device_node);
2122dc78baa2SNicolas Ferre 	}
2123dc78baa2SNicolas Ferre 
2124f784d9c9SBoris BREZILLON 	clk_disable_unprepare(atdma->clk);
2125dc78baa2SNicolas Ferre 
2126dc78baa2SNicolas Ferre 	return 0;
2127dc78baa2SNicolas Ferre }
2128dc78baa2SNicolas Ferre 
at_dma_shutdown(struct platform_device * pdev)2129dc78baa2SNicolas Ferre static void at_dma_shutdown(struct platform_device *pdev)
2130dc78baa2SNicolas Ferre {
2131dc78baa2SNicolas Ferre 	struct at_dma	*atdma = platform_get_drvdata(pdev);
2132dc78baa2SNicolas Ferre 
2133dc78baa2SNicolas Ferre 	at_dma_off(platform_get_drvdata(pdev));
2134f784d9c9SBoris BREZILLON 	clk_disable_unprepare(atdma->clk);
2135dc78baa2SNicolas Ferre }
2136dc78baa2SNicolas Ferre 
at_dma_prepare(struct device * dev)2137c0ba5947SNicolas Ferre static int at_dma_prepare(struct device *dev)
2138c0ba5947SNicolas Ferre {
21395c4a74a4SWolfram Sang 	struct at_dma *atdma = dev_get_drvdata(dev);
2140c0ba5947SNicolas Ferre 	struct dma_chan *chan, *_chan;
2141c0ba5947SNicolas Ferre 
21421c1114d8STudor Ambarus 	list_for_each_entry_safe(chan, _chan, &atdma->dma_device.channels,
2143c0ba5947SNicolas Ferre 			device_node) {
2144c0ba5947SNicolas Ferre 		struct at_dma_chan *atchan = to_at_dma_chan(chan);
2145c0ba5947SNicolas Ferre 		/* wait for transaction completion (except in cyclic case) */
21463c477482SNicolas Ferre 		if (atc_chan_is_enabled(atchan) && !atc_chan_is_cyclic(atchan))
2147c0ba5947SNicolas Ferre 			return -EAGAIN;
2148c0ba5947SNicolas Ferre 	}
2149c0ba5947SNicolas Ferre 	return 0;
2150c0ba5947SNicolas Ferre }
2151c0ba5947SNicolas Ferre 
atc_suspend_cyclic(struct at_dma_chan * atchan)2152c0ba5947SNicolas Ferre static void atc_suspend_cyclic(struct at_dma_chan *atchan)
2153c0ba5947SNicolas Ferre {
2154ac803b56STudor Ambarus 	struct dma_chan	*chan = &atchan->vc.chan;
2155c0ba5947SNicolas Ferre 
2156c0ba5947SNicolas Ferre 	/* Channel should be paused by user
2157c0ba5947SNicolas Ferre 	 * do it anyway even if it is not done already */
21583c477482SNicolas Ferre 	if (!atc_chan_is_paused(atchan)) {
2159c0ba5947SNicolas Ferre 		dev_warn(chan2dev(chan),
2160c0ba5947SNicolas Ferre 		"cyclic channel not paused, should be done by channel user\n");
21614facfe7fSMaxime Ripard 		atc_pause(chan);
2162c0ba5947SNicolas Ferre 	}
2163c0ba5947SNicolas Ferre 
2164c0ba5947SNicolas Ferre 	/* now preserve additional data for cyclic operations */
2165c0ba5947SNicolas Ferre 	/* next descriptor address in the cyclic list */
2166c0ba5947SNicolas Ferre 	atchan->save_dscr = channel_readl(atchan, DSCR);
2167c0ba5947SNicolas Ferre 
2168c0ba5947SNicolas Ferre 	vdbg_dump_regs(atchan);
2169c0ba5947SNicolas Ferre }
2170c0ba5947SNicolas Ferre 
at_dma_suspend_noirq(struct device * dev)217133f82d14SDan Williams static int at_dma_suspend_noirq(struct device *dev)
2172dc78baa2SNicolas Ferre {
21735c4a74a4SWolfram Sang 	struct at_dma *atdma = dev_get_drvdata(dev);
2174c0ba5947SNicolas Ferre 	struct dma_chan *chan, *_chan;
2175dc78baa2SNicolas Ferre 
2176c0ba5947SNicolas Ferre 	/* preserve data */
21771c1114d8STudor Ambarus 	list_for_each_entry_safe(chan, _chan, &atdma->dma_device.channels,
2178c0ba5947SNicolas Ferre 			device_node) {
2179c0ba5947SNicolas Ferre 		struct at_dma_chan *atchan = to_at_dma_chan(chan);
2180c0ba5947SNicolas Ferre 
21813c477482SNicolas Ferre 		if (atc_chan_is_cyclic(atchan))
2182c0ba5947SNicolas Ferre 			atc_suspend_cyclic(atchan);
2183c0ba5947SNicolas Ferre 		atchan->save_cfg = channel_readl(atchan, CFG);
2184c0ba5947SNicolas Ferre 	}
2185c0ba5947SNicolas Ferre 	atdma->save_imr = dma_readl(atdma, EBCIMR);
2186c0ba5947SNicolas Ferre 
2187c0ba5947SNicolas Ferre 	/* disable DMA controller */
2188c0ba5947SNicolas Ferre 	at_dma_off(atdma);
2189f784d9c9SBoris BREZILLON 	clk_disable_unprepare(atdma->clk);
2190dc78baa2SNicolas Ferre 	return 0;
2191dc78baa2SNicolas Ferre }
2192dc78baa2SNicolas Ferre 
atc_resume_cyclic(struct at_dma_chan * atchan)2193c0ba5947SNicolas Ferre static void atc_resume_cyclic(struct at_dma_chan *atchan)
2194c0ba5947SNicolas Ferre {
2195ac803b56STudor Ambarus 	struct at_dma	*atdma = to_at_dma(atchan->vc.chan.device);
2196c0ba5947SNicolas Ferre 
2197c0ba5947SNicolas Ferre 	/* restore channel status for cyclic descriptors list:
2198c0ba5947SNicolas Ferre 	 * next descriptor in the cyclic list at the time of suspend */
2199c0ba5947SNicolas Ferre 	channel_writel(atchan, SADDR, 0);
2200c0ba5947SNicolas Ferre 	channel_writel(atchan, DADDR, 0);
2201c0ba5947SNicolas Ferre 	channel_writel(atchan, CTRLA, 0);
2202c0ba5947SNicolas Ferre 	channel_writel(atchan, CTRLB, 0);
2203c0ba5947SNicolas Ferre 	channel_writel(atchan, DSCR, atchan->save_dscr);
2204c0ba5947SNicolas Ferre 	dma_writel(atdma, CHER, atchan->mask);
2205c0ba5947SNicolas Ferre 
2206c0ba5947SNicolas Ferre 	/* channel pause status should be removed by channel user
2207c0ba5947SNicolas Ferre 	 * We cannot take the initiative to do it here */
2208c0ba5947SNicolas Ferre 
2209c0ba5947SNicolas Ferre 	vdbg_dump_regs(atchan);
2210c0ba5947SNicolas Ferre }
2211c0ba5947SNicolas Ferre 
at_dma_resume_noirq(struct device * dev)221233f82d14SDan Williams static int at_dma_resume_noirq(struct device *dev)
2213dc78baa2SNicolas Ferre {
22145c4a74a4SWolfram Sang 	struct at_dma *atdma = dev_get_drvdata(dev);
2215c0ba5947SNicolas Ferre 	struct dma_chan *chan, *_chan;
2216dc78baa2SNicolas Ferre 
2217c0ba5947SNicolas Ferre 	/* bring back DMA controller */
2218f784d9c9SBoris BREZILLON 	clk_prepare_enable(atdma->clk);
2219dc78baa2SNicolas Ferre 	dma_writel(atdma, EN, AT_DMA_ENABLE);
2220c0ba5947SNicolas Ferre 
2221c0ba5947SNicolas Ferre 	/* clear any pending interrupt */
2222c0ba5947SNicolas Ferre 	while (dma_readl(atdma, EBCISR))
2223c0ba5947SNicolas Ferre 		cpu_relax();
2224c0ba5947SNicolas Ferre 
2225c0ba5947SNicolas Ferre 	/* restore saved data */
2226c0ba5947SNicolas Ferre 	dma_writel(atdma, EBCIER, atdma->save_imr);
22271c1114d8STudor Ambarus 	list_for_each_entry_safe(chan, _chan, &atdma->dma_device.channels,
2228c0ba5947SNicolas Ferre 			device_node) {
2229c0ba5947SNicolas Ferre 		struct at_dma_chan *atchan = to_at_dma_chan(chan);
2230c0ba5947SNicolas Ferre 
2231c0ba5947SNicolas Ferre 		channel_writel(atchan, CFG, atchan->save_cfg);
22323c477482SNicolas Ferre 		if (atc_chan_is_cyclic(atchan))
2233c0ba5947SNicolas Ferre 			atc_resume_cyclic(atchan);
2234c0ba5947SNicolas Ferre 	}
2235dc78baa2SNicolas Ferre 	return 0;
2236dc78baa2SNicolas Ferre }
2237dc78baa2SNicolas Ferre 
2238c23cd8c9STudor Ambarus static const struct dev_pm_ops __maybe_unused at_dma_dev_pm_ops = {
2239c0ba5947SNicolas Ferre 	.prepare = at_dma_prepare,
224033f82d14SDan Williams 	.suspend_noirq = at_dma_suspend_noirq,
224133f82d14SDan Williams 	.resume_noirq = at_dma_resume_noirq,
224233f82d14SDan Williams };
224333f82d14SDan Williams 
2244dc78baa2SNicolas Ferre static struct platform_driver at_dma_driver = {
22451d1bbd30SMaxin B. John 	.remove		= at_dma_remove,
2246dc78baa2SNicolas Ferre 	.shutdown	= at_dma_shutdown,
224767348450SNicolas Ferre 	.id_table	= atdma_devtypes,
2248dc78baa2SNicolas Ferre 	.driver = {
2249dc78baa2SNicolas Ferre 		.name	= "at_hdmac",
2250c23cd8c9STudor Ambarus 		.pm	= pm_ptr(&at_dma_dev_pm_ops),
2251c5115953SNicolas Ferre 		.of_match_table	= of_match_ptr(atmel_dma_dt_ids),
2252dc78baa2SNicolas Ferre 	},
2253dc78baa2SNicolas Ferre };
2254dc78baa2SNicolas Ferre 
at_dma_init(void)2255dc78baa2SNicolas Ferre static int __init at_dma_init(void)
2256dc78baa2SNicolas Ferre {
2257dc78baa2SNicolas Ferre 	return platform_driver_probe(&at_dma_driver, at_dma_probe);
2258dc78baa2SNicolas Ferre }
225993d0bec2SEric Xu subsys_initcall(at_dma_init);
2260dc78baa2SNicolas Ferre 
at_dma_exit(void)2261dc78baa2SNicolas Ferre static void __exit at_dma_exit(void)
2262dc78baa2SNicolas Ferre {
2263dc78baa2SNicolas Ferre 	platform_driver_unregister(&at_dma_driver);
2264dc78baa2SNicolas Ferre }
2265dc78baa2SNicolas Ferre module_exit(at_dma_exit);
2266dc78baa2SNicolas Ferre 
2267dc78baa2SNicolas Ferre MODULE_DESCRIPTION("Atmel AHB DMA Controller driver");
2268dc78baa2SNicolas Ferre MODULE_AUTHOR("Nicolas Ferre <nicolas.ferre@atmel.com>");
2269ac803b56STudor Ambarus MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus@microchip.com>");
2270dc78baa2SNicolas Ferre MODULE_LICENSE("GPL");
2271dc78baa2SNicolas Ferre MODULE_ALIAS("platform:at_hdmac");
2272