blob: 247843891e2491fbae2d44629b9bac47864e0eb6 [file] [log] [blame]
Khoronzhuk, Ivan9e02ad72014-10-22 17:47:56 +03001/*
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>
Mugunthan V Ndd82d032016-02-15 15:31:41 +053014#include <dma.h>
15#include <dm/device.h>
16#include <asm/omap_common.h>
Khoronzhuk, Ivan9e02ad72014-10-22 17:47:56 +030017#include <asm/ti-common/ti-edma3.h>
18
19#define EDMA3_SL_BASE(slot) (0x4000 + ((slot) << 5))
20#define EDMA3_SL_MAX_NUM 512
21#define EDMA3_SLOPT_FIFO_WIDTH_MASK (0x7 << 8)
22
23#define EDMA3_QCHMAP(ch) 0x0200 + ((ch) << 2)
24#define EDMA3_CHMAP_PARSET_MASK 0x1ff
25#define EDMA3_CHMAP_PARSET_SHIFT 0x5
26#define EDMA3_CHMAP_TRIGWORD_SHIFT 0x2
27
28#define EDMA3_QEMCR 0x314
29#define EDMA3_IPR 0x1068
30#define EDMA3_IPRH 0x106c
31#define EDMA3_ICR 0x1070
32#define EDMA3_ICRH 0x1074
33#define EDMA3_QEECR 0x1088
34#define EDMA3_QEESR 0x108c
35#define EDMA3_QSECR 0x1094
36
Mugunthan V Ndd82d032016-02-15 15:31:41 +053037struct ti_edma3_priv {
38 u32 base;
39};
40
Khoronzhuk, Ivan9e02ad72014-10-22 17:47:56 +030041/**
42 * qedma3_start - start qdma on a channel
43 * @base: base address of edma
44 * @cfg: pinter to struct edma3_channel_config where you can set
45 * the slot number to associate with, the chnum, which corresponds
46 * your quick channel number 0-7, complete code - transfer complete code
47 * and trigger slot word - which has to correspond to the word number in
48 * edma3_slot_layout struct for generating event.
49 *
50 */
51void qedma3_start(u32 base, struct edma3_channel_config *cfg)
52{
53 u32 qchmap;
54
55 /* Clear the pending int bit */
56 if (cfg->complete_code < 32)
57 __raw_writel(1 << cfg->complete_code, base + EDMA3_ICR);
58 else
59 __raw_writel(1 << cfg->complete_code, base + EDMA3_ICRH);
60
61 /* Map parameter set and trigger word 7 to quick channel */
62 qchmap = ((EDMA3_CHMAP_PARSET_MASK & cfg->slot)
63 << EDMA3_CHMAP_PARSET_SHIFT) |
64 (cfg->trigger_slot_word << EDMA3_CHMAP_TRIGWORD_SHIFT);
65
66 __raw_writel(qchmap, base + EDMA3_QCHMAP(cfg->chnum));
67
68 /* Clear missed event if set*/
69 __raw_writel(1 << cfg->chnum, base + EDMA3_QSECR);
70 __raw_writel(1 << cfg->chnum, base + EDMA3_QEMCR);
71
72 /* Enable qdma channel event */
73 __raw_writel(1 << cfg->chnum, base + EDMA3_QEESR);
74}
75
76/**
77 * edma3_set_dest - set initial DMA destination address in parameter RAM slot
78 * @base: base address of edma
79 * @slot: parameter RAM slot being configured
80 * @dst: physical address of destination (memory, controller FIFO, etc)
81 * @addressMode: INCR, except in very rare cases
82 * @width: ignored unless @addressMode is FIFO, else specifies the
83 * width to use when addressing the fifo (e.g. W8BIT, W32BIT)
84 *
85 * Note that the destination address is modified during the DMA transfer
86 * according to edma3_set_dest_index().
87 */
88void edma3_set_dest(u32 base, int slot, u32 dst, enum edma3_address_mode mode,
89 enum edma3_fifo_width width)
90{
91 u32 opt;
92 struct edma3_slot_layout *rg;
93
94 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
95
96 opt = __raw_readl(&rg->opt);
97 if (mode == FIFO)
98 opt = (opt & EDMA3_SLOPT_FIFO_WIDTH_MASK) |
99 (EDMA3_SLOPT_DST_ADDR_CONST_MODE |
100 EDMA3_SLOPT_FIFO_WIDTH_SET(width));
101 else
102 opt &= ~EDMA3_SLOPT_DST_ADDR_CONST_MODE;
103
104 __raw_writel(opt, &rg->opt);
105 __raw_writel(dst, &rg->dst);
106}
107
108/**
109 * edma3_set_dest_index - configure DMA destination address indexing
110 * @base: base address of edma
111 * @slot: parameter RAM slot being configured
112 * @bidx: byte offset between destination arrays in a frame
113 * @cidx: byte offset between destination frames in a block
114 *
115 * Offsets are specified to support either contiguous or discontiguous
116 * memory transfers, or repeated access to a hardware register, as needed.
117 * When accessing hardware registers, both offsets are normally zero.
118 */
119void edma3_set_dest_index(u32 base, unsigned slot, int bidx, int cidx)
120{
121 u32 src_dst_bidx;
122 u32 src_dst_cidx;
123 struct edma3_slot_layout *rg;
124
125 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
126
127 src_dst_bidx = __raw_readl(&rg->src_dst_bidx);
128 src_dst_cidx = __raw_readl(&rg->src_dst_cidx);
129
130 __raw_writel((src_dst_bidx & 0x0000ffff) | (bidx << 16),
131 &rg->src_dst_bidx);
132 __raw_writel((src_dst_cidx & 0x0000ffff) | (cidx << 16),
133 &rg->src_dst_cidx);
134}
135
136/**
137 * edma3_set_dest_addr - set destination address for slot only
138 */
139void edma3_set_dest_addr(u32 base, int slot, u32 dst)
140{
141 struct edma3_slot_layout *rg;
142
143 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
144 __raw_writel(dst, &rg->dst);
145}
146
147/**
148 * edma3_set_src - set initial DMA source address in parameter RAM slot
149 * @base: base address of edma
150 * @slot: parameter RAM slot being configured
151 * @src_port: physical address of source (memory, controller FIFO, etc)
152 * @mode: INCR, except in very rare cases
153 * @width: ignored unless @addressMode is FIFO, else specifies the
154 * width to use when addressing the fifo (e.g. W8BIT, W32BIT)
155 *
156 * Note that the source address is modified during the DMA transfer
157 * according to edma3_set_src_index().
158 */
159void edma3_set_src(u32 base, int slot, u32 src, enum edma3_address_mode mode,
160 enum edma3_fifo_width width)
161{
162 u32 opt;
163 struct edma3_slot_layout *rg;
164
165 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
166
167 opt = __raw_readl(&rg->opt);
168 if (mode == FIFO)
169 opt = (opt & EDMA3_SLOPT_FIFO_WIDTH_MASK) |
170 (EDMA3_SLOPT_DST_ADDR_CONST_MODE |
171 EDMA3_SLOPT_FIFO_WIDTH_SET(width));
172 else
173 opt &= ~EDMA3_SLOPT_DST_ADDR_CONST_MODE;
174
175 __raw_writel(opt, &rg->opt);
176 __raw_writel(src, &rg->src);
177}
178
179/**
180 * edma3_set_src_index - configure DMA source address indexing
181 * @base: base address of edma
182 * @slot: parameter RAM slot being configured
183 * @bidx: byte offset between source arrays in a frame
184 * @cidx: byte offset between source frames in a block
185 *
186 * Offsets are specified to support either contiguous or discontiguous
187 * memory transfers, or repeated access to a hardware register, as needed.
188 * When accessing hardware registers, both offsets are normally zero.
189 */
190void edma3_set_src_index(u32 base, unsigned slot, int bidx, int cidx)
191{
192 u32 src_dst_bidx;
193 u32 src_dst_cidx;
194 struct edma3_slot_layout *rg;
195
196 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
197
198 src_dst_bidx = __raw_readl(&rg->src_dst_bidx);
199 src_dst_cidx = __raw_readl(&rg->src_dst_cidx);
200
201 __raw_writel((src_dst_bidx & 0xffff0000) | bidx,
202 &rg->src_dst_bidx);
203 __raw_writel((src_dst_cidx & 0xffff0000) | cidx,
204 &rg->src_dst_cidx);
205}
206
207/**
208 * edma3_set_src_addr - set source address for slot only
209 */
210void edma3_set_src_addr(u32 base, int slot, u32 src)
211{
212 struct edma3_slot_layout *rg;
213
214 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
215 __raw_writel(src, &rg->src);
216}
217
218/**
219 * edma3_set_transfer_params - configure DMA transfer parameters
220 * @base: base address of edma
221 * @slot: parameter RAM slot being configured
222 * @acnt: how many bytes per array (at least one)
223 * @bcnt: how many arrays per frame (at least one)
224 * @ccnt: how many frames per block (at least one)
225 * @bcnt_rld: used only for A-Synchronized transfers; this specifies
226 * the value to reload into bcnt when it decrements to zero
227 * @sync_mode: ASYNC or ABSYNC
228 *
229 * See the EDMA3 documentation to understand how to configure and link
230 * transfers using the fields in PaRAM slots. If you are not doing it
231 * all at once with edma3_write_slot(), you will use this routine
232 * plus two calls each for source and destination, setting the initial
233 * address and saying how to index that address.
234 *
235 * An example of an A-Synchronized transfer is a serial link using a
236 * single word shift register. In that case, @acnt would be equal to
237 * that word size; the serial controller issues a DMA synchronization
238 * event to transfer each word, and memory access by the DMA transfer
239 * controller will be word-at-a-time.
240 *
241 * An example of an AB-Synchronized transfer is a device using a FIFO.
242 * In that case, @acnt equals the FIFO width and @bcnt equals its depth.
243 * The controller with the FIFO issues DMA synchronization events when
244 * the FIFO threshold is reached, and the DMA transfer controller will
245 * transfer one frame to (or from) the FIFO. It will probably use
246 * efficient burst modes to access memory.
247 */
248void edma3_set_transfer_params(u32 base, int slot, int acnt,
249 int bcnt, int ccnt, u16 bcnt_rld,
250 enum edma3_sync_dimension sync_mode)
251{
252 u32 opt;
253 u32 link_bcntrld;
254 struct edma3_slot_layout *rg;
255
256 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
257
258 link_bcntrld = __raw_readl(&rg->link_bcntrld);
259
260 __raw_writel((bcnt_rld << 16) | (0x0000ffff & link_bcntrld),
261 &rg->link_bcntrld);
262
263 opt = __raw_readl(&rg->opt);
264 if (sync_mode == ASYNC)
265 __raw_writel(opt & ~EDMA3_SLOPT_AB_SYNC, &rg->opt);
266 else
267 __raw_writel(opt | EDMA3_SLOPT_AB_SYNC, &rg->opt);
268
269 /* Set the acount, bcount, ccount registers */
270 __raw_writel((bcnt << 16) | (acnt & 0xffff), &rg->a_b_cnt);
271 __raw_writel(0xffff & ccnt, &rg->ccnt);
272}
273
274/**
275 * edma3_write_slot - write parameter RAM data for slot
276 * @base: base address of edma
277 * @slot: number of parameter RAM slot being modified
278 * @param: data to be written into parameter RAM slot
279 *
280 * Use this to assign all parameters of a transfer at once. This
281 * allows more efficient setup of transfers than issuing multiple
282 * calls to set up those parameters in small pieces, and provides
283 * complete control over all transfer options.
284 */
285void edma3_write_slot(u32 base, int slot, struct edma3_slot_layout *param)
286{
287 int i;
288 u32 *p = (u32 *)param;
289 u32 *addr = (u32 *)(base + EDMA3_SL_BASE(slot));
290
291 for (i = 0; i < sizeof(struct edma3_slot_layout)/4; i += 4)
292 __raw_writel(*p++, addr++);
293}
294
295/**
296 * edma3_read_slot - read parameter RAM data from slot
297 * @base: base address of edma
298 * @slot: number of parameter RAM slot being copied
299 * @param: where to store copy of parameter RAM data
300 *
301 * Use this to read data from a parameter RAM slot, perhaps to
302 * save them as a template for later reuse.
303 */
304void edma3_read_slot(u32 base, int slot, struct edma3_slot_layout *param)
305{
306 int i;
307 u32 *p = (u32 *)param;
308 u32 *addr = (u32 *)(base + EDMA3_SL_BASE(slot));
309
310 for (i = 0; i < sizeof(struct edma3_slot_layout)/4; i += 4)
311 *p++ = __raw_readl(addr++);
312}
313
314void edma3_slot_configure(u32 base, int slot, struct edma3_slot_config *cfg)
315{
316 struct edma3_slot_layout *rg;
317
318 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot));
319
320 __raw_writel(cfg->opt, &rg->opt);
321 __raw_writel(cfg->src, &rg->src);
322 __raw_writel((cfg->bcnt << 16) | (cfg->acnt & 0xffff), &rg->a_b_cnt);
323 __raw_writel(cfg->dst, &rg->dst);
324 __raw_writel((cfg->dst_bidx << 16) |
325 (cfg->src_bidx & 0xffff), &rg->src_dst_bidx);
326 __raw_writel((cfg->bcntrld << 16) |
327 (cfg->link & 0xffff), &rg->link_bcntrld);
328 __raw_writel((cfg->dst_cidx << 16) |
329 (cfg->src_cidx & 0xffff), &rg->src_dst_cidx);
330 __raw_writel(0xffff & cfg->ccnt, &rg->ccnt);
331}
332
333/**
334 * edma3_check_for_transfer - check if transfer coplete by checking
335 * interrupt pending bit. Clear interrupt pending bit if complete.
336 * @base: base address of edma
337 * @cfg: pinter to struct edma3_channel_config which was passed
338 * to qedma3_start when you started qdma channel
339 *
340 * Return 0 if complete, 1 if not.
341 */
342int edma3_check_for_transfer(u32 base, struct edma3_channel_config *cfg)
343{
344 u32 inum;
345 u32 ipr_base;
346 u32 icr_base;
347
348 if (cfg->complete_code < 32) {
349 ipr_base = base + EDMA3_IPR;
350 icr_base = base + EDMA3_ICR;
351 inum = 1 << cfg->complete_code;
352 } else {
353 ipr_base = base + EDMA3_IPRH;
354 icr_base = base + EDMA3_ICRH;
355 inum = 1 << (cfg->complete_code - 32);
356 }
357
358 /* check complete interrupt */
359 if (!(__raw_readl(ipr_base) & inum))
360 return 1;
361
362 /* clean up the pending int bit */
363 __raw_writel(inum, icr_base);
364
365 return 0;
366}
367
368/**
369 * qedma3_stop - stops dma on the channel passed
370 * @base: base address of edma
371 * @cfg: pinter to struct edma3_channel_config which was passed
372 * to qedma3_start when you started qdma channel
373 */
374void qedma3_stop(u32 base, struct edma3_channel_config *cfg)
375{
376 /* Disable qdma channel event */
377 __raw_writel(1 << cfg->chnum, base + EDMA3_QEECR);
378
379 /* clean up the interrupt indication */
380 if (cfg->complete_code < 32)
381 __raw_writel(1 << cfg->complete_code, base + EDMA3_ICR);
382 else
383 __raw_writel(1 << cfg->complete_code, base + EDMA3_ICRH);
384
385 /* Clear missed event if set*/
386 __raw_writel(1 << cfg->chnum, base + EDMA3_QSECR);
387 __raw_writel(1 << cfg->chnum, base + EDMA3_QEMCR);
388
389 /* Clear the channel map */
390 __raw_writel(0, base + EDMA3_QCHMAP(cfg->chnum));
391}
Vignesh Rfbe19092015-08-17 13:29:55 +0530392
Mugunthan V Ndd82d032016-02-15 15:31:41 +0530393void __edma3_transfer(unsigned long edma3_base_addr, unsigned int edma_slot_num,
394 void *dst, void *src, size_t len)
Vignesh Rfbe19092015-08-17 13:29:55 +0530395{
396 struct edma3_slot_config slot;
397 struct edma3_channel_config edma_channel;
398 int b_cnt_value = 1;
399 int rem_bytes = 0;
400 int a_cnt_value = len;
401 unsigned int addr = (unsigned int) (dst);
402 unsigned int max_acnt = 0x7FFFU;
403
404 if (len > max_acnt) {
405 b_cnt_value = (len / max_acnt);
406 rem_bytes = (len % max_acnt);
407 a_cnt_value = max_acnt;
408 }
409
410 slot.opt = 0;
411 slot.src = ((unsigned int) src);
412 slot.acnt = a_cnt_value;
413 slot.bcnt = b_cnt_value;
414 slot.ccnt = 1;
415 slot.src_bidx = a_cnt_value;
416 slot.dst_bidx = a_cnt_value;
417 slot.src_cidx = 0;
418 slot.dst_cidx = 0;
419 slot.link = EDMA3_PARSET_NULL_LINK;
420 slot.bcntrld = 0;
421 slot.opt = EDMA3_SLOPT_TRANS_COMP_INT_ENB |
422 EDMA3_SLOPT_COMP_CODE(0) |
423 EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC;
424
425 edma3_slot_configure(edma3_base_addr, edma_slot_num, &slot);
426 edma_channel.slot = edma_slot_num;
427 edma_channel.chnum = 0;
428 edma_channel.complete_code = 0;
429 /* set event trigger to dst update */
430 edma_channel.trigger_slot_word = EDMA3_TWORD(dst);
431
432 qedma3_start(edma3_base_addr, &edma_channel);
433 edma3_set_dest_addr(edma3_base_addr, edma_channel.slot, addr);
434
435 while (edma3_check_for_transfer(edma3_base_addr, &edma_channel))
436 ;
437 qedma3_stop(edma3_base_addr, &edma_channel);
438
439 if (rem_bytes != 0) {
440 slot.opt = 0;
441 slot.src =
442 (b_cnt_value * max_acnt) + ((unsigned int) src);
443 slot.acnt = rem_bytes;
444 slot.bcnt = 1;
445 slot.ccnt = 1;
446 slot.src_bidx = rem_bytes;
447 slot.dst_bidx = rem_bytes;
448 slot.src_cidx = 0;
449 slot.dst_cidx = 0;
450 slot.link = EDMA3_PARSET_NULL_LINK;
451 slot.bcntrld = 0;
452 slot.opt = EDMA3_SLOPT_TRANS_COMP_INT_ENB |
453 EDMA3_SLOPT_COMP_CODE(0) |
454 EDMA3_SLOPT_STATIC | EDMA3_SLOPT_AB_SYNC;
455 edma3_slot_configure(edma3_base_addr, edma_slot_num, &slot);
456 edma_channel.slot = edma_slot_num;
457 edma_channel.chnum = 0;
458 edma_channel.complete_code = 0;
459 /* set event trigger to dst update */
460 edma_channel.trigger_slot_word = EDMA3_TWORD(dst);
461
462 qedma3_start(edma3_base_addr, &edma_channel);
463 edma3_set_dest_addr(edma3_base_addr, edma_channel.slot, addr +
464 (max_acnt * b_cnt_value));
465 while (edma3_check_for_transfer(edma3_base_addr, &edma_channel))
466 ;
467 qedma3_stop(edma3_base_addr, &edma_channel);
468 }
469}
Mugunthan V Ndd82d032016-02-15 15:31:41 +0530470
471#ifndef CONFIG_DMA
472
473void edma3_transfer(unsigned long edma3_base_addr, unsigned int edma_slot_num,
474 void *dst, void *src, size_t len)
475{
476 __edma3_transfer(edma3_base_addr, edma_slot_num, dst, src, len);
477}
478
479#else
480
481static int ti_edma3_transfer(struct udevice *dev, int direction, void *dst,
482 void *src, size_t len)
483{
484 struct ti_edma3_priv *priv = dev_get_priv(dev);
485
486 /* enable edma3 clocks */
487 enable_edma3_clocks();
488
489 switch (direction) {
490 case DMA_MEM_TO_MEM:
491 __edma3_transfer(priv->base, 1, dst, src, len);
492 break;
493 default:
494 error("Transfer type not implemented in DMA driver\n");
495 break;
496 }
497
498 /* disable edma3 clocks */
499 disable_edma3_clocks();
500
501 return 0;
502}
503
504static int ti_edma3_ofdata_to_platdata(struct udevice *dev)
505{
506 struct ti_edma3_priv *priv = dev_get_priv(dev);
507
508 priv->base = dev_get_addr(dev);
509
510 return 0;
511}
512
513static int ti_edma3_probe(struct udevice *dev)
514{
515 struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
516
517 uc_priv->supported = DMA_SUPPORTS_MEM_TO_MEM;
518
519 return 0;
520}
521
522static const struct dma_ops ti_edma3_ops = {
523 .transfer = ti_edma3_transfer,
524};
525
526static const struct udevice_id ti_edma3_ids[] = {
527 { .compatible = "ti,edma3" },
528 { }
529};
530
531U_BOOT_DRIVER(ti_edma3) = {
532 .name = "ti_edma3",
533 .id = UCLASS_DMA,
534 .of_match = ti_edma3_ids,
535 .ops = &ti_edma3_ops,
536 .ofdata_to_platdata = ti_edma3_ofdata_to_platdata,
537 .probe = ti_edma3_probe,
538 .priv_auto_alloc_size = sizeof(struct ti_edma3_priv),
539};
540#endif /* CONFIG_DMA */