xref: /openbmc/linux/drivers/dma/idma64.h (revision 1fa0a7dc)
1 /*
2  * Driver for the Intel integrated DMA 64-bit
3  *
4  * Copyright (C) 2015 Intel 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 #ifndef __DMA_IDMA64_H__
12 #define __DMA_IDMA64_H__
13 
14 #include <linux/device.h>
15 #include <linux/io.h>
16 #include <linux/spinlock.h>
17 #include <linux/types.h>
18 
19 #include <linux/io-64-nonatomic-lo-hi.h>
20 
21 #include "virt-dma.h"
22 
23 /* Channel registers */
24 
25 #define IDMA64_CH_SAR		0x00	/* Source Address Register */
26 #define IDMA64_CH_DAR		0x08	/* Destination Address Register */
27 #define IDMA64_CH_LLP		0x10	/* Linked List Pointer */
28 #define IDMA64_CH_CTL_LO	0x18	/* Control Register Low */
29 #define IDMA64_CH_CTL_HI	0x1c	/* Control Register High */
30 #define IDMA64_CH_SSTAT		0x20
31 #define IDMA64_CH_DSTAT		0x28
32 #define IDMA64_CH_SSTATAR	0x30
33 #define IDMA64_CH_DSTATAR	0x38
34 #define IDMA64_CH_CFG_LO	0x40	/* Configuration Register Low */
35 #define IDMA64_CH_CFG_HI	0x44	/* Configuration Register High */
36 #define IDMA64_CH_SGR		0x48
37 #define IDMA64_CH_DSR		0x50
38 
39 #define IDMA64_CH_LENGTH	0x58
40 
41 /* Bitfields in CTL_LO */
42 #define IDMA64C_CTLL_INT_EN		(1 << 0)	/* irqs enabled? */
43 #define IDMA64C_CTLL_DST_WIDTH(x)	((x) << 1)	/* bytes per element */
44 #define IDMA64C_CTLL_SRC_WIDTH(x)	((x) << 4)
45 #define IDMA64C_CTLL_DST_INC		(0 << 8)	/* DAR update/not */
46 #define IDMA64C_CTLL_DST_FIX		(1 << 8)
47 #define IDMA64C_CTLL_SRC_INC		(0 << 10)	/* SAR update/not */
48 #define IDMA64C_CTLL_SRC_FIX		(1 << 10)
49 #define IDMA64C_CTLL_DST_MSIZE(x)	((x) << 11)	/* burst, #elements */
50 #define IDMA64C_CTLL_SRC_MSIZE(x)	((x) << 14)
51 #define IDMA64C_CTLL_FC_M2P		(1 << 20)	/* mem-to-periph */
52 #define IDMA64C_CTLL_FC_P2M		(2 << 20)	/* periph-to-mem */
53 #define IDMA64C_CTLL_LLP_D_EN		(1 << 27)	/* dest block chain */
54 #define IDMA64C_CTLL_LLP_S_EN		(1 << 28)	/* src block chain */
55 
56 /* Bitfields in CTL_HI */
57 #define IDMA64C_CTLH_BLOCK_TS_MASK	((1 << 17) - 1)
58 #define IDMA64C_CTLH_BLOCK_TS(x)	((x) & IDMA64C_CTLH_BLOCK_TS_MASK)
59 #define IDMA64C_CTLH_DONE		(1 << 17)
60 
61 /* Bitfields in CFG_LO */
62 #define IDMA64C_CFGL_DST_BURST_ALIGN	(1 << 0)	/* dst burst align */
63 #define IDMA64C_CFGL_SRC_BURST_ALIGN	(1 << 1)	/* src burst align */
64 #define IDMA64C_CFGL_CH_SUSP		(1 << 8)
65 #define IDMA64C_CFGL_FIFO_EMPTY		(1 << 9)
66 #define IDMA64C_CFGL_CH_DRAIN		(1 << 10)	/* drain FIFO */
67 #define IDMA64C_CFGL_DST_OPT_BL		(1 << 20)	/* optimize dst burst length */
68 #define IDMA64C_CFGL_SRC_OPT_BL		(1 << 21)	/* optimize src burst length */
69 
70 /* Bitfields in CFG_HI */
71 #define IDMA64C_CFGH_SRC_PER(x)		((x) << 0)	/* src peripheral */
72 #define IDMA64C_CFGH_DST_PER(x)		((x) << 4)	/* dst peripheral */
73 #define IDMA64C_CFGH_RD_ISSUE_THD(x)	((x) << 8)
74 #define IDMA64C_CFGH_WR_ISSUE_THD(x)	((x) << 18)
75 
76 /* Interrupt registers */
77 
78 #define IDMA64_INT_XFER		0x00
79 #define IDMA64_INT_BLOCK	0x08
80 #define IDMA64_INT_SRC_TRAN	0x10
81 #define IDMA64_INT_DST_TRAN	0x18
82 #define IDMA64_INT_ERROR	0x20
83 
84 #define IDMA64_RAW(x)		(0x2c0 + IDMA64_INT_##x)	/* r */
85 #define IDMA64_STATUS(x)	(0x2e8 + IDMA64_INT_##x)	/* r (raw & mask) */
86 #define IDMA64_MASK(x)		(0x310 + IDMA64_INT_##x)	/* rw (set = irq enabled) */
87 #define IDMA64_CLEAR(x)		(0x338 + IDMA64_INT_##x)	/* w (ack, affects "raw") */
88 
89 /* Common registers */
90 
91 #define IDMA64_STATUS_INT	0x360	/* r */
92 #define IDMA64_CFG		0x398
93 #define IDMA64_CH_EN		0x3a0
94 
95 /* Bitfields in CFG */
96 #define IDMA64_CFG_DMA_EN		(1 << 0)
97 
98 /* Hardware descriptor for Linked LIst transfers */
99 struct idma64_lli {
100 	u64		sar;
101 	u64		dar;
102 	u64		llp;
103 	u32		ctllo;
104 	u32		ctlhi;
105 	u32		sstat;
106 	u32		dstat;
107 };
108 
109 struct idma64_hw_desc {
110 	struct idma64_lli *lli;
111 	dma_addr_t llp;
112 	dma_addr_t phys;
113 	unsigned int len;
114 };
115 
116 struct idma64_desc {
117 	struct virt_dma_desc vdesc;
118 	enum dma_transfer_direction direction;
119 	struct idma64_hw_desc *hw;
120 	unsigned int ndesc;
121 	size_t length;
122 	enum dma_status status;
123 };
124 
125 static inline struct idma64_desc *to_idma64_desc(struct virt_dma_desc *vdesc)
126 {
127 	return container_of(vdesc, struct idma64_desc, vdesc);
128 }
129 
130 struct idma64_chan {
131 	struct virt_dma_chan vchan;
132 
133 	void __iomem *regs;
134 
135 	/* hardware configuration */
136 	enum dma_transfer_direction direction;
137 	unsigned int mask;
138 	struct dma_slave_config config;
139 
140 	void *pool;
141 	struct idma64_desc *desc;
142 };
143 
144 static inline struct idma64_chan *to_idma64_chan(struct dma_chan *chan)
145 {
146 	return container_of(chan, struct idma64_chan, vchan.chan);
147 }
148 
149 #define channel_set_bit(idma64, reg, mask)	\
150 	dma_writel(idma64, reg, ((mask) << 8) | (mask))
151 #define channel_clear_bit(idma64, reg, mask)	\
152 	dma_writel(idma64, reg, ((mask) << 8) | 0)
153 
154 static inline u32 idma64c_readl(struct idma64_chan *idma64c, int offset)
155 {
156 	return readl(idma64c->regs + offset);
157 }
158 
159 static inline void idma64c_writel(struct idma64_chan *idma64c, int offset,
160 				  u32 value)
161 {
162 	writel(value, idma64c->regs + offset);
163 }
164 
165 #define channel_readl(idma64c, reg)		\
166 	idma64c_readl(idma64c, IDMA64_CH_##reg)
167 #define channel_writel(idma64c, reg, value)	\
168 	idma64c_writel(idma64c, IDMA64_CH_##reg, (value))
169 
170 static inline u64 idma64c_readq(struct idma64_chan *idma64c, int offset)
171 {
172 	return lo_hi_readq(idma64c->regs + offset);
173 }
174 
175 static inline void idma64c_writeq(struct idma64_chan *idma64c, int offset,
176 				  u64 value)
177 {
178 	lo_hi_writeq(value, idma64c->regs + offset);
179 }
180 
181 #define channel_readq(idma64c, reg)		\
182 	idma64c_readq(idma64c, IDMA64_CH_##reg)
183 #define channel_writeq(idma64c, reg, value)	\
184 	idma64c_writeq(idma64c, IDMA64_CH_##reg, (value))
185 
186 struct idma64 {
187 	struct dma_device dma;
188 
189 	void __iomem *regs;
190 
191 	/* channels */
192 	unsigned short all_chan_mask;
193 	struct idma64_chan *chan;
194 };
195 
196 static inline struct idma64 *to_idma64(struct dma_device *ddev)
197 {
198 	return container_of(ddev, struct idma64, dma);
199 }
200 
201 static inline u32 idma64_readl(struct idma64 *idma64, int offset)
202 {
203 	return readl(idma64->regs + offset);
204 }
205 
206 static inline void idma64_writel(struct idma64 *idma64, int offset, u32 value)
207 {
208 	writel(value, idma64->regs + offset);
209 }
210 
211 #define dma_readl(idma64, reg)			\
212 	idma64_readl(idma64, IDMA64_##reg)
213 #define dma_writel(idma64, reg, value)		\
214 	idma64_writel(idma64, IDMA64_##reg, (value))
215 
216 /**
217  * struct idma64_chip - representation of iDMA 64-bit controller hardware
218  * @dev:		struct device of the DMA controller
219  * @sysdev:		struct device of the physical device that does DMA
220  * @irq:		irq line
221  * @regs:		memory mapped I/O space
222  * @idma64:		struct idma64 that is filed by idma64_probe()
223  */
224 struct idma64_chip {
225 	struct device	*dev;
226 	struct device	*sysdev;
227 	int		irq;
228 	void __iomem	*regs;
229 	struct idma64	*idma64;
230 };
231 
232 #endif /* __DMA_IDMA64_H__ */
233