19d831528SAngelo Dureghello /* SPDX-License-Identifier: GPL-2.0+ */
29d831528SAngelo Dureghello /*
39d831528SAngelo Dureghello * Copyright 2013-2014 Freescale Semiconductor, Inc.
49d831528SAngelo Dureghello * Copyright 2018 Angelo Dureghello <angelo@sysam.it>
59d831528SAngelo Dureghello */
69d831528SAngelo Dureghello #ifndef _FSL_EDMA_COMMON_H_
79d831528SAngelo Dureghello #define _FSL_EDMA_COMMON_H_
89d831528SAngelo Dureghello
90fa89f97SLaurentiu Tudor #include <linux/dma-direction.h>
10af802728SRobin Gong #include <linux/platform_device.h>
119d831528SAngelo Dureghello #include "virt-dma.h"
129d831528SAngelo Dureghello
139d831528SAngelo Dureghello #define EDMA_CR_EDBG BIT(1)
149d831528SAngelo Dureghello #define EDMA_CR_ERCA BIT(2)
159d831528SAngelo Dureghello #define EDMA_CR_ERGA BIT(3)
169d831528SAngelo Dureghello #define EDMA_CR_HOE BIT(4)
179d831528SAngelo Dureghello #define EDMA_CR_HALT BIT(5)
189d831528SAngelo Dureghello #define EDMA_CR_CLM BIT(6)
199d831528SAngelo Dureghello #define EDMA_CR_EMLM BIT(7)
209d831528SAngelo Dureghello #define EDMA_CR_ECX BIT(16)
219d831528SAngelo Dureghello #define EDMA_CR_CX BIT(17)
229d831528SAngelo Dureghello
234d6d3a90SAngelo Dureghello #define EDMA_SEEI_SEEI(x) ((x) & GENMASK(4, 0))
244d6d3a90SAngelo Dureghello #define EDMA_CEEI_CEEI(x) ((x) & GENMASK(4, 0))
254d6d3a90SAngelo Dureghello #define EDMA_CINT_CINT(x) ((x) & GENMASK(4, 0))
264d6d3a90SAngelo Dureghello #define EDMA_CERR_CERR(x) ((x) & GENMASK(4, 0))
279d831528SAngelo Dureghello
284d6d3a90SAngelo Dureghello #define EDMA_TCD_ATTR_DSIZE(x) (((x) & GENMASK(2, 0)))
294d6d3a90SAngelo Dureghello #define EDMA_TCD_ATTR_DMOD(x) (((x) & GENMASK(4, 0)) << 3)
304d6d3a90SAngelo Dureghello #define EDMA_TCD_ATTR_SSIZE(x) (((x) & GENMASK(2, 0)) << 8)
314d6d3a90SAngelo Dureghello #define EDMA_TCD_ATTR_SMOD(x) (((x) & GENMASK(4, 0)) << 11)
329d831528SAngelo Dureghello
33*a79f949aSFrank Li #define EDMA_TCD_ITER_MASK GENMASK(14, 0)
34*a79f949aSFrank Li #define EDMA_TCD_CITER_CITER(x) ((x) & EDMA_TCD_ITER_MASK)
35*a79f949aSFrank Li #define EDMA_TCD_BITER_BITER(x) ((x) & EDMA_TCD_ITER_MASK)
369d831528SAngelo Dureghello
379d831528SAngelo Dureghello #define EDMA_TCD_CSR_START BIT(0)
389d831528SAngelo Dureghello #define EDMA_TCD_CSR_INT_MAJOR BIT(1)
399d831528SAngelo Dureghello #define EDMA_TCD_CSR_INT_HALF BIT(2)
409d831528SAngelo Dureghello #define EDMA_TCD_CSR_D_REQ BIT(3)
419d831528SAngelo Dureghello #define EDMA_TCD_CSR_E_SG BIT(4)
429d831528SAngelo Dureghello #define EDMA_TCD_CSR_E_LINK BIT(5)
439d831528SAngelo Dureghello #define EDMA_TCD_CSR_ACTIVE BIT(6)
449d831528SAngelo Dureghello #define EDMA_TCD_CSR_DONE BIT(7)
459d831528SAngelo Dureghello
4672f5801aSFrank Li #define EDMA_V3_TCD_NBYTES_MLOFF_NBYTES(x) ((x) & GENMASK(9, 0))
4772f5801aSFrank Li #define EDMA_V3_TCD_NBYTES_MLOFF(x) (x << 10)
4872f5801aSFrank Li #define EDMA_V3_TCD_NBYTES_DMLOE (1 << 30)
4972f5801aSFrank Li #define EDMA_V3_TCD_NBYTES_SMLOE (1 << 31)
5072f5801aSFrank Li
519d831528SAngelo Dureghello #define EDMAMUX_CHCFG_DIS 0x0
529d831528SAngelo Dureghello #define EDMAMUX_CHCFG_ENBL 0x80
539d831528SAngelo Dureghello #define EDMAMUX_CHCFG_SOURCE(n) ((n) & 0x3F)
549d831528SAngelo Dureghello
559d831528SAngelo Dureghello #define DMAMUX_NR 2
569d831528SAngelo Dureghello
577536f8b3SFrank Li #define EDMA_TCD 0x1000
587536f8b3SFrank Li
599d831528SAngelo Dureghello #define FSL_EDMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
609d831528SAngelo Dureghello BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
619d831528SAngelo Dureghello BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
629d831528SAngelo Dureghello BIT(DMA_SLAVE_BUSWIDTH_8_BYTES))
6372f5801aSFrank Li
6472f5801aSFrank Li #define EDMA_V3_CH_SBR_RD BIT(22)
6572f5801aSFrank Li #define EDMA_V3_CH_SBR_WR BIT(21)
6672f5801aSFrank Li #define EDMA_V3_CH_CSR_ERQ BIT(0)
6772f5801aSFrank Li #define EDMA_V3_CH_CSR_EARQ BIT(1)
6872f5801aSFrank Li #define EDMA_V3_CH_CSR_EEI BIT(2)
6972f5801aSFrank Li #define EDMA_V3_CH_CSR_DONE BIT(30)
7072f5801aSFrank Li #define EDMA_V3_CH_CSR_ACTIVE BIT(31)
7172f5801aSFrank Li
729d831528SAngelo Dureghello enum fsl_edma_pm_state {
739d831528SAngelo Dureghello RUNNING = 0,
749d831528SAngelo Dureghello SUSPENDED,
759d831528SAngelo Dureghello };
769d831528SAngelo Dureghello
779d831528SAngelo Dureghello struct fsl_edma_hw_tcd {
789d831528SAngelo Dureghello __le32 saddr;
799d831528SAngelo Dureghello __le16 soff;
809d831528SAngelo Dureghello __le16 attr;
819d831528SAngelo Dureghello __le32 nbytes;
829d831528SAngelo Dureghello __le32 slast;
839d831528SAngelo Dureghello __le32 daddr;
849d831528SAngelo Dureghello __le16 doff;
859d831528SAngelo Dureghello __le16 citer;
869d831528SAngelo Dureghello __le32 dlast_sga;
879d831528SAngelo Dureghello __le16 csr;
889d831528SAngelo Dureghello __le16 biter;
899d831528SAngelo Dureghello };
909d831528SAngelo Dureghello
9172f5801aSFrank Li struct fsl_edma_hw_tcd64 {
9272f5801aSFrank Li __le64 saddr;
9372f5801aSFrank Li __le16 soff;
9472f5801aSFrank Li __le16 attr;
9572f5801aSFrank Li __le32 nbytes;
9672f5801aSFrank Li __le64 slast;
9772f5801aSFrank Li __le64 daddr;
9872f5801aSFrank Li __le64 dlast_sga;
9972f5801aSFrank Li __le16 doff;
10072f5801aSFrank Li __le16 citer;
10172f5801aSFrank Li __le16 csr;
10272f5801aSFrank Li __le16 biter;
103377eaf3bSAngelo Dureghello } __packed;
104377eaf3bSAngelo Dureghello
105377eaf3bSAngelo Dureghello struct fsl_edma3_ch_reg {
106377eaf3bSAngelo Dureghello __le32 ch_csr;
107377eaf3bSAngelo Dureghello __le32 ch_es;
108377eaf3bSAngelo Dureghello __le32 ch_int;
109377eaf3bSAngelo Dureghello __le32 ch_sbr;
110377eaf3bSAngelo Dureghello __le32 ch_pri;
111377eaf3bSAngelo Dureghello __le32 ch_mux;
112377eaf3bSAngelo Dureghello __le32 ch_mattr; /* edma4, reserved for edma3 */
113377eaf3bSAngelo Dureghello __le32 ch_reserved;
114377eaf3bSAngelo Dureghello union {
115377eaf3bSAngelo Dureghello struct fsl_edma_hw_tcd tcd;
116377eaf3bSAngelo Dureghello struct fsl_edma_hw_tcd64 tcd64;
117377eaf3bSAngelo Dureghello };
118377eaf3bSAngelo Dureghello } __packed;
119377eaf3bSAngelo Dureghello
120377eaf3bSAngelo Dureghello /*
121377eaf3bSAngelo Dureghello * These are iomem pointers, for both v32 and v64.
122377eaf3bSAngelo Dureghello */
123377eaf3bSAngelo Dureghello struct edma_regs {
124377eaf3bSAngelo Dureghello void __iomem *cr;
125377eaf3bSAngelo Dureghello void __iomem *es;
126377eaf3bSAngelo Dureghello void __iomem *erqh;
1279d831528SAngelo Dureghello void __iomem *erql; /* aka erq on v32 */
1289d831528SAngelo Dureghello void __iomem *eeih;
1299d831528SAngelo Dureghello void __iomem *eeil; /* aka eei on v32 */
1309d831528SAngelo Dureghello void __iomem *seei;
1319d831528SAngelo Dureghello void __iomem *ceei;
1329d831528SAngelo Dureghello void __iomem *serq;
1339d831528SAngelo Dureghello void __iomem *cerq;
1349d831528SAngelo Dureghello void __iomem *cint;
1359d831528SAngelo Dureghello void __iomem *cerr;
1369d831528SAngelo Dureghello void __iomem *ssrt;
1379d831528SAngelo Dureghello void __iomem *cdne;
1389d831528SAngelo Dureghello void __iomem *inth;
1399d831528SAngelo Dureghello void __iomem *intl;
1400e819e35SVinod Koul void __iomem *errh;
1410e819e35SVinod Koul void __iomem *errl;
142e0674853SJoy Zou };
1439d831528SAngelo Dureghello
1440fa89f97SLaurentiu Tudor struct fsl_edma_sw_tcd {
1450fa89f97SLaurentiu Tudor dma_addr_t ptcd;
1460fa89f97SLaurentiu Tudor void *vtcd;
1479b05554cSFrank Li };
1487536f8b3SFrank Li
14972f5801aSFrank Li struct fsl_edma_chan {
15072f5801aSFrank Li struct virt_dma_chan vchan;
15172f5801aSFrank Li enum dma_status status;
15272f5801aSFrank Li enum fsl_edma_pm_state pm_state;
15372f5801aSFrank Li bool idle;
15472f5801aSFrank Li u32 slave_id;
15572f5801aSFrank Li struct fsl_edma_engine *edma;
15672f5801aSFrank Li struct fsl_edma_desc *edesc;
15772f5801aSFrank Li struct dma_slave_config cfg;
15872f5801aSFrank Li u32 attr;
15972f5801aSFrank Li bool is_sw;
16072f5801aSFrank Li struct dma_pool *tcd_pool;
1619d831528SAngelo Dureghello dma_addr_t dma_dev_addr;
1629d831528SAngelo Dureghello u32 dma_dev_size;
1639d831528SAngelo Dureghello enum dma_data_direction dma_dir;
1649d831528SAngelo Dureghello char chan_name[32];
1659d831528SAngelo Dureghello void __iomem *tcd;
1669d831528SAngelo Dureghello void __iomem *mux_addr;
1670e819e35SVinod Koul u32 real_count;
1689d831528SAngelo Dureghello struct work_struct issue_worker;
1699d831528SAngelo Dureghello struct platform_device *pdev;
1709d831528SAngelo Dureghello struct device *pd_dev;
1719d831528SAngelo Dureghello u32 srcid;
1729e006b24SFrank Li struct clk *clk;
1739e006b24SFrank Li int priority;
174c26e6114SFrank Li int hw_chanid;
175c26e6114SFrank Li int txirq;
176c26e6114SFrank Li bool is_rxchan;
17772f5801aSFrank Li bool is_remote;
17872f5801aSFrank Li bool is_multi_fifo;
17972f5801aSFrank Li };
18072f5801aSFrank Li
18172f5801aSFrank Li struct fsl_edma_desc {
18272f5801aSFrank Li struct virt_dma_desc vdesc;
18372f5801aSFrank Li struct fsl_edma_chan *echan;
18472f5801aSFrank Li bool iscyclic;
18572f5801aSFrank Li enum dma_transfer_direction dirn;
18672f5801aSFrank Li unsigned int n_tcds;
1873c67c523SFrank Li struct fsl_edma_sw_tcd tcd[];
1883c67c523SFrank Li };
1893c67c523SFrank Li
1903c67c523SFrank Li #define FSL_EDMA_DRV_HAS_DMACLK BIT(0)
19172f5801aSFrank Li #define FSL_EDMA_DRV_MUX_SWAP BIT(1)
19272f5801aSFrank Li #define FSL_EDMA_DRV_CONFIG32 BIT(2)
19372f5801aSFrank Li #define FSL_EDMA_DRV_WRAP_IO BIT(3)
19472f5801aSFrank Li #define FSL_EDMA_DRV_EDMA64 BIT(4)
1953c67c523SFrank Li #define FSL_EDMA_DRV_HAS_PD BIT(5)
1963c67c523SFrank Li #define FSL_EDMA_DRV_HAS_CHCLK BIT(6)
1973c67c523SFrank Li #define FSL_EDMA_DRV_HAS_CHMUX BIT(7)
1983c67c523SFrank Li /* imx8 QM audio edma remote local swapped */
1993c67c523SFrank Li #define FSL_EDMA_DRV_QUIRK_SWAPPED BIT(8)
2003c67c523SFrank Li /* control and status register is in tcd address space, edma3 reg layout */
2013c67c523SFrank Li #define FSL_EDMA_DRV_SPLIT_REG BIT(9)
2023c67c523SFrank Li #define FSL_EDMA_DRV_BUS_8BYTE BIT(10)
2033c67c523SFrank Li #define FSL_EDMA_DRV_DEV_TO_DEV BIT(11)
20472f5801aSFrank Li #define FSL_EDMA_DRV_ALIGN_64BYTE BIT(12)
205af802728SRobin Gong /* Need clean CHn_CSR DONE before enable TCD's ESG */
20672f5801aSFrank Li #define FSL_EDMA_DRV_CLEAR_DONE_E_SG BIT(13)
20772f5801aSFrank Li /* Need clean CHn_CSR DONE before enable TCD's MAJORELINK */
20872f5801aSFrank Li #define FSL_EDMA_DRV_CLEAR_DONE_E_LINK BIT(14)
2099e006b24SFrank Li #define FSL_EDMA_DRV_TCD64 BIT(15)
210af802728SRobin Gong
211af802728SRobin Gong #define FSL_EDMA_DRV_EDMA3 (FSL_EDMA_DRV_SPLIT_REG | \
212af802728SRobin Gong FSL_EDMA_DRV_BUS_8BYTE | \
213af802728SRobin Gong FSL_EDMA_DRV_DEV_TO_DEV | \
2149d831528SAngelo Dureghello FSL_EDMA_DRV_ALIGN_64BYTE | \
2159d831528SAngelo Dureghello FSL_EDMA_DRV_CLEAR_DONE_E_SG | \
2169d831528SAngelo Dureghello FSL_EDMA_DRV_CLEAR_DONE_E_LINK)
2179d831528SAngelo Dureghello
2189d831528SAngelo Dureghello #define FSL_EDMA_DRV_EDMA4 (FSL_EDMA_DRV_SPLIT_REG | \
219232a7f18SRobin Gong FSL_EDMA_DRV_BUS_8BYTE | \
22072f5801aSFrank Li FSL_EDMA_DRV_DEV_TO_DEV | \
2219d831528SAngelo Dureghello FSL_EDMA_DRV_ALIGN_64BYTE | \
222af802728SRobin Gong FSL_EDMA_DRV_CLEAR_DONE_E_LINK)
2239d831528SAngelo Dureghello
2249d831528SAngelo Dureghello struct fsl_edma_drvdata {
2259d831528SAngelo Dureghello u32 dmamuxs; /* only used before v3 */
2269d831528SAngelo Dureghello u32 chreg_off;
227377eaf3bSAngelo Dureghello u32 chreg_space_sz;
22872f5801aSFrank Li u32 flags;
229c223bafdSKees Cook u32 mux_off; /* channel mux register offset */
2309d831528SAngelo Dureghello u32 mux_skip; /* how much skip for each channel */
2319d831528SAngelo Dureghello int (*setup_irq)(struct platform_device *pdev,
2327536f8b3SFrank Li struct fsl_edma_engine *fsl_edma);
2337536f8b3SFrank Li };
2347536f8b3SFrank Li
2357536f8b3SFrank Li struct fsl_edma_engine {
2367536f8b3SFrank Li struct dma_device dma_dev;
2377536f8b3SFrank Li void __iomem *membase;
2387536f8b3SFrank Li void __iomem *muxbase[DMAMUX_NR];
2397536f8b3SFrank Li struct clk *muxclk[DMAMUX_NR];
2407536f8b3SFrank Li struct clk *dmaclk;
2417536f8b3SFrank Li struct clk *chclk;
24272f5801aSFrank Li struct mutex fsl_edma_mutex;
24372f5801aSFrank Li const struct fsl_edma_drvdata *drvdata;
24472f5801aSFrank Li u32 n_chans;
24572f5801aSFrank Li int txirq;
24672f5801aSFrank Li int errirq;
24772f5801aSFrank Li bool big_endian;
24872f5801aSFrank Li struct edma_regs regs;
24972f5801aSFrank Li u64 chan_masked;
2509d831528SAngelo Dureghello struct fsl_edma_chan chans[] __counted_by(n_chans);
2519d831528SAngelo Dureghello };
2529d831528SAngelo Dureghello
2539d831528SAngelo Dureghello #define edma_read_tcdreg_c(chan, _tcd, __name) \
2549d831528SAngelo Dureghello (sizeof((_tcd)->__name) == sizeof(u64) ? \
2559d831528SAngelo Dureghello edma_readq(chan->edma, &(_tcd)->__name) : \
2569d831528SAngelo Dureghello ((sizeof((_tcd)->__name) == sizeof(u32)) ? \
2579d831528SAngelo Dureghello edma_readl(chan->edma, &(_tcd)->__name) : \
2589d831528SAngelo Dureghello edma_readw(chan->edma, &(_tcd)->__name) \
2599d831528SAngelo Dureghello ))
2609d831528SAngelo Dureghello
2619d831528SAngelo Dureghello #define edma_read_tcdreg(chan, __name) \
2629d831528SAngelo Dureghello ((fsl_edma_drvflags(chan) & FSL_EDMA_DRV_TCD64) ? \
2639d831528SAngelo Dureghello edma_read_tcdreg_c(chan, ((struct fsl_edma_hw_tcd64 __iomem *)chan->tcd), __name) : \
2647536f8b3SFrank Li edma_read_tcdreg_c(chan, ((struct fsl_edma_hw_tcd __iomem *)chan->tcd), __name) \
2657536f8b3SFrank Li )
2667536f8b3SFrank Li
2677536f8b3SFrank Li #define edma_write_tcdreg_c(chan, _tcd, _val, __name) \
2687536f8b3SFrank Li do { \
2697536f8b3SFrank Li switch (sizeof(_tcd->__name)) { \
2707536f8b3SFrank Li case sizeof(u64): \
2717536f8b3SFrank Li edma_writeq(chan->edma, (u64 __force)_val, &_tcd->__name); \
2729d831528SAngelo Dureghello break; \
2739d831528SAngelo Dureghello case sizeof(u32): \
2749d831528SAngelo Dureghello edma_writel(chan->edma, (u32 __force)_val, &_tcd->__name); \
2759d831528SAngelo Dureghello break; \
2769d831528SAngelo Dureghello case sizeof(u16): \
2779d831528SAngelo Dureghello edma_writew(chan->edma, (u16 __force)_val, &_tcd->__name); \
2789d831528SAngelo Dureghello break; \
2799d831528SAngelo Dureghello case sizeof(u8): \
2809d831528SAngelo Dureghello edma_writeb(chan->edma, (u8 __force)_val, &_tcd->__name); \
2819d831528SAngelo Dureghello break; \
2829d831528SAngelo Dureghello } \
2839d831528SAngelo Dureghello } while (0)
2849d831528SAngelo Dureghello
2859d831528SAngelo Dureghello #define edma_write_tcdreg(chan, val, __name) \
2869d831528SAngelo Dureghello do { \
2879d831528SAngelo Dureghello struct fsl_edma_hw_tcd64 __iomem *tcd64_r = (struct fsl_edma_hw_tcd64 __iomem *)chan->tcd; \
2889d831528SAngelo Dureghello struct fsl_edma_hw_tcd __iomem *tcd_r = (struct fsl_edma_hw_tcd __iomem *)chan->tcd; \
2899d831528SAngelo Dureghello \
2909d831528SAngelo Dureghello if (fsl_edma_drvflags(chan) & FSL_EDMA_DRV_TCD64) \
2919d831528SAngelo Dureghello edma_write_tcdreg_c(chan, tcd64_r, val, __name); \
2929d831528SAngelo Dureghello else \
2939d831528SAngelo Dureghello edma_write_tcdreg_c(chan, tcd_r, val, __name); \
2949d831528SAngelo Dureghello } while (0)
2959d831528SAngelo Dureghello
2969d831528SAngelo Dureghello #define edma_cp_tcd_to_reg(chan, __tcd, __name) \
2979d831528SAngelo Dureghello do { \
2989d831528SAngelo Dureghello struct fsl_edma_hw_tcd64 __iomem *tcd64_r = (struct fsl_edma_hw_tcd64 __iomem *)chan->tcd; \
2999d831528SAngelo Dureghello struct fsl_edma_hw_tcd __iomem *tcd_r = (struct fsl_edma_hw_tcd __iomem *)chan->tcd; \
3009d831528SAngelo Dureghello struct fsl_edma_hw_tcd64 *tcd64_m = (struct fsl_edma_hw_tcd64 *)__tcd; \
3019d831528SAngelo Dureghello struct fsl_edma_hw_tcd *tcd_m = (struct fsl_edma_hw_tcd *)__tcd; \
3029d831528SAngelo Dureghello \
3039d831528SAngelo Dureghello if (fsl_edma_drvflags(chan) & FSL_EDMA_DRV_TCD64) \
3049d831528SAngelo Dureghello edma_write_tcdreg_c(chan, tcd64_r, tcd64_m->__name, __name); \
3059d831528SAngelo Dureghello else \
30672f5801aSFrank Li edma_write_tcdreg_c(chan, tcd_r, tcd_m->__name, __name); \
30772f5801aSFrank Li } while (0)
30872f5801aSFrank Li
30972f5801aSFrank Li #define edma_readl_chreg(chan, __name) \
31072f5801aSFrank Li edma_readl(chan->edma, \
3119d831528SAngelo Dureghello (void __iomem *)&(container_of(((__force void *)chan->tcd),\
3129d831528SAngelo Dureghello struct fsl_edma3_ch_reg, tcd)->__name))
3139d831528SAngelo Dureghello
3149d831528SAngelo Dureghello #define edma_writel_chreg(chan, val, __name) \
3159d831528SAngelo Dureghello edma_writel(chan->edma, val, \
31679434f9bSFrank Li (void __iomem *)&(container_of(((__force void *)chan->tcd),\
31779434f9bSFrank Li struct fsl_edma3_ch_reg, tcd)->__name))
31879434f9bSFrank Li
31979434f9bSFrank Li #define fsl_edma_get_tcd(_chan, _tcd, _field) \
32079434f9bSFrank Li (fsl_edma_drvflags(_chan) & FSL_EDMA_DRV_TCD64 ? (((struct fsl_edma_hw_tcd64 *)_tcd)->_field) : \
32179434f9bSFrank Li (((struct fsl_edma_hw_tcd *)_tcd)->_field))
32279434f9bSFrank Li
3239d831528SAngelo Dureghello #define fsl_edma_le_to_cpu(x) \
3249d831528SAngelo Dureghello (sizeof(x) == sizeof(u64) ? le64_to_cpu((__force __le64)(x)) : \
3259d831528SAngelo Dureghello (sizeof(x) == sizeof(u32) ? le32_to_cpu((__force __le32)(x)) : \
3269d831528SAngelo Dureghello le16_to_cpu((__force __le16)(x))))
3279d831528SAngelo Dureghello
3289d831528SAngelo Dureghello #define fsl_edma_get_tcd_to_cpu(_chan, _tcd, _field) \
3299d831528SAngelo Dureghello (fsl_edma_drvflags(_chan) & FSL_EDMA_DRV_TCD64 ? \
3309d831528SAngelo Dureghello fsl_edma_le_to_cpu(((struct fsl_edma_hw_tcd64 *)_tcd)->_field) : \
3319d831528SAngelo Dureghello fsl_edma_le_to_cpu(((struct fsl_edma_hw_tcd *)_tcd)->_field))
3329d831528SAngelo Dureghello
3339d831528SAngelo Dureghello #define fsl_edma_set_tcd_to_le_c(_tcd, _val, _field) \
3349d831528SAngelo Dureghello do { \
3359d831528SAngelo Dureghello switch (sizeof((_tcd)->_field)) { \
3369d831528SAngelo Dureghello case sizeof(u64): \
3379d831528SAngelo Dureghello *(__force __le64 *)(&((_tcd)->_field)) = cpu_to_le64(_val); \
3389d831528SAngelo Dureghello break; \
3399d831528SAngelo Dureghello case sizeof(u32): \
3409d831528SAngelo Dureghello *(__force __le32 *)(&((_tcd)->_field)) = cpu_to_le32(_val); \
3419d831528SAngelo Dureghello break; \
342e0674853SJoy Zou case sizeof(u16): \
343e0674853SJoy Zou *(__force __le16 *)(&((_tcd)->_field)) = cpu_to_le16(_val); \
344e0674853SJoy Zou break; \
3459d831528SAngelo Dureghello } \
3469d831528SAngelo Dureghello } while (0)
3479d831528SAngelo Dureghello
3489d831528SAngelo Dureghello #define fsl_edma_set_tcd_to_le(_chan, _tcd, _val, _field) \
3499d831528SAngelo Dureghello do { \
350377eaf3bSAngelo Dureghello if (fsl_edma_drvflags(_chan) & FSL_EDMA_DRV_TCD64) \
3519d831528SAngelo Dureghello fsl_edma_set_tcd_to_le_c((struct fsl_edma_hw_tcd64 *)_tcd, _val, _field); \
3529d831528SAngelo Dureghello else \
353 fsl_edma_set_tcd_to_le_c((struct fsl_edma_hw_tcd *)_tcd, _val, _field); \
354 } while (0)
355
356 /*
357 * R/W functions for big- or little-endian registers:
358 * The eDMA controller's endian is independent of the CPU core's endian.
359 * For the big-endian IP module, the offset for 8-bit or 16-bit registers
360 * should also be swapped opposite to that in little-endian IP.
361 */
edma_readq(struct fsl_edma_engine * edma,void __iomem * addr)362 static inline u64 edma_readq(struct fsl_edma_engine *edma, void __iomem *addr)
363 {
364 u64 l, h;
365
366 if (edma->big_endian) {
367 l = ioread32be(addr);
368 h = ioread32be(addr + 4);
369 } else {
370 l = ioread32(addr);
371 h = ioread32(addr + 4);
372 }
373
374 return (h << 32) | l;
375 }
376
edma_readl(struct fsl_edma_engine * edma,void __iomem * addr)377 static inline u32 edma_readl(struct fsl_edma_engine *edma, void __iomem *addr)
378 {
379 if (edma->big_endian)
380 return ioread32be(addr);
381 else
382 return ioread32(addr);
383 }
384
edma_readw(struct fsl_edma_engine * edma,void __iomem * addr)385 static inline u16 edma_readw(struct fsl_edma_engine *edma, void __iomem *addr)
386 {
387 if (edma->big_endian)
388 return ioread16be(addr);
389 else
390 return ioread16(addr);
391 }
392
edma_writeb(struct fsl_edma_engine * edma,u8 val,void __iomem * addr)393 static inline void edma_writeb(struct fsl_edma_engine *edma,
394 u8 val, void __iomem *addr)
395 {
396 /* swap the reg offset for these in big-endian mode */
397 if (edma->big_endian)
398 iowrite8(val, (void __iomem *)((unsigned long)addr ^ 0x3));
399 else
400 iowrite8(val, addr);
401 }
402
edma_writew(struct fsl_edma_engine * edma,u16 val,void __iomem * addr)403 static inline void edma_writew(struct fsl_edma_engine *edma,
404 u16 val, void __iomem *addr)
405 {
406 /* swap the reg offset for these in big-endian mode */
407 if (edma->big_endian)
408 iowrite16be(val, (void __iomem *)((unsigned long)addr ^ 0x2));
409 else
410 iowrite16(val, addr);
411 }
412
edma_writel(struct fsl_edma_engine * edma,u32 val,void __iomem * addr)413 static inline void edma_writel(struct fsl_edma_engine *edma,
414 u32 val, void __iomem *addr)
415 {
416 if (edma->big_endian)
417 iowrite32be(val, addr);
418 else
419 iowrite32(val, addr);
420 }
421
edma_writeq(struct fsl_edma_engine * edma,u64 val,void __iomem * addr)422 static inline void edma_writeq(struct fsl_edma_engine *edma,
423 u64 val, void __iomem *addr)
424 {
425 if (edma->big_endian) {
426 iowrite32be(val & 0xFFFFFFFF, addr);
427 iowrite32be(val >> 32, addr + 4);
428 } else {
429 iowrite32(val & 0xFFFFFFFF, addr);
430 iowrite32(val >> 32, addr + 4);
431 }
432 }
433
to_fsl_edma_chan(struct dma_chan * chan)434 static inline struct fsl_edma_chan *to_fsl_edma_chan(struct dma_chan *chan)
435 {
436 return container_of(chan, struct fsl_edma_chan, vchan.chan);
437 }
438
fsl_edma_drvflags(struct fsl_edma_chan * fsl_chan)439 static inline u32 fsl_edma_drvflags(struct fsl_edma_chan *fsl_chan)
440 {
441 return fsl_chan->edma->drvdata->flags;
442 }
443
to_fsl_edma_desc(struct virt_dma_desc * vd)444 static inline struct fsl_edma_desc *to_fsl_edma_desc(struct virt_dma_desc *vd)
445 {
446 return container_of(vd, struct fsl_edma_desc, vdesc);
447 }
448
fsl_edma_err_chan_handler(struct fsl_edma_chan * fsl_chan)449 static inline void fsl_edma_err_chan_handler(struct fsl_edma_chan *fsl_chan)
450 {
451 fsl_chan->status = DMA_ERROR;
452 fsl_chan->idle = true;
453 }
454
455 void fsl_edma_tx_chan_handler(struct fsl_edma_chan *fsl_chan);
456 void fsl_edma_disable_request(struct fsl_edma_chan *fsl_chan);
457 void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan,
458 unsigned int slot, bool enable);
459 void fsl_edma_free_desc(struct virt_dma_desc *vdesc);
460 int fsl_edma_terminate_all(struct dma_chan *chan);
461 int fsl_edma_pause(struct dma_chan *chan);
462 int fsl_edma_resume(struct dma_chan *chan);
463 int fsl_edma_slave_config(struct dma_chan *chan,
464 struct dma_slave_config *cfg);
465 enum dma_status fsl_edma_tx_status(struct dma_chan *chan,
466 dma_cookie_t cookie, struct dma_tx_state *txstate);
467 struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
468 struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
469 size_t period_len, enum dma_transfer_direction direction,
470 unsigned long flags);
471 struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
472 struct dma_chan *chan, struct scatterlist *sgl,
473 unsigned int sg_len, enum dma_transfer_direction direction,
474 unsigned long flags, void *context);
475 struct dma_async_tx_descriptor *fsl_edma_prep_memcpy(
476 struct dma_chan *chan, dma_addr_t dma_dst, dma_addr_t dma_src,
477 size_t len, unsigned long flags);
478 void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan);
479 void fsl_edma_issue_pending(struct dma_chan *chan);
480 int fsl_edma_alloc_chan_resources(struct dma_chan *chan);
481 void fsl_edma_free_chan_resources(struct dma_chan *chan);
482 void fsl_edma_cleanup_vchan(struct dma_device *dmadev);
483 void fsl_edma_setup_regs(struct fsl_edma_engine *edma);
484
485 #endif /* _FSL_EDMA_COMMON_H_ */
486