1*9d831528SAngelo Dureghello /* SPDX-License-Identifier: GPL-2.0+ */ 2*9d831528SAngelo Dureghello /* 3*9d831528SAngelo Dureghello * Copyright 2013-2014 Freescale Semiconductor, Inc. 4*9d831528SAngelo Dureghello * Copyright 2018 Angelo Dureghello <angelo@sysam.it> 5*9d831528SAngelo Dureghello */ 6*9d831528SAngelo Dureghello #ifndef _FSL_EDMA_COMMON_H_ 7*9d831528SAngelo Dureghello #define _FSL_EDMA_COMMON_H_ 8*9d831528SAngelo Dureghello 9*9d831528SAngelo Dureghello #include "virt-dma.h" 10*9d831528SAngelo Dureghello 11*9d831528SAngelo Dureghello #define EDMA_CR 0x00 12*9d831528SAngelo Dureghello #define EDMA_ES 0x04 13*9d831528SAngelo Dureghello #define EDMA_ERQ 0x0C 14*9d831528SAngelo Dureghello #define EDMA_EEI 0x14 15*9d831528SAngelo Dureghello #define EDMA_SERQ 0x1B 16*9d831528SAngelo Dureghello #define EDMA_CERQ 0x1A 17*9d831528SAngelo Dureghello #define EDMA_SEEI 0x19 18*9d831528SAngelo Dureghello #define EDMA_CEEI 0x18 19*9d831528SAngelo Dureghello #define EDMA_CINT 0x1F 20*9d831528SAngelo Dureghello #define EDMA_CERR 0x1E 21*9d831528SAngelo Dureghello #define EDMA_SSRT 0x1D 22*9d831528SAngelo Dureghello #define EDMA_CDNE 0x1C 23*9d831528SAngelo Dureghello #define EDMA_INTR 0x24 24*9d831528SAngelo Dureghello #define EDMA_ERR 0x2C 25*9d831528SAngelo Dureghello 26*9d831528SAngelo Dureghello #define EDMA_TCD_SADDR(x) (0x1000 + 32 * (x)) 27*9d831528SAngelo Dureghello #define EDMA_TCD_SOFF(x) (0x1004 + 32 * (x)) 28*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR(x) (0x1006 + 32 * (x)) 29*9d831528SAngelo Dureghello #define EDMA_TCD_NBYTES(x) (0x1008 + 32 * (x)) 30*9d831528SAngelo Dureghello #define EDMA_TCD_SLAST(x) (0x100C + 32 * (x)) 31*9d831528SAngelo Dureghello #define EDMA_TCD_DADDR(x) (0x1010 + 32 * (x)) 32*9d831528SAngelo Dureghello #define EDMA_TCD_DOFF(x) (0x1014 + 32 * (x)) 33*9d831528SAngelo Dureghello #define EDMA_TCD_CITER_ELINK(x) (0x1016 + 32 * (x)) 34*9d831528SAngelo Dureghello #define EDMA_TCD_CITER(x) (0x1016 + 32 * (x)) 35*9d831528SAngelo Dureghello #define EDMA_TCD_DLAST_SGA(x) (0x1018 + 32 * (x)) 36*9d831528SAngelo Dureghello #define EDMA_TCD_CSR(x) (0x101C + 32 * (x)) 37*9d831528SAngelo Dureghello #define EDMA_TCD_BITER_ELINK(x) (0x101E + 32 * (x)) 38*9d831528SAngelo Dureghello #define EDMA_TCD_BITER(x) (0x101E + 32 * (x)) 39*9d831528SAngelo Dureghello 40*9d831528SAngelo Dureghello #define EDMA_CR_EDBG BIT(1) 41*9d831528SAngelo Dureghello #define EDMA_CR_ERCA BIT(2) 42*9d831528SAngelo Dureghello #define EDMA_CR_ERGA BIT(3) 43*9d831528SAngelo Dureghello #define EDMA_CR_HOE BIT(4) 44*9d831528SAngelo Dureghello #define EDMA_CR_HALT BIT(5) 45*9d831528SAngelo Dureghello #define EDMA_CR_CLM BIT(6) 46*9d831528SAngelo Dureghello #define EDMA_CR_EMLM BIT(7) 47*9d831528SAngelo Dureghello #define EDMA_CR_ECX BIT(16) 48*9d831528SAngelo Dureghello #define EDMA_CR_CX BIT(17) 49*9d831528SAngelo Dureghello 50*9d831528SAngelo Dureghello #define EDMA_SEEI_SEEI(x) ((x) & 0x1F) 51*9d831528SAngelo Dureghello #define EDMA_CEEI_CEEI(x) ((x) & 0x1F) 52*9d831528SAngelo Dureghello #define EDMA_CINT_CINT(x) ((x) & 0x1F) 53*9d831528SAngelo Dureghello #define EDMA_CERR_CERR(x) ((x) & 0x1F) 54*9d831528SAngelo Dureghello 55*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR_DSIZE(x) (((x) & 0x0007)) 56*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR_DMOD(x) (((x) & 0x001F) << 3) 57*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR_SSIZE(x) (((x) & 0x0007) << 8) 58*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR_SMOD(x) (((x) & 0x001F) << 11) 59*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR_SSIZE_8BIT (0x0000) 60*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR_SSIZE_16BIT (0x0100) 61*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR_SSIZE_32BIT (0x0200) 62*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR_SSIZE_64BIT (0x0300) 63*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR_SSIZE_32BYTE (0x0500) 64*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR_DSIZE_8BIT (0x0000) 65*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR_DSIZE_16BIT (0x0001) 66*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR_DSIZE_32BIT (0x0002) 67*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR_DSIZE_64BIT (0x0003) 68*9d831528SAngelo Dureghello #define EDMA_TCD_ATTR_DSIZE_32BYTE (0x0005) 69*9d831528SAngelo Dureghello 70*9d831528SAngelo Dureghello #define EDMA_TCD_SOFF_SOFF(x) (x) 71*9d831528SAngelo Dureghello #define EDMA_TCD_NBYTES_NBYTES(x) (x) 72*9d831528SAngelo Dureghello #define EDMA_TCD_SLAST_SLAST(x) (x) 73*9d831528SAngelo Dureghello #define EDMA_TCD_DADDR_DADDR(x) (x) 74*9d831528SAngelo Dureghello #define EDMA_TCD_CITER_CITER(x) ((x) & 0x7FFF) 75*9d831528SAngelo Dureghello #define EDMA_TCD_DOFF_DOFF(x) (x) 76*9d831528SAngelo Dureghello #define EDMA_TCD_DLAST_SGA_DLAST_SGA(x) (x) 77*9d831528SAngelo Dureghello #define EDMA_TCD_BITER_BITER(x) ((x) & 0x7FFF) 78*9d831528SAngelo Dureghello 79*9d831528SAngelo Dureghello #define EDMA_TCD_CSR_START BIT(0) 80*9d831528SAngelo Dureghello #define EDMA_TCD_CSR_INT_MAJOR BIT(1) 81*9d831528SAngelo Dureghello #define EDMA_TCD_CSR_INT_HALF BIT(2) 82*9d831528SAngelo Dureghello #define EDMA_TCD_CSR_D_REQ BIT(3) 83*9d831528SAngelo Dureghello #define EDMA_TCD_CSR_E_SG BIT(4) 84*9d831528SAngelo Dureghello #define EDMA_TCD_CSR_E_LINK BIT(5) 85*9d831528SAngelo Dureghello #define EDMA_TCD_CSR_ACTIVE BIT(6) 86*9d831528SAngelo Dureghello #define EDMA_TCD_CSR_DONE BIT(7) 87*9d831528SAngelo Dureghello 88*9d831528SAngelo Dureghello #define EDMAMUX_CHCFG_DIS 0x0 89*9d831528SAngelo Dureghello #define EDMAMUX_CHCFG_ENBL 0x80 90*9d831528SAngelo Dureghello #define EDMAMUX_CHCFG_SOURCE(n) ((n) & 0x3F) 91*9d831528SAngelo Dureghello 92*9d831528SAngelo Dureghello #define DMAMUX_NR 2 93*9d831528SAngelo Dureghello 94*9d831528SAngelo Dureghello #define FSL_EDMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ 95*9d831528SAngelo Dureghello BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ 96*9d831528SAngelo Dureghello BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \ 97*9d831528SAngelo Dureghello BIT(DMA_SLAVE_BUSWIDTH_8_BYTES)) 98*9d831528SAngelo Dureghello enum fsl_edma_pm_state { 99*9d831528SAngelo Dureghello RUNNING = 0, 100*9d831528SAngelo Dureghello SUSPENDED, 101*9d831528SAngelo Dureghello }; 102*9d831528SAngelo Dureghello 103*9d831528SAngelo Dureghello struct fsl_edma_hw_tcd { 104*9d831528SAngelo Dureghello __le32 saddr; 105*9d831528SAngelo Dureghello __le16 soff; 106*9d831528SAngelo Dureghello __le16 attr; 107*9d831528SAngelo Dureghello __le32 nbytes; 108*9d831528SAngelo Dureghello __le32 slast; 109*9d831528SAngelo Dureghello __le32 daddr; 110*9d831528SAngelo Dureghello __le16 doff; 111*9d831528SAngelo Dureghello __le16 citer; 112*9d831528SAngelo Dureghello __le32 dlast_sga; 113*9d831528SAngelo Dureghello __le16 csr; 114*9d831528SAngelo Dureghello __le16 biter; 115*9d831528SAngelo Dureghello }; 116*9d831528SAngelo Dureghello 117*9d831528SAngelo Dureghello struct fsl_edma_sw_tcd { 118*9d831528SAngelo Dureghello dma_addr_t ptcd; 119*9d831528SAngelo Dureghello struct fsl_edma_hw_tcd *vtcd; 120*9d831528SAngelo Dureghello }; 121*9d831528SAngelo Dureghello 122*9d831528SAngelo Dureghello struct fsl_edma_slave_config { 123*9d831528SAngelo Dureghello enum dma_transfer_direction dir; 124*9d831528SAngelo Dureghello enum dma_slave_buswidth addr_width; 125*9d831528SAngelo Dureghello u32 dev_addr; 126*9d831528SAngelo Dureghello u32 burst; 127*9d831528SAngelo Dureghello u32 attr; 128*9d831528SAngelo Dureghello }; 129*9d831528SAngelo Dureghello 130*9d831528SAngelo Dureghello struct fsl_edma_chan { 131*9d831528SAngelo Dureghello struct virt_dma_chan vchan; 132*9d831528SAngelo Dureghello enum dma_status status; 133*9d831528SAngelo Dureghello enum fsl_edma_pm_state pm_state; 134*9d831528SAngelo Dureghello bool idle; 135*9d831528SAngelo Dureghello u32 slave_id; 136*9d831528SAngelo Dureghello struct fsl_edma_engine *edma; 137*9d831528SAngelo Dureghello struct fsl_edma_desc *edesc; 138*9d831528SAngelo Dureghello struct fsl_edma_slave_config fsc; 139*9d831528SAngelo Dureghello struct dma_pool *tcd_pool; 140*9d831528SAngelo Dureghello }; 141*9d831528SAngelo Dureghello 142*9d831528SAngelo Dureghello struct fsl_edma_desc { 143*9d831528SAngelo Dureghello struct virt_dma_desc vdesc; 144*9d831528SAngelo Dureghello struct fsl_edma_chan *echan; 145*9d831528SAngelo Dureghello bool iscyclic; 146*9d831528SAngelo Dureghello unsigned int n_tcds; 147*9d831528SAngelo Dureghello struct fsl_edma_sw_tcd tcd[]; 148*9d831528SAngelo Dureghello }; 149*9d831528SAngelo Dureghello 150*9d831528SAngelo Dureghello struct fsl_edma_engine { 151*9d831528SAngelo Dureghello struct dma_device dma_dev; 152*9d831528SAngelo Dureghello void __iomem *membase; 153*9d831528SAngelo Dureghello void __iomem *muxbase[DMAMUX_NR]; 154*9d831528SAngelo Dureghello struct clk *muxclk[DMAMUX_NR]; 155*9d831528SAngelo Dureghello struct mutex fsl_edma_mutex; 156*9d831528SAngelo Dureghello u32 n_chans; 157*9d831528SAngelo Dureghello int txirq; 158*9d831528SAngelo Dureghello int errirq; 159*9d831528SAngelo Dureghello bool big_endian; 160*9d831528SAngelo Dureghello struct fsl_edma_chan chans[]; 161*9d831528SAngelo Dureghello }; 162*9d831528SAngelo Dureghello 163*9d831528SAngelo Dureghello /* 164*9d831528SAngelo Dureghello * R/W functions for big- or little-endian registers: 165*9d831528SAngelo Dureghello * The eDMA controller's endian is independent of the CPU core's endian. 166*9d831528SAngelo Dureghello * For the big-endian IP module, the offset for 8-bit or 16-bit registers 167*9d831528SAngelo Dureghello * should also be swapped opposite to that in little-endian IP. 168*9d831528SAngelo Dureghello */ 169*9d831528SAngelo Dureghello static inline u32 edma_readl(struct fsl_edma_engine *edma, void __iomem *addr) 170*9d831528SAngelo Dureghello { 171*9d831528SAngelo Dureghello if (edma->big_endian) 172*9d831528SAngelo Dureghello return ioread32be(addr); 173*9d831528SAngelo Dureghello else 174*9d831528SAngelo Dureghello return ioread32(addr); 175*9d831528SAngelo Dureghello } 176*9d831528SAngelo Dureghello 177*9d831528SAngelo Dureghello static inline void edma_writeb(struct fsl_edma_engine *edma, 178*9d831528SAngelo Dureghello u8 val, void __iomem *addr) 179*9d831528SAngelo Dureghello { 180*9d831528SAngelo Dureghello /* swap the reg offset for these in big-endian mode */ 181*9d831528SAngelo Dureghello if (edma->big_endian) 182*9d831528SAngelo Dureghello iowrite8(val, (void __iomem *)((unsigned long)addr ^ 0x3)); 183*9d831528SAngelo Dureghello else 184*9d831528SAngelo Dureghello iowrite8(val, addr); 185*9d831528SAngelo Dureghello } 186*9d831528SAngelo Dureghello 187*9d831528SAngelo Dureghello static inline void edma_writew(struct fsl_edma_engine *edma, 188*9d831528SAngelo Dureghello u16 val, void __iomem *addr) 189*9d831528SAngelo Dureghello { 190*9d831528SAngelo Dureghello /* swap the reg offset for these in big-endian mode */ 191*9d831528SAngelo Dureghello if (edma->big_endian) 192*9d831528SAngelo Dureghello iowrite16be(val, (void __iomem *)((unsigned long)addr ^ 0x2)); 193*9d831528SAngelo Dureghello else 194*9d831528SAngelo Dureghello iowrite16(val, addr); 195*9d831528SAngelo Dureghello } 196*9d831528SAngelo Dureghello 197*9d831528SAngelo Dureghello static inline void edma_writel(struct fsl_edma_engine *edma, 198*9d831528SAngelo Dureghello u32 val, void __iomem *addr) 199*9d831528SAngelo Dureghello { 200*9d831528SAngelo Dureghello if (edma->big_endian) 201*9d831528SAngelo Dureghello iowrite32be(val, addr); 202*9d831528SAngelo Dureghello else 203*9d831528SAngelo Dureghello iowrite32(val, addr); 204*9d831528SAngelo Dureghello } 205*9d831528SAngelo Dureghello 206*9d831528SAngelo Dureghello static inline struct fsl_edma_chan *to_fsl_edma_chan(struct dma_chan *chan) 207*9d831528SAngelo Dureghello { 208*9d831528SAngelo Dureghello return container_of(chan, struct fsl_edma_chan, vchan.chan); 209*9d831528SAngelo Dureghello } 210*9d831528SAngelo Dureghello 211*9d831528SAngelo Dureghello static inline struct fsl_edma_desc *to_fsl_edma_desc(struct virt_dma_desc *vd) 212*9d831528SAngelo Dureghello { 213*9d831528SAngelo Dureghello return container_of(vd, struct fsl_edma_desc, vdesc); 214*9d831528SAngelo Dureghello } 215*9d831528SAngelo Dureghello 216*9d831528SAngelo Dureghello void fsl_edma_disable_request(struct fsl_edma_chan *fsl_chan); 217*9d831528SAngelo Dureghello void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan, 218*9d831528SAngelo Dureghello unsigned int slot, bool enable); 219*9d831528SAngelo Dureghello void fsl_edma_free_desc(struct virt_dma_desc *vdesc); 220*9d831528SAngelo Dureghello int fsl_edma_terminate_all(struct dma_chan *chan); 221*9d831528SAngelo Dureghello int fsl_edma_pause(struct dma_chan *chan); 222*9d831528SAngelo Dureghello int fsl_edma_resume(struct dma_chan *chan); 223*9d831528SAngelo Dureghello int fsl_edma_slave_config(struct dma_chan *chan, 224*9d831528SAngelo Dureghello struct dma_slave_config *cfg); 225*9d831528SAngelo Dureghello enum dma_status fsl_edma_tx_status(struct dma_chan *chan, 226*9d831528SAngelo Dureghello dma_cookie_t cookie, struct dma_tx_state *txstate); 227*9d831528SAngelo Dureghello struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic( 228*9d831528SAngelo Dureghello struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len, 229*9d831528SAngelo Dureghello size_t period_len, enum dma_transfer_direction direction, 230*9d831528SAngelo Dureghello unsigned long flags); 231*9d831528SAngelo Dureghello struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg( 232*9d831528SAngelo Dureghello struct dma_chan *chan, struct scatterlist *sgl, 233*9d831528SAngelo Dureghello unsigned int sg_len, enum dma_transfer_direction direction, 234*9d831528SAngelo Dureghello unsigned long flags, void *context); 235*9d831528SAngelo Dureghello void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan); 236*9d831528SAngelo Dureghello void fsl_edma_issue_pending(struct dma_chan *chan); 237*9d831528SAngelo Dureghello int fsl_edma_alloc_chan_resources(struct dma_chan *chan); 238*9d831528SAngelo Dureghello void fsl_edma_free_chan_resources(struct dma_chan *chan); 239*9d831528SAngelo Dureghello void fsl_edma_cleanup_vchan(struct dma_device *dmadev); 240*9d831528SAngelo Dureghello 241*9d831528SAngelo Dureghello #endif /* _FSL_EDMA_COMMON_H_ */ 242