fsl-edma-common.c (3eb66e91a25497065c5322b1268cbc3953642227) fsl-edma-common.c (0fa89f972da607540497f11afbb47af6fea5bce0)
1// SPDX-License-Identifier: GPL-2.0+
2//
3// Copyright (c) 2013-2014 Freescale Semiconductor, Inc
4// Copyright (c) 2017 Sysam, Angelo Dureghello <angelo@sysam.it>
5
6#include <linux/dmapool.h>
7#include <linux/module.h>
8#include <linux/slab.h>
1// SPDX-License-Identifier: GPL-2.0+
2//
3// Copyright (c) 2013-2014 Freescale Semiconductor, Inc
4// Copyright (c) 2017 Sysam, Angelo Dureghello <angelo@sysam.it>
5
6#include <linux/dmapool.h>
7#include <linux/module.h>
8#include <linux/slab.h>
9#include <linux/dma-mapping.h>
9
10#include "fsl-edma-common.h"
11
12#define EDMA_CR 0x00
13#define EDMA_ES 0x04
14#define EDMA_ERQ 0x0C
15#define EDMA_EEI 0x14
16#define EDMA_SERQ 0x1B

--- 151 unchanged lines hidden (view full) ---

168 fsl_chan->status = DMA_IN_PROGRESS;
169 fsl_chan->idle = false;
170 }
171 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
172 return 0;
173}
174EXPORT_SYMBOL_GPL(fsl_edma_resume);
175
10
11#include "fsl-edma-common.h"
12
13#define EDMA_CR 0x00
14#define EDMA_ES 0x04
15#define EDMA_ERQ 0x0C
16#define EDMA_EEI 0x14
17#define EDMA_SERQ 0x1B

--- 151 unchanged lines hidden (view full) ---

