Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Driver for the Intel integrated DMA 64-bit
0004  *
0005  * Copyright (C) 2015 Intel Corporation
0006  */
0007 
0008 #ifndef __DMA_IDMA64_H__
0009 #define __DMA_IDMA64_H__
0010 
0011 #include <linux/device.h>
0012 #include <linux/io.h>
0013 #include <linux/spinlock.h>
0014 #include <linux/types.h>
0015 
0016 #include <linux/io-64-nonatomic-lo-hi.h>
0017 
0018 #include "virt-dma.h"
0019 
0020 /* Channel registers */
0021 
0022 #define IDMA64_CH_SAR       0x00    /* Source Address Register */
0023 #define IDMA64_CH_DAR       0x08    /* Destination Address Register */
0024 #define IDMA64_CH_LLP       0x10    /* Linked List Pointer */
0025 #define IDMA64_CH_CTL_LO    0x18    /* Control Register Low */
0026 #define IDMA64_CH_CTL_HI    0x1c    /* Control Register High */
0027 #define IDMA64_CH_SSTAT     0x20
0028 #define IDMA64_CH_DSTAT     0x28
0029 #define IDMA64_CH_SSTATAR   0x30
0030 #define IDMA64_CH_DSTATAR   0x38
0031 #define IDMA64_CH_CFG_LO    0x40    /* Configuration Register Low */
0032 #define IDMA64_CH_CFG_HI    0x44    /* Configuration Register High */
0033 #define IDMA64_CH_SGR       0x48
0034 #define IDMA64_CH_DSR       0x50
0035 
0036 #define IDMA64_CH_LENGTH    0x58
0037 
0038 /* Bitfields in CTL_LO */
0039 #define IDMA64C_CTLL_INT_EN     (1 << 0)    /* irqs enabled? */
0040 #define IDMA64C_CTLL_DST_WIDTH(x)   ((x) << 1)  /* bytes per element */
0041 #define IDMA64C_CTLL_SRC_WIDTH(x)   ((x) << 4)
0042 #define IDMA64C_CTLL_DST_INC        (0 << 8)    /* DAR update/not */
0043 #define IDMA64C_CTLL_DST_FIX        (1 << 8)
0044 #define IDMA64C_CTLL_SRC_INC        (0 << 10)   /* SAR update/not */
0045 #define IDMA64C_CTLL_SRC_FIX        (1 << 10)
0046 #define IDMA64C_CTLL_DST_MSIZE(x)   ((x) << 11) /* burst, #elements */
0047 #define IDMA64C_CTLL_SRC_MSIZE(x)   ((x) << 14)
0048 #define IDMA64C_CTLL_FC_M2P     (1 << 20)   /* mem-to-periph */
0049 #define IDMA64C_CTLL_FC_P2M     (2 << 20)   /* periph-to-mem */
0050 #define IDMA64C_CTLL_LLP_D_EN       (1 << 27)   /* dest block chain */
0051 #define IDMA64C_CTLL_LLP_S_EN       (1 << 28)   /* src block chain */
0052 
0053 /* Bitfields in CTL_HI */
0054 #define IDMA64C_CTLH_BLOCK_TS_MASK  ((1 << 17) - 1)
0055 #define IDMA64C_CTLH_BLOCK_TS(x)    ((x) & IDMA64C_CTLH_BLOCK_TS_MASK)
0056 #define IDMA64C_CTLH_DONE       (1 << 17)
0057 
0058 /* Bitfields in CFG_LO */
0059 #define IDMA64C_CFGL_DST_BURST_ALIGN    (1 << 0)    /* dst burst align */
0060 #define IDMA64C_CFGL_SRC_BURST_ALIGN    (1 << 1)    /* src burst align */
0061 #define IDMA64C_CFGL_CH_SUSP        (1 << 8)
0062 #define IDMA64C_CFGL_FIFO_EMPTY     (1 << 9)
0063 #define IDMA64C_CFGL_CH_DRAIN       (1 << 10)   /* drain FIFO */
0064 #define IDMA64C_CFGL_DST_OPT_BL     (1 << 20)   /* optimize dst burst length */
0065 #define IDMA64C_CFGL_SRC_OPT_BL     (1 << 21)   /* optimize src burst length */
0066 
0067 /* Bitfields in CFG_HI */
0068 #define IDMA64C_CFGH_SRC_PER(x)     ((x) << 0)  /* src peripheral */
0069 #define IDMA64C_CFGH_DST_PER(x)     ((x) << 4)  /* dst peripheral */
0070 #define IDMA64C_CFGH_RD_ISSUE_THD(x)    ((x) << 8)
0071 #define IDMA64C_CFGH_WR_ISSUE_THD(x)    ((x) << 18)
0072 
0073 /* Interrupt registers */
0074 
0075 #define IDMA64_INT_XFER     0x00
0076 #define IDMA64_INT_BLOCK    0x08
0077 #define IDMA64_INT_SRC_TRAN 0x10
0078 #define IDMA64_INT_DST_TRAN 0x18
0079 #define IDMA64_INT_ERROR    0x20
0080 
0081 #define IDMA64_RAW(x)       (0x2c0 + IDMA64_INT_##x)    /* r */
0082 #define IDMA64_STATUS(x)    (0x2e8 + IDMA64_INT_##x)    /* r (raw & mask) */
0083 #define IDMA64_MASK(x)      (0x310 + IDMA64_INT_##x)    /* rw (set = irq enabled) */
0084 #define IDMA64_CLEAR(x)     (0x338 + IDMA64_INT_##x)    /* w (ack, affects "raw") */
0085 
0086 /* Common registers */
0087 
0088 #define IDMA64_STATUS_INT   0x360   /* r */
0089 #define IDMA64_CFG      0x398
0090 #define IDMA64_CH_EN        0x3a0
0091 
0092 /* Bitfields in CFG */
0093 #define IDMA64_CFG_DMA_EN       (1 << 0)
0094 
0095 /* Hardware descriptor for Linked LIst transfers */
0096 struct idma64_lli {
0097     u64     sar;
0098     u64     dar;
0099     u64     llp;
0100     u32     ctllo;
0101     u32     ctlhi;
0102     u32     sstat;
0103     u32     dstat;
0104 };
0105 
0106 struct idma64_hw_desc {
0107     struct idma64_lli *lli;
0108     dma_addr_t llp;
0109     dma_addr_t phys;
0110     unsigned int len;
0111 };
0112 
0113 struct idma64_desc {
0114     struct virt_dma_desc vdesc;
0115     enum dma_transfer_direction direction;
0116     struct idma64_hw_desc *hw;
0117     unsigned int ndesc;
0118     size_t length;
0119     enum dma_status status;
0120 };
0121 
0122 static inline struct idma64_desc *to_idma64_desc(struct virt_dma_desc *vdesc)
0123 {
0124     return container_of(vdesc, struct idma64_desc, vdesc);
0125 }
0126 
0127 struct idma64_chan {
0128     struct virt_dma_chan vchan;
0129 
0130     void __iomem *regs;
0131 
0132     /* hardware configuration */
0133     enum dma_transfer_direction direction;
0134     unsigned int mask;
0135     struct dma_slave_config config;
0136 
0137     void *pool;
0138     struct idma64_desc *desc;
0139 };
0140 
0141 static inline struct idma64_chan *to_idma64_chan(struct dma_chan *chan)
0142 {
0143     return container_of(chan, struct idma64_chan, vchan.chan);
0144 }
0145 
0146 #define channel_set_bit(idma64, reg, mask)  \
0147     dma_writel(idma64, reg, ((mask) << 8) | (mask))
0148 #define channel_clear_bit(idma64, reg, mask)    \
0149     dma_writel(idma64, reg, ((mask) << 8) | 0)
0150 
0151 static inline u32 idma64c_readl(struct idma64_chan *idma64c, int offset)
0152 {
0153     return readl(idma64c->regs + offset);
0154 }
0155 
0156 static inline void idma64c_writel(struct idma64_chan *idma64c, int offset,
0157                   u32 value)
0158 {
0159     writel(value, idma64c->regs + offset);
0160 }
0161 
0162 #define channel_readl(idma64c, reg)     \
0163     idma64c_readl(idma64c, IDMA64_CH_##reg)
0164 #define channel_writel(idma64c, reg, value) \
0165     idma64c_writel(idma64c, IDMA64_CH_##reg, (value))
0166 
0167 static inline u64 idma64c_readq(struct idma64_chan *idma64c, int offset)
0168 {
0169     return lo_hi_readq(idma64c->regs + offset);
0170 }
0171 
0172 static inline void idma64c_writeq(struct idma64_chan *idma64c, int offset,
0173                   u64 value)
0174 {
0175     lo_hi_writeq(value, idma64c->regs + offset);
0176 }
0177 
0178 #define channel_readq(idma64c, reg)     \
0179     idma64c_readq(idma64c, IDMA64_CH_##reg)
0180 #define channel_writeq(idma64c, reg, value) \
0181     idma64c_writeq(idma64c, IDMA64_CH_##reg, (value))
0182 
0183 struct idma64 {
0184     struct dma_device dma;
0185 
0186     void __iomem *regs;
0187 
0188     /* channels */
0189     unsigned short all_chan_mask;
0190     struct idma64_chan *chan;
0191 };
0192 
0193 static inline struct idma64 *to_idma64(struct dma_device *ddev)
0194 {
0195     return container_of(ddev, struct idma64, dma);
0196 }
0197 
0198 static inline u32 idma64_readl(struct idma64 *idma64, int offset)
0199 {
0200     return readl(idma64->regs + offset);
0201 }
0202 
0203 static inline void idma64_writel(struct idma64 *idma64, int offset, u32 value)
0204 {
0205     writel(value, idma64->regs + offset);
0206 }
0207 
0208 #define dma_readl(idma64, reg)          \
0209     idma64_readl(idma64, IDMA64_##reg)
0210 #define dma_writel(idma64, reg, value)      \
0211     idma64_writel(idma64, IDMA64_##reg, (value))
0212 
0213 /**
0214  * struct idma64_chip - representation of iDMA 64-bit controller hardware
0215  * @dev:        struct device of the DMA controller
0216  * @sysdev:     struct device of the physical device that does DMA
0217  * @irq:        irq line
0218  * @regs:       memory mapped I/O space
0219  * @idma64:     struct idma64 that is filed by idma64_probe()
0220  */
0221 struct idma64_chip {
0222     struct device   *dev;
0223     struct device   *sysdev;
0224     int     irq;
0225     void __iomem    *regs;
0226     struct idma64   *idma64;
0227 };
0228 
0229 #endif /* __DMA_IDMA64_H__ */