diff options
Diffstat (limited to 'drivers/dma/fsl-edma-common.h')
-rw-r--r-- | drivers/dma/fsl-edma-common.h | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h index cfc41915eaa1..3cc0cc8fc2d0 100644 --- a/drivers/dma/fsl-edma-common.h +++ b/drivers/dma/fsl-edma-common.h @@ -42,6 +42,11 @@ #define EDMA_TCD_CSR_ACTIVE BIT(6) #define EDMA_TCD_CSR_DONE BIT(7) +#define EDMA_V3_TCD_NBYTES_MLOFF_NBYTES(x) ((x) & GENMASK(9, 0)) +#define EDMA_V3_TCD_NBYTES_MLOFF(x) (x << 10) +#define EDMA_V3_TCD_NBYTES_DMLOE (1 << 30) +#define EDMA_V3_TCD_NBYTES_SMLOE (1 << 31) + #define EDMAMUX_CHCFG_DIS 0x0 #define EDMAMUX_CHCFG_ENBL 0x80 #define EDMAMUX_CHCFG_SOURCE(n) ((n) & 0x3F) @@ -54,6 +59,15 @@ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES)) + +#define EDMA_V3_CH_SBR_RD BIT(22) +#define EDMA_V3_CH_SBR_WR BIT(21) +#define EDMA_V3_CH_CSR_ERQ BIT(0) +#define EDMA_V3_CH_CSR_EARQ BIT(1) +#define EDMA_V3_CH_CSR_EEI BIT(2) +#define EDMA_V3_CH_CSR_DONE BIT(30) +#define EDMA_V3_CH_CSR_ACTIVE BIT(31) + enum fsl_edma_pm_state { RUNNING = 0, SUSPENDED, @@ -73,6 +87,18 @@ struct fsl_edma_hw_tcd { __le16 biter; }; +struct fsl_edma3_ch_reg { + __le32 ch_csr; + __le32 ch_es; + __le32 ch_int; + __le32 ch_sbr; + __le32 ch_pri; + __le32 ch_mux; + __le32 ch_mattr; /* edma4, reserved for edma3 */ + __le32 ch_reserved; + struct fsl_edma_hw_tcd tcd; +} __packed; + /* * These are iomem pointers, for both v32 and v64. */ @@ -119,6 +145,18 @@ struct fsl_edma_chan { enum dma_data_direction dma_dir; char chan_name[32]; struct fsl_edma_hw_tcd __iomem *tcd; + u32 real_count; + struct work_struct issue_worker; + struct platform_device *pdev; + struct device *pd_dev; + u32 srcid; + struct clk *clk; + int priority; + int hw_chanid; + int txirq; + bool is_rxchan; + bool is_remote; + bool is_multi_fifo; }; struct fsl_edma_desc { @@ -135,8 +173,26 @@ struct fsl_edma_desc { #define FSL_EDMA_DRV_CONFIG32 BIT(2) #define FSL_EDMA_DRV_WRAP_IO BIT(3) #define FSL_EDMA_DRV_EDMA64 BIT(4) +#define FSL_EDMA_DRV_HAS_PD BIT(5) +#define FSL_EDMA_DRV_HAS_CHCLK BIT(6) +#define FSL_EDMA_DRV_HAS_CHMUX BIT(7) +/* imx8 QM audio edma remote local swapped */ +#define FSL_EDMA_DRV_QUIRK_SWAPPED BIT(8) +/* control and status register is in tcd address space, edma3 reg layout */ +#define FSL_EDMA_DRV_SPLIT_REG BIT(9) +#define FSL_EDMA_DRV_BUS_8BYTE BIT(10) +#define FSL_EDMA_DRV_DEV_TO_DEV BIT(11) +#define FSL_EDMA_DRV_ALIGN_64BYTE BIT(12) + +#define FSL_EDMA_DRV_EDMA3 (FSL_EDMA_DRV_SPLIT_REG | \ + FSL_EDMA_DRV_BUS_8BYTE | \ + FSL_EDMA_DRV_DEV_TO_DEV | \ + FSL_EDMA_DRV_ALIGN_64BYTE) + struct fsl_edma_drvdata { - u32 dmamuxs; + u32 dmamuxs; /* only used before v3 */ + u32 chreg_off; + u32 chreg_space_sz; u32 flags; int (*setup_irq)(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma); @@ -148,6 +204,7 @@ struct fsl_edma_engine { void __iomem *muxbase[DMAMUX_NR]; struct clk *muxclk[DMAMUX_NR]; struct clk *dmaclk; + struct clk *chclk; struct mutex fsl_edma_mutex; const struct fsl_edma_drvdata *drvdata; u32 n_chans; @@ -155,6 +212,7 @@ struct fsl_edma_engine { int errirq; bool big_endian; struct edma_regs regs; + u64 chan_masked; struct fsl_edma_chan chans[]; }; @@ -168,6 +226,14 @@ struct fsl_edma_engine { edma_writel(chan->edma, (u32 __force)val, &chan->tcd->__name) : \ edma_writew(chan->edma, (u16 __force)val, &chan->tcd->__name)) +#define edma_readl_chreg(chan, __name) \ + edma_readl(chan->edma, \ + (void __iomem *)&(container_of(chan->tcd, struct fsl_edma3_ch_reg, tcd)->__name)) + +#define edma_writel_chreg(chan, val, __name) \ + edma_writel(chan->edma, val, \ + (void __iomem *)&(container_of(chan->tcd, struct fsl_edma3_ch_reg, tcd)->__name)) + /* * R/W functions for big- or little-endian registers: * The eDMA controller's endian is independent of the CPU core's endian. @@ -224,6 +290,11 @@ static inline struct fsl_edma_chan *to_fsl_edma_chan(struct dma_chan *chan) return container_of(chan, struct fsl_edma_chan, vchan.chan); } +static inline u32 fsl_edma_drvflags(struct fsl_edma_chan *fsl_chan) +{ + return fsl_chan->edma->drvdata->flags; +} + static inline struct fsl_edma_desc *to_fsl_edma_desc(struct virt_dma_desc *vd) { return container_of(vd, struct fsl_edma_desc, vdesc); |