169 fsl_chan->status = DMA_IN_PROGRESS;
170 fsl_chan->idle = false;
171 }
172 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
173 return 0;
174}
175EXPORT_SYMBOL_GPL(fsl_edma_resume);
176
177static void fsl_edma_unprep_slave_dma(struct fsl_edma_chan *fsl_chan)
178{
179 if (fsl_chan->dma_dir != DMA_NONE)
180 dma_unmap_resource(fsl_chan->vchan.chan.device->dev,
181 fsl_chan->dma_dev_addr,
182 fsl_chan->dma_dev_size,
183 fsl_chan->dma_dir, 0);
184 fsl_chan->dma_dir = DMA_NONE;
185}
186
187static bool fsl_edma_prep_slave_dma(struct fsl_edma_chan *fsl_chan,
188 enum dma_transfer_direction dir)
189{
190 struct device *dev = fsl_chan->vchan.chan.device->dev;
191 enum dma_data_direction dma_dir;
192 phys_addr_t addr = 0;
193 u32 size = 0;
194
195 switch (dir) {
196 case DMA_MEM_TO_DEV:
197 dma_dir = DMA_FROM_DEVICE;
198 addr = fsl_chan->cfg.dst_addr;
199 size = fsl_chan->cfg.dst_maxburst;
200 break;
201 case DMA_DEV_TO_MEM:
202 dma_dir = DMA_TO_DEVICE;
203 addr = fsl_chan->cfg.src_addr;
204 size = fsl_chan->cfg.src_maxburst;
205 break;
206 default:
207 dma_dir = DMA_NONE;
208 break;
209 }
210
211 /* Already mapped for this config? */
212 if (fsl_chan->dma_dir == dma_dir)
213 return true;
214
215 fsl_edma_unprep_slave_dma(fsl_chan);
216
217 fsl_chan->dma_dev_addr = dma_map_resource(dev, addr, size, dma_dir, 0);
218 if (dma_mapping_error(dev, fsl_chan->dma_dev_addr))
219 return false;
220 fsl_chan->dma_dev_size = size;
221 fsl_chan->dma_dir = dma_dir;
222
223 return true;
224}
225
176int fsl_edma_slave_config(struct dma_chan *chan,
177 struct dma_slave_config *cfg)
178{
179 struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
180
181 memcpy(&fsl_chan->cfg, cfg, sizeof(*cfg));
226int fsl_edma_slave_config(struct dma_chan *chan,
227 struct dma_slave_config *cfg)
228{
229 struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
230
231 memcpy(&fsl_chan->cfg, cfg, sizeof(*cfg));
232 fsl_edma_unprep_slave_dma(fsl_chan);
182
183 return 0;
184}
185EXPORT_SYMBOL_GPL(fsl_edma_slave_config);
186
187static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan,
188 struct virt_dma_desc *vdesc, bool in_progress)
189{

--- 144 unchanged lines hidden (view full) ---

334}
335
336static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan,
337 int sg_len)
338{
339 struct fsl_edma_desc *fsl_desc;
340 int i;
341
233
234 return 0;
235}
236EXPORT_SYMBOL_GPL(fsl_edma_slave_config);
237
238static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan,
239 struct virt_dma_desc *vdesc, bool in_progress)
240{

--- 144 unchanged lines hidden (view full) ---

385}
386
387static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan,
388 int sg_len)
389{
390 struct fsl_edma_desc *fsl_desc;
391 int i;
392
342 fsl_desc = kzalloc(sizeof(*fsl_desc) +
343 sizeof(struct fsl_edma_sw_tcd) *
344 sg_len, GFP_NOWAIT);
393 fsl_desc = kzalloc(struct_size(fsl_desc, tcd, sg_len), GFP_NOWAIT);
345 if (!fsl_desc)
346 return NULL;
347
348 fsl_desc->echan = fsl_chan;
349 fsl_desc->n_tcds = sg_len;
350 for (i = 0; i < sg_len; i++) {
351 fsl_desc->tcd[i].vtcd = dma_pool_alloc(fsl_chan->tcd_pool,
352 GFP_NOWAIT, &fsl_desc->tcd[i].ptcd);

--- 20 unchanged lines hidden (view full) ---

373 dma_addr_t dma_buf_next;
374 int sg_len, i;
375 u32 src_addr, dst_addr, last_sg, nbytes;
376 u16 soff, doff, iter;
377
378 if (!is_slave_direction(direction))
379 return NULL;
380
394 if (!fsl_desc)
395 return NULL;
396
397 fsl_desc->echan = fsl_chan;
398 fsl_desc->n_tcds = sg_len;
399 for (i = 0; i < sg_len; i++) {
400 fsl_desc->tcd[i].vtcd = dma_pool_alloc(fsl_chan->tcd_pool,
401 GFP_NOWAIT, &fsl_desc->tcd[i].ptcd);

--- 20 unchanged lines hidden (view full) ---

422 dma_addr_t dma_buf_next;
423 int sg_len, i;
424 u32 src_addr, dst_addr, last_sg, nbytes;
425 u16 soff, doff, iter;
426
427 if (!is_slave_direction(direction))
428 return NULL;
429
430 if (!fsl_edma_prep_slave_dma(fsl_chan, direction))
431 return NULL;
432
381 sg_len = buf_len / period_len;
382 fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
383 if (!fsl_desc)
384 return NULL;
385 fsl_desc->iscyclic = true;
386 fsl_desc->dirn = direction;
387
388 dma_buf_next = dma_addr;

--- 15 unchanged lines hidden (view full) ---

404 if (dma_buf_next >= dma_addr + buf_len)
405 dma_buf_next = dma_addr;
406
407 /* get next sg's physical address */
408 last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd;
409
410 if (direction == DMA_MEM_TO_DEV) {
411 src_addr = dma_buf_next;
433 sg_len = buf_len / period_len;
434 fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
435 if (!fsl_desc)
436 return NULL;
437 fsl_desc->iscyclic = true;
438 fsl_desc->dirn = direction;
439
440 dma_buf_next = dma_addr;

--- 15 unchanged lines hidden (view full) ---

456 if (dma_buf_next >= dma_addr + buf_len)
457 dma_buf_next = dma_addr;
458
459 /* get next sg's physical address */
460 last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd;
461
462 if (direction == DMA_MEM_TO_DEV) {
463 src_addr = dma_buf_next;
412 dst_addr = fsl_chan->cfg.dst_addr;
464 dst_addr = fsl_chan->dma_dev_addr;
413 soff = fsl_chan->cfg.dst_addr_width;
414 doff = 0;
415 } else {
465 soff = fsl_chan->cfg.dst_addr_width;
466 doff = 0;
467 } else {
416 src_addr = fsl_chan->cfg.src_addr;
468 src_addr = fsl_chan->dma_dev_addr;
417 dst_addr = dma_buf_next;
418 soff = 0;
419 doff = fsl_chan->cfg.src_addr_width;
420 }
421
422 fsl_edma_fill_tcd(fsl_desc->tcd[i].vtcd, src_addr, dst_addr,
423 fsl_chan->attr, soff, nbytes, 0, iter,
424 iter, doff, last_sg, true, false, true);

--- 14 unchanged lines hidden (view full) ---

439 struct scatterlist *sg;
440 u32 src_addr, dst_addr, last_sg, nbytes;
441 u16 soff, doff, iter;
442 int i;
443
444 if (!is_slave_direction(direction))
445 return NULL;
446
469 dst_addr = dma_buf_next;
470 soff = 0;
471 doff = fsl_chan->cfg.src_addr_width;
472 }
473
474 fsl_edma_fill_tcd(fsl_desc->tcd[i].vtcd, src_addr, dst_addr,
475 fsl_chan->attr, soff, nbytes, 0, iter,
476 iter, doff, last_sg, true, false, true);

--- 14 unchanged lines hidden (view full) ---

491 struct scatterlist *sg;
492 u32 src_addr, dst_addr, last_sg, nbytes;
493 u16 soff, doff, iter;
494 int i;
495
496 if (!is_slave_direction(direction))
497 return NULL;
498
499 if (!fsl_edma_prep_slave_dma(fsl_chan, direction))
500 return NULL;
501
447 fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
448 if (!fsl_desc)
449 return NULL;
450 fsl_desc->iscyclic = false;
451 fsl_desc->dirn = direction;
452
453 if (direction == DMA_MEM_TO_DEV) {
454 fsl_chan->attr =

--- 8 unchanged lines hidden (view full) ---

463 }
464
465 for_each_sg(sgl, sg, sg_len, i) {
466 /* get next sg's physical address */
467 last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd;
468
469 if (direction == DMA_MEM_TO_DEV) {
470 src_addr = sg_dma_address(sg);
502 fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len);
503 if (!fsl_desc)
504 return NULL;
505 fsl_desc->iscyclic = false;
506 fsl_desc->dirn = direction;
507
508 if (direction == DMA_MEM_TO_DEV) {
509 fsl_chan->attr =

--- 8 unchanged lines hidden (view full) ---

518 }
519
520 for_each_sg(sgl, sg, sg_len, i) {
521 /* get next sg's physical address */
522 last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd;
523
524 if (direction == DMA_MEM_TO_DEV) {
525 src_addr = sg_dma_address(sg);
471 dst_addr = fsl_chan->cfg.dst_addr;
526 dst_addr = fsl_chan->dma_dev_addr;
472 soff = fsl_chan->cfg.dst_addr_width;
473 doff = 0;
474 } else {
527 soff = fsl_chan->cfg.dst_addr_width;
528 doff = 0;
529 } else {
475 src_addr = fsl_chan->cfg.src_addr;
530 src_addr = fsl_chan->dma_dev_addr;
476 dst_addr = sg_dma_address(sg);
477 soff = 0;
478 doff = fsl_chan->cfg.src_addr_width;
479 }
480
481 iter = sg_dma_len(sg) / nbytes;
482 if (i < sg_len - 1) {
483 last_sg = fsl_desc->tcd[(i + 1)].ptcd;

--- 66 unchanged lines hidden (view full) ---

550 unsigned long flags;
551 LIST_HEAD(head);
552
553 spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
554 fsl_edma_disable_request(fsl_chan);
555 fsl_edma_chan_mux(fsl_chan, 0, false);
556 fsl_chan->edesc = NULL;
557 vchan_get_all_descriptors(&fsl_chan->vchan, &head);
531 dst_addr = sg_dma_address(sg);
532 soff = 0;
533 doff = fsl_chan->cfg.src_addr_width;
534 }
535
536 iter = sg_dma_len(sg) / nbytes;
537 if (i < sg_len - 1) {
538 last_sg = fsl_desc->tcd[(i + 1)].ptcd;

--- 66 unchanged lines hidden (view full) ---

605 unsigned long flags;
606 LIST_HEAD(head);
607
608 spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
609 fsl_edma_disable_request(fsl_chan);
610 fsl_edma_chan_mux(fsl_chan, 0, false);
611 fsl_chan->edesc = NULL;
612 vchan_get_all_descriptors(&fsl_chan->vchan, &head);
613 fsl_edma_unprep_slave_dma(fsl_chan);
558 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
559
560 vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
561 dma_pool_destroy(fsl_chan->tcd_pool);
562 fsl_chan->tcd_pool = NULL;
563}
564EXPORT_SYMBOL_GPL(fsl_edma_free_chan_resources);
565

--- 61 unchanged lines hidden ---
614 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
615
616 vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
617 dma_pool_destroy(fsl_chan->tcd_pool);
618 fsl_chan->tcd_pool = NULL;
619}
620EXPORT_SYMBOL_GPL(fsl_edma_free_chan_resources);
621

--- 61 unchanged lines hidden ---