xref: /openbmc/linux/drivers/dma/idma64.h (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
2667dfed9SAndy Shevchenko /*
3667dfed9SAndy Shevchenko  * Driver for the Intel integrated DMA 64-bit
4667dfed9SAndy Shevchenko  *
5667dfed9SAndy Shevchenko  * Copyright (C) 2015 Intel Corporation
6667dfed9SAndy Shevchenko  */
7667dfed9SAndy Shevchenko 
8667dfed9SAndy Shevchenko #ifndef __DMA_IDMA64_H__
9667dfed9SAndy Shevchenko #define __DMA_IDMA64_H__
10667dfed9SAndy Shevchenko 
11667dfed9SAndy Shevchenko #include <linux/device.h>
12667dfed9SAndy Shevchenko #include <linux/io.h>
13667dfed9SAndy Shevchenko #include <linux/spinlock.h>
14667dfed9SAndy Shevchenko #include <linux/types.h>
15667dfed9SAndy Shevchenko 
16a1cbaad7SArnd Bergmann #include <linux/io-64-nonatomic-lo-hi.h>
1797c37accSAndy Shevchenko 
18667dfed9SAndy Shevchenko #include "virt-dma.h"
19667dfed9SAndy Shevchenko 
20667dfed9SAndy Shevchenko /* Channel registers */
21667dfed9SAndy Shevchenko 
22667dfed9SAndy Shevchenko #define IDMA64_CH_SAR		0x00	/* Source Address Register */
23667dfed9SAndy Shevchenko #define IDMA64_CH_DAR		0x08	/* Destination Address Register */
24667dfed9SAndy Shevchenko #define IDMA64_CH_LLP		0x10	/* Linked List Pointer */
25667dfed9SAndy Shevchenko #define IDMA64_CH_CTL_LO	0x18	/* Control Register Low */
26667dfed9SAndy Shevchenko #define IDMA64_CH_CTL_HI	0x1c	/* Control Register High */
27667dfed9SAndy Shevchenko #define IDMA64_CH_SSTAT		0x20
28667dfed9SAndy Shevchenko #define IDMA64_CH_DSTAT		0x28
29667dfed9SAndy Shevchenko #define IDMA64_CH_SSTATAR	0x30
30667dfed9SAndy Shevchenko #define IDMA64_CH_DSTATAR	0x38
31667dfed9SAndy Shevchenko #define IDMA64_CH_CFG_LO	0x40	/* Configuration Register Low */
32667dfed9SAndy Shevchenko #define IDMA64_CH_CFG_HI	0x44	/* Configuration Register High */
33667dfed9SAndy Shevchenko #define IDMA64_CH_SGR		0x48
34667dfed9SAndy Shevchenko #define IDMA64_CH_DSR		0x50
35667dfed9SAndy Shevchenko 
36667dfed9SAndy Shevchenko #define IDMA64_CH_LENGTH	0x58
37667dfed9SAndy Shevchenko 
38667dfed9SAndy Shevchenko /* Bitfields in CTL_LO */
39667dfed9SAndy Shevchenko #define IDMA64C_CTLL_INT_EN		(1 << 0)	/* irqs enabled? */
40667dfed9SAndy Shevchenko #define IDMA64C_CTLL_DST_WIDTH(x)	((x) << 1)	/* bytes per element */
41667dfed9SAndy Shevchenko #define IDMA64C_CTLL_SRC_WIDTH(x)	((x) << 4)
42667dfed9SAndy Shevchenko #define IDMA64C_CTLL_DST_INC		(0 << 8)	/* DAR update/not */
43667dfed9SAndy Shevchenko #define IDMA64C_CTLL_DST_FIX		(1 << 8)
44667dfed9SAndy Shevchenko #define IDMA64C_CTLL_SRC_INC		(0 << 10)	/* SAR update/not */
45667dfed9SAndy Shevchenko #define IDMA64C_CTLL_SRC_FIX		(1 << 10)
46667dfed9SAndy Shevchenko #define IDMA64C_CTLL_DST_MSIZE(x)	((x) << 11)	/* burst, #elements */
47667dfed9SAndy Shevchenko #define IDMA64C_CTLL_SRC_MSIZE(x)	((x) << 14)
48667dfed9SAndy Shevchenko #define IDMA64C_CTLL_FC_M2P		(1 << 20)	/* mem-to-periph */
49667dfed9SAndy Shevchenko #define IDMA64C_CTLL_FC_P2M		(2 << 20)	/* periph-to-mem */
50667dfed9SAndy Shevchenko #define IDMA64C_CTLL_LLP_D_EN		(1 << 27)	/* dest block chain */
51667dfed9SAndy Shevchenko #define IDMA64C_CTLL_LLP_S_EN		(1 << 28)	/* src block chain */
52667dfed9SAndy Shevchenko 
53667dfed9SAndy Shevchenko /* Bitfields in CTL_HI */
54e3fdb189SAndy Shevchenko #define IDMA64C_CTLH_BLOCK_TS_MASK	((1 << 17) - 1)
55e3fdb189SAndy Shevchenko #define IDMA64C_CTLH_BLOCK_TS(x)	((x) & IDMA64C_CTLH_BLOCK_TS_MASK)
56667dfed9SAndy Shevchenko #define IDMA64C_CTLH_DONE		(1 << 17)
57667dfed9SAndy Shevchenko 
58667dfed9SAndy Shevchenko /* Bitfields in CFG_LO */
59667dfed9SAndy Shevchenko #define IDMA64C_CFGL_DST_BURST_ALIGN	(1 << 0)	/* dst burst align */
60667dfed9SAndy Shevchenko #define IDMA64C_CFGL_SRC_BURST_ALIGN	(1 << 1)	/* src burst align */
61667dfed9SAndy Shevchenko #define IDMA64C_CFGL_CH_SUSP		(1 << 8)
62667dfed9SAndy Shevchenko #define IDMA64C_CFGL_FIFO_EMPTY		(1 << 9)
63667dfed9SAndy Shevchenko #define IDMA64C_CFGL_CH_DRAIN		(1 << 10)	/* drain FIFO */
64667dfed9SAndy Shevchenko #define IDMA64C_CFGL_DST_OPT_BL		(1 << 20)	/* optimize dst burst length */
65667dfed9SAndy Shevchenko #define IDMA64C_CFGL_SRC_OPT_BL		(1 << 21)	/* optimize src burst length */
66667dfed9SAndy Shevchenko 
67667dfed9SAndy Shevchenko /* Bitfields in CFG_HI */
68667dfed9SAndy Shevchenko #define IDMA64C_CFGH_SRC_PER(x)		((x) << 0)	/* src peripheral */
69667dfed9SAndy Shevchenko #define IDMA64C_CFGH_DST_PER(x)		((x) << 4)	/* dst peripheral */
70667dfed9SAndy Shevchenko #define IDMA64C_CFGH_RD_ISSUE_THD(x)	((x) << 8)
718e2067beSAndy Shevchenko #define IDMA64C_CFGH_WR_ISSUE_THD(x)	((x) << 18)
72667dfed9SAndy Shevchenko 
73667dfed9SAndy Shevchenko /* Interrupt registers */
74667dfed9SAndy Shevchenko 
75667dfed9SAndy Shevchenko #define IDMA64_INT_XFER		0x00
76667dfed9SAndy Shevchenko #define IDMA64_INT_BLOCK	0x08
77667dfed9SAndy Shevchenko #define IDMA64_INT_SRC_TRAN	0x10
78667dfed9SAndy Shevchenko #define IDMA64_INT_DST_TRAN	0x18
79667dfed9SAndy Shevchenko #define IDMA64_INT_ERROR	0x20
80667dfed9SAndy Shevchenko 
81667dfed9SAndy Shevchenko #define IDMA64_RAW(x)		(0x2c0 + IDMA64_INT_##x)	/* r */
82667dfed9SAndy Shevchenko #define IDMA64_STATUS(x)	(0x2e8 + IDMA64_INT_##x)	/* r (raw & mask) */
83667dfed9SAndy Shevchenko #define IDMA64_MASK(x)		(0x310 + IDMA64_INT_##x)	/* rw (set = irq enabled) */
84667dfed9SAndy Shevchenko #define IDMA64_CLEAR(x)		(0x338 + IDMA64_INT_##x)	/* w (ack, affects "raw") */
85667dfed9SAndy Shevchenko 
86667dfed9SAndy Shevchenko /* Common registers */
87667dfed9SAndy Shevchenko 
88667dfed9SAndy Shevchenko #define IDMA64_STATUS_INT	0x360	/* r */
89667dfed9SAndy Shevchenko #define IDMA64_CFG		0x398
90667dfed9SAndy Shevchenko #define IDMA64_CH_EN		0x3a0
91667dfed9SAndy Shevchenko 
92667dfed9SAndy Shevchenko /* Bitfields in CFG */
93667dfed9SAndy Shevchenko #define IDMA64_CFG_DMA_EN		(1 << 0)
94667dfed9SAndy Shevchenko 
95667dfed9SAndy Shevchenko /* Hardware descriptor for Linked LIst transfers */
96667dfed9SAndy Shevchenko struct idma64_lli {
97667dfed9SAndy Shevchenko 	u64		sar;
98667dfed9SAndy Shevchenko 	u64		dar;
99667dfed9SAndy Shevchenko 	u64		llp;
100667dfed9SAndy Shevchenko 	u32		ctllo;
101667dfed9SAndy Shevchenko 	u32		ctlhi;
102667dfed9SAndy Shevchenko 	u32		sstat;
103667dfed9SAndy Shevchenko 	u32		dstat;
104667dfed9SAndy Shevchenko };
105667dfed9SAndy Shevchenko 
106667dfed9SAndy Shevchenko struct idma64_hw_desc {
107667dfed9SAndy Shevchenko 	struct idma64_lli *lli;
108667dfed9SAndy Shevchenko 	dma_addr_t llp;
109667dfed9SAndy Shevchenko 	dma_addr_t phys;
110667dfed9SAndy Shevchenko 	unsigned int len;
111667dfed9SAndy Shevchenko };
112667dfed9SAndy Shevchenko 
113667dfed9SAndy Shevchenko struct idma64_desc {
114667dfed9SAndy Shevchenko 	struct virt_dma_desc vdesc;
115667dfed9SAndy Shevchenko 	enum dma_transfer_direction direction;
116667dfed9SAndy Shevchenko 	struct idma64_hw_desc *hw;
117667dfed9SAndy Shevchenko 	unsigned int ndesc;
118667dfed9SAndy Shevchenko 	size_t length;
119667dfed9SAndy Shevchenko 	enum dma_status status;
120667dfed9SAndy Shevchenko };
121667dfed9SAndy Shevchenko 
to_idma64_desc(struct virt_dma_desc * vdesc)122667dfed9SAndy Shevchenko static inline struct idma64_desc *to_idma64_desc(struct virt_dma_desc *vdesc)
123667dfed9SAndy Shevchenko {
124667dfed9SAndy Shevchenko 	return container_of(vdesc, struct idma64_desc, vdesc);
125667dfed9SAndy Shevchenko }
126667dfed9SAndy Shevchenko 
127667dfed9SAndy Shevchenko struct idma64_chan {
128667dfed9SAndy Shevchenko 	struct virt_dma_chan vchan;
129667dfed9SAndy Shevchenko 
130667dfed9SAndy Shevchenko 	void __iomem *regs;
131667dfed9SAndy Shevchenko 
132667dfed9SAndy Shevchenko 	/* hardware configuration */
133667dfed9SAndy Shevchenko 	enum dma_transfer_direction direction;
134667dfed9SAndy Shevchenko 	unsigned int mask;
135667dfed9SAndy Shevchenko 	struct dma_slave_config config;
136667dfed9SAndy Shevchenko 
137667dfed9SAndy Shevchenko 	void *pool;
138667dfed9SAndy Shevchenko 	struct idma64_desc *desc;
139667dfed9SAndy Shevchenko };
140667dfed9SAndy Shevchenko 
to_idma64_chan(struct dma_chan * chan)141667dfed9SAndy Shevchenko static inline struct idma64_chan *to_idma64_chan(struct dma_chan *chan)
142667dfed9SAndy Shevchenko {
143667dfed9SAndy Shevchenko 	return container_of(chan, struct idma64_chan, vchan.chan);
144667dfed9SAndy Shevchenko }
145667dfed9SAndy Shevchenko 
146667dfed9SAndy Shevchenko #define channel_set_bit(idma64, reg, mask)	\
147667dfed9SAndy Shevchenko 	dma_writel(idma64, reg, ((mask) << 8) | (mask))
148667dfed9SAndy Shevchenko #define channel_clear_bit(idma64, reg, mask)	\
149667dfed9SAndy Shevchenko 	dma_writel(idma64, reg, ((mask) << 8) | 0)
150667dfed9SAndy Shevchenko 
idma64c_readl(struct idma64_chan * idma64c,int offset)151667dfed9SAndy Shevchenko static inline u32 idma64c_readl(struct idma64_chan *idma64c, int offset)
152667dfed9SAndy Shevchenko {
153667dfed9SAndy Shevchenko 	return readl(idma64c->regs + offset);
154667dfed9SAndy Shevchenko }
155667dfed9SAndy Shevchenko 
idma64c_writel(struct idma64_chan * idma64c,int offset,u32 value)156667dfed9SAndy Shevchenko static inline void idma64c_writel(struct idma64_chan *idma64c, int offset,
157667dfed9SAndy Shevchenko 				  u32 value)
158667dfed9SAndy Shevchenko {
159667dfed9SAndy Shevchenko 	writel(value, idma64c->regs + offset);
160667dfed9SAndy Shevchenko }
161667dfed9SAndy Shevchenko 
162667dfed9SAndy Shevchenko #define channel_readl(idma64c, reg)		\
163667dfed9SAndy Shevchenko 	idma64c_readl(idma64c, IDMA64_CH_##reg)
164667dfed9SAndy Shevchenko #define channel_writel(idma64c, reg, value)	\
165667dfed9SAndy Shevchenko 	idma64c_writel(idma64c, IDMA64_CH_##reg, (value))
166667dfed9SAndy Shevchenko 
idma64c_readq(struct idma64_chan * idma64c,int offset)167667dfed9SAndy Shevchenko static inline u64 idma64c_readq(struct idma64_chan *idma64c, int offset)
168667dfed9SAndy Shevchenko {
16997c37accSAndy Shevchenko 	return lo_hi_readq(idma64c->regs + offset);
170667dfed9SAndy Shevchenko }
171667dfed9SAndy Shevchenko 
idma64c_writeq(struct idma64_chan * idma64c,int offset,u64 value)172667dfed9SAndy Shevchenko static inline void idma64c_writeq(struct idma64_chan *idma64c, int offset,
173667dfed9SAndy Shevchenko 				  u64 value)
174667dfed9SAndy Shevchenko {
17597c37accSAndy Shevchenko 	lo_hi_writeq(value, idma64c->regs + offset);
176667dfed9SAndy Shevchenko }
177667dfed9SAndy Shevchenko 
178667dfed9SAndy Shevchenko #define channel_readq(idma64c, reg)		\
179667dfed9SAndy Shevchenko 	idma64c_readq(idma64c, IDMA64_CH_##reg)
180667dfed9SAndy Shevchenko #define channel_writeq(idma64c, reg, value)	\
181667dfed9SAndy Shevchenko 	idma64c_writeq(idma64c, IDMA64_CH_##reg, (value))
182667dfed9SAndy Shevchenko 
183667dfed9SAndy Shevchenko struct idma64 {
184667dfed9SAndy Shevchenko 	struct dma_device dma;
185667dfed9SAndy Shevchenko 
186667dfed9SAndy Shevchenko 	void __iomem *regs;
187667dfed9SAndy Shevchenko 
188667dfed9SAndy Shevchenko 	/* channels */
189667dfed9SAndy Shevchenko 	unsigned short all_chan_mask;
190667dfed9SAndy Shevchenko 	struct idma64_chan *chan;
191667dfed9SAndy Shevchenko };
192667dfed9SAndy Shevchenko 
to_idma64(struct dma_device * ddev)193667dfed9SAndy Shevchenko static inline struct idma64 *to_idma64(struct dma_device *ddev)
194667dfed9SAndy Shevchenko {
195667dfed9SAndy Shevchenko 	return container_of(ddev, struct idma64, dma);
196667dfed9SAndy Shevchenko }
197667dfed9SAndy Shevchenko 
idma64_readl(struct idma64 * idma64,int offset)198667dfed9SAndy Shevchenko static inline u32 idma64_readl(struct idma64 *idma64, int offset)
199667dfed9SAndy Shevchenko {
200667dfed9SAndy Shevchenko 	return readl(idma64->regs + offset);
201667dfed9SAndy Shevchenko }
202667dfed9SAndy Shevchenko 
idma64_writel(struct idma64 * idma64,int offset,u32 value)203667dfed9SAndy Shevchenko static inline void idma64_writel(struct idma64 *idma64, int offset, u32 value)
204667dfed9SAndy Shevchenko {
205667dfed9SAndy Shevchenko 	writel(value, idma64->regs + offset);
206667dfed9SAndy Shevchenko }
207667dfed9SAndy Shevchenko 
208667dfed9SAndy Shevchenko #define dma_readl(idma64, reg)			\
209667dfed9SAndy Shevchenko 	idma64_readl(idma64, IDMA64_##reg)
210667dfed9SAndy Shevchenko #define dma_writel(idma64, reg, value)		\
211667dfed9SAndy Shevchenko 	idma64_writel(idma64, IDMA64_##reg, (value))
212667dfed9SAndy Shevchenko 
213667dfed9SAndy Shevchenko /**
214581ec089SAndy Shevchenko  * struct idma64_chip - representation of iDMA 64-bit controller hardware
215667dfed9SAndy Shevchenko  * @dev:		struct device of the DMA controller
2165ba846b1SAndy Shevchenko  * @sysdev:		struct device of the physical device that does DMA
217667dfed9SAndy Shevchenko  * @irq:		irq line
218667dfed9SAndy Shevchenko  * @regs:		memory mapped I/O space
219667dfed9SAndy Shevchenko  * @idma64:		struct idma64 that is filed by idma64_probe()
220667dfed9SAndy Shevchenko  */
221667dfed9SAndy Shevchenko struct idma64_chip {
222667dfed9SAndy Shevchenko 	struct device	*dev;
2235ba846b1SAndy Shevchenko 	struct device	*sysdev;
224667dfed9SAndy Shevchenko 	int		irq;
225667dfed9SAndy Shevchenko 	void __iomem	*regs;
226667dfed9SAndy Shevchenko 	struct idma64	*idma64;
227667dfed9SAndy Shevchenko };
228667dfed9SAndy Shevchenko 
229667dfed9SAndy Shevchenko #endif /* __DMA_IDMA64_H__ */
230