Commit | Line | Data |
---|---|---|
9d831528 AD |
1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
2 | /* | |
3 | * Copyright 2013-2014 Freescale Semiconductor, Inc. | |
4 | * Copyright 2018 Angelo Dureghello <angelo@sysam.it> | |
5 | */ | |
6 | #ifndef _FSL_EDMA_COMMON_H_ | |
7 | #define _FSL_EDMA_COMMON_H_ | |
8 | ||
0fa89f97 | 9 | #include <linux/dma-direction.h> |
af802728 | 10 | #include <linux/platform_device.h> |
9d831528 AD |
11 | #include "virt-dma.h" |
12 | ||
9d831528 AD |
13 | #define EDMA_CR_EDBG BIT(1) |
14 | #define EDMA_CR_ERCA BIT(2) | |
15 | #define EDMA_CR_ERGA BIT(3) | |
16 | #define EDMA_CR_HOE BIT(4) | |
17 | #define EDMA_CR_HALT BIT(5) | |
18 | #define EDMA_CR_CLM BIT(6) | |
19 | #define EDMA_CR_EMLM BIT(7) | |
20 | #define EDMA_CR_ECX BIT(16) | |
21 | #define EDMA_CR_CX BIT(17) | |
22 | ||
4d6d3a90 AD |
23 | #define EDMA_SEEI_SEEI(x) ((x) & GENMASK(4, 0)) |
24 | #define EDMA_CEEI_CEEI(x) ((x) & GENMASK(4, 0)) | |
25 | #define EDMA_CINT_CINT(x) ((x) & GENMASK(4, 0)) | |
26 | #define EDMA_CERR_CERR(x) ((x) & GENMASK(4, 0)) | |
9d831528 | 27 | |
4d6d3a90 AD |
28 | #define EDMA_TCD_ATTR_DSIZE(x) (((x) & GENMASK(2, 0))) |
29 | #define EDMA_TCD_ATTR_DMOD(x) (((x) & GENMASK(4, 0)) << 3) | |
30 | #define EDMA_TCD_ATTR_SSIZE(x) (((x) & GENMASK(2, 0)) << 8) | |
31 | #define EDMA_TCD_ATTR_SMOD(x) (((x) & GENMASK(4, 0)) << 11) | |
9d831528 | 32 | |
4d6d3a90 AD |
33 | #define EDMA_TCD_CITER_CITER(x) ((x) & GENMASK(14, 0)) |
34 | #define EDMA_TCD_BITER_BITER(x) ((x) & GENMASK(14, 0)) | |
9d831528 AD |
35 | |
36 | #define EDMA_TCD_CSR_START BIT(0) | |
37 | #define EDMA_TCD_CSR_INT_MAJOR BIT(1) | |
38 | #define EDMA_TCD_CSR_INT_HALF BIT(2) | |
39 | #define EDMA_TCD_CSR_D_REQ BIT(3) | |
40 | #define EDMA_TCD_CSR_E_SG BIT(4) | |
41 | #define EDMA_TCD_CSR_E_LINK BIT(5) | |
42 | #define EDMA_TCD_CSR_ACTIVE BIT(6) | |
43 | #define EDMA_TCD_CSR_DONE BIT(7) | |
44 | ||
72f5801a FL |
45 | #define EDMA_V3_TCD_NBYTES_MLOFF_NBYTES(x) ((x) & GENMASK(9, 0)) |
46 | #define EDMA_V3_TCD_NBYTES_MLOFF(x) (x << 10) | |
47 | #define EDMA_V3_TCD_NBYTES_DMLOE (1 << 30) | |
48 | #define EDMA_V3_TCD_NBYTES_SMLOE (1 << 31) | |
49 | ||
9d831528 AD |
50 | #define EDMAMUX_CHCFG_DIS 0x0 |
51 | #define EDMAMUX_CHCFG_ENBL 0x80 | |
52 | #define EDMAMUX_CHCFG_SOURCE(n) ((n) & 0x3F) | |
53 | ||
54 | #define DMAMUX_NR 2 | |
55 | ||
7536f8b3 FL |
56 | #define EDMA_TCD 0x1000 |
57 | ||
9d831528 AD |
58 | #define FSL_EDMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ |
59 | BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ | |
60 | BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \ | |
61 | BIT(DMA_SLAVE_BUSWIDTH_8_BYTES)) | |
72f5801a FL |
62 | |
63 | #define EDMA_V3_CH_SBR_RD BIT(22) | |
64 | #define EDMA_V3_CH_SBR_WR BIT(21) | |
65 | #define EDMA_V3_CH_CSR_ERQ BIT(0) | |
66 | #define EDMA_V3_CH_CSR_EARQ BIT(1) | |
67 | #define EDMA_V3_CH_CSR_EEI BIT(2) | |
68 | #define EDMA_V3_CH_CSR_DONE BIT(30) | |
69 | #define EDMA_V3_CH_CSR_ACTIVE BIT(31) | |
70 | ||
9d831528 AD |
71 | enum fsl_edma_pm_state { |
72 | RUNNING = 0, | |
73 | SUSPENDED, | |
74 | }; | |
75 | ||
76 | struct fsl_edma_hw_tcd { | |
77 | __le32 saddr; | |
78 | __le16 soff; | |
79 | __le16 attr; | |
80 | __le32 nbytes; | |
81 | __le32 slast; | |
82 | __le32 daddr; | |
83 | __le16 doff; | |
84 | __le16 citer; | |
85 | __le32 dlast_sga; | |
86 | __le16 csr; | |
87 | __le16 biter; | |
88 | }; | |
89 | ||
72f5801a FL |
90 | struct fsl_edma3_ch_reg { |
91 | __le32 ch_csr; | |
92 | __le32 ch_es; | |
93 | __le32 ch_int; | |
94 | __le32 ch_sbr; | |
95 | __le32 ch_pri; | |
96 | __le32 ch_mux; | |
97 | __le32 ch_mattr; /* edma4, reserved for edma3 */ | |
98 | __le32 ch_reserved; | |
99 | struct fsl_edma_hw_tcd tcd; | |
100 | } __packed; | |
101 | ||
377eaf3b AD |
102 | /* |
103 | * These are iomem pointers, for both v32 and v64. | |
104 | */ | |
105 | struct edma_regs { | |
106 | void __iomem *cr; | |
107 | void __iomem *es; | |
108 | void __iomem *erqh; | |
109 | void __iomem *erql; /* aka erq on v32 */ | |
110 | void __iomem *eeih; | |
111 | void __iomem *eeil; /* aka eei on v32 */ | |
112 | void __iomem *seei; | |
113 | void __iomem *ceei; | |
114 | void __iomem *serq; | |
115 | void __iomem *cerq; | |
116 | void __iomem *cint; | |
117 | void __iomem *cerr; | |
118 | void __iomem *ssrt; | |
119 | void __iomem *cdne; | |
120 | void __iomem *inth; | |
121 | void __iomem *intl; | |
122 | void __iomem *errh; | |
123 | void __iomem *errl; | |
377eaf3b AD |
124 | }; |
125 | ||
9d831528 AD |
126 | struct fsl_edma_sw_tcd { |
127 | dma_addr_t ptcd; | |
128 | struct fsl_edma_hw_tcd *vtcd; | |
129 | }; | |
130 | ||
9d831528 AD |
131 | struct fsl_edma_chan { |
132 | struct virt_dma_chan vchan; | |
133 | enum dma_status status; | |
134 | enum fsl_edma_pm_state pm_state; | |
135 | bool idle; | |
136 | u32 slave_id; | |
137 | struct fsl_edma_engine *edma; | |
138 | struct fsl_edma_desc *edesc; | |
0e819e35 VK |
139 | struct dma_slave_config cfg; |
140 | u32 attr; | |
e0674853 | 141 | bool is_sw; |
9d831528 | 142 | struct dma_pool *tcd_pool; |
0fa89f97 LT |
143 | dma_addr_t dma_dev_addr; |
144 | u32 dma_dev_size; | |
145 | enum dma_data_direction dma_dir; | |
9b05554c | 146 | char chan_name[32]; |
7536f8b3 | 147 | struct fsl_edma_hw_tcd __iomem *tcd; |
72f5801a FL |
148 | u32 real_count; |
149 | struct work_struct issue_worker; | |
150 | struct platform_device *pdev; | |
151 | struct device *pd_dev; | |
152 | u32 srcid; | |
153 | struct clk *clk; | |
154 | int priority; | |
155 | int hw_chanid; | |
156 | int txirq; | |
157 | bool is_rxchan; | |
158 | bool is_remote; | |
159 | bool is_multi_fifo; | |
9d831528 AD |
160 | }; |
161 | ||
162 | struct fsl_edma_desc { | |
163 | struct virt_dma_desc vdesc; | |
164 | struct fsl_edma_chan *echan; | |
165 | bool iscyclic; | |
0e819e35 | 166 | enum dma_transfer_direction dirn; |
9d831528 AD |
167 | unsigned int n_tcds; |
168 | struct fsl_edma_sw_tcd tcd[]; | |
169 | }; | |
170 | ||
9e006b24 FL |
171 | #define FSL_EDMA_DRV_HAS_DMACLK BIT(0) |
172 | #define FSL_EDMA_DRV_MUX_SWAP BIT(1) | |
c26e6114 FL |
173 | #define FSL_EDMA_DRV_CONFIG32 BIT(2) |
174 | #define FSL_EDMA_DRV_WRAP_IO BIT(3) | |
175 | #define FSL_EDMA_DRV_EDMA64 BIT(4) | |
72f5801a FL |
176 | #define FSL_EDMA_DRV_HAS_PD BIT(5) |
177 | #define FSL_EDMA_DRV_HAS_CHCLK BIT(6) | |
178 | #define FSL_EDMA_DRV_HAS_CHMUX BIT(7) | |
179 | /* imx8 QM audio edma remote local swapped */ | |
180 | #define FSL_EDMA_DRV_QUIRK_SWAPPED BIT(8) | |
181 | /* control and status register is in tcd address space, edma3 reg layout */ | |
182 | #define FSL_EDMA_DRV_SPLIT_REG BIT(9) | |
183 | #define FSL_EDMA_DRV_BUS_8BYTE BIT(10) | |
184 | #define FSL_EDMA_DRV_DEV_TO_DEV BIT(11) | |
185 | #define FSL_EDMA_DRV_ALIGN_64BYTE BIT(12) | |
3c67c523 FL |
186 | /* Need clean CHn_CSR DONE before enable TCD's ESG */ |
187 | #define FSL_EDMA_DRV_CLEAR_DONE_E_SG BIT(13) | |
188 | /* Need clean CHn_CSR DONE before enable TCD's MAJORELINK */ | |
189 | #define FSL_EDMA_DRV_CLEAR_DONE_E_LINK BIT(14) | |
72f5801a FL |
190 | |
191 | #define FSL_EDMA_DRV_EDMA3 (FSL_EDMA_DRV_SPLIT_REG | \ | |
192 | FSL_EDMA_DRV_BUS_8BYTE | \ | |
193 | FSL_EDMA_DRV_DEV_TO_DEV | \ | |
3c67c523 FL |
194 | FSL_EDMA_DRV_ALIGN_64BYTE | \ |
195 | FSL_EDMA_DRV_CLEAR_DONE_E_SG | \ | |
196 | FSL_EDMA_DRV_CLEAR_DONE_E_LINK) | |
197 | ||
198 | #define FSL_EDMA_DRV_EDMA4 (FSL_EDMA_DRV_SPLIT_REG | \ | |
199 | FSL_EDMA_DRV_BUS_8BYTE | \ | |
200 | FSL_EDMA_DRV_DEV_TO_DEV | \ | |
201 | FSL_EDMA_DRV_ALIGN_64BYTE | \ | |
202 | FSL_EDMA_DRV_CLEAR_DONE_E_LINK) | |
72f5801a | 203 | |
af802728 | 204 | struct fsl_edma_drvdata { |
72f5801a FL |
205 | u32 dmamuxs; /* only used before v3 */ |
206 | u32 chreg_off; | |
207 | u32 chreg_space_sz; | |
9e006b24 | 208 | u32 flags; |
af802728 RG |
209 | int (*setup_irq)(struct platform_device *pdev, |
210 | struct fsl_edma_engine *fsl_edma); | |
211 | }; | |
212 | ||
9d831528 AD |
213 | struct fsl_edma_engine { |
214 | struct dma_device dma_dev; | |
215 | void __iomem *membase; | |
216 | void __iomem *muxbase[DMAMUX_NR]; | |
217 | struct clk *muxclk[DMAMUX_NR]; | |
232a7f18 | 218 | struct clk *dmaclk; |
72f5801a | 219 | struct clk *chclk; |
9d831528 | 220 | struct mutex fsl_edma_mutex; |
af802728 | 221 | const struct fsl_edma_drvdata *drvdata; |
9d831528 AD |
222 | u32 n_chans; |
223 | int txirq; | |
224 | int errirq; | |
225 | bool big_endian; | |
377eaf3b | 226 | struct edma_regs regs; |
72f5801a | 227 | u64 chan_masked; |
9d831528 AD |
228 | struct fsl_edma_chan chans[]; |
229 | }; | |
230 | ||
7536f8b3 FL |
231 | #define edma_read_tcdreg(chan, __name) \ |
232 | (sizeof(chan->tcd->__name) == sizeof(u32) ? \ | |
233 | edma_readl(chan->edma, &chan->tcd->__name) : \ | |
234 | edma_readw(chan->edma, &chan->tcd->__name)) | |
235 | ||
236 | #define edma_write_tcdreg(chan, val, __name) \ | |
237 | (sizeof(chan->tcd->__name) == sizeof(u32) ? \ | |
238 | edma_writel(chan->edma, (u32 __force)val, &chan->tcd->__name) : \ | |
239 | edma_writew(chan->edma, (u16 __force)val, &chan->tcd->__name)) | |
240 | ||
72f5801a FL |
241 | #define edma_readl_chreg(chan, __name) \ |
242 | edma_readl(chan->edma, \ | |
243 | (void __iomem *)&(container_of(chan->tcd, struct fsl_edma3_ch_reg, tcd)->__name)) | |
244 | ||
245 | #define edma_writel_chreg(chan, val, __name) \ | |
246 | edma_writel(chan->edma, val, \ | |
247 | (void __iomem *)&(container_of(chan->tcd, struct fsl_edma3_ch_reg, tcd)->__name)) | |
248 | ||
9d831528 AD |
249 | /* |
250 | * R/W functions for big- or little-endian registers: | |
251 | * The eDMA controller's endian is independent of the CPU core's endian. | |
252 | * For the big-endian IP module, the offset for 8-bit or 16-bit registers | |
253 | * should also be swapped opposite to that in little-endian IP. | |
254 | */ | |
255 | static inline u32 edma_readl(struct fsl_edma_engine *edma, void __iomem *addr) | |
256 | { | |
257 | if (edma->big_endian) | |
258 | return ioread32be(addr); | |
259 | else | |
260 | return ioread32(addr); | |
261 | } | |
262 | ||
7536f8b3 FL |
263 | static inline u16 edma_readw(struct fsl_edma_engine *edma, void __iomem *addr) |
264 | { | |
265 | if (edma->big_endian) | |
266 | return ioread16be(addr); | |
267 | else | |
268 | return ioread16(addr); | |
269 | } | |
270 | ||
9d831528 AD |
271 | static inline void edma_writeb(struct fsl_edma_engine *edma, |
272 | u8 val, void __iomem *addr) | |
273 | { | |
274 | /* swap the reg offset for these in big-endian mode */ | |
275 | if (edma->big_endian) | |
276 | iowrite8(val, (void __iomem *)((unsigned long)addr ^ 0x3)); | |
277 | else | |
278 | iowrite8(val, addr); | |
279 | } | |
280 | ||
281 | static inline void edma_writew(struct fsl_edma_engine *edma, | |
282 | u16 val, void __iomem *addr) | |
283 | { | |
284 | /* swap the reg offset for these in big-endian mode */ | |
285 | if (edma->big_endian) | |
286 | iowrite16be(val, (void __iomem *)((unsigned long)addr ^ 0x2)); | |
287 | else | |
288 | iowrite16(val, addr); | |
289 | } | |
290 | ||
291 | static inline void edma_writel(struct fsl_edma_engine *edma, | |
292 | u32 val, void __iomem *addr) | |
293 | { | |
294 | if (edma->big_endian) | |
295 | iowrite32be(val, addr); | |
296 | else | |
297 | iowrite32(val, addr); | |
298 | } | |
299 | ||
300 | static inline struct fsl_edma_chan *to_fsl_edma_chan(struct dma_chan *chan) | |
301 | { | |
302 | return container_of(chan, struct fsl_edma_chan, vchan.chan); | |
303 | } | |
304 | ||
72f5801a FL |
305 | static inline u32 fsl_edma_drvflags(struct fsl_edma_chan *fsl_chan) |
306 | { | |
307 | return fsl_chan->edma->drvdata->flags; | |
308 | } | |
309 | ||
9d831528 AD |
310 | static inline struct fsl_edma_desc *to_fsl_edma_desc(struct virt_dma_desc *vd) |
311 | { | |
312 | return container_of(vd, struct fsl_edma_desc, vdesc); | |
313 | } | |
314 | ||
79434f9b FL |
315 | static inline void fsl_edma_err_chan_handler(struct fsl_edma_chan *fsl_chan) |
316 | { | |
317 | fsl_chan->status = DMA_ERROR; | |
318 | fsl_chan->idle = true; | |
319 | } | |
320 | ||
321 | void fsl_edma_tx_chan_handler(struct fsl_edma_chan *fsl_chan); | |
9d831528 AD |
322 | void fsl_edma_disable_request(struct fsl_edma_chan *fsl_chan); |
323 | void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan, | |
324 | unsigned int slot, bool enable); | |
325 | void fsl_edma_free_desc(struct virt_dma_desc *vdesc); | |
326 | int fsl_edma_terminate_all(struct dma_chan *chan); | |
327 | int fsl_edma_pause(struct dma_chan *chan); | |
328 | int fsl_edma_resume(struct dma_chan *chan); | |
329 | int fsl_edma_slave_config(struct dma_chan *chan, | |
330 | struct dma_slave_config *cfg); | |
331 | enum dma_status fsl_edma_tx_status(struct dma_chan *chan, | |
332 | dma_cookie_t cookie, struct dma_tx_state *txstate); | |
333 | struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic( | |
334 | struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len, | |
335 | size_t period_len, enum dma_transfer_direction direction, | |
336 | unsigned long flags); | |
337 | struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg( | |
338 | struct dma_chan *chan, struct scatterlist *sgl, | |
339 | unsigned int sg_len, enum dma_transfer_direction direction, | |
340 | unsigned long flags, void *context); | |
e0674853 JZ |
341 | struct dma_async_tx_descriptor *fsl_edma_prep_memcpy( |
342 | struct dma_chan *chan, dma_addr_t dma_dst, dma_addr_t dma_src, | |
343 | size_t len, unsigned long flags); | |
9d831528 AD |
344 | void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan); |
345 | void fsl_edma_issue_pending(struct dma_chan *chan); | |
346 | int fsl_edma_alloc_chan_resources(struct dma_chan *chan); | |
347 | void fsl_edma_free_chan_resources(struct dma_chan *chan); | |
348 | void fsl_edma_cleanup_vchan(struct dma_device *dmadev); | |
377eaf3b | 349 | void fsl_edma_setup_regs(struct fsl_edma_engine *edma); |
9d831528 AD |
350 | |
351 | #endif /* _FSL_EDMA_COMMON_H_ */ |