xref: /openbmc/linux/drivers/dma/txx9dmac.h (revision c4c3c32d)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Driver for the TXx9 SoC DMA Controller
4  *
5  * Copyright (C) 2009 Atsushi Nemoto
6  */
7 #ifndef TXX9DMAC_H
8 #define TXX9DMAC_H
9 
10 #include <linux/dmaengine.h>
11 #include <asm/txx9/dmac.h>
12 
13 /*
14  * Design Notes:
15  *
16  * This DMAC have four channels and one FIFO buffer.  Each channel can
17  * be configured for memory-memory or device-memory transfer, but only
18  * one channel can do alignment-free memory-memory transfer at a time
19  * while the channel should occupy the FIFO buffer for effective
20  * transfers.
21  *
22  * Instead of dynamically assign the FIFO buffer to channels, I chose
23  * make one dedicated channel for memory-memory transfer.  The
24  * dedicated channel is public.  Other channels are private and used
25  * for slave transfer.  Some devices in the SoC are wired to certain
26  * DMA channel.
27  */
28 
29 #ifdef CONFIG_MACH_TX49XX
30 static inline bool txx9_dma_have_SMPCHN(void)
31 {
32 	return true;
33 }
34 #define TXX9_DMA_USE_SIMPLE_CHAIN
35 #else
36 static inline bool txx9_dma_have_SMPCHN(void)
37 {
38 	return false;
39 }
40 #endif
41 
42 #ifdef __LITTLE_ENDIAN
43 #ifdef CONFIG_MACH_TX49XX
44 #define CCR_LE	TXX9_DMA_CCR_LE
45 #define MCR_LE	0
46 #else
47 #define CCR_LE	0
48 #define MCR_LE	TXX9_DMA_MCR_LE
49 #endif
50 #else
51 #define CCR_LE	0
52 #define MCR_LE	0
53 #endif
54 
55 /*
56  * Redefine this macro to handle differences between 32- and 64-bit
57  * addressing, big vs. little endian, etc.
58  */
59 #ifdef __BIG_ENDIAN
60 #define TXX9_DMA_REG32(name)		u32 __pad_##name; u32 name
61 #else
62 #define TXX9_DMA_REG32(name)		u32 name; u32 __pad_##name
63 #endif
64 
65 /* Hardware register definitions. */
66 struct txx9dmac_cregs {
67 #if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)
68 	TXX9_DMA_REG32(CHAR);	/* Chain Address Register */
69 #else
70 	u64 CHAR;		/* Chain Address Register */
71 #endif
72 	u64 SAR;		/* Source Address Register */
73 	u64 DAR;		/* Destination Address Register */
74 	TXX9_DMA_REG32(CNTR);	/* Count Register */
75 	TXX9_DMA_REG32(SAIR);	/* Source Address Increment Register */
76 	TXX9_DMA_REG32(DAIR);	/* Destination Address Increment Register */
77 	TXX9_DMA_REG32(CCR);	/* Channel Control Register */
78 	TXX9_DMA_REG32(CSR);	/* Channel Status Register */
79 };
80 struct txx9dmac_cregs32 {
81 	u32 CHAR;
82 	u32 SAR;
83 	u32 DAR;
84 	u32 CNTR;
85 	u32 SAIR;
86 	u32 DAIR;
87 	u32 CCR;
88 	u32 CSR;
89 };
90 
91 struct txx9dmac_regs {
92 	/* per-channel registers */
93 	struct txx9dmac_cregs	CHAN[TXX9_DMA_MAX_NR_CHANNELS];
94 	u64	__pad[9];
95 	u64	MFDR;		/* Memory Fill Data Register */
96 	TXX9_DMA_REG32(MCR);	/* Master Control Register */
97 };
98 struct txx9dmac_regs32 {
99 	struct txx9dmac_cregs32	CHAN[TXX9_DMA_MAX_NR_CHANNELS];
100 	u32	__pad[9];
101 	u32	MFDR;
102 	u32	MCR;
103 };
104 
105 /* bits for MCR */
106 #define TXX9_DMA_MCR_EIS(ch)	(0x10000000<<(ch))
107 #define TXX9_DMA_MCR_DIS(ch)	(0x01000000<<(ch))
108 #define TXX9_DMA_MCR_RSFIF	0x00000080
109 #define TXX9_DMA_MCR_FIFUM(ch)	(0x00000008<<(ch))
110 #define TXX9_DMA_MCR_LE		0x00000004
111 #define TXX9_DMA_MCR_RPRT	0x00000002
112 #define TXX9_DMA_MCR_MSTEN	0x00000001
113 
114 /* bits for CCRn */
115 #define TXX9_DMA_CCR_IMMCHN	0x20000000
116 #define TXX9_DMA_CCR_USEXFSZ	0x10000000
117 #define TXX9_DMA_CCR_LE		0x08000000
118 #define TXX9_DMA_CCR_DBINH	0x04000000
119 #define TXX9_DMA_CCR_SBINH	0x02000000
120 #define TXX9_DMA_CCR_CHRST	0x01000000
121 #define TXX9_DMA_CCR_RVBYTE	0x00800000
122 #define TXX9_DMA_CCR_ACKPOL	0x00400000
123 #define TXX9_DMA_CCR_REQPL	0x00200000
124 #define TXX9_DMA_CCR_EGREQ	0x00100000
125 #define TXX9_DMA_CCR_CHDN	0x00080000
126 #define TXX9_DMA_CCR_DNCTL	0x00060000
127 #define TXX9_DMA_CCR_EXTRQ	0x00010000
128 #define TXX9_DMA_CCR_INTRQD	0x0000e000
129 #define TXX9_DMA_CCR_INTENE	0x00001000
130 #define TXX9_DMA_CCR_INTENC	0x00000800
131 #define TXX9_DMA_CCR_INTENT	0x00000400
132 #define TXX9_DMA_CCR_CHNEN	0x00000200
133 #define TXX9_DMA_CCR_XFACT	0x00000100
134 #define TXX9_DMA_CCR_SMPCHN	0x00000020
135 #define TXX9_DMA_CCR_XFSZ(order)	(((order) << 2) & 0x0000001c)
136 #define TXX9_DMA_CCR_XFSZ_1	TXX9_DMA_CCR_XFSZ(0)
137 #define TXX9_DMA_CCR_XFSZ_2	TXX9_DMA_CCR_XFSZ(1)
138 #define TXX9_DMA_CCR_XFSZ_4	TXX9_DMA_CCR_XFSZ(2)
139 #define TXX9_DMA_CCR_XFSZ_8	TXX9_DMA_CCR_XFSZ(3)
140 #define TXX9_DMA_CCR_XFSZ_X4	TXX9_DMA_CCR_XFSZ(4)
141 #define TXX9_DMA_CCR_XFSZ_X8	TXX9_DMA_CCR_XFSZ(5)
142 #define TXX9_DMA_CCR_XFSZ_X16	TXX9_DMA_CCR_XFSZ(6)
143 #define TXX9_DMA_CCR_XFSZ_X32	TXX9_DMA_CCR_XFSZ(7)
144 #define TXX9_DMA_CCR_MEMIO	0x00000002
145 #define TXX9_DMA_CCR_SNGAD	0x00000001
146 
147 /* bits for CSRn */
148 #define TXX9_DMA_CSR_CHNEN	0x00000400
149 #define TXX9_DMA_CSR_STLXFER	0x00000200
150 #define TXX9_DMA_CSR_XFACT	0x00000100
151 #define TXX9_DMA_CSR_ABCHC	0x00000080
152 #define TXX9_DMA_CSR_NCHNC	0x00000040
153 #define TXX9_DMA_CSR_NTRNFC	0x00000020
154 #define TXX9_DMA_CSR_EXTDN	0x00000010
155 #define TXX9_DMA_CSR_CFERR	0x00000008
156 #define TXX9_DMA_CSR_CHERR	0x00000004
157 #define TXX9_DMA_CSR_DESERR	0x00000002
158 #define TXX9_DMA_CSR_SORERR	0x00000001
159 
160 struct txx9dmac_chan {
161 	struct dma_chan		chan;
162 	struct dma_device	dma;
163 	struct txx9dmac_dev	*ddev;
164 	void __iomem		*ch_regs;
165 	struct tasklet_struct	tasklet;
166 	int			irq;
167 	u32			ccr;
168 
169 	spinlock_t		lock;
170 
171 	/* these other elements are all protected by lock */
172 	struct list_head	active_list;
173 	struct list_head	queue;
174 	struct list_head	free_list;
175 
176 	unsigned int		descs_allocated;
177 };
178 
179 struct txx9dmac_dev {
180 	void __iomem		*regs;
181 	struct tasklet_struct	tasklet;
182 	int			irq;
183 	struct txx9dmac_chan	*chan[TXX9_DMA_MAX_NR_CHANNELS];
184 	bool			have_64bit_regs;
185 	unsigned int		descsize;
186 };
187 
188 static inline bool __is_dmac64(const struct txx9dmac_dev *ddev)
189 {
190 	return ddev->have_64bit_regs;
191 }
192 
193 static inline bool is_dmac64(const struct txx9dmac_chan *dc)
194 {
195 	return __is_dmac64(dc->ddev);
196 }
197 
198 #ifdef TXX9_DMA_USE_SIMPLE_CHAIN
199 /* Hardware descriptor definition. (for simple-chain) */
200 struct txx9dmac_hwdesc {
201 #if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)
202 	TXX9_DMA_REG32(CHAR);
203 #else
204 	u64 CHAR;
205 #endif
206 	u64 SAR;
207 	u64 DAR;
208 	TXX9_DMA_REG32(CNTR);
209 };
210 struct txx9dmac_hwdesc32 {
211 	u32 CHAR;
212 	u32 SAR;
213 	u32 DAR;
214 	u32 CNTR;
215 };
216 #else
217 #define txx9dmac_hwdesc txx9dmac_cregs
218 #define txx9dmac_hwdesc32 txx9dmac_cregs32
219 #endif
220 
221 struct txx9dmac_desc {
222 	/* FIRST values the hardware uses */
223 	union {
224 		struct txx9dmac_hwdesc hwdesc;
225 		struct txx9dmac_hwdesc32 hwdesc32;
226 	};
227 
228 	/* THEN values for driver housekeeping */
229 	struct list_head		desc_node ____cacheline_aligned;
230 	struct list_head		tx_list;
231 	struct dma_async_tx_descriptor	txd;
232 	size_t				len;
233 };
234 
235 #ifdef TXX9_DMA_USE_SIMPLE_CHAIN
236 
237 static inline bool txx9dmac_chan_INTENT(struct txx9dmac_chan *dc)
238 {
239 	return (dc->ccr & TXX9_DMA_CCR_INTENT) != 0;
240 }
241 
242 static inline void txx9dmac_chan_set_INTENT(struct txx9dmac_chan *dc)
243 {
244 	dc->ccr |= TXX9_DMA_CCR_INTENT;
245 }
246 
247 static inline void txx9dmac_desc_set_INTENT(struct txx9dmac_dev *ddev,
248 					    struct txx9dmac_desc *desc)
249 {
250 }
251 
252 static inline void txx9dmac_chan_set_SMPCHN(struct txx9dmac_chan *dc)
253 {
254 	dc->ccr |= TXX9_DMA_CCR_SMPCHN;
255 }
256 
257 static inline void txx9dmac_desc_set_nosimple(struct txx9dmac_dev *ddev,
258 					      struct txx9dmac_desc *desc,
259 					      u32 sair, u32 dair, u32 ccr)
260 {
261 }
262 
263 #else /* TXX9_DMA_USE_SIMPLE_CHAIN */
264 
265 static inline bool txx9dmac_chan_INTENT(struct txx9dmac_chan *dc)
266 {
267 	return true;
268 }
269 
270 static void txx9dmac_chan_set_INTENT(struct txx9dmac_chan *dc)
271 {
272 }
273 
274 static inline void txx9dmac_desc_set_INTENT(struct txx9dmac_dev *ddev,
275 					    struct txx9dmac_desc *desc)
276 {
277 	if (__is_dmac64(ddev))
278 		desc->hwdesc.CCR |= TXX9_DMA_CCR_INTENT;
279 	else
280 		desc->hwdesc32.CCR |= TXX9_DMA_CCR_INTENT;
281 }
282 
283 static inline void txx9dmac_chan_set_SMPCHN(struct txx9dmac_chan *dc)
284 {
285 }
286 
287 static inline void txx9dmac_desc_set_nosimple(struct txx9dmac_dev *ddev,
288 					      struct txx9dmac_desc *desc,
289 					      u32 sai, u32 dai, u32 ccr)
290 {
291 	if (__is_dmac64(ddev)) {
292 		desc->hwdesc.SAIR = sai;
293 		desc->hwdesc.DAIR = dai;
294 		desc->hwdesc.CCR = ccr;
295 	} else {
296 		desc->hwdesc32.SAIR = sai;
297 		desc->hwdesc32.DAIR = dai;
298 		desc->hwdesc32.CCR = ccr;
299 	}
300 }
301 
302 #endif /* TXX9_DMA_USE_SIMPLE_CHAIN */
303 
304 #endif /* TXX9DMAC_H */
305