1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/of_device.h>
18#include <linux/of_dma.h>
19#include <linux/platform_device.h>
20#include <linux/interrupt.h>
21#include <linux/remoteproc.h>
22
23#include "st_fdma.h"
24
25static inline struct st_fdma_chan *to_st_fdma_chan(struct dma_chan *c)
26{
27 return container_of(c, struct st_fdma_chan, vchan.chan);
28}
29
30static struct st_fdma_desc *to_st_fdma_desc(struct virt_dma_desc *vd)
31{
32 return container_of(vd, struct st_fdma_desc, vdesc);
33}
34
35static int st_fdma_dreq_get(struct st_fdma_chan *fchan)
36{
37 struct st_fdma_dev *fdev = fchan->fdev;
38 u32 req_line_cfg = fchan->cfg.req_line;
39 u32 dreq_line;
40 int try = 0;
41
42
43
44
45
46
47 do {
48 if (fdev->dreq_mask == ~0L) {
49 dev_err(fdev->dev, "No req lines available\n");
50 return -EINVAL;
51 }
52
53 if (try || req_line_cfg >= ST_FDMA_NR_DREQS) {
54 dev_err(fdev->dev, "Invalid or used req line\n");
55 return -EINVAL;
56 } else {
57 dreq_line = req_line_cfg;
58 }
59
60 try++;
61 } while (test_and_set_bit(dreq_line, &fdev->dreq_mask));
62
63 dev_dbg(fdev->dev, "get dreq_line:%d mask:%#lx\n",
64 dreq_line, fdev->dreq_mask);
65
66 return dreq_line;
67}
68
69static void st_fdma_dreq_put(struct st_fdma_chan *fchan)
70{
71 struct st_fdma_dev *fdev = fchan->fdev;
72
73 dev_dbg(fdev->dev, "put dreq_line:%#x\n", fchan->dreq_line);
74 clear_bit(fchan->dreq_line, &fdev->dreq_mask);
75}
76
77static void st_fdma_xfer_desc(struct st_fdma_chan *fchan)
78{
79 struct virt_dma_desc *vdesc;
80 unsigned long nbytes, ch_cmd, cmd;
81
82 vdesc = vchan_next_desc(&fchan->vchan);
83 if (!vdesc)
84 return;
85
86 fchan->fdesc = to_st_fdma_desc(vdesc);
87 nbytes = fchan->fdesc->node[0].desc->nbytes;
88 cmd = FDMA_CMD_START(fchan->vchan.chan.chan_id);
89 ch_cmd = fchan->fdesc->node[0].pdesc | FDMA_CH_CMD_STA_START;
90
91
92 fnode_write(fchan, nbytes, FDMA_CNTN_OFST);
93 fchan_write(fchan, ch_cmd, FDMA_CH_CMD_OFST);
94 writel(cmd,
95 fchan->fdev->slim_rproc->peri + FDMA_CMD_SET_OFST);
96
97 dev_dbg(fchan->fdev->dev, "start chan:%d\n", fchan->vchan.chan.chan_id);
98}
99
100static void st_fdma_ch_sta_update(struct st_fdma_chan *fchan,
101 unsigned long int_sta)
102{
103 unsigned long ch_sta, ch_err;
104 int ch_id = fchan->vchan.chan.chan_id;
105 struct st_fdma_dev *fdev = fchan->fdev;
106
107 ch_sta = fchan_read(fchan, FDMA_CH_CMD_OFST);
108 ch_err = ch_sta & FDMA_CH_CMD_ERR_MASK;
109 ch_sta &= FDMA_CH_CMD_STA_MASK;
110
111 if (int_sta & FDMA_INT_STA_ERR) {
112 dev_warn(fdev->dev, "chan:%d, error:%ld\n", ch_id, ch_err);
113 fchan->status = DMA_ERROR;
114 return;
115 }
116
117 switch (ch_sta) {
118 case FDMA_CH_CMD_STA_PAUSED:
119 fchan->status = DMA_PAUSED;
120 break;
121
122 case FDMA_CH_CMD_STA_RUNNING:
123 fchan->status = DMA_IN_PROGRESS;
124 break;
125 }
126}
127
128static irqreturn_t st_fdma_irq_handler(int irq, void *dev_id)
129{
130 struct st_fdma_dev *fdev = dev_id;
131 irqreturn_t ret = IRQ_NONE;
132 struct st_fdma_chan *fchan = &fdev->chans[0];
133 unsigned long int_sta, clr;
134
135 int_sta = fdma_read(fdev, FDMA_INT_STA_OFST);
136 clr = int_sta;
137
138 for (; int_sta != 0 ; int_sta >>= 2, fchan++) {
139 if (!(int_sta & (FDMA_INT_STA_CH | FDMA_INT_STA_ERR)))
140 continue;
141
142 spin_lock(&fchan->vchan.lock);
143 st_fdma_ch_sta_update(fchan, int_sta);
144
145 if (fchan->fdesc) {
146 if (!fchan->fdesc->iscyclic) {
147 list_del(&fchan->fdesc->vdesc.node);
148 vchan_cookie_complete(&fchan->fdesc->vdesc);
149 fchan->fdesc = NULL;
150 fchan->status = DMA_COMPLETE;
151 } else {
152 vchan_cyclic_callback(&fchan->fdesc->vdesc);
153 }
154
155
156 if (!fchan->fdesc)
157 st_fdma_xfer_desc(fchan);
158 }
159
160 spin_unlock(&fchan->vchan.lock);
161 ret = IRQ_HANDLED;
162 }
163
164 fdma_write(fdev, clr, FDMA_INT_CLR_OFST);
165
166 return ret;
167}
168
169static struct dma_chan *st_fdma_of_xlate(struct of_phandle_args *dma_spec,
170 struct of_dma *ofdma)
171{
172 struct st_fdma_dev *fdev = ofdma->of_dma_data;
173 struct dma_chan *chan;
174 struct st_fdma_chan *fchan;
175 int ret;
176
177 if (dma_spec->args_count < 1)
178 return ERR_PTR(-EINVAL);
179
180 if (fdev->dma_device.dev->of_node != dma_spec->np)
181 return ERR_PTR(-EINVAL);
182
183 ret = rproc_boot(fdev->slim_rproc->rproc);
184 if (ret == -ENOENT)
185 return ERR_PTR(-EPROBE_DEFER);
186 else if (ret)
187 return ERR_PTR(ret);
188
189 chan = dma_get_any_slave_channel(&fdev->dma_device);
190 if (!chan)
191 goto err_chan;
192
193 fchan = to_st_fdma_chan(chan);
194
195 fchan->cfg.of_node = dma_spec->np;
196 fchan->cfg.req_line = dma_spec->args[0];
197 fchan->cfg.req_ctrl = 0;
198 fchan->cfg.type = ST_FDMA_TYPE_FREE_RUN;
199
200 if (dma_spec->args_count > 1)
201 fchan->cfg.req_ctrl = dma_spec->args[1]
202 & FDMA_REQ_CTRL_CFG_MASK;
203
204 if (dma_spec->args_count > 2)
205 fchan->cfg.type = dma_spec->args[2];
206
207 if (fchan->cfg.type == ST_FDMA_TYPE_FREE_RUN) {
208 fchan->dreq_line = 0;
209 } else {
210 fchan->dreq_line = st_fdma_dreq_get(fchan);
211 if (IS_ERR_VALUE(fchan->dreq_line)) {
212 chan = ERR_PTR(fchan->dreq_line);
213 goto err_chan;
214 }
215 }
216
217 dev_dbg(fdev->dev, "xlate req_line:%d type:%d req_ctrl:%#lx\n",
218 fchan->cfg.req_line, fchan->cfg.type, fchan->cfg.req_ctrl);
219
220 return chan;
221
222err_chan:
223 rproc_shutdown(fdev->slim_rproc->rproc);
224 return chan;
225
226}
227
228static void st_fdma_free_desc(struct virt_dma_desc *vdesc)
229{
230 struct st_fdma_desc *fdesc;
231 int i;
232
233 fdesc = to_st_fdma_desc(vdesc);
234 for (i = 0; i < fdesc->n_nodes; i++)
235 dma_pool_free(fdesc->fchan->node_pool, fdesc->node[i].desc,
236 fdesc->node[i].pdesc);
237 kfree(fdesc);
238}
239
240static struct st_fdma_desc *st_fdma_alloc_desc(struct st_fdma_chan *fchan,
241 int sg_len)
242{
243 struct st_fdma_desc *fdesc;
244 int i;
245
246 fdesc = kzalloc(struct_size(fdesc, node, sg_len), GFP_NOWAIT);
247 if (!fdesc)
248 return NULL;
249
250 fdesc->fchan = fchan;
251 fdesc->n_nodes = sg_len;
252 for (i = 0; i < sg_len; i++) {
253 fdesc->node[i].desc = dma_pool_alloc(fchan->node_pool,
254 GFP_NOWAIT, &fdesc->node[i].pdesc);
255 if (!fdesc->node[i].desc)
256 goto err;
257 }
258 return fdesc;
259
260err:
261 while (--i >= 0)
262 dma_pool_free(fchan->node_pool, fdesc->node[i].desc,
263 fdesc->node[i].pdesc);
264 kfree(fdesc);
265 return NULL;
266}
267
268static int st_fdma_alloc_chan_res(struct dma_chan *chan)
269{
270 struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
271
272
273 fchan->node_pool = dma_pool_create(dev_name(&chan->dev->device),
274 fchan->fdev->dev,
275 sizeof(struct st_fdma_hw_node),
276 __alignof__(struct st_fdma_hw_node),
277 0);
278
279 if (!fchan->node_pool) {
280 dev_err(fchan->fdev->dev, "unable to allocate desc pool\n");
281 return -ENOMEM;
282 }
283
284 dev_dbg(fchan->fdev->dev, "alloc ch_id:%d type:%d\n",
285 fchan->vchan.chan.chan_id, fchan->cfg.type);
286
287 return 0;
288}
289
290static void st_fdma_free_chan_res(struct dma_chan *chan)
291{
292 struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
293 struct rproc *rproc = fchan->fdev->slim_rproc->rproc;
294 unsigned long flags;
295
296 dev_dbg(fchan->fdev->dev, "%s: freeing chan:%d\n",
297 __func__, fchan->vchan.chan.chan_id);
298
299 if (fchan->cfg.type != ST_FDMA_TYPE_FREE_RUN)
300 st_fdma_dreq_put(fchan);
301
302 spin_lock_irqsave(&fchan->vchan.lock, flags);
303 fchan->fdesc = NULL;
304 spin_unlock_irqrestore(&fchan->vchan.lock, flags);
305
306 dma_pool_destroy(fchan->node_pool);
307 fchan->node_pool = NULL;
308 memset(&fchan->cfg, 0, sizeof(struct st_fdma_cfg));
309
310 rproc_shutdown(rproc);
311}
312
313static struct dma_async_tx_descriptor *st_fdma_prep_dma_memcpy(
314 struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
315 size_t len, unsigned long flags)
316{
317 struct st_fdma_chan *fchan;
318 struct st_fdma_desc *fdesc;
319 struct st_fdma_hw_node *hw_node;
320
321 if (!len)
322 return NULL;
323
324 fchan = to_st_fdma_chan(chan);
325
326
327 fdesc = st_fdma_alloc_desc(fchan, 1);
328 if (!fdesc) {
329 dev_err(fchan->fdev->dev, "no memory for desc\n");
330 return NULL;
331 }
332
333 hw_node = fdesc->node[0].desc;
334 hw_node->next = 0;
335 hw_node->control = FDMA_NODE_CTRL_REQ_MAP_FREE_RUN;
336 hw_node->control |= FDMA_NODE_CTRL_SRC_INCR;
337 hw_node->control |= FDMA_NODE_CTRL_DST_INCR;
338 hw_node->control |= FDMA_NODE_CTRL_INT_EON;
339 hw_node->nbytes = len;
340 hw_node->saddr = src;
341 hw_node->daddr = dst;
342 hw_node->generic.length = len;
343 hw_node->generic.sstride = 0;
344 hw_node->generic.dstride = 0;
345
346 return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags);
347}
348
349static int config_reqctrl(struct st_fdma_chan *fchan,
350 enum dma_transfer_direction direction)
351{
352 u32 maxburst = 0, addr = 0;
353 enum dma_slave_buswidth width;
354 int ch_id = fchan->vchan.chan.chan_id;
355 struct st_fdma_dev *fdev = fchan->fdev;
356
357 switch (direction) {
358
359 case DMA_DEV_TO_MEM:
360 fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_WNR;
361 maxburst = fchan->scfg.src_maxburst;
362 width = fchan->scfg.src_addr_width;
363 addr = fchan->scfg.src_addr;
364 break;
365
366 case DMA_MEM_TO_DEV:
367 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_WNR;
368 maxburst = fchan->scfg.dst_maxburst;
369 width = fchan->scfg.dst_addr_width;
370 addr = fchan->scfg.dst_addr;
371 break;
372
373 default:
374 return -EINVAL;
375 }
376
377 fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_OPCODE_MASK;
378
379 switch (width) {
380
381 case DMA_SLAVE_BUSWIDTH_1_BYTE:
382 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST1;
383 break;
384
385 case DMA_SLAVE_BUSWIDTH_2_BYTES:
386 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST2;
387 break;
388
389 case DMA_SLAVE_BUSWIDTH_4_BYTES:
390 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST4;
391 break;
392
393 case DMA_SLAVE_BUSWIDTH_8_BYTES:
394 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST8;
395 break;
396
397 default:
398 return -EINVAL;
399 }
400
401 fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_NUM_OPS_MASK;
402 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_NUM_OPS(maxburst-1);
403 dreq_write(fchan, fchan->cfg.req_ctrl, FDMA_REQ_CTRL_OFST);
404
405 fchan->cfg.dev_addr = addr;
406 fchan->cfg.dir = direction;
407
408 dev_dbg(fdev->dev, "chan:%d config_reqctrl:%#x req_ctrl:%#lx\n",
409 ch_id, addr, fchan->cfg.req_ctrl);
410
411 return 0;
412}
413
414static void fill_hw_node(struct st_fdma_hw_node *hw_node,
415 struct st_fdma_chan *fchan,
416 enum dma_transfer_direction direction)
417{
418 if (direction == DMA_MEM_TO_DEV) {
419 hw_node->control |= FDMA_NODE_CTRL_SRC_INCR;
420 hw_node->control |= FDMA_NODE_CTRL_DST_STATIC;
421 hw_node->daddr = fchan->cfg.dev_addr;
422 } else {
423 hw_node->control |= FDMA_NODE_CTRL_SRC_STATIC;
424 hw_node->control |= FDMA_NODE_CTRL_DST_INCR;
425 hw_node->saddr = fchan->cfg.dev_addr;
426 }
427
428 hw_node->generic.sstride = 0;
429 hw_node->generic.dstride = 0;
430}
431
432static inline struct st_fdma_chan *st_fdma_prep_common(struct dma_chan *chan,
433 size_t len, enum dma_transfer_direction direction)
434{
435 struct st_fdma_chan *fchan;
436
437 if (!chan || !len)
438 return NULL;
439
440 fchan = to_st_fdma_chan(chan);
441
442 if (!is_slave_direction(direction)) {
443 dev_err(fchan->fdev->dev, "bad direction?\n");
444 return NULL;
445 }
446
447 return fchan;
448}
449
450static struct dma_async_tx_descriptor *st_fdma_prep_dma_cyclic(
451 struct dma_chan *chan, dma_addr_t buf_addr, size_t len,
452 size_t period_len, enum dma_transfer_direction direction,
453 unsigned long flags)
454{
455 struct st_fdma_chan *fchan;
456 struct st_fdma_desc *fdesc;
457 int sg_len, i;
458
459 fchan = st_fdma_prep_common(chan, len, direction);
460 if (!fchan)
461 return NULL;
462
463 if (!period_len)
464 return NULL;
465
466 if (config_reqctrl(fchan, direction)) {
467 dev_err(fchan->fdev->dev, "bad width or direction\n");
468 return NULL;
469 }
470
471
472 if (len % period_len != 0) {
473 dev_err(fchan->fdev->dev, "len is not multiple of period\n");
474 return NULL;
475 }
476
477 sg_len = len / period_len;
478 fdesc = st_fdma_alloc_desc(fchan, sg_len);
479 if (!fdesc) {
480 dev_err(fchan->fdev->dev, "no memory for desc\n");
481 return NULL;
482 }
483
484 fdesc->iscyclic = true;
485
486 for (i = 0; i < sg_len; i++) {
487 struct st_fdma_hw_node *hw_node = fdesc->node[i].desc;
488
489 hw_node->next = fdesc->node[(i + 1) % sg_len].pdesc;
490
491 hw_node->control =
492 FDMA_NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line);
493 hw_node->control |= FDMA_NODE_CTRL_INT_EON;
494
495 fill_hw_node(hw_node, fchan, direction);
496
497 if (direction == DMA_MEM_TO_DEV)
498 hw_node->saddr = buf_addr + (i * period_len);
499 else
500 hw_node->daddr = buf_addr + (i * period_len);
501
502 hw_node->nbytes = period_len;
503 hw_node->generic.length = period_len;
504 }
505
506 return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags);
507}
508
509static struct dma_async_tx_descriptor *st_fdma_prep_slave_sg(
510 struct dma_chan *chan, struct scatterlist *sgl,
511 unsigned int sg_len, enum dma_transfer_direction direction,
512 unsigned long flags, void *context)
513{
514 struct st_fdma_chan *fchan;
515 struct st_fdma_desc *fdesc;
516 struct st_fdma_hw_node *hw_node;
517 struct scatterlist *sg;
518 int i;
519
520 fchan = st_fdma_prep_common(chan, sg_len, direction);
521 if (!fchan)
522 return NULL;
523
524 if (!sgl)
525 return NULL;
526
527 fdesc = st_fdma_alloc_desc(fchan, sg_len);
528 if (!fdesc) {
529 dev_err(fchan->fdev->dev, "no memory for desc\n");
530 return NULL;
531 }
532
533 fdesc->iscyclic = false;
534
535 for_each_sg(sgl, sg, sg_len, i) {
536 hw_node = fdesc->node[i].desc;
537
538 hw_node->next = fdesc->node[(i + 1) % sg_len].pdesc;
539 hw_node->control = FDMA_NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line);
540
541 fill_hw_node(hw_node, fchan, direction);
542
543 if (direction == DMA_MEM_TO_DEV)
544 hw_node->saddr = sg_dma_address(sg);
545 else
546 hw_node->daddr = sg_dma_address(sg);
547
548 hw_node->nbytes = sg_dma_len(sg);
549 hw_node->generic.length = sg_dma_len(sg);
550 }
551
552
553 hw_node->control |= FDMA_NODE_CTRL_INT_EON;
554
555 return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags);
556}
557
558static size_t st_fdma_desc_residue(struct st_fdma_chan *fchan,
559 struct virt_dma_desc *vdesc,
560 bool in_progress)
561{
562 struct st_fdma_desc *fdesc = fchan->fdesc;
563 size_t residue = 0;
564 dma_addr_t cur_addr = 0;
565 int i;
566
567 if (in_progress) {
568 cur_addr = fchan_read(fchan, FDMA_CH_CMD_OFST);
569 cur_addr &= FDMA_CH_CMD_DATA_MASK;
570 }
571
572 for (i = fchan->fdesc->n_nodes - 1 ; i >= 0; i--) {
573 if (cur_addr == fdesc->node[i].pdesc) {
574 residue += fnode_read(fchan, FDMA_CNTN_OFST);
575 break;
576 }
577 residue += fdesc->node[i].desc->nbytes;
578 }
579
580 return residue;
581}
582
583static enum dma_status st_fdma_tx_status(struct dma_chan *chan,
584 dma_cookie_t cookie,
585 struct dma_tx_state *txstate)
586{
587 struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
588 struct virt_dma_desc *vd;
589 enum dma_status ret;
590 unsigned long flags;
591
592 ret = dma_cookie_status(chan, cookie, txstate);
593 if (ret == DMA_COMPLETE || !txstate)
594 return ret;
595
596 spin_lock_irqsave(&fchan->vchan.lock, flags);
597 vd = vchan_find_desc(&fchan->vchan, cookie);
598 if (fchan->fdesc && cookie == fchan->fdesc->vdesc.tx.cookie)
599 txstate->residue = st_fdma_desc_residue(fchan, vd, true);
600 else if (vd)
601 txstate->residue = st_fdma_desc_residue(fchan, vd, false);
602 else
603 txstate->residue = 0;
604
605 spin_unlock_irqrestore(&fchan->vchan.lock, flags);
606
607 return ret;
608}
609
610static void st_fdma_issue_pending(struct dma_chan *chan)
611{
612 struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
613 unsigned long flags;
614
615 spin_lock_irqsave(&fchan->vchan.lock, flags);
616
617 if (vchan_issue_pending(&fchan->vchan) && !fchan->fdesc)
618 st_fdma_xfer_desc(fchan);
619
620 spin_unlock_irqrestore(&fchan->vchan.lock, flags);
621}
622
623static int st_fdma_pause(struct dma_chan *chan)
624{
625 unsigned long flags;
626 struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
627 int ch_id = fchan->vchan.chan.chan_id;
628 unsigned long cmd = FDMA_CMD_PAUSE(ch_id);
629
630 dev_dbg(fchan->fdev->dev, "pause chan:%d\n", ch_id);
631
632 spin_lock_irqsave(&fchan->vchan.lock, flags);
633 if (fchan->fdesc)
634 fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST);
635 spin_unlock_irqrestore(&fchan->vchan.lock, flags);
636
637 return 0;
638}
639
640static int st_fdma_resume(struct dma_chan *chan)
641{
642 unsigned long flags;
643 unsigned long val;
644 struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
645 int ch_id = fchan->vchan.chan.chan_id;
646
647 dev_dbg(fchan->fdev->dev, "resume chan:%d\n", ch_id);
648
649 spin_lock_irqsave(&fchan->vchan.lock, flags);
650 if (fchan->fdesc) {
651 val = fchan_read(fchan, FDMA_CH_CMD_OFST);
652 val &= FDMA_CH_CMD_DATA_MASK;
653 fchan_write(fchan, val, FDMA_CH_CMD_OFST);
654 }
655 spin_unlock_irqrestore(&fchan->vchan.lock, flags);
656
657 return 0;
658}
659
660static int st_fdma_terminate_all(struct dma_chan *chan)
661{
662 unsigned long flags;
663 LIST_HEAD(head);
664 struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
665 int ch_id = fchan->vchan.chan.chan_id;
666 unsigned long cmd = FDMA_CMD_PAUSE(ch_id);
667
668 dev_dbg(fchan->fdev->dev, "terminate chan:%d\n", ch_id);
669
670 spin_lock_irqsave(&fchan->vchan.lock, flags);
671 fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST);
672 fchan->fdesc = NULL;
673 vchan_get_all_descriptors(&fchan->vchan, &head);
674 spin_unlock_irqrestore(&fchan->vchan.lock, flags);
675 vchan_dma_desc_free_list(&fchan->vchan, &head);
676
677 return 0;
678}
679
680static int st_fdma_slave_config(struct dma_chan *chan,
681 struct dma_slave_config *slave_cfg)
682{
683 struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
684
685 memcpy(&fchan->scfg, slave_cfg, sizeof(fchan->scfg));
686 return 0;
687}
688
689static const struct st_fdma_driverdata fdma_mpe31_stih407_11 = {
690 .name = "STiH407",
691 .id = 0,
692};
693
694static const struct st_fdma_driverdata fdma_mpe31_stih407_12 = {
695 .name = "STiH407",
696 .id = 1,
697};
698
699static const struct st_fdma_driverdata fdma_mpe31_stih407_13 = {
700 .name = "STiH407",
701 .id = 2,
702};
703
704static const struct of_device_id st_fdma_match[] = {
705 { .compatible = "st,stih407-fdma-mpe31-11"
706 , .data = &fdma_mpe31_stih407_11 },
707 { .compatible = "st,stih407-fdma-mpe31-12"
708 , .data = &fdma_mpe31_stih407_12 },
709 { .compatible = "st,stih407-fdma-mpe31-13"
710 , .data = &fdma_mpe31_stih407_13 },
711 {},
712};
713MODULE_DEVICE_TABLE(of, st_fdma_match);
714
715static int st_fdma_parse_dt(struct platform_device *pdev,
716 const struct st_fdma_driverdata *drvdata,
717 struct st_fdma_dev *fdev)
718{
719 snprintf(fdev->fw_name, FW_NAME_SIZE, "fdma_%s_%d.elf",
720 drvdata->name, drvdata->id);
721
722 return of_property_read_u32(pdev->dev.of_node, "dma-channels",
723 &fdev->nr_channels);
724}
725#define FDMA_DMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
726 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
727 BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
728 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
729
730static void st_fdma_free(struct st_fdma_dev *fdev)
731{
732 struct st_fdma_chan *fchan;
733 int i;
734
735 for (i = 0; i < fdev->nr_channels; i++) {
736 fchan = &fdev->chans[i];
737 list_del(&fchan->vchan.chan.device_node);
738 tasklet_kill(&fchan->vchan.task);
739 }
740}
741
742static int st_fdma_probe(struct platform_device *pdev)
743{
744 struct st_fdma_dev *fdev;
745 const struct of_device_id *match;
746 struct device_node *np = pdev->dev.of_node;
747 const struct st_fdma_driverdata *drvdata;
748 int ret, i;
749
750 match = of_match_device((st_fdma_match), &pdev->dev);
751 if (!match || !match->data) {
752 dev_err(&pdev->dev, "No device match found\n");
753 return -ENODEV;
754 }
755
756 drvdata = match->data;
757
758 fdev = devm_kzalloc(&pdev->dev, sizeof(*fdev), GFP_KERNEL);
759 if (!fdev)
760 return -ENOMEM;
761
762 ret = st_fdma_parse_dt(pdev, drvdata, fdev);
763 if (ret) {
764 dev_err(&pdev->dev, "unable to find platform data\n");
765 goto err;
766 }
767
768 fdev->chans = devm_kcalloc(&pdev->dev, fdev->nr_channels,
769 sizeof(struct st_fdma_chan), GFP_KERNEL);
770 if (!fdev->chans)
771 return -ENOMEM;
772
773 fdev->dev = &pdev->dev;
774 fdev->drvdata = drvdata;
775 platform_set_drvdata(pdev, fdev);
776
777 fdev->irq = platform_get_irq(pdev, 0);
778 if (fdev->irq < 0) {
779 dev_err(&pdev->dev, "Failed to get irq resource\n");
780 return -EINVAL;
781 }
782
783 ret = devm_request_irq(&pdev->dev, fdev->irq, st_fdma_irq_handler, 0,
784 dev_name(&pdev->dev), fdev);
785 if (ret) {
786 dev_err(&pdev->dev, "Failed to request irq (%d)\n", ret);
787 goto err;
788 }
789
790 fdev->slim_rproc = st_slim_rproc_alloc(pdev, fdev->fw_name);
791 if (IS_ERR(fdev->slim_rproc)) {
792 ret = PTR_ERR(fdev->slim_rproc);
793 dev_err(&pdev->dev, "slim_rproc_alloc failed (%d)\n", ret);
794 goto err;
795 }
796
797
798 INIT_LIST_HEAD(&fdev->dma_device.channels);
799 for (i = 0; i < fdev->nr_channels; i++) {
800 struct st_fdma_chan *fchan = &fdev->chans[i];
801
802 fchan->fdev = fdev;
803 fchan->vchan.desc_free = st_fdma_free_desc;
804 vchan_init(&fchan->vchan, &fdev->dma_device);
805 }
806
807
808 fdev->dreq_mask = BIT(0) | BIT(31);
809
810 dma_cap_set(DMA_SLAVE, fdev->dma_device.cap_mask);
811 dma_cap_set(DMA_CYCLIC, fdev->dma_device.cap_mask);
812 dma_cap_set(DMA_MEMCPY, fdev->dma_device.cap_mask);
813
814 fdev->dma_device.dev = &pdev->dev;
815 fdev->dma_device.device_alloc_chan_resources = st_fdma_alloc_chan_res;
816 fdev->dma_device.device_free_chan_resources = st_fdma_free_chan_res;
817 fdev->dma_device.device_prep_dma_cyclic = st_fdma_prep_dma_cyclic;
818 fdev->dma_device.device_prep_slave_sg = st_fdma_prep_slave_sg;
819 fdev->dma_device.device_prep_dma_memcpy = st_fdma_prep_dma_memcpy;
820 fdev->dma_device.device_tx_status = st_fdma_tx_status;
821 fdev->dma_device.device_issue_pending = st_fdma_issue_pending;
822 fdev->dma_device.device_terminate_all = st_fdma_terminate_all;
823 fdev->dma_device.device_config = st_fdma_slave_config;
824 fdev->dma_device.device_pause = st_fdma_pause;
825 fdev->dma_device.device_resume = st_fdma_resume;
826
827 fdev->dma_device.src_addr_widths = FDMA_DMA_BUSWIDTHS;
828 fdev->dma_device.dst_addr_widths = FDMA_DMA_BUSWIDTHS;
829 fdev->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
830 fdev->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
831
832 ret = dmaenginem_async_device_register(&fdev->dma_device);
833 if (ret) {
834 dev_err(&pdev->dev,
835 "Failed to register DMA device (%d)\n", ret);
836 goto err_rproc;
837 }
838
839 ret = of_dma_controller_register(np, st_fdma_of_xlate, fdev);
840 if (ret) {
841 dev_err(&pdev->dev,
842 "Failed to register controller (%d)\n", ret);
843 goto err_rproc;
844 }
845
846 dev_info(&pdev->dev, "ST FDMA engine driver, irq:%d\n", fdev->irq);
847
848 return 0;
849
850err_rproc:
851 st_fdma_free(fdev);
852 st_slim_rproc_put(fdev->slim_rproc);
853err:
854 return ret;
855}
856
857static int st_fdma_remove(struct platform_device *pdev)
858{
859 struct st_fdma_dev *fdev = platform_get_drvdata(pdev);
860
861 devm_free_irq(&pdev->dev, fdev->irq, fdev);
862 st_slim_rproc_put(fdev->slim_rproc);
863 of_dma_controller_free(pdev->dev.of_node);
864
865 return 0;
866}
867
868static struct platform_driver st_fdma_platform_driver = {
869 .driver = {
870 .name = DRIVER_NAME,
871 .of_match_table = st_fdma_match,
872 },
873 .probe = st_fdma_probe,
874 .remove = st_fdma_remove,
875};
876module_platform_driver(st_fdma_platform_driver);
877
878MODULE_LICENSE("GPL v2");
879MODULE_DESCRIPTION("STMicroelectronics FDMA engine driver");
880MODULE_AUTHOR("Ludovic.barre <Ludovic.barre@st.com>");
881MODULE_AUTHOR("Peter Griffin <peter.griffin@linaro.org>");
882MODULE_ALIAS("platform: " DRIVER_NAME);
883