1 /* SPDX-License-Identifier: GPL-2.0 */
2 // (C) 2017-2018 Synopsys, Inc. (www.synopsys.com)
5 * Synopsys DesignWare AXI DMA Controller driver.
7 * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
10 #ifndef _AXI_DMA_PLATFORM_H
11 #define _AXI_DMA_PLATFORM_H
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>
19 #include "../virt-dma.h"
21 #define DMAC_MAX_CHANNELS 32
22 #define DMAC_MAX_MASTERS 2
23 #define DMAC_MAX_BLK_SIZE 0x200000
25 struct dw_axi_dma_hcfg
{
29 u32 block_size
[DMAC_MAX_CHANNELS
];
30 u32 priority
[DMAC_MAX_CHANNELS
];
31 /* maximum supported axi burst length */
33 /* Register map for DMAX_NUM_CHANNELS <= 8 */
34 bool reg_map_8_channels
;
35 bool restrict_axi_burst_len
;
40 struct axi_dma_chip
*chip
;
41 void __iomem
*chan_regs
;
44 atomic_t descs_allocated
;
46 struct dma_pool
*desc_pool
;
47 struct virt_dma_chan vc
;
49 struct axi_dma_desc
*desc
;
50 struct dma_slave_config config
;
51 enum dma_transfer_direction direction
;
53 /* these other elements are all protected by vc.lock */
58 struct dma_device dma
;
59 struct dw_axi_dma_hcfg
*hdata
;
60 struct device_dma_parameters dma_parms
;
63 struct axi_dma_chan
*chan
;
68 int irq
[DMAC_MAX_CHANNELS
];
70 void __iomem
*apb_regs
;
73 struct dw_axi_dma
*dw
;
76 /* LLI == Linked List Item */
77 struct __packed axi_dma_lli
{
93 struct axi_dma_hw_desc
{
94 struct axi_dma_lli
*lli
;
100 struct axi_dma_hw_desc
*hw_desc
;
102 struct virt_dma_desc vd
;
103 struct axi_dma_chan
*chan
;
104 u32 completed_blocks
;
110 struct axi_dma_chan_config
{
121 static inline struct device
*dchan2dev(struct dma_chan
*dchan
)
123 return &dchan
->dev
->device
;
126 static inline struct device
*chan2dev(struct axi_dma_chan
*chan
)
128 return &chan
->vc
.chan
.dev
->device
;
131 static inline struct axi_dma_desc
*vd_to_axi_desc(struct virt_dma_desc
*vd
)
133 return container_of(vd
, struct axi_dma_desc
, vd
);
136 static inline struct axi_dma_chan
*vc_to_axi_dma_chan(struct virt_dma_chan
*vc
)
138 return container_of(vc
, struct axi_dma_chan
, vc
);
141 static inline struct axi_dma_chan
*dchan_to_axi_dma_chan(struct dma_chan
*dchan
)
143 return vc_to_axi_dma_chan(to_virt_chan(dchan
));
147 #define COMMON_REG_LEN 0x100
148 #define CHAN_REG_LEN 0x100
150 /* Common registers offset */
151 #define DMAC_ID 0x000 /* R DMAC ID */
152 #define DMAC_COMPVER 0x008 /* R DMAC Component Version */
153 #define DMAC_CFG 0x010 /* R/W DMAC Configuration */
154 #define DMAC_CHEN 0x018 /* R/W DMAC Channel Enable */
155 #define DMAC_CHEN_L 0x018 /* R/W DMAC Channel Enable 00-31 */
156 #define DMAC_CHEN_H 0x01C /* R/W DMAC Channel Enable 32-63 */
157 #define DMAC_CHSUSPREG 0x020 /* R/W DMAC Channel Suspend */
158 #define DMAC_CHABORTREG 0x028 /* R/W DMAC Channel Abort */
159 #define DMAC_INTSTATUS 0x030 /* R DMAC Interrupt Status */
160 #define DMAC_COMMON_INTCLEAR 0x038 /* W DMAC Interrupt Clear */
161 #define DMAC_COMMON_INTSTATUS_ENA 0x040 /* R DMAC Interrupt Status Enable */
162 #define DMAC_COMMON_INTSIGNAL_ENA 0x048 /* R/W DMAC Interrupt Signal Enable */
163 #define DMAC_COMMON_INTSTATUS 0x050 /* R DMAC Interrupt Status */
164 #define DMAC_RESET 0x058 /* R DMAC Reset Register1 */
166 /* DMA channel registers offset */
167 #define CH_SAR 0x000 /* R/W Chan Source Address */
168 #define CH_DAR 0x008 /* R/W Chan Destination Address */
169 #define CH_BLOCK_TS 0x010 /* R/W Chan Block Transfer Size */
170 #define CH_CTL 0x018 /* R/W Chan Control */
171 #define CH_CTL_L 0x018 /* R/W Chan Control 00-31 */
172 #define CH_CTL_H 0x01C /* R/W Chan Control 32-63 */
173 #define CH_CFG 0x020 /* R/W Chan Configuration */
174 #define CH_CFG_L 0x020 /* R/W Chan Configuration 00-31 */
175 #define CH_CFG_H 0x024 /* R/W Chan Configuration 32-63 */
176 #define CH_LLP 0x028 /* R/W Chan Linked List Pointer */
177 #define CH_STATUS 0x030 /* R Chan Status */
178 #define CH_SWHSSRC 0x038 /* R/W Chan SW Handshake Source */
179 #define CH_SWHSDST 0x040 /* R/W Chan SW Handshake Destination */
180 #define CH_BLK_TFR_RESUMEREQ 0x048 /* W Chan Block Transfer Resume Req */
181 #define CH_AXI_ID 0x050 /* R/W Chan AXI ID */
182 #define CH_AXI_QOS 0x058 /* R/W Chan AXI QOS */
183 #define CH_SSTAT 0x060 /* R Chan Source Status */
184 #define CH_DSTAT 0x068 /* R Chan Destination Status */
185 #define CH_SSTATAR 0x070 /* R/W Chan Source Status Fetch Addr */
186 #define CH_DSTATAR 0x078 /* R/W Chan Destination Status Fetch Addr */
187 #define CH_INTSTATUS_ENA 0x080 /* R/W Chan Interrupt Status Enable */
188 #define CH_INTSTATUS 0x088 /* R/W Chan Interrupt Status */
189 #define CH_INTSIGNAL_ENA 0x090 /* R/W Chan Interrupt Signal Enable */
190 #define CH_INTCLEAR 0x098 /* W Chan Interrupt Clear */
192 /* These Apb registers are used by Intel KeemBay SoC */
193 #define DMAC_APB_CFG 0x000 /* DMAC Apb Configuration Register */
194 #define DMAC_APB_STAT 0x004 /* DMAC Apb Status Register */
195 #define DMAC_APB_DEBUG_STAT_0 0x008 /* DMAC Apb Debug Status Register 0 */
196 #define DMAC_APB_DEBUG_STAT_1 0x00C /* DMAC Apb Debug Status Register 1 */
197 #define DMAC_APB_HW_HS_SEL_0 0x010 /* DMAC Apb HW HS register 0 */
198 #define DMAC_APB_HW_HS_SEL_1 0x014 /* DMAC Apb HW HS register 1 */
199 #define DMAC_APB_LPI 0x018 /* DMAC Apb Low Power Interface Reg */
200 #define DMAC_APB_BYTE_WR_CH_EN 0x01C /* DMAC Apb Byte Write Enable */
201 #define DMAC_APB_HALFWORD_WR_CH_EN 0x020 /* DMAC Halfword write enables */
203 #define UNUSED_CHANNEL 0x3F /* Set unused DMA channel to 0x3F */
204 #define DMA_APB_HS_SEL_BIT_SIZE 0x08 /* HW handshake bits per channel */
205 #define DMA_APB_HS_SEL_MASK 0xFF /* HW handshake select masks */
206 #define MAX_BLOCK_SIZE 0x1000 /* 1024 blocks * 4 bytes data width */
207 #define DMA_REG_MAP_CH_REF 0x08 /* Channel count to choose register map */
210 #define DMAC_EN_POS 0
211 #define DMAC_EN_MASK BIT(DMAC_EN_POS)
214 #define INT_EN_MASK BIT(INT_EN_POS)
217 #define DMAC_CHAN_EN_SHIFT 0
218 #define DMAC_CHAN_EN_WE_SHIFT 8
220 #define DMAC_CHAN_SUSP_SHIFT 16
221 #define DMAC_CHAN_SUSP_WE_SHIFT 24
224 #define DMAC_CHAN_EN2_WE_SHIFT 16
226 /* DMAC CHAN BLOCKS */
227 #define DMAC_CHAN_BLOCK_SHIFT 32
228 #define DMAC_CHAN_16 16
231 #define DMAC_CHAN_SUSP2_SHIFT 0
232 #define DMAC_CHAN_SUSP2_WE_SHIFT 16
235 #define CH_CTL_H_ARLEN_EN BIT(6)
236 #define CH_CTL_H_ARLEN_POS 7
237 #define CH_CTL_H_AWLEN_EN BIT(15)
238 #define CH_CTL_H_AWLEN_POS 16
241 DWAXIDMAC_ARWLEN_1
= 0,
242 DWAXIDMAC_ARWLEN_2
= 1,
243 DWAXIDMAC_ARWLEN_4
= 3,
244 DWAXIDMAC_ARWLEN_8
= 7,
245 DWAXIDMAC_ARWLEN_16
= 15,
246 DWAXIDMAC_ARWLEN_32
= 31,
247 DWAXIDMAC_ARWLEN_64
= 63,
248 DWAXIDMAC_ARWLEN_128
= 127,
249 DWAXIDMAC_ARWLEN_256
= 255,
250 DWAXIDMAC_ARWLEN_MIN
= DWAXIDMAC_ARWLEN_1
,
251 DWAXIDMAC_ARWLEN_MAX
= DWAXIDMAC_ARWLEN_256
254 #define CH_CTL_H_LLI_LAST BIT(30)
255 #define CH_CTL_H_LLI_VALID BIT(31)
258 #define CH_CTL_L_LAST_WRITE_EN BIT(30)
260 #define CH_CTL_L_DST_MSIZE_POS 18
261 #define CH_CTL_L_SRC_MSIZE_POS 14
264 DWAXIDMAC_BURST_TRANS_LEN_1
= 0,
265 DWAXIDMAC_BURST_TRANS_LEN_4
,
266 DWAXIDMAC_BURST_TRANS_LEN_8
,
267 DWAXIDMAC_BURST_TRANS_LEN_16
,
268 DWAXIDMAC_BURST_TRANS_LEN_32
,
269 DWAXIDMAC_BURST_TRANS_LEN_64
,
270 DWAXIDMAC_BURST_TRANS_LEN_128
,
271 DWAXIDMAC_BURST_TRANS_LEN_256
,
272 DWAXIDMAC_BURST_TRANS_LEN_512
,
273 DWAXIDMAC_BURST_TRANS_LEN_1024
276 #define CH_CTL_L_DST_WIDTH_POS 11
277 #define CH_CTL_L_SRC_WIDTH_POS 8
279 #define CH_CTL_L_DST_INC_POS 6
280 #define CH_CTL_L_SRC_INC_POS 4
282 DWAXIDMAC_CH_CTL_L_INC
= 0,
283 DWAXIDMAC_CH_CTL_L_NOINC
286 #define CH_CTL_L_DST_MAST BIT(2)
287 #define CH_CTL_L_SRC_MAST BIT(0)
290 #define CH_CFG_H_PRIORITY_POS 17
291 #define CH_CFG_H_DST_PER_POS 12
292 #define CH_CFG_H_SRC_PER_POS 7
293 #define CH_CFG_H_HS_SEL_DST_POS 4
294 #define CH_CFG_H_HS_SEL_SRC_POS 3
296 DWAXIDMAC_HS_SEL_HW
= 0,
300 #define CH_CFG_H_TT_FC_POS 0
302 DWAXIDMAC_TT_FC_MEM_TO_MEM_DMAC
= 0,
303 DWAXIDMAC_TT_FC_MEM_TO_PER_DMAC
,
304 DWAXIDMAC_TT_FC_PER_TO_MEM_DMAC
,
305 DWAXIDMAC_TT_FC_PER_TO_PER_DMAC
,
306 DWAXIDMAC_TT_FC_PER_TO_MEM_SRC
,
307 DWAXIDMAC_TT_FC_PER_TO_PER_SRC
,
308 DWAXIDMAC_TT_FC_MEM_TO_PER_DST
,
309 DWAXIDMAC_TT_FC_PER_TO_PER_DST
313 #define CH_CFG_L_DST_MULTBLK_TYPE_POS 2
314 #define CH_CFG_L_SRC_MULTBLK_TYPE_POS 0
316 DWAXIDMAC_MBLK_TYPE_CONTIGUOUS
= 0,
317 DWAXIDMAC_MBLK_TYPE_RELOAD
,
318 DWAXIDMAC_MBLK_TYPE_SHADOW_REG
,
319 DWAXIDMAC_MBLK_TYPE_LL
323 #define CH_CFG2_L_SRC_PER_POS 4
324 #define CH_CFG2_L_DST_PER_POS 11
326 #define CH_CFG2_H_TT_FC_POS 0
327 #define CH_CFG2_H_HS_SEL_SRC_POS 3
328 #define CH_CFG2_H_HS_SEL_DST_POS 4
329 #define CH_CFG2_H_PRIORITY_POS 20
332 * DW AXI DMA channel interrupts
334 * @DWAXIDMAC_IRQ_NONE: Bitmask of no one interrupt
335 * @DWAXIDMAC_IRQ_BLOCK_TRF: Block transfer complete
336 * @DWAXIDMAC_IRQ_DMA_TRF: Dma transfer complete
337 * @DWAXIDMAC_IRQ_SRC_TRAN: Source transaction complete
338 * @DWAXIDMAC_IRQ_DST_TRAN: Destination transaction complete
339 * @DWAXIDMAC_IRQ_SRC_DEC_ERR: Source decode error
340 * @DWAXIDMAC_IRQ_DST_DEC_ERR: Destination decode error
341 * @DWAXIDMAC_IRQ_SRC_SLV_ERR: Source slave error
342 * @DWAXIDMAC_IRQ_DST_SLV_ERR: Destination slave error
343 * @DWAXIDMAC_IRQ_LLI_RD_DEC_ERR: LLI read decode error
344 * @DWAXIDMAC_IRQ_LLI_WR_DEC_ERR: LLI write decode error
345 * @DWAXIDMAC_IRQ_LLI_RD_SLV_ERR: LLI read slave error
346 * @DWAXIDMAC_IRQ_LLI_WR_SLV_ERR: LLI write slave error
347 * @DWAXIDMAC_IRQ_INVALID_ERR: LLI invalid error or Shadow register error
348 * @DWAXIDMAC_IRQ_MULTIBLKTYPE_ERR: Slave Interface Multiblock type error
349 * @DWAXIDMAC_IRQ_DEC_ERR: Slave Interface decode error
350 * @DWAXIDMAC_IRQ_WR2RO_ERR: Slave Interface write to read only error
351 * @DWAXIDMAC_IRQ_RD2RWO_ERR: Slave Interface read to write only error
352 * @DWAXIDMAC_IRQ_WRONCHEN_ERR: Slave Interface write to channel error
353 * @DWAXIDMAC_IRQ_SHADOWREG_ERR: Slave Interface shadow reg error
354 * @DWAXIDMAC_IRQ_WRONHOLD_ERR: Slave Interface hold error
355 * @DWAXIDMAC_IRQ_LOCK_CLEARED: Lock Cleared Status
356 * @DWAXIDMAC_IRQ_SRC_SUSPENDED: Source Suspended Status
357 * @DWAXIDMAC_IRQ_SUSPENDED: Channel Suspended Status
358 * @DWAXIDMAC_IRQ_DISABLED: Channel Disabled Status
359 * @DWAXIDMAC_IRQ_ABORTED: Channel Aborted Status
360 * @DWAXIDMAC_IRQ_ALL_ERR: Bitmask of all error interrupts
361 * @DWAXIDMAC_IRQ_ALL: Bitmask of all interrupts
364 DWAXIDMAC_IRQ_NONE
= 0,
365 DWAXIDMAC_IRQ_BLOCK_TRF
= BIT(0),
366 DWAXIDMAC_IRQ_DMA_TRF
= BIT(1),
367 DWAXIDMAC_IRQ_SRC_TRAN
= BIT(3),
368 DWAXIDMAC_IRQ_DST_TRAN
= BIT(4),
369 DWAXIDMAC_IRQ_SRC_DEC_ERR
= BIT(5),
370 DWAXIDMAC_IRQ_DST_DEC_ERR
= BIT(6),
371 DWAXIDMAC_IRQ_SRC_SLV_ERR
= BIT(7),
372 DWAXIDMAC_IRQ_DST_SLV_ERR
= BIT(8),
373 DWAXIDMAC_IRQ_LLI_RD_DEC_ERR
= BIT(9),
374 DWAXIDMAC_IRQ_LLI_WR_DEC_ERR
= BIT(10),
375 DWAXIDMAC_IRQ_LLI_RD_SLV_ERR
= BIT(11),
376 DWAXIDMAC_IRQ_LLI_WR_SLV_ERR
= BIT(12),
377 DWAXIDMAC_IRQ_INVALID_ERR
= BIT(13),
378 DWAXIDMAC_IRQ_MULTIBLKTYPE_ERR
= BIT(14),
379 DWAXIDMAC_IRQ_DEC_ERR
= BIT(16),
380 DWAXIDMAC_IRQ_WR2RO_ERR
= BIT(17),
381 DWAXIDMAC_IRQ_RD2RWO_ERR
= BIT(18),
382 DWAXIDMAC_IRQ_WRONCHEN_ERR
= BIT(19),
383 DWAXIDMAC_IRQ_SHADOWREG_ERR
= BIT(20),
384 DWAXIDMAC_IRQ_WRONHOLD_ERR
= BIT(21),
385 DWAXIDMAC_IRQ_LOCK_CLEARED
= BIT(27),
386 DWAXIDMAC_IRQ_SRC_SUSPENDED
= BIT(28),
387 DWAXIDMAC_IRQ_SUSPENDED
= BIT(29),
388 DWAXIDMAC_IRQ_DISABLED
= BIT(30),
389 DWAXIDMAC_IRQ_ABORTED
= BIT(31),
390 DWAXIDMAC_IRQ_ALL_ERR
= (GENMASK(21, 16) | GENMASK(14, 5)),
391 DWAXIDMAC_IRQ_ALL
= GENMASK(31, 0)
395 DWAXIDMAC_TRANS_WIDTH_8
= 0,
396 DWAXIDMAC_TRANS_WIDTH_16
,
397 DWAXIDMAC_TRANS_WIDTH_32
,
398 DWAXIDMAC_TRANS_WIDTH_64
,
399 DWAXIDMAC_TRANS_WIDTH_128
,
400 DWAXIDMAC_TRANS_WIDTH_256
,
401 DWAXIDMAC_TRANS_WIDTH_512
,
402 DWAXIDMAC_TRANS_WIDTH_MAX
= DWAXIDMAC_TRANS_WIDTH_512
405 #endif /* _AXI_DMA_PLATFORM_H */