linux/drivers/dma/dw_dmac_regs.h
<<
>>
Prefs
   1/*
   2 * Driver for the Synopsys DesignWare AHB DMA Controller
   3 *
   4 * Copyright (C) 2005-2007 Atmel Corporation
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10
  11#include <linux/dw_dmac.h>
  12
  13#define DW_DMA_MAX_NR_CHANNELS  8
  14
  15/*
  16 * Redefine this macro to handle differences between 32- and 64-bit
  17 * addressing, big vs. little endian, etc.
  18 */
  19#define DW_REG(name)            u32 name; u32 __pad_##name
  20
  21/* Hardware register definitions. */
  22struct dw_dma_chan_regs {
  23        DW_REG(SAR);            /* Source Address Register */
  24        DW_REG(DAR);            /* Destination Address Register */
  25        DW_REG(LLP);            /* Linked List Pointer */
  26        u32     CTL_LO;         /* Control Register Low */
  27        u32     CTL_HI;         /* Control Register High */
  28        DW_REG(SSTAT);
  29        DW_REG(DSTAT);
  30        DW_REG(SSTATAR);
  31        DW_REG(DSTATAR);
  32        u32     CFG_LO;         /* Configuration Register Low */
  33        u32     CFG_HI;         /* Configuration Register High */
  34        DW_REG(SGR);
  35        DW_REG(DSR);
  36};
  37
  38struct dw_dma_irq_regs {
  39        DW_REG(XFER);
  40        DW_REG(BLOCK);
  41        DW_REG(SRC_TRAN);
  42        DW_REG(DST_TRAN);
  43        DW_REG(ERROR);
  44};
  45
  46struct dw_dma_regs {
  47        /* per-channel registers */
  48        struct dw_dma_chan_regs CHAN[DW_DMA_MAX_NR_CHANNELS];
  49
  50        /* irq handling */
  51        struct dw_dma_irq_regs  RAW;            /* r */
  52        struct dw_dma_irq_regs  STATUS;         /* r (raw & mask) */
  53        struct dw_dma_irq_regs  MASK;           /* rw (set = irq enabled) */
  54        struct dw_dma_irq_regs  CLEAR;          /* w (ack, affects "raw") */
  55
  56        DW_REG(STATUS_INT);                     /* r */
  57
  58        /* software handshaking */
  59        DW_REG(REQ_SRC);
  60        DW_REG(REQ_DST);
  61        DW_REG(SGL_REQ_SRC);
  62        DW_REG(SGL_REQ_DST);
  63        DW_REG(LAST_SRC);
  64        DW_REG(LAST_DST);
  65
  66        /* miscellaneous */
  67        DW_REG(CFG);
  68        DW_REG(CH_EN);
  69        DW_REG(ID);
  70        DW_REG(TEST);
  71
  72        /* optional encoded params, 0x3c8..0x3 */
  73};
  74
  75/* Bitfields in CTL_LO */
  76#define DWC_CTLL_INT_EN         (1 << 0)        /* irqs enabled? */
  77#define DWC_CTLL_DST_WIDTH(n)   ((n)<<1)        /* bytes per element */
  78#define DWC_CTLL_SRC_WIDTH(n)   ((n)<<4)
  79#define DWC_CTLL_DST_INC        (0<<7)          /* DAR update/not */
  80#define DWC_CTLL_DST_DEC        (1<<7)
  81#define DWC_CTLL_DST_FIX        (2<<7)
  82#define DWC_CTLL_SRC_INC        (0<<7)          /* SAR update/not */
  83#define DWC_CTLL_SRC_DEC        (1<<9)
  84#define DWC_CTLL_SRC_FIX        (2<<9)
  85#define DWC_CTLL_DST_MSIZE(n)   ((n)<<11)       /* burst, #elements */
  86#define DWC_CTLL_SRC_MSIZE(n)   ((n)<<14)
  87#define DWC_CTLL_S_GATH_EN      (1 << 17)       /* src gather, !FIX */
  88#define DWC_CTLL_D_SCAT_EN      (1 << 18)       /* dst scatter, !FIX */
  89#define DWC_CTLL_FC_M2M         (0 << 20)       /* mem-to-mem */
  90#define DWC_CTLL_FC_M2P         (1 << 20)       /* mem-to-periph */
  91#define DWC_CTLL_FC_P2M         (2 << 20)       /* periph-to-mem */
  92#define DWC_CTLL_FC_P2P         (3 << 20)       /* periph-to-periph */
  93/* plus 4 transfer types for peripheral-as-flow-controller */
  94#define DWC_CTLL_DMS(n)         ((n)<<23)       /* dst master select */
  95#define DWC_CTLL_SMS(n)         ((n)<<25)       /* src master select */
  96#define DWC_CTLL_LLP_D_EN       (1 << 27)       /* dest block chain */
  97#define DWC_CTLL_LLP_S_EN       (1 << 28)       /* src block chain */
  98
  99/* Bitfields in CTL_HI */
 100#define DWC_CTLH_DONE           0x00001000
 101#define DWC_CTLH_BLOCK_TS_MASK  0x00000fff
 102
 103/* Bitfields in CFG_LO. Platform-configurable bits are in <linux/dw_dmac.h> */
 104#define DWC_CFGL_CH_SUSP        (1 << 8)        /* pause xfer */
 105#define DWC_CFGL_FIFO_EMPTY     (1 << 9)        /* pause xfer */
 106#define DWC_CFGL_HS_DST         (1 << 10)       /* handshake w/dst */
 107#define DWC_CFGL_HS_SRC         (1 << 11)       /* handshake w/src */
 108#define DWC_CFGL_MAX_BURST(x)   ((x) << 20)
 109#define DWC_CFGL_RELOAD_SAR     (1 << 30)
 110#define DWC_CFGL_RELOAD_DAR     (1 << 31)
 111
 112/* Bitfields in CFG_HI. Platform-configurable bits are in <linux/dw_dmac.h> */
 113#define DWC_CFGH_DS_UPD_EN      (1 << 5)
 114#define DWC_CFGH_SS_UPD_EN      (1 << 6)
 115
 116/* Bitfields in SGR */
 117#define DWC_SGR_SGI(x)          ((x) << 0)
 118#define DWC_SGR_SGC(x)          ((x) << 20)
 119
 120/* Bitfields in DSR */
 121#define DWC_DSR_DSI(x)          ((x) << 0)
 122#define DWC_DSR_DSC(x)          ((x) << 20)
 123
 124/* Bitfields in CFG */
 125#define DW_CFG_DMA_EN           (1 << 0)
 126
 127#define DW_REGLEN               0x400
 128
 129enum dw_dmac_flags {
 130        DW_DMA_IS_CYCLIC = 0,
 131};
 132
 133struct dw_dma_chan {
 134        struct dma_chan         chan;
 135        void __iomem            *ch_regs;
 136        u8                      mask;
 137
 138        spinlock_t              lock;
 139
 140        /* these other elements are all protected by lock */
 141        unsigned long           flags;
 142        dma_cookie_t            completed;
 143        struct list_head        active_list;
 144        struct list_head        queue;
 145        struct list_head        free_list;
 146        struct dw_cyclic_desc   *cdesc;
 147
 148        unsigned int            descs_allocated;
 149};
 150
 151static inline struct dw_dma_chan_regs __iomem *
 152__dwc_regs(struct dw_dma_chan *dwc)
 153{
 154        return dwc->ch_regs;
 155}
 156
 157#define channel_readl(dwc, name) \
 158        __raw_readl(&(__dwc_regs(dwc)->name))
 159#define channel_writel(dwc, name, val) \
 160        __raw_writel((val), &(__dwc_regs(dwc)->name))
 161
 162static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan)
 163{
 164        return container_of(chan, struct dw_dma_chan, chan);
 165}
 166
 167struct dw_dma {
 168        struct dma_device       dma;
 169        void __iomem            *regs;
 170        struct tasklet_struct   tasklet;
 171        struct clk              *clk;
 172
 173        u8                      all_chan_mask;
 174
 175        struct dw_dma_chan      chan[0];
 176};
 177
 178static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw)
 179{
 180        return dw->regs;
 181}
 182
 183#define dma_readl(dw, name) \
 184        __raw_readl(&(__dw_regs(dw)->name))
 185#define dma_writel(dw, name, val) \
 186        __raw_writel((val), &(__dw_regs(dw)->name))
 187
 188#define channel_set_bit(dw, reg, mask) \
 189        dma_writel(dw, reg, ((mask) << 8) | (mask))
 190#define channel_clear_bit(dw, reg, mask) \
 191        dma_writel(dw, reg, ((mask) << 8) | 0)
 192
 193static inline struct dw_dma *to_dw_dma(struct dma_device *ddev)
 194{
 195        return container_of(ddev, struct dw_dma, dma);
 196}
 197
 198/* LLI == Linked List Item; a.k.a. DMA block descriptor */
 199struct dw_lli {
 200        /* values that are not changed by hardware */
 201        dma_addr_t      sar;
 202        dma_addr_t      dar;
 203        dma_addr_t      llp;            /* chain to next lli */
 204        u32             ctllo;
 205        /* values that may get written back: */
 206        u32             ctlhi;
 207        /* sstat and dstat can snapshot peripheral register state.
 208         * silicon config may discard either or both...
 209         */
 210        u32             sstat;
 211        u32             dstat;
 212};
 213
 214struct dw_desc {
 215        /* FIRST values the hardware uses */
 216        struct dw_lli                   lli;
 217
 218        /* THEN values for driver housekeeping */
 219        struct list_head                desc_node;
 220        struct list_head                tx_list;
 221        struct dma_async_tx_descriptor  txd;
 222        size_t                          len;
 223};
 224
 225static inline struct dw_desc *
 226txd_to_dw_desc(struct dma_async_tx_descriptor *txd)
 227{
 228        return container_of(txd, struct dw_desc, txd);
 229}
 230