linux/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
<<
>>
Prefs
   1// SPDX-License-Identifier:  GPL-2.0
   2// (C) 2017-2018 Synopsys, Inc. (www.synopsys.com)
   3
   4/*
   5 * Synopsys DesignWare AXI DMA Controller driver.
   6 *
   7 * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
   8 */
   9
  10#ifndef _AXI_DMA_PLATFORM_H
  11#define _AXI_DMA_PLATFORM_H
  12
  13#include <linux/bitops.h>
  14#include <linux/clk.h>
  15#include <linux/device.h>
  16#include <linux/dmaengine.h>
  17#include <linux/types.h>
  18
  19#include "../virt-dma.h"
  20
  21#define DMAC_MAX_CHANNELS       8
  22#define DMAC_MAX_MASTERS        2
  23#define DMAC_MAX_BLK_SIZE       0x200000
  24
  25struct dw_axi_dma_hcfg {
  26        u32     nr_channels;
  27        u32     nr_masters;
  28        u32     m_data_width;
  29        u32     block_size[DMAC_MAX_CHANNELS];
  30        u32     priority[DMAC_MAX_CHANNELS];
  31        /* maximum supported axi burst length */
  32        u32     axi_rw_burst_len;
  33        bool    restrict_axi_burst_len;
  34};
  35
  36struct axi_dma_chan {
  37        struct axi_dma_chip             *chip;
  38        void __iomem                    *chan_regs;
  39        u8                              id;
  40        atomic_t                        descs_allocated;
  41
  42        struct virt_dma_chan            vc;
  43
  44        /* these other elements are all protected by vc.lock */
  45        bool                            is_paused;
  46};
  47
  48struct dw_axi_dma {
  49        struct dma_device       dma;
  50        struct dw_axi_dma_hcfg  *hdata;
  51        struct dma_pool         *desc_pool;
  52
  53        /* channels */
  54        struct axi_dma_chan     *chan;
  55};
  56
  57struct axi_dma_chip {
  58        struct device           *dev;
  59        int                     irq;
  60        void __iomem            *regs;
  61        struct clk              *core_clk;
  62        struct clk              *cfgr_clk;
  63        struct dw_axi_dma       *dw;
  64};
  65
  66/* LLI == Linked List Item */
  67struct __packed axi_dma_lli {
  68        __le64          sar;
  69        __le64          dar;
  70        __le32          block_ts_lo;
  71        __le32          block_ts_hi;
  72        __le64          llp;
  73        __le32          ctl_lo;
  74        __le32          ctl_hi;
  75        __le32          sstat;
  76        __le32          dstat;
  77        __le32          status_lo;
  78        __le32          status_hi;
  79        __le32          reserved_lo;
  80        __le32          reserved_hi;
  81};
  82
  83struct axi_dma_desc {
  84        struct axi_dma_lli              lli;
  85
  86        struct virt_dma_desc            vd;
  87        struct axi_dma_chan             *chan;
  88        struct list_head                xfer_list;
  89};
  90
  91static inline struct device *dchan2dev(struct dma_chan *dchan)
  92{
  93        return &dchan->dev->device;
  94}
  95
  96static inline struct device *chan2dev(struct axi_dma_chan *chan)
  97{
  98        return &chan->vc.chan.dev->device;
  99}
 100
 101static inline struct axi_dma_desc *vd_to_axi_desc(struct virt_dma_desc *vd)
 102{
 103        return container_of(vd, struct axi_dma_desc, vd);
 104}
 105
 106static inline struct axi_dma_chan *vc_to_axi_dma_chan(struct virt_dma_chan *vc)
 107{
 108        return container_of(vc, struct axi_dma_chan, vc);
 109}
 110
 111static inline struct axi_dma_chan *dchan_to_axi_dma_chan(struct dma_chan *dchan)
 112{
 113        return vc_to_axi_dma_chan(to_virt_chan(dchan));
 114}
 115
 116
 117#define COMMON_REG_LEN          0x100
 118#define CHAN_REG_LEN            0x100
 119
 120/* Common registers offset */
 121#define DMAC_ID                 0x000 /* R DMAC ID */
 122#define DMAC_COMPVER            0x008 /* R DMAC Component Version */
 123#define DMAC_CFG                0x010 /* R/W DMAC Configuration */
 124#define DMAC_CHEN               0x018 /* R/W DMAC Channel Enable */
 125#define DMAC_CHEN_L             0x018 /* R/W DMAC Channel Enable 00-31 */
 126#define DMAC_CHEN_H             0x01C /* R/W DMAC Channel Enable 32-63 */
 127#define DMAC_INTSTATUS          0x030 /* R DMAC Interrupt Status */
 128#define DMAC_COMMON_INTCLEAR    0x038 /* W DMAC Interrupt Clear */
 129#define DMAC_COMMON_INTSTATUS_ENA 0x040 /* R DMAC Interrupt Status Enable */
 130#define DMAC_COMMON_INTSIGNAL_ENA 0x048 /* R/W DMAC Interrupt Signal Enable */
 131#define DMAC_COMMON_INTSTATUS   0x050 /* R DMAC Interrupt Status */
 132#define DMAC_RESET              0x058 /* R DMAC Reset Register1 */
 133
 134/* DMA channel registers offset */
 135#define CH_SAR                  0x000 /* R/W Chan Source Address */
 136#define CH_DAR                  0x008 /* R/W Chan Destination Address */
 137#define CH_BLOCK_TS             0x010 /* R/W Chan Block Transfer Size */
 138#define CH_CTL                  0x018 /* R/W Chan Control */
 139#define CH_CTL_L                0x018 /* R/W Chan Control 00-31 */
 140#define CH_CTL_H                0x01C /* R/W Chan Control 32-63 */
 141#define CH_CFG                  0x020 /* R/W Chan Configuration */
 142#define CH_CFG_L                0x020 /* R/W Chan Configuration 00-31 */
 143#define CH_CFG_H                0x024 /* R/W Chan Configuration 32-63 */
 144#define CH_LLP                  0x028 /* R/W Chan Linked List Pointer */
 145#define CH_STATUS               0x030 /* R Chan Status */
 146#define CH_SWHSSRC              0x038 /* R/W Chan SW Handshake Source */
 147#define CH_SWHSDST              0x040 /* R/W Chan SW Handshake Destination */
 148#define CH_BLK_TFR_RESUMEREQ    0x048 /* W Chan Block Transfer Resume Req */
 149#define CH_AXI_ID               0x050 /* R/W Chan AXI ID */
 150#define CH_AXI_QOS              0x058 /* R/W Chan AXI QOS */
 151#define CH_SSTAT                0x060 /* R Chan Source Status */
 152#define CH_DSTAT                0x068 /* R Chan Destination Status */
 153#define CH_SSTATAR              0x070 /* R/W Chan Source Status Fetch Addr */
 154#define CH_DSTATAR              0x078 /* R/W Chan Destination Status Fetch Addr */
 155#define CH_INTSTATUS_ENA        0x080 /* R/W Chan Interrupt Status Enable */
 156#define CH_INTSTATUS            0x088 /* R/W Chan Interrupt Status */
 157#define CH_INTSIGNAL_ENA        0x090 /* R/W Chan Interrupt Signal Enable */
 158#define CH_INTCLEAR             0x098 /* W Chan Interrupt Clear */
 159
 160
 161/* DMAC_CFG */
 162#define DMAC_EN_POS                     0
 163#define DMAC_EN_MASK                    BIT(DMAC_EN_POS)
 164
 165#define INT_EN_POS                      1
 166#define INT_EN_MASK                     BIT(INT_EN_POS)
 167
 168#define DMAC_CHAN_EN_SHIFT              0
 169#define DMAC_CHAN_EN_WE_SHIFT           8
 170
 171#define DMAC_CHAN_SUSP_SHIFT            16
 172#define DMAC_CHAN_SUSP_WE_SHIFT         24
 173
 174/* CH_CTL_H */
 175#define CH_CTL_H_ARLEN_EN               BIT(6)
 176#define CH_CTL_H_ARLEN_POS              7
 177#define CH_CTL_H_AWLEN_EN               BIT(15)
 178#define CH_CTL_H_AWLEN_POS              16
 179
 180enum {
 181        DWAXIDMAC_ARWLEN_1              = 0,
 182        DWAXIDMAC_ARWLEN_2              = 1,
 183        DWAXIDMAC_ARWLEN_4              = 3,
 184        DWAXIDMAC_ARWLEN_8              = 7,
 185        DWAXIDMAC_ARWLEN_16             = 15,
 186        DWAXIDMAC_ARWLEN_32             = 31,
 187        DWAXIDMAC_ARWLEN_64             = 63,
 188        DWAXIDMAC_ARWLEN_128            = 127,
 189        DWAXIDMAC_ARWLEN_256            = 255,
 190        DWAXIDMAC_ARWLEN_MIN            = DWAXIDMAC_ARWLEN_1,
 191        DWAXIDMAC_ARWLEN_MAX            = DWAXIDMAC_ARWLEN_256
 192};
 193
 194#define CH_CTL_H_LLI_LAST               BIT(30)
 195#define CH_CTL_H_LLI_VALID              BIT(31)
 196
 197/* CH_CTL_L */
 198#define CH_CTL_L_LAST_WRITE_EN          BIT(30)
 199
 200#define CH_CTL_L_DST_MSIZE_POS          18
 201#define CH_CTL_L_SRC_MSIZE_POS          14
 202
 203enum {
 204        DWAXIDMAC_BURST_TRANS_LEN_1     = 0,
 205        DWAXIDMAC_BURST_TRANS_LEN_4,
 206        DWAXIDMAC_BURST_TRANS_LEN_8,
 207        DWAXIDMAC_BURST_TRANS_LEN_16,
 208        DWAXIDMAC_BURST_TRANS_LEN_32,
 209        DWAXIDMAC_BURST_TRANS_LEN_64,
 210        DWAXIDMAC_BURST_TRANS_LEN_128,
 211        DWAXIDMAC_BURST_TRANS_LEN_256,
 212        DWAXIDMAC_BURST_TRANS_LEN_512,
 213        DWAXIDMAC_BURST_TRANS_LEN_1024
 214};
 215
 216#define CH_CTL_L_DST_WIDTH_POS          11
 217#define CH_CTL_L_SRC_WIDTH_POS          8
 218
 219#define CH_CTL_L_DST_INC_POS            6
 220#define CH_CTL_L_SRC_INC_POS            4
 221enum {
 222        DWAXIDMAC_CH_CTL_L_INC          = 0,
 223        DWAXIDMAC_CH_CTL_L_NOINC
 224};
 225
 226#define CH_CTL_L_DST_MAST               BIT(2)
 227#define CH_CTL_L_SRC_MAST               BIT(0)
 228
 229/* CH_CFG_H */
 230#define CH_CFG_H_PRIORITY_POS           17
 231#define CH_CFG_H_HS_SEL_DST_POS         4
 232#define CH_CFG_H_HS_SEL_SRC_POS         3
 233enum {
 234        DWAXIDMAC_HS_SEL_HW             = 0,
 235        DWAXIDMAC_HS_SEL_SW
 236};
 237
 238#define CH_CFG_H_TT_FC_POS              0
 239enum {
 240        DWAXIDMAC_TT_FC_MEM_TO_MEM_DMAC = 0,
 241        DWAXIDMAC_TT_FC_MEM_TO_PER_DMAC,
 242        DWAXIDMAC_TT_FC_PER_TO_MEM_DMAC,
 243        DWAXIDMAC_TT_FC_PER_TO_PER_DMAC,
 244        DWAXIDMAC_TT_FC_PER_TO_MEM_SRC,
 245        DWAXIDMAC_TT_FC_PER_TO_PER_SRC,
 246        DWAXIDMAC_TT_FC_MEM_TO_PER_DST,
 247        DWAXIDMAC_TT_FC_PER_TO_PER_DST
 248};
 249
 250/* CH_CFG_L */
 251#define CH_CFG_L_DST_MULTBLK_TYPE_POS   2
 252#define CH_CFG_L_SRC_MULTBLK_TYPE_POS   0
 253enum {
 254        DWAXIDMAC_MBLK_TYPE_CONTIGUOUS  = 0,
 255        DWAXIDMAC_MBLK_TYPE_RELOAD,
 256        DWAXIDMAC_MBLK_TYPE_SHADOW_REG,
 257        DWAXIDMAC_MBLK_TYPE_LL
 258};
 259
 260/**
 261 * DW AXI DMA channel interrupts
 262 *
 263 * @DWAXIDMAC_IRQ_NONE: Bitmask of no one interrupt
 264 * @DWAXIDMAC_IRQ_BLOCK_TRF: Block transfer complete
 265 * @DWAXIDMAC_IRQ_DMA_TRF: Dma transfer complete
 266 * @DWAXIDMAC_IRQ_SRC_TRAN: Source transaction complete
 267 * @DWAXIDMAC_IRQ_DST_TRAN: Destination transaction complete
 268 * @DWAXIDMAC_IRQ_SRC_DEC_ERR: Source decode error
 269 * @DWAXIDMAC_IRQ_DST_DEC_ERR: Destination decode error
 270 * @DWAXIDMAC_IRQ_SRC_SLV_ERR: Source slave error
 271 * @DWAXIDMAC_IRQ_DST_SLV_ERR: Destination slave error
 272 * @DWAXIDMAC_IRQ_LLI_RD_DEC_ERR: LLI read decode error
 273 * @DWAXIDMAC_IRQ_LLI_WR_DEC_ERR: LLI write decode error
 274 * @DWAXIDMAC_IRQ_LLI_RD_SLV_ERR: LLI read slave error
 275 * @DWAXIDMAC_IRQ_LLI_WR_SLV_ERR: LLI write slave error
 276 * @DWAXIDMAC_IRQ_INVALID_ERR: LLI invalid error or Shadow register error
 277 * @DWAXIDMAC_IRQ_MULTIBLKTYPE_ERR: Slave Interface Multiblock type error
 278 * @DWAXIDMAC_IRQ_DEC_ERR: Slave Interface decode error
 279 * @DWAXIDMAC_IRQ_WR2RO_ERR: Slave Interface write to read only error
 280 * @DWAXIDMAC_IRQ_RD2RWO_ERR: Slave Interface read to write only error
 281 * @DWAXIDMAC_IRQ_WRONCHEN_ERR: Slave Interface write to channel error
 282 * @DWAXIDMAC_IRQ_SHADOWREG_ERR: Slave Interface shadow reg error
 283 * @DWAXIDMAC_IRQ_WRONHOLD_ERR: Slave Interface hold error
 284 * @DWAXIDMAC_IRQ_LOCK_CLEARED: Lock Cleared Status
 285 * @DWAXIDMAC_IRQ_SRC_SUSPENDED: Source Suspended Status
 286 * @DWAXIDMAC_IRQ_SUSPENDED: Channel Suspended Status
 287 * @DWAXIDMAC_IRQ_DISABLED: Channel Disabled Status
 288 * @DWAXIDMAC_IRQ_ABORTED: Channel Aborted Status
 289 * @DWAXIDMAC_IRQ_ALL_ERR: Bitmask of all error interrupts
 290 * @DWAXIDMAC_IRQ_ALL: Bitmask of all interrupts
 291 */
 292enum {
 293        DWAXIDMAC_IRQ_NONE              = 0,
 294        DWAXIDMAC_IRQ_BLOCK_TRF         = BIT(0),
 295        DWAXIDMAC_IRQ_DMA_TRF           = BIT(1),
 296        DWAXIDMAC_IRQ_SRC_TRAN          = BIT(3),
 297        DWAXIDMAC_IRQ_DST_TRAN          = BIT(4),
 298        DWAXIDMAC_IRQ_SRC_DEC_ERR       = BIT(5),
 299        DWAXIDMAC_IRQ_DST_DEC_ERR       = BIT(6),
 300        DWAXIDMAC_IRQ_SRC_SLV_ERR       = BIT(7),
 301        DWAXIDMAC_IRQ_DST_SLV_ERR       = BIT(8),
 302        DWAXIDMAC_IRQ_LLI_RD_DEC_ERR    = BIT(9),
 303        DWAXIDMAC_IRQ_LLI_WR_DEC_ERR    = BIT(10),
 304        DWAXIDMAC_IRQ_LLI_RD_SLV_ERR    = BIT(11),
 305        DWAXIDMAC_IRQ_LLI_WR_SLV_ERR    = BIT(12),
 306        DWAXIDMAC_IRQ_INVALID_ERR       = BIT(13),
 307        DWAXIDMAC_IRQ_MULTIBLKTYPE_ERR  = BIT(14),
 308        DWAXIDMAC_IRQ_DEC_ERR           = BIT(16),
 309        DWAXIDMAC_IRQ_WR2RO_ERR         = BIT(17),
 310        DWAXIDMAC_IRQ_RD2RWO_ERR        = BIT(18),
 311        DWAXIDMAC_IRQ_WRONCHEN_ERR      = BIT(19),
 312        DWAXIDMAC_IRQ_SHADOWREG_ERR     = BIT(20),
 313        DWAXIDMAC_IRQ_WRONHOLD_ERR      = BIT(21),
 314        DWAXIDMAC_IRQ_LOCK_CLEARED      = BIT(27),
 315        DWAXIDMAC_IRQ_SRC_SUSPENDED     = BIT(28),
 316        DWAXIDMAC_IRQ_SUSPENDED         = BIT(29),
 317        DWAXIDMAC_IRQ_DISABLED          = BIT(30),
 318        DWAXIDMAC_IRQ_ABORTED           = BIT(31),
 319        DWAXIDMAC_IRQ_ALL_ERR           = (GENMASK(21, 16) | GENMASK(14, 5)),
 320        DWAXIDMAC_IRQ_ALL               = GENMASK(31, 0)
 321};
 322
 323enum {
 324        DWAXIDMAC_TRANS_WIDTH_8         = 0,
 325        DWAXIDMAC_TRANS_WIDTH_16,
 326        DWAXIDMAC_TRANS_WIDTH_32,
 327        DWAXIDMAC_TRANS_WIDTH_64,
 328        DWAXIDMAC_TRANS_WIDTH_128,
 329        DWAXIDMAC_TRANS_WIDTH_256,
 330        DWAXIDMAC_TRANS_WIDTH_512,
 331        DWAXIDMAC_TRANS_WIDTH_MAX       = DWAXIDMAC_TRANS_WIDTH_512
 332};
 333
 334#endif /* _AXI_DMA_PLATFORM_H */
 335