1
2
3
4
5
6
7
8
9
10
11
12#include <asm/io.h>
13#include <common.h>
14#include <dma.h>
15#include <dm/device.h>
16#include <asm/omap_common.h>
17#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
37struct ti_edma3_priv {
38 u32 base;
39};
40
41
42
43
44
45
46
47
48
49
50
51void qedma3_start(u32 base, struct edma3_channel_config *cfg)
52{
53 u32 qchmap;
54
55
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
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
69 __raw_writel(1 << cfg->chnum, base + EDMA3_QSECR);
70 __raw_writel(1 << cfg->chnum, base + EDMA3_QEMCR);
71
72
73 __raw_writel(1 << cfg->chnum, base + EDMA3_QEESR);
74}
75
76
77
78
79
80
81
82
83
84
85
86
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
110
111
112
113
114
115
116
117
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
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
149
150
151
152
153
154
155
156
157
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
181
182
183
184
185
186
187
188
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
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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
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
270 __raw_writel((bcnt << 16) | (acnt & 0xffff), &rg->a_b_cnt);
271 __raw_writel(0xffff & ccnt, &rg->ccnt);
272}
273
274
275
276
277
278
279
280
281
282
283
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
297
298
299
300
301
302
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
335
336
337
338
339
340
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
359 if (!(__raw_readl(ipr_base) & inum))
360 return 1;
361
362
363 __raw_writel(inum, icr_base);
364
365 return 0;
366}
367
368
369
370
371
372
373
374void qedma3_stop(u32 base, struct edma3_channel_config *cfg)
375{
376
377 __raw_writel(1 << cfg->chnum, base + EDMA3_QEECR);
378
379
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
386 __raw_writel(1 << cfg->chnum, base + EDMA3_QSECR);
387 __raw_writel(1 << cfg->chnum, base + EDMA3_QEMCR);
388
389
390 __raw_writel(0, base + EDMA3_QCHMAP(cfg->chnum));
391}
392
393void __edma3_transfer(unsigned long edma3_base_addr, unsigned int edma_slot_num,
394 void *dst, void *src, size_t len)
395{
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
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
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}
470
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
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
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
541