Lines Matching +full:big +full:- +full:endian +full:- +full:regs

1 // SPDX-License-Identifier: GPL-2.0+
3 // Copyright (c) 2013-2014 Freescale Semiconductor, Inc
9 #include <linux/dma-mapping.h>
11 #include "fsl-edma-common.h"
47 struct edma_regs *regs = &fsl_chan->edma->regs; in fsl_edma_enable_request() local
48 u32 ch = fsl_chan->vchan.chan.chan_id; in fsl_edma_enable_request()
50 if (fsl_chan->edma->drvdata->version == v1) { in fsl_edma_enable_request()
51 edma_writeb(fsl_chan->edma, EDMA_SEEI_SEEI(ch), regs->seei); in fsl_edma_enable_request()
52 edma_writeb(fsl_chan->edma, ch, regs->serq); in fsl_edma_enable_request()
54 /* ColdFire is big endian, and accesses natively in fsl_edma_enable_request()
55 * big endian I/O peripherals in fsl_edma_enable_request()
57 iowrite8(EDMA_SEEI_SEEI(ch), regs->seei); in fsl_edma_enable_request()
58 iowrite8(ch, regs->serq); in fsl_edma_enable_request()
64 struct edma_regs *regs = &fsl_chan->edma->regs; in fsl_edma_disable_request() local
65 u32 ch = fsl_chan->vchan.chan.chan_id; in fsl_edma_disable_request()
67 if (fsl_chan->edma->drvdata->version == v1) { in fsl_edma_disable_request()
68 edma_writeb(fsl_chan->edma, ch, regs->cerq); in fsl_edma_disable_request()
69 edma_writeb(fsl_chan->edma, EDMA_CEEI_CEEI(ch), regs->ceei); in fsl_edma_disable_request()
71 /* ColdFire is big endian, and accesses natively in fsl_edma_disable_request()
72 * big endian I/O peripherals in fsl_edma_disable_request()
74 iowrite8(ch, regs->cerq); in fsl_edma_disable_request()
75 iowrite8(EDMA_CEEI_CEEI(ch), regs->ceei); in fsl_edma_disable_request()
109 u32 ch = fsl_chan->vchan.chan.chan_id; in fsl_edma_chan_mux()
112 int endian_diff[4] = {3, 1, -1, -3}; in fsl_edma_chan_mux()
113 u32 dmamux_nr = fsl_chan->edma->drvdata->dmamuxs; in fsl_edma_chan_mux()
115 chans_per_mux = fsl_chan->edma->n_chans / dmamux_nr; in fsl_edma_chan_mux()
116 ch_off = fsl_chan->vchan.chan.chan_id % chans_per_mux; in fsl_edma_chan_mux()
118 if (fsl_chan->edma->drvdata->mux_swap) in fsl_edma_chan_mux()
121 muxaddr = fsl_chan->edma->muxbase[ch / chans_per_mux]; in fsl_edma_chan_mux()
124 if (fsl_chan->edma->drvdata->version == v3) in fsl_edma_chan_mux()
153 for (i = 0; i < fsl_desc->n_tcds; i++) in fsl_edma_free_desc()
154 dma_pool_free(fsl_desc->echan->tcd_pool, fsl_desc->tcd[i].vtcd, in fsl_edma_free_desc()
155 fsl_desc->tcd[i].ptcd); in fsl_edma_free_desc()
166 spin_lock_irqsave(&fsl_chan->vchan.lock, flags); in fsl_edma_terminate_all()
168 fsl_chan->edesc = NULL; in fsl_edma_terminate_all()
169 fsl_chan->idle = true; in fsl_edma_terminate_all()
170 vchan_get_all_descriptors(&fsl_chan->vchan, &head); in fsl_edma_terminate_all()
171 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); in fsl_edma_terminate_all()
172 vchan_dma_desc_free_list(&fsl_chan->vchan, &head); in fsl_edma_terminate_all()
182 spin_lock_irqsave(&fsl_chan->vchan.lock, flags); in fsl_edma_pause()
183 if (fsl_chan->edesc) { in fsl_edma_pause()
185 fsl_chan->status = DMA_PAUSED; in fsl_edma_pause()
186 fsl_chan->idle = true; in fsl_edma_pause()
188 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); in fsl_edma_pause()
198 spin_lock_irqsave(&fsl_chan->vchan.lock, flags); in fsl_edma_resume()
199 if (fsl_chan->edesc) { in fsl_edma_resume()
201 fsl_chan->status = DMA_IN_PROGRESS; in fsl_edma_resume()
202 fsl_chan->idle = false; in fsl_edma_resume()
204 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); in fsl_edma_resume()
211 if (fsl_chan->dma_dir != DMA_NONE) in fsl_edma_unprep_slave_dma()
212 dma_unmap_resource(fsl_chan->vchan.chan.device->dev, in fsl_edma_unprep_slave_dma()
213 fsl_chan->dma_dev_addr, in fsl_edma_unprep_slave_dma()
214 fsl_chan->dma_dev_size, in fsl_edma_unprep_slave_dma()
215 fsl_chan->dma_dir, 0); in fsl_edma_unprep_slave_dma()
216 fsl_chan->dma_dir = DMA_NONE; in fsl_edma_unprep_slave_dma()
222 struct device *dev = fsl_chan->vchan.chan.device->dev; in fsl_edma_prep_slave_dma()
230 addr = fsl_chan->cfg.dst_addr; in fsl_edma_prep_slave_dma()
231 size = fsl_chan->cfg.dst_maxburst; in fsl_edma_prep_slave_dma()
235 addr = fsl_chan->cfg.src_addr; in fsl_edma_prep_slave_dma()
236 size = fsl_chan->cfg.src_maxburst; in fsl_edma_prep_slave_dma()
244 if (fsl_chan->dma_dir == dma_dir) in fsl_edma_prep_slave_dma()
249 fsl_chan->dma_dev_addr = dma_map_resource(dev, addr, size, dma_dir, 0); in fsl_edma_prep_slave_dma()
250 if (dma_mapping_error(dev, fsl_chan->dma_dev_addr)) in fsl_edma_prep_slave_dma()
252 fsl_chan->dma_dev_size = size; in fsl_edma_prep_slave_dma()
253 fsl_chan->dma_dir = dma_dir; in fsl_edma_prep_slave_dma()
263 memcpy(&fsl_chan->cfg, cfg, sizeof(*cfg)); in fsl_edma_slave_config()
273 struct fsl_edma_desc *edesc = fsl_chan->edesc; in fsl_edma_desc_residue()
274 struct edma_regs *regs = &fsl_chan->edma->regs; in fsl_edma_desc_residue() local
275 u32 ch = fsl_chan->vchan.chan.chan_id; in fsl_edma_desc_residue()
276 enum dma_transfer_direction dir = edesc->dirn; in fsl_edma_desc_residue()
282 for (len = i = 0; i < fsl_chan->edesc->n_tcds; i++) in fsl_edma_desc_residue()
283 len += le32_to_cpu(edesc->tcd[i].vtcd->nbytes) in fsl_edma_desc_residue()
284 * le16_to_cpu(edesc->tcd[i].vtcd->biter); in fsl_edma_desc_residue()
290 cur_addr = edma_readl(fsl_chan->edma, &regs->tcd[ch].saddr); in fsl_edma_desc_residue()
292 cur_addr = edma_readl(fsl_chan->edma, &regs->tcd[ch].daddr); in fsl_edma_desc_residue()
295 for (i = 0; i < fsl_chan->edesc->n_tcds; i++) { in fsl_edma_desc_residue()
296 size = le32_to_cpu(edesc->tcd[i].vtcd->nbytes) in fsl_edma_desc_residue()
297 * le16_to_cpu(edesc->tcd[i].vtcd->biter); in fsl_edma_desc_residue()
299 dma_addr = le32_to_cpu(edesc->tcd[i].vtcd->saddr); in fsl_edma_desc_residue()
301 dma_addr = le32_to_cpu(edesc->tcd[i].vtcd->daddr); in fsl_edma_desc_residue()
303 len -= size; in fsl_edma_desc_residue()
305 len += dma_addr + size - cur_addr; in fsl_edma_desc_residue()
326 return fsl_chan->status; in fsl_edma_tx_status()
328 spin_lock_irqsave(&fsl_chan->vchan.lock, flags); in fsl_edma_tx_status()
329 vdesc = vchan_find_desc(&fsl_chan->vchan, cookie); in fsl_edma_tx_status()
330 if (fsl_chan->edesc && cookie == fsl_chan->edesc->vdesc.tx.cookie) in fsl_edma_tx_status()
331 txstate->residue = in fsl_edma_tx_status()
334 txstate->residue = in fsl_edma_tx_status()
337 txstate->residue = 0; in fsl_edma_tx_status()
339 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); in fsl_edma_tx_status()
341 return fsl_chan->status; in fsl_edma_tx_status()
348 struct fsl_edma_engine *edma = fsl_chan->edma; in fsl_edma_set_tcd_regs()
349 struct edma_regs *regs = &fsl_chan->edma->regs; in fsl_edma_set_tcd_regs() local
350 u32 ch = fsl_chan->vchan.chan.chan_id; in fsl_edma_set_tcd_regs()
354 * endian format. However, we need to load the TCD registers in in fsl_edma_set_tcd_regs()
355 * big- or little-endian obeying the eDMA engine model endian, in fsl_edma_set_tcd_regs()
358 edma_writew(edma, 0, &regs->tcd[ch].csr); in fsl_edma_set_tcd_regs()
360 edma_writel(edma, (s32)tcd->saddr, &regs->tcd[ch].saddr); in fsl_edma_set_tcd_regs()
361 edma_writel(edma, (s32)tcd->daddr, &regs->tcd[ch].daddr); in fsl_edma_set_tcd_regs()
363 edma_writew(edma, (s16)tcd->attr, &regs->tcd[ch].attr); in fsl_edma_set_tcd_regs()
364 edma_writew(edma, tcd->soff, &regs->tcd[ch].soff); in fsl_edma_set_tcd_regs()
366 edma_writel(edma, (s32)tcd->nbytes, &regs->tcd[ch].nbytes); in fsl_edma_set_tcd_regs()
367 edma_writel(edma, (s32)tcd->slast, &regs->tcd[ch].slast); in fsl_edma_set_tcd_regs()
369 edma_writew(edma, (s16)tcd->citer, &regs->tcd[ch].citer); in fsl_edma_set_tcd_regs()
370 edma_writew(edma, (s16)tcd->biter, &regs->tcd[ch].biter); in fsl_edma_set_tcd_regs()
371 edma_writew(edma, (s16)tcd->doff, &regs->tcd[ch].doff); in fsl_edma_set_tcd_regs()
373 edma_writel(edma, (s32)tcd->dlast_sga, in fsl_edma_set_tcd_regs()
374 &regs->tcd[ch].dlast_sga); in fsl_edma_set_tcd_regs()
376 edma_writew(edma, (s16)tcd->csr, &regs->tcd[ch].csr); in fsl_edma_set_tcd_regs()
389 * endian format irrespective of the register endian model. in fsl_edma_fill_tcd()
390 * So we put the value in little endian in memory, waiting in fsl_edma_fill_tcd()
393 tcd->saddr = cpu_to_le32(src); in fsl_edma_fill_tcd()
394 tcd->daddr = cpu_to_le32(dst); in fsl_edma_fill_tcd()
396 tcd->attr = cpu_to_le16(attr); in fsl_edma_fill_tcd()
398 tcd->soff = cpu_to_le16(soff); in fsl_edma_fill_tcd()
400 tcd->nbytes = cpu_to_le32(nbytes); in fsl_edma_fill_tcd()
401 tcd->slast = cpu_to_le32(slast); in fsl_edma_fill_tcd()
403 tcd->citer = cpu_to_le16(EDMA_TCD_CITER_CITER(citer)); in fsl_edma_fill_tcd()
404 tcd->doff = cpu_to_le16(doff); in fsl_edma_fill_tcd()
406 tcd->dlast_sga = cpu_to_le32(dlast_sga); in fsl_edma_fill_tcd()
408 tcd->biter = cpu_to_le16(EDMA_TCD_BITER_BITER(biter)); in fsl_edma_fill_tcd()
418 tcd->csr = cpu_to_le16(csr); in fsl_edma_fill_tcd()
431 fsl_desc->echan = fsl_chan; in fsl_edma_alloc_desc()
432 fsl_desc->n_tcds = sg_len; in fsl_edma_alloc_desc()
434 fsl_desc->tcd[i].vtcd = dma_pool_alloc(fsl_chan->tcd_pool, in fsl_edma_alloc_desc()
435 GFP_NOWAIT, &fsl_desc->tcd[i].ptcd); in fsl_edma_alloc_desc()
436 if (!fsl_desc->tcd[i].vtcd) in fsl_edma_alloc_desc()
442 while (--i >= 0) in fsl_edma_alloc_desc()
443 dma_pool_free(fsl_chan->tcd_pool, fsl_desc->tcd[i].vtcd, in fsl_edma_alloc_desc()
444 fsl_desc->tcd[i].ptcd); in fsl_edma_alloc_desc()
471 fsl_desc->iscyclic = true; in fsl_edma_prep_dma_cyclic()
472 fsl_desc->dirn = direction; in fsl_edma_prep_dma_cyclic()
476 fsl_chan->attr = in fsl_edma_prep_dma_cyclic()
477 fsl_edma_get_tcd_attr(fsl_chan->cfg.dst_addr_width); in fsl_edma_prep_dma_cyclic()
478 nbytes = fsl_chan->cfg.dst_addr_width * in fsl_edma_prep_dma_cyclic()
479 fsl_chan->cfg.dst_maxburst; in fsl_edma_prep_dma_cyclic()
481 fsl_chan->attr = in fsl_edma_prep_dma_cyclic()
482 fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width); in fsl_edma_prep_dma_cyclic()
483 nbytes = fsl_chan->cfg.src_addr_width * in fsl_edma_prep_dma_cyclic()
484 fsl_chan->cfg.src_maxburst; in fsl_edma_prep_dma_cyclic()
494 last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd; in fsl_edma_prep_dma_cyclic()
498 dst_addr = fsl_chan->dma_dev_addr; in fsl_edma_prep_dma_cyclic()
499 soff = fsl_chan->cfg.dst_addr_width; in fsl_edma_prep_dma_cyclic()
502 src_addr = fsl_chan->dma_dev_addr; in fsl_edma_prep_dma_cyclic()
505 doff = fsl_chan->cfg.src_addr_width; in fsl_edma_prep_dma_cyclic()
508 fsl_edma_fill_tcd(fsl_desc->tcd[i].vtcd, src_addr, dst_addr, in fsl_edma_prep_dma_cyclic()
509 fsl_chan->attr, soff, nbytes, 0, iter, in fsl_edma_prep_dma_cyclic()
514 return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags); in fsl_edma_prep_dma_cyclic()
539 fsl_desc->iscyclic = false; in fsl_edma_prep_slave_sg()
540 fsl_desc->dirn = direction; in fsl_edma_prep_slave_sg()
543 fsl_chan->attr = in fsl_edma_prep_slave_sg()
544 fsl_edma_get_tcd_attr(fsl_chan->cfg.dst_addr_width); in fsl_edma_prep_slave_sg()
545 nbytes = fsl_chan->cfg.dst_addr_width * in fsl_edma_prep_slave_sg()
546 fsl_chan->cfg.dst_maxburst; in fsl_edma_prep_slave_sg()
548 fsl_chan->attr = in fsl_edma_prep_slave_sg()
549 fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width); in fsl_edma_prep_slave_sg()
550 nbytes = fsl_chan->cfg.src_addr_width * in fsl_edma_prep_slave_sg()
551 fsl_chan->cfg.src_maxburst; in fsl_edma_prep_slave_sg()
556 last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd; in fsl_edma_prep_slave_sg()
560 dst_addr = fsl_chan->dma_dev_addr; in fsl_edma_prep_slave_sg()
561 soff = fsl_chan->cfg.dst_addr_width; in fsl_edma_prep_slave_sg()
564 src_addr = fsl_chan->dma_dev_addr; in fsl_edma_prep_slave_sg()
567 doff = fsl_chan->cfg.src_addr_width; in fsl_edma_prep_slave_sg()
571 if (i < sg_len - 1) { in fsl_edma_prep_slave_sg()
572 last_sg = fsl_desc->tcd[(i + 1)].ptcd; in fsl_edma_prep_slave_sg()
573 fsl_edma_fill_tcd(fsl_desc->tcd[i].vtcd, src_addr, in fsl_edma_prep_slave_sg()
574 dst_addr, fsl_chan->attr, soff, in fsl_edma_prep_slave_sg()
579 fsl_edma_fill_tcd(fsl_desc->tcd[i].vtcd, src_addr, in fsl_edma_prep_slave_sg()
580 dst_addr, fsl_chan->attr, soff, in fsl_edma_prep_slave_sg()
586 return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags); in fsl_edma_prep_slave_sg()
594 lockdep_assert_held(&fsl_chan->vchan.lock); in fsl_edma_xfer_desc()
596 vdesc = vchan_next_desc(&fsl_chan->vchan); in fsl_edma_xfer_desc()
599 fsl_chan->edesc = to_fsl_edma_desc(vdesc); in fsl_edma_xfer_desc()
600 fsl_edma_set_tcd_regs(fsl_chan, fsl_chan->edesc->tcd[0].vtcd); in fsl_edma_xfer_desc()
602 fsl_chan->status = DMA_IN_PROGRESS; in fsl_edma_xfer_desc()
603 fsl_chan->idle = false; in fsl_edma_xfer_desc()
612 spin_lock_irqsave(&fsl_chan->vchan.lock, flags); in fsl_edma_issue_pending()
614 if (unlikely(fsl_chan->pm_state != RUNNING)) { in fsl_edma_issue_pending()
615 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); in fsl_edma_issue_pending()
620 if (vchan_issue_pending(&fsl_chan->vchan) && !fsl_chan->edesc) in fsl_edma_issue_pending()
623 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); in fsl_edma_issue_pending()
631 fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev, in fsl_edma_alloc_chan_resources()
644 spin_lock_irqsave(&fsl_chan->vchan.lock, flags); in fsl_edma_free_chan_resources()
647 fsl_chan->edesc = NULL; in fsl_edma_free_chan_resources()
648 vchan_get_all_descriptors(&fsl_chan->vchan, &head); in fsl_edma_free_chan_resources()
650 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); in fsl_edma_free_chan_resources()
652 vchan_dma_desc_free_list(&fsl_chan->vchan, &head); in fsl_edma_free_chan_resources()
653 dma_pool_destroy(fsl_chan->tcd_pool); in fsl_edma_free_chan_resources()
654 fsl_chan->tcd_pool = NULL; in fsl_edma_free_chan_resources()
663 &dmadev->channels, vchan.chan.device_node) { in fsl_edma_cleanup_vchan()
664 list_del(&chan->vchan.chan.device_node); in fsl_edma_cleanup_vchan()
665 tasklet_kill(&chan->vchan.task); in fsl_edma_cleanup_vchan()
681 edma->regs.cr = edma->membase + EDMA_CR; in fsl_edma_setup_regs()
682 edma->regs.es = edma->membase + EDMA_ES; in fsl_edma_setup_regs()
683 edma->regs.erql = edma->membase + EDMA_ERQ; in fsl_edma_setup_regs()
684 edma->regs.eeil = edma->membase + EDMA_EEI; in fsl_edma_setup_regs()
686 edma->regs.serq = edma->membase + ((edma->drvdata->version == v2) ? in fsl_edma_setup_regs()
688 edma->regs.cerq = edma->membase + ((edma->drvdata->version == v2) ? in fsl_edma_setup_regs()
690 edma->regs.seei = edma->membase + ((edma->drvdata->version == v2) ? in fsl_edma_setup_regs()
692 edma->regs.ceei = edma->membase + ((edma->drvdata->version == v2) ? in fsl_edma_setup_regs()
694 edma->regs.cint = edma->membase + ((edma->drvdata->version == v2) ? in fsl_edma_setup_regs()
696 edma->regs.cerr = edma->membase + ((edma->drvdata->version == v2) ? in fsl_edma_setup_regs()
698 edma->regs.ssrt = edma->membase + ((edma->drvdata->version == v2) ? in fsl_edma_setup_regs()
700 edma->regs.cdne = edma->membase + ((edma->drvdata->version == v2) ? in fsl_edma_setup_regs()
702 edma->regs.intl = edma->membase + ((edma->drvdata->version == v2) ? in fsl_edma_setup_regs()
704 edma->regs.errl = edma->membase + ((edma->drvdata->version == v2) ? in fsl_edma_setup_regs()
707 if (edma->drvdata->version == v2) { in fsl_edma_setup_regs()
708 edma->regs.erqh = edma->membase + EDMA64_ERQH; in fsl_edma_setup_regs()
709 edma->regs.eeih = edma->membase + EDMA64_EEIH; in fsl_edma_setup_regs()
710 edma->regs.errh = edma->membase + EDMA64_ERRH; in fsl_edma_setup_regs()
711 edma->regs.inth = edma->membase + EDMA64_INTH; in fsl_edma_setup_regs()
714 edma->regs.tcd = edma->membase + EDMA_TCD; in fsl_edma_setup_regs()