xref: /openbmc/u-boot/drivers/dma/ti-edma3.c (revision a65b25d1)
1 /*
2  * Enhanced Direct Memory Access (EDMA3) Controller
3  *
4  * (C) Copyright 2014
5  *     Texas Instruments Incorporated, <www.ti.com>
6  *
7  * Author: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
8  *
9  * SPDX-License-Identifier:     GPL-2.0+
10  */
11 
12 #include <asm/io.h>
13 #include <common.h>
14 #include <asm/ti-common/ti-edma3.h>
15 
16 #define EDMA3_SL_BASE(slot)			(0x4000 + ((slot) << 5))
17 #define EDMA3_SL_MAX_NUM			512
18 #define EDMA3_SLOPT_FIFO_WIDTH_MASK		(0x7 << 8)
19 
20 #define EDMA3_QCHMAP(ch)			0x0200 + ((ch) << 2)
21 #define EDMA3_CHMAP_PARSET_MASK			0x1ff
22 #define EDMA3_CHMAP_PARSET_SHIFT		0x5
23 #define EDMA3_CHMAP_TRIGWORD_SHIFT		0x2
24 
25 #define EDMA3_QEMCR				0x314
26 #define EDMA3_IPR				0x1068
27 #define EDMA3_IPRH				0x106c
28 #define EDMA3_ICR				0x1070
29 #define EDMA3_ICRH				0x1074
30 #define EDMA3_QEECR				0x1088
31 #define EDMA3_QEESR				0x108c
32 #define EDMA3_QSECR				0x1094
33 
34 /**
35  * qedma3_start - start qdma on a channel
36  * @base: base address of edma
37  * @cfg: pinter to struct edma3_channel_config where you can set
38  * the slot number to associate with, the chnum, which corresponds
39  * your quick channel number 0-7, complete code - transfer complete code
40  * and trigger slot word - which has to correspond to the word number in
41  * edma3_slot_layout struct for generating event.
42  *
43  */
44 void qedma3_start(u32 base, struct edma3_channel_config *cfg)
45 {
46 	u32 qchmap;
47 
48 	/* Clear the pending int bit */
49 	if (cfg->complete_code < 32)
50 		__raw_writel(1 << cfg->complete_code, base + EDMA3_ICR);
51 	else
52 		__raw_writel(1 << cfg->complete_code, base + EDMA3_ICRH);
53 
54 	/* Map parameter set and trigger word 7 to quick channel */
55 	qchmap = ((EDMA3_CHMAP_PARSET_MASK & cfg->slot)
56 		  << EDMA3_CHMAP_PARSET_SHIFT) |
57 		  (cfg->trigger_slot_word << EDMA3_CHMAP_TRIGWORD_SHIFT);
58 
59 	__raw_writel(qchmap, base + EDMA3_QCHMAP(cfg->chnum));
60 
61 	/* Clear missed event if set*/
62 	__raw_writel(1 << cfg->chnum, base + EDMA3_QSECR);
63 	__raw_writel(1 << cfg->chnum, base + EDMA3_QEMCR);
64 
65 	/* Enable qdma channel event */
66 	__raw_writel(1 << cfg->chnum, base + EDMA3_QEESR);
67 }
68 
69 /**
70  * edma3_set_dest - set initial DMA destination address in parameter RAM slot
71  * @base: base address of edma
72  * @slot: parameter RAM slot being configured
73  * @dst: physical address of destination (memory, controller FIFO, etc)
74  * @addressMode: INCR, except in very rare cases
75  * @width: ignored unless @addressMode is FIFO, else specifies the
76  *	width to use when addressing the fifo (e.g. W8BIT, W32BIT)
77  *
78  * Note that the destination address is modified during the DMA transfer
79  * according to edma3_set_dest_index().
80  */
81 void edma3_set_dest(u32 base, int slot, u32 dst, enum edma3_address_mode mode,
82 		    enum edma3_fifo_width width)
83 {
84 	u32 opt;
85 	struct edma3_slot_layout *rg;
86 
87 	rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
88 
89 	opt = __raw_readl(&rg->opt);
90 	if (mode == FIFO)
91 		opt = (opt & EDMA3_SLOPT_FIFO_WIDTH_MASK) |
92 		       (EDMA3_SLOPT_DST_ADDR_CONST_MODE |
93 			EDMA3_SLOPT_FIFO_WIDTH_SET(width));
94 	else
95 		opt &= ~EDMA3_SLOPT_DST_ADDR_CONST_MODE;
96 
97 	__raw_writel(opt, &rg->opt);
98 	__raw_writel(dst, &rg->dst);
99 }
100 
101 /**
102  * edma3_set_dest_index - configure DMA destination address indexing
103  * @base: base address of edma
104  * @slot: parameter RAM slot being configured
105  * @bidx: byte offset between destination arrays in a frame
106  * @cidx: byte offset between destination frames in a block
107  *
108  * Offsets are specified to support either contiguous or discontiguous
109  * memory transfers, or repeated access to a hardware register, as needed.
110  * When accessing hardware registers, both offsets are normally zero.
111  */
112 void edma3_set_dest_index(u32 base, unsigned slot, int bidx, int cidx)
113 {
114 	u32 src_dst_bidx;
115 	u32 src_dst_cidx;
116 	struct edma3_slot_layout *rg;
117 
118 	rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
119 
120 	src_dst_bidx = __raw_readl(&rg->src_dst_bidx);
121 	src_dst_cidx = __raw_readl(&rg->src_dst_cidx);
122 
123 	__raw_writel((src_dst_bidx & 0x0000ffff) | (bidx << 16),
124 		     &rg->src_dst_bidx);
125 	__raw_writel((src_dst_cidx & 0x0000ffff) | (cidx << 16),
126 		     &rg->src_dst_cidx);
127 }
128 
129 /**
130  * edma3_set_dest_addr - set destination address for slot only
131  */
132 void edma3_set_dest_addr(u32 base, int slot, u32 dst)
133 {
134 	struct edma3_slot_layout *rg;
135 
136 	rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
137 	__raw_writel(dst, &rg->dst);
138 }
139 
140 /**
141  * edma3_set_src - set initial DMA source address in parameter RAM slot
142  * @base: base address of edma
143  * @slot: parameter RAM slot being configured
144  * @src_port: physical address of source (memory, controller FIFO, etc)
145  * @mode: INCR, except in very rare cases
146  * @width: ignored unless @addressMode is FIFO, else specifies the
147  *	width to use when addressing the fifo (e.g. W8BIT, W32BIT)
148  *
149  * Note that the source address is modified during the DMA transfer
150  * according to edma3_set_src_index().
151  */
152 void edma3_set_src(u32 base, int slot, u32 src, enum edma3_address_mode mode,
153 		   enum edma3_fifo_width width)
154 {
155 	u32 opt;
156 	struct edma3_slot_layout *rg;
157 
158 	rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
159 
160 	opt = __raw_readl(&rg->opt);
161 	if (mode == FIFO)
162 		opt = (opt & EDMA3_SLOPT_FIFO_WIDTH_MASK) |
163 		       (EDMA3_SLOPT_DST_ADDR_CONST_MODE |
164 			EDMA3_SLOPT_FIFO_WIDTH_SET(width));
165 	else
166 		opt &= ~EDMA3_SLOPT_DST_ADDR_CONST_MODE;
167 
168 	__raw_writel(opt, &rg->opt);
169 	__raw_writel(src, &rg->src);
170 }
171 
172 /**
173  * edma3_set_src_index - configure DMA source address indexing
174  * @base: base address of edma
175  * @slot: parameter RAM slot being configured
176  * @bidx: byte offset between source arrays in a frame
177  * @cidx: byte offset between source frames in a block
178  *
179  * Offsets are specified to support either contiguous or discontiguous
180  * memory transfers, or repeated access to a hardware register, as needed.
181  * When accessing hardware registers, both offsets are normally zero.
182  */
183 void edma3_set_src_index(u32 base, unsigned slot, int bidx, int cidx)
184 {
185 	u32 src_dst_bidx;
186 	u32 src_dst_cidx;
187 	struct edma3_slot_layout *rg;
188 
189 	rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
190 
191 	src_dst_bidx = __raw_readl(&rg->src_dst_bidx);
192 	src_dst_cidx = __raw_readl(&rg->src_dst_cidx);
193 
194 	__raw_writel((src_dst_bidx & 0xffff0000) | bidx,
195 		     &rg->src_dst_bidx);
196 	__raw_writel((src_dst_cidx & 0xffff0000) | cidx,
197 		     &rg->src_dst_cidx);
198 }
199 
200 /**
201  * edma3_set_src_addr - set source address for slot only
202  */
203 void edma3_set_src_addr(u32 base, int slot, u32 src)
204 {
205 	struct edma3_slot_layout *rg;
206 
207 	rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
208 	__raw_writel(src, &rg->src);
209 }
210 
211 /**
212  * edma3_set_transfer_params - configure DMA transfer parameters
213  * @base: base address of edma
214  * @slot: parameter RAM slot being configured
215  * @acnt: how many bytes per array (at least one)
216  * @bcnt: how many arrays per frame (at least one)
217  * @ccnt: how many frames per block (at least one)
218  * @bcnt_rld: used only for A-Synchronized transfers; this specifies
219  *	the value to reload into bcnt when it decrements to zero
220  * @sync_mode: ASYNC or ABSYNC
221  *
222  * See the EDMA3 documentation to understand how to configure and link
223  * transfers using the fields in PaRAM slots.  If you are not doing it
224  * all at once with edma3_write_slot(), you will use this routine
225  * plus two calls each for source and destination, setting the initial
226  * address and saying how to index that address.
227  *
228  * An example of an A-Synchronized transfer is a serial link using a
229  * single word shift register.  In that case, @acnt would be equal to
230  * that word size; the serial controller issues a DMA synchronization
231  * event to transfer each word, and memory access by the DMA transfer
232  * controller will be word-at-a-time.
233  *
234  * An example of an AB-Synchronized transfer is a device using a FIFO.
235  * In that case, @acnt equals the FIFO width and @bcnt equals its depth.
236  * The controller with the FIFO issues DMA synchronization events when
237  * the FIFO threshold is reached, and the DMA transfer controller will
238  * transfer one frame to (or from) the FIFO.  It will probably use
239  * efficient burst modes to access memory.
240  */
241 void edma3_set_transfer_params(u32 base, int slot, int acnt,
242 			       int bcnt, int ccnt, u16 bcnt_rld,
243 			       enum edma3_sync_dimension sync_mode)
244 {
245 	u32 opt;
246 	u32 link_bcntrld;
247 	struct edma3_slot_layout *rg;
248 
249 	rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
250 
251 	link_bcntrld = __raw_readl(&rg->link_bcntrld);
252 
253 	__raw_writel((bcnt_rld << 16) | (0x0000ffff & link_bcntrld),
254 		     &rg->link_bcntrld);
255 
256 	opt = __raw_readl(&rg->opt);
257 	if (sync_mode == ASYNC)
258 		__raw_writel(opt & ~EDMA3_SLOPT_AB_SYNC, &rg->opt);
259 	else
260 		__raw_writel(opt | EDMA3_SLOPT_AB_SYNC, &rg->opt);
261 
262 	/* Set the acount, bcount, ccount registers */
263 	__raw_writel((bcnt << 16) | (acnt & 0xffff), &rg->a_b_cnt);
264 	__raw_writel(0xffff & ccnt, &rg->ccnt);
265 }
266 
267 /**
268  * edma3_write_slot - write parameter RAM data for slot
269  * @base: base address of edma
270  * @slot: number of parameter RAM slot being modified
271  * @param: data to be written into parameter RAM slot
272  *
273  * Use this to assign all parameters of a transfer at once.  This
274  * allows more efficient setup of transfers than issuing multiple
275  * calls to set up those parameters in small pieces, and provides
276  * complete control over all transfer options.
277  */
278 void edma3_write_slot(u32 base, int slot, struct edma3_slot_layout *param)
279 {
280 	int i;
281 	u32 *p = (u32 *)param;
282 	u32 *addr = (u32 *)(base + EDMA3_SL_BASE(slot));
283 
284 	for (i = 0; i < sizeof(struct edma3_slot_layout)/4; i += 4)
285 		__raw_writel(*p++, addr++);
286 }
287 
288 /**
289  * edma3_read_slot - read parameter RAM data from slot
290  * @base: base address of edma
291  * @slot: number of parameter RAM slot being copied
292  * @param: where to store copy of parameter RAM data
293  *
294  * Use this to read data from a parameter RAM slot, perhaps to
295  * save them as a template for later reuse.
296  */
297 void edma3_read_slot(u32 base, int slot, struct edma3_slot_layout *param)
298 {
299 	int i;
300 	u32 *p = (u32 *)param;
301 	u32 *addr = (u32 *)(base + EDMA3_SL_BASE(slot));
302 
303 	for (i = 0; i < sizeof(struct edma3_slot_layout)/4; i += 4)
304 		*p++ = __raw_readl(addr++);
305 }
306 
307 void edma3_slot_configure(u32 base, int slot, struct edma3_slot_config *cfg)
308 {
309 	struct edma3_slot_layout *rg;
310 
311 	rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
312 
313 	__raw_writel(cfg->opt, &rg->opt);
314 	__raw_writel(cfg->src, &rg->src);
315 	__raw_writel((cfg->bcnt << 16) | (cfg->acnt & 0xffff), &rg->a_b_cnt);
316 	__raw_writel(cfg->dst, &rg->dst);
317 	__raw_writel((cfg->dst_bidx << 16) |
318 		     (cfg->src_bidx & 0xffff), &rg->src_dst_bidx);
319 	__raw_writel((cfg->bcntrld << 16) |
320 		     (cfg->link & 0xffff), &rg->link_bcntrld);
321 	__raw_writel((cfg->dst_cidx << 16) |
322 		     (cfg->src_cidx & 0xffff), &rg->src_dst_cidx);
323 	__raw_writel(0xffff & cfg->ccnt, &rg->ccnt);
324 }
325 
326 /**
327  * edma3_check_for_transfer - check if transfer coplete by checking
328  * interrupt pending bit. Clear interrupt pending bit if complete.
329  * @base: base address of edma
330  * @cfg: pinter to struct edma3_channel_config which was passed
331  * to qedma3_start when you started qdma channel
332  *
333  * Return 0 if complete, 1 if not.
334  */
335 int edma3_check_for_transfer(u32 base, struct edma3_channel_config *cfg)
336 {
337 	u32 inum;
338 	u32 ipr_base;
339 	u32 icr_base;
340 
341 	if (cfg->complete_code < 32) {
342 		ipr_base = base + EDMA3_IPR;
343 		icr_base = base + EDMA3_ICR;
344 		inum = 1 << cfg->complete_code;
345 	} else {
346 		ipr_base = base + EDMA3_IPRH;
347 		icr_base = base + EDMA3_ICRH;
348 		inum = 1 << (cfg->complete_code - 32);
349 	}
350 
351 	/* check complete interrupt */
352 	if (!(__raw_readl(ipr_base) & inum))
353 		return 1;
354 
355 	/* clean up the pending int bit */
356 	__raw_writel(inum, icr_base);
357 
358 	return 0;
359 }
360 
361 /**
362  * qedma3_stop - stops dma on the channel passed
363  * @base: base address of edma
364  * @cfg: pinter to struct edma3_channel_config which was passed
365  * to qedma3_start when you started qdma channel
366  */
367 void qedma3_stop(u32 base, struct edma3_channel_config *cfg)
368 {
369 	/* Disable qdma channel event */
370 	__raw_writel(1 << cfg->chnum, base + EDMA3_QEECR);
371 
372 	/* clean up the interrupt indication */
373 	if (cfg->complete_code < 32)
374 		__raw_writel(1 << cfg->complete_code, base + EDMA3_ICR);
375 	else
376 		__raw_writel(1 << cfg->complete_code, base + EDMA3_ICRH);
377 
378 	/* Clear missed event if set*/
379 	__raw_writel(1 << cfg->chnum, base + EDMA3_QSECR);
380 	__raw_writel(1 << cfg->chnum, base + EDMA3_QEMCR);
381 
382 	/* Clear the channel map */
383 	__raw_writel(0, base + EDMA3_QCHMAP(cfg->chnum));
384 }
385