0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _AXI_DMA_PLATFORM_H
0011 #define _AXI_DMA_PLATFORM_H
0012
0013 #include <linux/bitops.h>
0014 #include <linux/clk.h>
0015 #include <linux/device.h>
0016 #include <linux/dmaengine.h>
0017 #include <linux/types.h>
0018
0019 #include "../virt-dma.h"
0020
0021 #define DMAC_MAX_CHANNELS 16
0022 #define DMAC_MAX_MASTERS 2
0023 #define DMAC_MAX_BLK_SIZE 0x200000
0024
0025 struct dw_axi_dma_hcfg {
0026 u32 nr_channels;
0027 u32 nr_masters;
0028 u32 m_data_width;
0029 u32 block_size[DMAC_MAX_CHANNELS];
0030 u32 priority[DMAC_MAX_CHANNELS];
0031
0032 u32 axi_rw_burst_len;
0033
0034 bool reg_map_8_channels;
0035 bool restrict_axi_burst_len;
0036 };
0037
0038 struct axi_dma_chan {
0039 struct axi_dma_chip *chip;
0040 void __iomem *chan_regs;
0041 u8 id;
0042 u8 hw_handshake_num;
0043 atomic_t descs_allocated;
0044
0045 struct dma_pool *desc_pool;
0046 struct virt_dma_chan vc;
0047
0048 struct axi_dma_desc *desc;
0049 struct dma_slave_config config;
0050 enum dma_transfer_direction direction;
0051 bool cyclic;
0052
0053 bool is_paused;
0054 };
0055
0056 struct dw_axi_dma {
0057 struct dma_device dma;
0058 struct dw_axi_dma_hcfg *hdata;
0059 struct device_dma_parameters dma_parms;
0060
0061
0062 struct axi_dma_chan *chan;
0063 };
0064
0065 struct axi_dma_chip {
0066 struct device *dev;
0067 int irq;
0068 void __iomem *regs;
0069 void __iomem *apb_regs;
0070 struct clk *core_clk;
0071 struct clk *cfgr_clk;
0072 struct dw_axi_dma *dw;
0073 };
0074
0075
0076 struct __packed axi_dma_lli {
0077 __le64 sar;
0078 __le64 dar;
0079 __le32 block_ts_lo;
0080 __le32 block_ts_hi;
0081 __le64 llp;
0082 __le32 ctl_lo;
0083 __le32 ctl_hi;
0084 __le32 sstat;
0085 __le32 dstat;
0086 __le32 status_lo;
0087 __le32 status_hi;
0088 __le32 reserved_lo;
0089 __le32 reserved_hi;
0090 };
0091
0092 struct axi_dma_hw_desc {
0093 struct axi_dma_lli *lli;
0094 dma_addr_t llp;
0095 u32 len;
0096 };
0097
0098 struct axi_dma_desc {
0099 struct axi_dma_hw_desc *hw_desc;
0100
0101 struct virt_dma_desc vd;
0102 struct axi_dma_chan *chan;
0103 u32 completed_blocks;
0104 u32 length;
0105 u32 period_len;
0106 };
0107
0108 struct axi_dma_chan_config {
0109 u8 dst_multblk_type;
0110 u8 src_multblk_type;
0111 u8 dst_per;
0112 u8 src_per;
0113 u8 tt_fc;
0114 u8 prior;
0115 u8 hs_sel_dst;
0116 u8 hs_sel_src;
0117 };
0118
0119 static inline struct device *dchan2dev(struct dma_chan *dchan)
0120 {
0121 return &dchan->dev->device;
0122 }
0123
0124 static inline struct device *chan2dev(struct axi_dma_chan *chan)
0125 {
0126 return &chan->vc.chan.dev->device;
0127 }
0128
0129 static inline struct axi_dma_desc *vd_to_axi_desc(struct virt_dma_desc *vd)
0130 {
0131 return container_of(vd, struct axi_dma_desc, vd);
0132 }
0133
0134 static inline struct axi_dma_chan *vc_to_axi_dma_chan(struct virt_dma_chan *vc)
0135 {
0136 return container_of(vc, struct axi_dma_chan, vc);
0137 }
0138
0139 static inline struct axi_dma_chan *dchan_to_axi_dma_chan(struct dma_chan *dchan)
0140 {
0141 return vc_to_axi_dma_chan(to_virt_chan(dchan));
0142 }
0143
0144
0145 #define COMMON_REG_LEN 0x100
0146 #define CHAN_REG_LEN 0x100
0147
0148
0149 #define DMAC_ID 0x000
0150 #define DMAC_COMPVER 0x008
0151 #define DMAC_CFG 0x010
0152 #define DMAC_CHEN 0x018
0153 #define DMAC_CHEN_L 0x018
0154 #define DMAC_CHEN_H 0x01C
0155 #define DMAC_CHSUSPREG 0x020
0156 #define DMAC_CHABORTREG 0x028
0157 #define DMAC_INTSTATUS 0x030
0158 #define DMAC_COMMON_INTCLEAR 0x038
0159 #define DMAC_COMMON_INTSTATUS_ENA 0x040
0160 #define DMAC_COMMON_INTSIGNAL_ENA 0x048
0161 #define DMAC_COMMON_INTSTATUS 0x050
0162 #define DMAC_RESET 0x058
0163
0164
0165 #define CH_SAR 0x000
0166 #define CH_DAR 0x008
0167 #define CH_BLOCK_TS 0x010
0168 #define CH_CTL 0x018
0169 #define CH_CTL_L 0x018
0170 #define CH_CTL_H 0x01C
0171 #define CH_CFG 0x020
0172 #define CH_CFG_L 0x020
0173 #define CH_CFG_H 0x024
0174 #define CH_LLP 0x028
0175 #define CH_STATUS 0x030
0176 #define CH_SWHSSRC 0x038
0177 #define CH_SWHSDST 0x040
0178 #define CH_BLK_TFR_RESUMEREQ 0x048
0179 #define CH_AXI_ID 0x050
0180 #define CH_AXI_QOS 0x058
0181 #define CH_SSTAT 0x060
0182 #define CH_DSTAT 0x068
0183 #define CH_SSTATAR 0x070
0184 #define CH_DSTATAR 0x078
0185 #define CH_INTSTATUS_ENA 0x080
0186 #define CH_INTSTATUS 0x088
0187 #define CH_INTSIGNAL_ENA 0x090
0188 #define CH_INTCLEAR 0x098
0189
0190
0191 #define DMAC_APB_CFG 0x000
0192 #define DMAC_APB_STAT 0x004
0193 #define DMAC_APB_DEBUG_STAT_0 0x008
0194 #define DMAC_APB_DEBUG_STAT_1 0x00C
0195 #define DMAC_APB_HW_HS_SEL_0 0x010
0196 #define DMAC_APB_HW_HS_SEL_1 0x014
0197 #define DMAC_APB_LPI 0x018
0198 #define DMAC_APB_BYTE_WR_CH_EN 0x01C
0199 #define DMAC_APB_HALFWORD_WR_CH_EN 0x020
0200
0201 #define UNUSED_CHANNEL 0x3F
0202 #define DMA_APB_HS_SEL_BIT_SIZE 0x08
0203 #define DMA_APB_HS_SEL_MASK 0xFF
0204 #define MAX_BLOCK_SIZE 0x1000
0205 #define DMA_REG_MAP_CH_REF 0x08
0206
0207
0208 #define DMAC_EN_POS 0
0209 #define DMAC_EN_MASK BIT(DMAC_EN_POS)
0210
0211 #define INT_EN_POS 1
0212 #define INT_EN_MASK BIT(INT_EN_POS)
0213
0214
0215 #define DMAC_CHAN_EN_SHIFT 0
0216 #define DMAC_CHAN_EN_WE_SHIFT 8
0217
0218 #define DMAC_CHAN_SUSP_SHIFT 16
0219 #define DMAC_CHAN_SUSP_WE_SHIFT 24
0220
0221
0222 #define DMAC_CHAN_EN2_WE_SHIFT 16
0223
0224
0225 #define DMAC_CHAN_SUSP2_SHIFT 0
0226 #define DMAC_CHAN_SUSP2_WE_SHIFT 16
0227
0228
0229 #define CH_CTL_H_ARLEN_EN BIT(6)
0230 #define CH_CTL_H_ARLEN_POS 7
0231 #define CH_CTL_H_AWLEN_EN BIT(15)
0232 #define CH_CTL_H_AWLEN_POS 16
0233
0234 enum {
0235 DWAXIDMAC_ARWLEN_1 = 0,
0236 DWAXIDMAC_ARWLEN_2 = 1,
0237 DWAXIDMAC_ARWLEN_4 = 3,
0238 DWAXIDMAC_ARWLEN_8 = 7,
0239 DWAXIDMAC_ARWLEN_16 = 15,
0240 DWAXIDMAC_ARWLEN_32 = 31,
0241 DWAXIDMAC_ARWLEN_64 = 63,
0242 DWAXIDMAC_ARWLEN_128 = 127,
0243 DWAXIDMAC_ARWLEN_256 = 255,
0244 DWAXIDMAC_ARWLEN_MIN = DWAXIDMAC_ARWLEN_1,
0245 DWAXIDMAC_ARWLEN_MAX = DWAXIDMAC_ARWLEN_256
0246 };
0247
0248 #define CH_CTL_H_LLI_LAST BIT(30)
0249 #define CH_CTL_H_LLI_VALID BIT(31)
0250
0251
0252 #define CH_CTL_L_LAST_WRITE_EN BIT(30)
0253
0254 #define CH_CTL_L_DST_MSIZE_POS 18
0255 #define CH_CTL_L_SRC_MSIZE_POS 14
0256
0257 enum {
0258 DWAXIDMAC_BURST_TRANS_LEN_1 = 0,
0259 DWAXIDMAC_BURST_TRANS_LEN_4,
0260 DWAXIDMAC_BURST_TRANS_LEN_8,
0261 DWAXIDMAC_BURST_TRANS_LEN_16,
0262 DWAXIDMAC_BURST_TRANS_LEN_32,
0263 DWAXIDMAC_BURST_TRANS_LEN_64,
0264 DWAXIDMAC_BURST_TRANS_LEN_128,
0265 DWAXIDMAC_BURST_TRANS_LEN_256,
0266 DWAXIDMAC_BURST_TRANS_LEN_512,
0267 DWAXIDMAC_BURST_TRANS_LEN_1024
0268 };
0269
0270 #define CH_CTL_L_DST_WIDTH_POS 11
0271 #define CH_CTL_L_SRC_WIDTH_POS 8
0272
0273 #define CH_CTL_L_DST_INC_POS 6
0274 #define CH_CTL_L_SRC_INC_POS 4
0275 enum {
0276 DWAXIDMAC_CH_CTL_L_INC = 0,
0277 DWAXIDMAC_CH_CTL_L_NOINC
0278 };
0279
0280 #define CH_CTL_L_DST_MAST BIT(2)
0281 #define CH_CTL_L_SRC_MAST BIT(0)
0282
0283
0284 #define CH_CFG_H_PRIORITY_POS 17
0285 #define CH_CFG_H_DST_PER_POS 12
0286 #define CH_CFG_H_SRC_PER_POS 7
0287 #define CH_CFG_H_HS_SEL_DST_POS 4
0288 #define CH_CFG_H_HS_SEL_SRC_POS 3
0289 enum {
0290 DWAXIDMAC_HS_SEL_HW = 0,
0291 DWAXIDMAC_HS_SEL_SW
0292 };
0293
0294 #define CH_CFG_H_TT_FC_POS 0
0295 enum {
0296 DWAXIDMAC_TT_FC_MEM_TO_MEM_DMAC = 0,
0297 DWAXIDMAC_TT_FC_MEM_TO_PER_DMAC,
0298 DWAXIDMAC_TT_FC_PER_TO_MEM_DMAC,
0299 DWAXIDMAC_TT_FC_PER_TO_PER_DMAC,
0300 DWAXIDMAC_TT_FC_PER_TO_MEM_SRC,
0301 DWAXIDMAC_TT_FC_PER_TO_PER_SRC,
0302 DWAXIDMAC_TT_FC_MEM_TO_PER_DST,
0303 DWAXIDMAC_TT_FC_PER_TO_PER_DST
0304 };
0305
0306
0307 #define CH_CFG_L_DST_MULTBLK_TYPE_POS 2
0308 #define CH_CFG_L_SRC_MULTBLK_TYPE_POS 0
0309 enum {
0310 DWAXIDMAC_MBLK_TYPE_CONTIGUOUS = 0,
0311 DWAXIDMAC_MBLK_TYPE_RELOAD,
0312 DWAXIDMAC_MBLK_TYPE_SHADOW_REG,
0313 DWAXIDMAC_MBLK_TYPE_LL
0314 };
0315
0316
0317 #define CH_CFG2_L_SRC_PER_POS 4
0318 #define CH_CFG2_L_DST_PER_POS 11
0319
0320 #define CH_CFG2_H_TT_FC_POS 0
0321 #define CH_CFG2_H_HS_SEL_SRC_POS 3
0322 #define CH_CFG2_H_HS_SEL_DST_POS 4
0323 #define CH_CFG2_H_PRIORITY_POS 20
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357 enum {
0358 DWAXIDMAC_IRQ_NONE = 0,
0359 DWAXIDMAC_IRQ_BLOCK_TRF = BIT(0),
0360 DWAXIDMAC_IRQ_DMA_TRF = BIT(1),
0361 DWAXIDMAC_IRQ_SRC_TRAN = BIT(3),
0362 DWAXIDMAC_IRQ_DST_TRAN = BIT(4),
0363 DWAXIDMAC_IRQ_SRC_DEC_ERR = BIT(5),
0364 DWAXIDMAC_IRQ_DST_DEC_ERR = BIT(6),
0365 DWAXIDMAC_IRQ_SRC_SLV_ERR = BIT(7),
0366 DWAXIDMAC_IRQ_DST_SLV_ERR = BIT(8),
0367 DWAXIDMAC_IRQ_LLI_RD_DEC_ERR = BIT(9),
0368 DWAXIDMAC_IRQ_LLI_WR_DEC_ERR = BIT(10),
0369 DWAXIDMAC_IRQ_LLI_RD_SLV_ERR = BIT(11),
0370 DWAXIDMAC_IRQ_LLI_WR_SLV_ERR = BIT(12),
0371 DWAXIDMAC_IRQ_INVALID_ERR = BIT(13),
0372 DWAXIDMAC_IRQ_MULTIBLKTYPE_ERR = BIT(14),
0373 DWAXIDMAC_IRQ_DEC_ERR = BIT(16),
0374 DWAXIDMAC_IRQ_WR2RO_ERR = BIT(17),
0375 DWAXIDMAC_IRQ_RD2RWO_ERR = BIT(18),
0376 DWAXIDMAC_IRQ_WRONCHEN_ERR = BIT(19),
0377 DWAXIDMAC_IRQ_SHADOWREG_ERR = BIT(20),
0378 DWAXIDMAC_IRQ_WRONHOLD_ERR = BIT(21),
0379 DWAXIDMAC_IRQ_LOCK_CLEARED = BIT(27),
0380 DWAXIDMAC_IRQ_SRC_SUSPENDED = BIT(28),
0381 DWAXIDMAC_IRQ_SUSPENDED = BIT(29),
0382 DWAXIDMAC_IRQ_DISABLED = BIT(30),
0383 DWAXIDMAC_IRQ_ABORTED = BIT(31),
0384 DWAXIDMAC_IRQ_ALL_ERR = (GENMASK(21, 16) | GENMASK(14, 5)),
0385 DWAXIDMAC_IRQ_ALL = GENMASK(31, 0)
0386 };
0387
0388 enum {
0389 DWAXIDMAC_TRANS_WIDTH_8 = 0,
0390 DWAXIDMAC_TRANS_WIDTH_16,
0391 DWAXIDMAC_TRANS_WIDTH_32,
0392 DWAXIDMAC_TRANS_WIDTH_64,
0393 DWAXIDMAC_TRANS_WIDTH_128,
0394 DWAXIDMAC_TRANS_WIDTH_256,
0395 DWAXIDMAC_TRANS_WIDTH_512,
0396 DWAXIDMAC_TRANS_WIDTH_MAX = DWAXIDMAC_TRANS_WIDTH_512
0397 };
0398
0399 #endif