linux/drivers/dma/fsl-edma-common.h
<<
>>
Prefs
   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
   9#include <linux/dma-direction.h>
  10#include <linux/platform_device.h>
  11#include "virt-dma.h"
  12
  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
  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))
  27
  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)
  32#define EDMA_TCD_ATTR_DSIZE_8BIT        0
  33#define EDMA_TCD_ATTR_DSIZE_16BIT       BIT(0)
  34#define EDMA_TCD_ATTR_DSIZE_32BIT       BIT(1)
  35#define EDMA_TCD_ATTR_DSIZE_64BIT       (BIT(0) | BIT(1))
  36#define EDMA_TCD_ATTR_DSIZE_32BYTE      (BIT(2) | BIT(0))
  37#define EDMA_TCD_ATTR_SSIZE_8BIT        0
  38#define EDMA_TCD_ATTR_SSIZE_16BIT       (EDMA_TCD_ATTR_DSIZE_16BIT << 8)
  39#define EDMA_TCD_ATTR_SSIZE_32BIT       (EDMA_TCD_ATTR_DSIZE_32BIT << 8)
  40#define EDMA_TCD_ATTR_SSIZE_64BIT       (EDMA_TCD_ATTR_DSIZE_64BIT << 8)
  41#define EDMA_TCD_ATTR_SSIZE_32BYTE      (EDMA_TCD_ATTR_DSIZE_32BYTE << 8)
  42
  43#define EDMA_TCD_CITER_CITER(x)         ((x) & GENMASK(14, 0))
  44#define EDMA_TCD_BITER_BITER(x)         ((x) & GENMASK(14, 0))
  45
  46#define EDMA_TCD_CSR_START              BIT(0)
  47#define EDMA_TCD_CSR_INT_MAJOR          BIT(1)
  48#define EDMA_TCD_CSR_INT_HALF           BIT(2)
  49#define EDMA_TCD_CSR_D_REQ              BIT(3)
  50#define EDMA_TCD_CSR_E_SG               BIT(4)
  51#define EDMA_TCD_CSR_E_LINK             BIT(5)
  52#define EDMA_TCD_CSR_ACTIVE             BIT(6)
  53#define EDMA_TCD_CSR_DONE               BIT(7)
  54
  55#define EDMAMUX_CHCFG_DIS               0x0
  56#define EDMAMUX_CHCFG_ENBL              0x80
  57#define EDMAMUX_CHCFG_SOURCE(n)         ((n) & 0x3F)
  58
  59#define DMAMUX_NR       2
  60
  61#define FSL_EDMA_BUSWIDTHS      (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
  62                                 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
  63                                 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
  64                                 BIT(DMA_SLAVE_BUSWIDTH_8_BYTES))
  65enum fsl_edma_pm_state {
  66        RUNNING = 0,
  67        SUSPENDED,
  68};
  69
  70struct fsl_edma_hw_tcd {
  71        __le32  saddr;
  72        __le16  soff;
  73        __le16  attr;
  74        __le32  nbytes;
  75        __le32  slast;
  76        __le32  daddr;
  77        __le16  doff;
  78        __le16  citer;
  79        __le32  dlast_sga;
  80        __le16  csr;
  81        __le16  biter;
  82};
  83
  84/*
  85 * These are iomem pointers, for both v32 and v64.
  86 */
  87struct edma_regs {
  88        void __iomem *cr;
  89        void __iomem *es;
  90        void __iomem *erqh;
  91        void __iomem *erql;     /* aka erq on v32 */
  92        void __iomem *eeih;
  93        void __iomem *eeil;     /* aka eei on v32 */
  94        void __iomem *seei;
  95        void __iomem *ceei;
  96        void __iomem *serq;
  97        void __iomem *cerq;
  98        void __iomem *cint;
  99        void __iomem *cerr;
 100        void __iomem *ssrt;
 101        void __iomem *cdne;
 102        void __iomem *inth;
 103        void __iomem *intl;
 104        void __iomem *errh;
 105        void __iomem *errl;
 106        struct fsl_edma_hw_tcd __iomem *tcd;
 107};
 108
 109struct fsl_edma_sw_tcd {
 110        dma_addr_t                      ptcd;
 111        struct fsl_edma_hw_tcd          *vtcd;
 112};
 113
 114struct fsl_edma_chan {
 115        struct virt_dma_chan            vchan;
 116        enum dma_status                 status;
 117        enum fsl_edma_pm_state          pm_state;
 118        bool                            idle;
 119        u32                             slave_id;
 120        struct fsl_edma_engine          *edma;
 121        struct fsl_edma_desc            *edesc;
 122        struct dma_slave_config         cfg;
 123        u32                             attr;
 124        bool                            is_sw;
 125        struct dma_pool                 *tcd_pool;
 126        dma_addr_t                      dma_dev_addr;
 127        u32                             dma_dev_size;
 128        enum dma_data_direction         dma_dir;
 129        char                            chan_name[16];
 130};
 131
 132struct fsl_edma_desc {
 133        struct virt_dma_desc            vdesc;
 134        struct fsl_edma_chan            *echan;
 135        bool                            iscyclic;
 136        enum dma_transfer_direction     dirn;
 137        unsigned int                    n_tcds;
 138        struct fsl_edma_sw_tcd          tcd[];
 139};
 140
 141enum edma_version {
 142        v1, /* 32ch, Vybrid, mpc57x, etc */
 143        v2, /* 64ch Coldfire */
 144        v3, /* 32ch, i.mx7ulp */
 145};
 146
 147struct fsl_edma_drvdata {
 148        enum edma_version       version;
 149        u32                     dmamuxs;
 150        bool                    has_dmaclk;
 151        bool                    mux_swap;
 152        int                     (*setup_irq)(struct platform_device *pdev,
 153                                             struct fsl_edma_engine *fsl_edma);
 154};
 155
 156struct fsl_edma_engine {
 157        struct dma_device       dma_dev;
 158        void __iomem            *membase;
 159        void __iomem            *muxbase[DMAMUX_NR];
 160        struct clk              *muxclk[DMAMUX_NR];
 161        struct clk              *dmaclk;
 162        struct mutex            fsl_edma_mutex;
 163        const struct fsl_edma_drvdata *drvdata;
 164        u32                     n_chans;
 165        int                     txirq;
 166        int                     errirq;
 167        bool                    big_endian;
 168        struct edma_regs        regs;
 169        struct fsl_edma_chan    chans[];
 170};
 171
 172/*
 173 * R/W functions for big- or little-endian registers:
 174 * The eDMA controller's endian is independent of the CPU core's endian.
 175 * For the big-endian IP module, the offset for 8-bit or 16-bit registers
 176 * should also be swapped opposite to that in little-endian IP.
 177 */
 178static inline u32 edma_readl(struct fsl_edma_engine *edma, void __iomem *addr)
 179{
 180        if (edma->big_endian)
 181                return ioread32be(addr);
 182        else
 183                return ioread32(addr);
 184}
 185
 186static inline void edma_writeb(struct fsl_edma_engine *edma,
 187                               u8 val, void __iomem *addr)
 188{
 189        /* swap the reg offset for these in big-endian mode */
 190        if (edma->big_endian)
 191                iowrite8(val, (void __iomem *)((unsigned long)addr ^ 0x3));
 192        else
 193                iowrite8(val, addr);
 194}
 195
 196static inline void edma_writew(struct fsl_edma_engine *edma,
 197                               u16 val, void __iomem *addr)
 198{
 199        /* swap the reg offset for these in big-endian mode */
 200        if (edma->big_endian)
 201                iowrite16be(val, (void __iomem *)((unsigned long)addr ^ 0x2));
 202        else
 203                iowrite16(val, addr);
 204}
 205
 206static inline void edma_writel(struct fsl_edma_engine *edma,
 207                               u32 val, void __iomem *addr)
 208{
 209        if (edma->big_endian)
 210                iowrite32be(val, addr);
 211        else
 212                iowrite32(val, addr);
 213}
 214
 215static inline struct fsl_edma_chan *to_fsl_edma_chan(struct dma_chan *chan)
 216{
 217        return container_of(chan, struct fsl_edma_chan, vchan.chan);
 218}
 219
 220static inline struct fsl_edma_desc *to_fsl_edma_desc(struct virt_dma_desc *vd)
 221{
 222        return container_of(vd, struct fsl_edma_desc, vdesc);
 223}
 224
 225void fsl_edma_disable_request(struct fsl_edma_chan *fsl_chan);
 226void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan,
 227                        unsigned int slot, bool enable);
 228void fsl_edma_free_desc(struct virt_dma_desc *vdesc);
 229int fsl_edma_terminate_all(struct dma_chan *chan);
 230int fsl_edma_pause(struct dma_chan *chan);
 231int fsl_edma_resume(struct dma_chan *chan);
 232int fsl_edma_slave_config(struct dma_chan *chan,
 233                                 struct dma_slave_config *cfg);
 234enum dma_status fsl_edma_tx_status(struct dma_chan *chan,
 235                dma_cookie_t cookie, struct dma_tx_state *txstate);
 236struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
 237                struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
 238                size_t period_len, enum dma_transfer_direction direction,
 239                unsigned long flags);
 240struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
 241                struct dma_chan *chan, struct scatterlist *sgl,
 242                unsigned int sg_len, enum dma_transfer_direction direction,
 243                unsigned long flags, void *context);
 244struct dma_async_tx_descriptor *fsl_edma_prep_memcpy(
 245                struct dma_chan *chan, dma_addr_t dma_dst, dma_addr_t dma_src,
 246                size_t len, unsigned long flags);
 247void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan);
 248void fsl_edma_issue_pending(struct dma_chan *chan);
 249int fsl_edma_alloc_chan_resources(struct dma_chan *chan);
 250void fsl_edma_free_chan_resources(struct dma_chan *chan);
 251void fsl_edma_cleanup_vchan(struct dma_device *dmadev);
 252void fsl_edma_setup_regs(struct fsl_edma_engine *edma);
 253
 254#endif /* _FSL_EDMA_COMMON_H_ */
 255