Lines Matching +full:es +full:- +full:enable
1 // SPDX-License-Identifier: GPL-2.0-or-later
11 * written by Hongjun Chen <hong-jun.chen@freescale.com>.
22 * - chunked transfers (described by s/g lists with more than one item) are
24 * - transfers on MPC8308 always start from software as this SoC does not have
26 * - memory <-> I/O memory transfer chunks of sizes of 1, 2, 4, 16 (for
35 #include <linux/dma-mapping.h>
98 u32 dmaerqh; /* DMA enable request high(channels 63~32) */
99 u32 dmaerql; /* DMA enable request low(channels 31~0) */
100 u32 dmaeeih; /* DMA enable error interrupt high(ch63~32) */
101 u32 dmaeeil; /* DMA enable error interrupt low(ch31~0) */
103 u8 dmaserq; /* DMA set enable request */
104 u8 dmacerq; /* DMA clear enable request */
105 u8 dmaseei; /* DMA set enable error interrupt */
106 u8 dmaceei; /* DMA clear enable error interrupt */
148 u32 citer_elink:1; /* Enable channel-to-channel linking on
161 u32 biter_elink:1; /* Enable channel-to-channel linking on major
170 u32 major_elink:1; /* Enable channel-to-channel linking on major
173 u32 e_sg:1; /* Enable scatter/gather processing */
175 u32 int_half:1; /* Enable an interrupt when major counter is
178 u32 int_maj:1; /* Enable an interrupt when major iteration
243 return container_of(mchan, struct mpc_dma, channels[c->chan_id]); in dma_chan_to_mpc_dma()
250 * a) mchan->lock is acquired,
251 * b) mchan->active list is empty,
252 * c) mchan->queued list contains at least one entry.
256 struct mpc_dma *mdma = dma_chan_to_mpc_dma(&mchan->chan); in mpc_dma_execute()
260 int cid = mchan->chan.chan_id; in mpc_dma_execute()
262 while (!list_empty(&mchan->queued)) { in mpc_dma_execute()
263 mdesc = list_first_entry(&mchan->queued, in mpc_dma_execute()
266 * Grab either several mem-to-mem transfer descriptors in mpc_dma_execute()
268 * don't mix mem-to-mem and peripheral transfer descriptors in mpc_dma_execute()
271 if (mdesc->will_access_peripheral) { in mpc_dma_execute()
272 if (list_empty(&mchan->active)) in mpc_dma_execute()
273 list_move_tail(&mdesc->node, &mchan->active); in mpc_dma_execute()
276 list_move_tail(&mdesc->node, &mchan->active); in mpc_dma_execute()
281 list_for_each_entry(mdesc, &mchan->active, node) { in mpc_dma_execute()
290 prev->tcd->dlast_sga = mdesc->tcd_paddr; in mpc_dma_execute()
291 prev->tcd->e_sg = 1; in mpc_dma_execute()
292 mdesc->tcd->start = 1; in mpc_dma_execute()
297 prev->tcd->int_maj = 1; in mpc_dma_execute()
300 memcpy_toio(&mdma->tcd[cid], first->tcd, sizeof(struct mpc_dma_tcd)); in mpc_dma_execute()
303 mdma->tcd[cid].e_sg = 1; in mpc_dma_execute()
305 if (mdma->is_mpc8308) { in mpc_dma_execute()
307 out_8(&mdma->regs->dmassrt, cid); in mpc_dma_execute()
308 } else if (first->will_access_peripheral) { in mpc_dma_execute()
310 out_8(&mdma->regs->dmaserq, cid); in mpc_dma_execute()
313 out_8(&mdma->regs->dmassrt, cid); in mpc_dma_execute()
318 static void mpc_dma_irq_process(struct mpc_dma *mdma, u32 is, u32 es, int off) in mpc_dma_irq_process() argument
322 u32 status = is | es; in mpc_dma_irq_process()
325 while ((ch = fls(status) - 1) >= 0) { in mpc_dma_irq_process()
327 mchan = &mdma->channels[ch + off]; in mpc_dma_irq_process()
329 spin_lock(&mchan->lock); in mpc_dma_irq_process()
331 out_8(&mdma->regs->dmacint, ch + off); in mpc_dma_irq_process()
332 out_8(&mdma->regs->dmacerr, ch + off); in mpc_dma_irq_process()
335 if (es & (1 << ch)) in mpc_dma_irq_process()
336 list_for_each_entry(mdesc, &mchan->active, node) in mpc_dma_irq_process()
337 mdesc->error = -EIO; in mpc_dma_irq_process()
340 list_splice_tail_init(&mchan->active, &mchan->completed); in mpc_dma_irq_process()
341 if (!list_empty(&mchan->queued)) in mpc_dma_irq_process()
344 spin_unlock(&mchan->lock); in mpc_dma_irq_process()
352 uint es; in mpc_dma_irq() local
355 es = in_be32(&mdma->regs->dmaes); in mpc_dma_irq()
356 spin_lock(&mdma->error_status_lock); in mpc_dma_irq()
357 if ((es & MPC_DMA_DMAES_VLD) && mdma->error_status == 0) in mpc_dma_irq()
358 mdma->error_status = es; in mpc_dma_irq()
359 spin_unlock(&mdma->error_status_lock); in mpc_dma_irq()
362 if (mdma->dma.chancnt > 32) { in mpc_dma_irq()
363 mpc_dma_irq_process(mdma, in_be32(&mdma->regs->dmainth), in mpc_dma_irq()
364 in_be32(&mdma->regs->dmaerrh), 32); in mpc_dma_irq()
366 mpc_dma_irq_process(mdma, in_be32(&mdma->regs->dmaintl), in mpc_dma_irq()
367 in_be32(&mdma->regs->dmaerrl), 0); in mpc_dma_irq()
370 tasklet_schedule(&mdma->tasklet); in mpc_dma_irq()
386 for (i = 0; i < mdma->dma.chancnt; i++) { in mpc_dma_process_completed()
387 mchan = &mdma->channels[i]; in mpc_dma_process_completed()
390 spin_lock_irqsave(&mchan->lock, flags); in mpc_dma_process_completed()
391 if (!list_empty(&mchan->completed)) in mpc_dma_process_completed()
392 list_splice_tail_init(&mchan->completed, &list); in mpc_dma_process_completed()
393 spin_unlock_irqrestore(&mchan->lock, flags); in mpc_dma_process_completed()
400 desc = &mdesc->desc; in mpc_dma_process_completed()
404 last_cookie = desc->cookie; in mpc_dma_process_completed()
409 spin_lock_irqsave(&mchan->lock, flags); in mpc_dma_process_completed()
410 list_splice_tail_init(&list, &mchan->free); in mpc_dma_process_completed()
411 mchan->chan.completed_cookie = last_cookie; in mpc_dma_process_completed()
412 spin_unlock_irqrestore(&mchan->lock, flags); in mpc_dma_process_completed()
421 uint es; in mpc_dma_tasklet() local
423 spin_lock_irqsave(&mdma->error_status_lock, flags); in mpc_dma_tasklet()
424 es = mdma->error_status; in mpc_dma_tasklet()
425 mdma->error_status = 0; in mpc_dma_tasklet()
426 spin_unlock_irqrestore(&mdma->error_status_lock, flags); in mpc_dma_tasklet()
429 if (es) { in mpc_dma_tasklet()
430 dev_err(mdma->dma.dev, in mpc_dma_tasklet()
432 MPC_DMA_DMAES_ERRCHN(es)); in mpc_dma_tasklet()
434 if (es & MPC_DMA_DMAES_GPE) in mpc_dma_tasklet()
435 dev_err(mdma->dma.dev, "- Group Priority Error\n"); in mpc_dma_tasklet()
436 if (es & MPC_DMA_DMAES_CPE) in mpc_dma_tasklet()
437 dev_err(mdma->dma.dev, "- Channel Priority Error\n"); in mpc_dma_tasklet()
438 if (es & MPC_DMA_DMAES_SAE) in mpc_dma_tasklet()
439 dev_err(mdma->dma.dev, "- Source Address Error\n"); in mpc_dma_tasklet()
440 if (es & MPC_DMA_DMAES_SOE) in mpc_dma_tasklet()
441 dev_err(mdma->dma.dev, "- Source Offset Configuration Error\n"); in mpc_dma_tasklet()
442 if (es & MPC_DMA_DMAES_DAE) in mpc_dma_tasklet()
443 dev_err(mdma->dma.dev, "- Destination Address Error\n"); in mpc_dma_tasklet()
444 if (es & MPC_DMA_DMAES_DOE) in mpc_dma_tasklet()
445 dev_err(mdma->dma.dev, "- Destination Offset Configuration Error\n"); in mpc_dma_tasklet()
446 if (es & MPC_DMA_DMAES_NCE) in mpc_dma_tasklet()
447 dev_err(mdma->dma.dev, "- NBytes/Citter Configuration Error\n"); in mpc_dma_tasklet()
448 if (es & MPC_DMA_DMAES_SGE) in mpc_dma_tasklet()
449 dev_err(mdma->dma.dev, "- Scatter/Gather Configuration Error\n"); in mpc_dma_tasklet()
450 if (es & MPC_DMA_DMAES_SBE) in mpc_dma_tasklet()
451 dev_err(mdma->dma.dev, "- Source Bus Error\n"); in mpc_dma_tasklet()
452 if (es & MPC_DMA_DMAES_DBE) in mpc_dma_tasklet()
453 dev_err(mdma->dma.dev, "- Destination Bus Error\n"); in mpc_dma_tasklet()
462 struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(txd->chan); in mpc_dma_tx_submit()
469 spin_lock_irqsave(&mchan->lock, flags); in mpc_dma_tx_submit()
472 list_move_tail(&mdesc->node, &mchan->queued); in mpc_dma_tx_submit()
475 if (list_empty(&mchan->active)) in mpc_dma_tx_submit()
480 spin_unlock_irqrestore(&mchan->lock, flags); in mpc_dma_tx_submit()
498 tcd = dma_alloc_coherent(mdma->dma.dev, in mpc_dma_alloc_chan_resources()
502 return -ENOMEM; in mpc_dma_alloc_chan_resources()
508 dev_notice(mdma->dma.dev, in mpc_dma_alloc_chan_resources()
513 dma_async_tx_descriptor_init(&mdesc->desc, chan); in mpc_dma_alloc_chan_resources()
514 mdesc->desc.flags = DMA_CTRL_ACK; in mpc_dma_alloc_chan_resources()
515 mdesc->desc.tx_submit = mpc_dma_tx_submit; in mpc_dma_alloc_chan_resources()
517 mdesc->tcd = &tcd[i]; in mpc_dma_alloc_chan_resources()
518 mdesc->tcd_paddr = tcd_paddr + (i * sizeof(struct mpc_dma_tcd)); in mpc_dma_alloc_chan_resources()
520 list_add_tail(&mdesc->node, &descs); in mpc_dma_alloc_chan_resources()
525 dma_free_coherent(mdma->dma.dev, in mpc_dma_alloc_chan_resources()
528 return -ENOMEM; in mpc_dma_alloc_chan_resources()
531 spin_lock_irqsave(&mchan->lock, flags); in mpc_dma_alloc_chan_resources()
532 mchan->tcd = tcd; in mpc_dma_alloc_chan_resources()
533 mchan->tcd_paddr = tcd_paddr; in mpc_dma_alloc_chan_resources()
534 list_splice_tail_init(&descs, &mchan->free); in mpc_dma_alloc_chan_resources()
535 spin_unlock_irqrestore(&mchan->lock, flags); in mpc_dma_alloc_chan_resources()
537 /* Enable Error Interrupt */ in mpc_dma_alloc_chan_resources()
538 out_8(&mdma->regs->dmaseei, chan->chan_id); in mpc_dma_alloc_chan_resources()
554 spin_lock_irqsave(&mchan->lock, flags); in mpc_dma_free_chan_resources()
557 BUG_ON(!list_empty(&mchan->prepared)); in mpc_dma_free_chan_resources()
558 BUG_ON(!list_empty(&mchan->queued)); in mpc_dma_free_chan_resources()
559 BUG_ON(!list_empty(&mchan->active)); in mpc_dma_free_chan_resources()
560 BUG_ON(!list_empty(&mchan->completed)); in mpc_dma_free_chan_resources()
563 list_splice_tail_init(&mchan->free, &descs); in mpc_dma_free_chan_resources()
564 tcd = mchan->tcd; in mpc_dma_free_chan_resources()
565 tcd_paddr = mchan->tcd_paddr; in mpc_dma_free_chan_resources()
567 spin_unlock_irqrestore(&mchan->lock, flags); in mpc_dma_free_chan_resources()
570 dma_free_coherent(mdma->dma.dev, in mpc_dma_free_chan_resources()
579 out_8(&mdma->regs->dmaceei, chan->chan_id); in mpc_dma_free_chan_resources()
611 spin_lock_irqsave(&mchan->lock, iflags); in mpc_dma_prep_memcpy()
612 if (!list_empty(&mchan->free)) { in mpc_dma_prep_memcpy()
613 mdesc = list_first_entry(&mchan->free, struct mpc_dma_desc, in mpc_dma_prep_memcpy()
615 list_del(&mdesc->node); in mpc_dma_prep_memcpy()
617 spin_unlock_irqrestore(&mchan->lock, iflags); in mpc_dma_prep_memcpy()
625 mdesc->error = 0; in mpc_dma_prep_memcpy()
626 mdesc->will_access_peripheral = 0; in mpc_dma_prep_memcpy()
627 tcd = mdesc->tcd; in mpc_dma_prep_memcpy()
633 tcd->ssize = MPC_DMA_TSIZE_32; in mpc_dma_prep_memcpy()
634 tcd->dsize = MPC_DMA_TSIZE_32; in mpc_dma_prep_memcpy()
635 tcd->soff = 32; in mpc_dma_prep_memcpy()
636 tcd->doff = 32; in mpc_dma_prep_memcpy()
637 } else if (!mdma->is_mpc8308 && IS_ALIGNED(src | dst | len, 16)) { in mpc_dma_prep_memcpy()
639 tcd->ssize = MPC_DMA_TSIZE_16; in mpc_dma_prep_memcpy()
640 tcd->dsize = MPC_DMA_TSIZE_16; in mpc_dma_prep_memcpy()
641 tcd->soff = 16; in mpc_dma_prep_memcpy()
642 tcd->doff = 16; in mpc_dma_prep_memcpy()
644 tcd->ssize = MPC_DMA_TSIZE_4; in mpc_dma_prep_memcpy()
645 tcd->dsize = MPC_DMA_TSIZE_4; in mpc_dma_prep_memcpy()
646 tcd->soff = 4; in mpc_dma_prep_memcpy()
647 tcd->doff = 4; in mpc_dma_prep_memcpy()
649 tcd->ssize = MPC_DMA_TSIZE_2; in mpc_dma_prep_memcpy()
650 tcd->dsize = MPC_DMA_TSIZE_2; in mpc_dma_prep_memcpy()
651 tcd->soff = 2; in mpc_dma_prep_memcpy()
652 tcd->doff = 2; in mpc_dma_prep_memcpy()
654 tcd->ssize = MPC_DMA_TSIZE_1; in mpc_dma_prep_memcpy()
655 tcd->dsize = MPC_DMA_TSIZE_1; in mpc_dma_prep_memcpy()
656 tcd->soff = 1; in mpc_dma_prep_memcpy()
657 tcd->doff = 1; in mpc_dma_prep_memcpy()
660 tcd->saddr = src; in mpc_dma_prep_memcpy()
661 tcd->daddr = dst; in mpc_dma_prep_memcpy()
662 tcd->nbytes = len; in mpc_dma_prep_memcpy()
663 tcd->biter = 1; in mpc_dma_prep_memcpy()
664 tcd->citer = 1; in mpc_dma_prep_memcpy()
667 spin_lock_irqsave(&mchan->lock, iflags); in mpc_dma_prep_memcpy()
668 list_add_tail(&mdesc->node, &mchan->prepared); in mpc_dma_prep_memcpy()
669 spin_unlock_irqrestore(&mchan->lock, iflags); in mpc_dma_prep_memcpy()
671 return &mdesc->desc; in mpc_dma_prep_memcpy()
707 spin_lock_irqsave(&mchan->lock, iflags); in mpc_dma_prep_slave_sg()
709 mdesc = list_first_entry(&mchan->free, in mpc_dma_prep_slave_sg()
712 spin_unlock_irqrestore(&mchan->lock, iflags); in mpc_dma_prep_slave_sg()
718 list_del(&mdesc->node); in mpc_dma_prep_slave_sg()
721 per_paddr = mchan->src_per_paddr; in mpc_dma_prep_slave_sg()
722 tcd_nunits = mchan->src_tcd_nunits; in mpc_dma_prep_slave_sg()
724 per_paddr = mchan->dst_per_paddr; in mpc_dma_prep_slave_sg()
725 tcd_nunits = mchan->dst_tcd_nunits; in mpc_dma_prep_slave_sg()
728 spin_unlock_irqrestore(&mchan->lock, iflags); in mpc_dma_prep_slave_sg()
733 mdesc->error = 0; in mpc_dma_prep_slave_sg()
734 mdesc->will_access_peripheral = 1; in mpc_dma_prep_slave_sg()
737 tcd = mdesc->tcd; in mpc_dma_prep_slave_sg()
742 tcd->saddr = per_paddr; in mpc_dma_prep_slave_sg()
743 tcd->daddr = sg_dma_address(sg); in mpc_dma_prep_slave_sg()
745 if (!IS_ALIGNED(sg_dma_address(sg), mchan->dwidth)) in mpc_dma_prep_slave_sg()
748 tcd->soff = 0; in mpc_dma_prep_slave_sg()
749 tcd->doff = mchan->dwidth; in mpc_dma_prep_slave_sg()
751 tcd->saddr = sg_dma_address(sg); in mpc_dma_prep_slave_sg()
752 tcd->daddr = per_paddr; in mpc_dma_prep_slave_sg()
754 if (!IS_ALIGNED(sg_dma_address(sg), mchan->swidth)) in mpc_dma_prep_slave_sg()
757 tcd->soff = mchan->swidth; in mpc_dma_prep_slave_sg()
758 tcd->doff = 0; in mpc_dma_prep_slave_sg()
761 tcd->ssize = buswidth_to_dmatsize(mchan->swidth); in mpc_dma_prep_slave_sg()
762 tcd->dsize = buswidth_to_dmatsize(mchan->dwidth); in mpc_dma_prep_slave_sg()
764 if (mdma->is_mpc8308) { in mpc_dma_prep_slave_sg()
765 tcd->nbytes = sg_dma_len(sg); in mpc_dma_prep_slave_sg()
766 if (!IS_ALIGNED(tcd->nbytes, mchan->swidth)) in mpc_dma_prep_slave_sg()
770 tcd->biter = 1; in mpc_dma_prep_slave_sg()
771 tcd->citer = 1; in mpc_dma_prep_slave_sg()
774 tcd->nbytes = tcd_nunits * tcd->ssize; in mpc_dma_prep_slave_sg()
775 if (!IS_ALIGNED(len, tcd->nbytes)) in mpc_dma_prep_slave_sg()
778 iter = len / tcd->nbytes; in mpc_dma_prep_slave_sg()
784 tcd->biter = iter & 0x1ff; in mpc_dma_prep_slave_sg()
785 tcd->biter_linkch = iter >> 9; in mpc_dma_prep_slave_sg()
786 tcd->citer = tcd->biter; in mpc_dma_prep_slave_sg()
787 tcd->citer_linkch = tcd->biter_linkch; in mpc_dma_prep_slave_sg()
790 tcd->e_sg = 0; in mpc_dma_prep_slave_sg()
791 tcd->d_req = 1; in mpc_dma_prep_slave_sg()
794 spin_lock_irqsave(&mchan->lock, iflags); in mpc_dma_prep_slave_sg()
795 list_add_tail(&mdesc->node, &mchan->prepared); in mpc_dma_prep_slave_sg()
796 spin_unlock_irqrestore(&mchan->lock, iflags); in mpc_dma_prep_slave_sg()
799 return &mdesc->desc; in mpc_dma_prep_slave_sg()
803 spin_lock_irqsave(&mchan->lock, iflags); in mpc_dma_prep_slave_sg()
804 list_add_tail(&mdesc->node, &mchan->free); in mpc_dma_prep_slave_sg()
805 spin_unlock_irqrestore(&mchan->lock, iflags); in mpc_dma_prep_slave_sg()
833 struct mpc_dma *mdma = dma_chan_to_mpc_dma(&mchan->chan); in mpc_dma_device_config()
838 * - only transfers between a peripheral device and memory are in mpc_dma_device_config()
840 * - transfer chunk sizes of 1, 2, 4, 16 (for MPC512x), and 32 bytes in mpc_dma_device_config()
845 * - during the transfer, the RAM address is incremented by the size in mpc_dma_device_config()
847 * - the peripheral port's address is constant during the transfer. in mpc_dma_device_config()
850 if (!IS_ALIGNED(cfg->src_addr, cfg->src_addr_width) || in mpc_dma_device_config()
851 !IS_ALIGNED(cfg->dst_addr, cfg->dst_addr_width)) { in mpc_dma_device_config()
852 return -EINVAL; in mpc_dma_device_config()
855 if (!is_buswidth_valid(cfg->src_addr_width, mdma->is_mpc8308) || in mpc_dma_device_config()
856 !is_buswidth_valid(cfg->dst_addr_width, mdma->is_mpc8308)) in mpc_dma_device_config()
857 return -EINVAL; in mpc_dma_device_config()
859 spin_lock_irqsave(&mchan->lock, flags); in mpc_dma_device_config()
861 mchan->src_per_paddr = cfg->src_addr; in mpc_dma_device_config()
862 mchan->src_tcd_nunits = cfg->src_maxburst; in mpc_dma_device_config()
863 mchan->swidth = cfg->src_addr_width; in mpc_dma_device_config()
864 mchan->dst_per_paddr = cfg->dst_addr; in mpc_dma_device_config()
865 mchan->dst_tcd_nunits = cfg->dst_maxburst; in mpc_dma_device_config()
866 mchan->dwidth = cfg->dst_addr_width; in mpc_dma_device_config()
869 if (mchan->src_tcd_nunits == 0) in mpc_dma_device_config()
870 mchan->src_tcd_nunits = 1; in mpc_dma_device_config()
871 if (mchan->dst_tcd_nunits == 0) in mpc_dma_device_config()
872 mchan->dst_tcd_nunits = 1; in mpc_dma_device_config()
874 spin_unlock_irqrestore(&mchan->lock, flags); in mpc_dma_device_config()
886 spin_lock_irqsave(&mchan->lock, flags); in mpc_dma_device_terminate_all()
888 out_8(&mdma->regs->dmacerq, chan->chan_id); in mpc_dma_device_terminate_all()
889 list_splice_tail_init(&mchan->prepared, &mchan->free); in mpc_dma_device_terminate_all()
890 list_splice_tail_init(&mchan->queued, &mchan->free); in mpc_dma_device_terminate_all()
891 list_splice_tail_init(&mchan->active, &mchan->free); in mpc_dma_device_terminate_all()
893 spin_unlock_irqrestore(&mchan->lock, flags); in mpc_dma_device_terminate_all()
900 struct device_node *dn = op->dev.of_node; in mpc_dma_probe()
901 struct device *dev = &op->dev; in mpc_dma_probe()
912 retval = -ENOMEM; in mpc_dma_probe()
916 mdma->irq = irq_of_parse_and_map(dn, 0); in mpc_dma_probe()
917 if (!mdma->irq) { in mpc_dma_probe()
919 retval = -EINVAL; in mpc_dma_probe()
923 if (of_device_is_compatible(dn, "fsl,mpc8308-dma")) { in mpc_dma_probe()
924 mdma->is_mpc8308 = 1; in mpc_dma_probe()
925 mdma->irq2 = irq_of_parse_and_map(dn, 1); in mpc_dma_probe()
926 if (!mdma->irq2) { in mpc_dma_probe()
928 retval = -EINVAL; in mpc_dma_probe()
944 retval = -EBUSY; in mpc_dma_probe()
948 mdma->regs = devm_ioremap(dev, regs_start, regs_size); in mpc_dma_probe()
949 if (!mdma->regs) { in mpc_dma_probe()
951 retval = -ENOMEM; in mpc_dma_probe()
955 mdma->tcd = (struct mpc_dma_tcd *)((u8 *)(mdma->regs) in mpc_dma_probe()
958 retval = request_irq(mdma->irq, &mpc_dma_irq, 0, DRV_NAME, mdma); in mpc_dma_probe()
961 retval = -EINVAL; in mpc_dma_probe()
965 if (mdma->is_mpc8308) { in mpc_dma_probe()
966 retval = request_irq(mdma->irq2, &mpc_dma_irq, 0, in mpc_dma_probe()
970 retval = -EINVAL; in mpc_dma_probe()
975 spin_lock_init(&mdma->error_status_lock); in mpc_dma_probe()
977 dma = &mdma->dma; in mpc_dma_probe()
978 dma->dev = dev; in mpc_dma_probe()
979 dma->device_alloc_chan_resources = mpc_dma_alloc_chan_resources; in mpc_dma_probe()
980 dma->device_free_chan_resources = mpc_dma_free_chan_resources; in mpc_dma_probe()
981 dma->device_issue_pending = mpc_dma_issue_pending; in mpc_dma_probe()
982 dma->device_tx_status = mpc_dma_tx_status; in mpc_dma_probe()
983 dma->device_prep_dma_memcpy = mpc_dma_prep_memcpy; in mpc_dma_probe()
984 dma->device_prep_slave_sg = mpc_dma_prep_slave_sg; in mpc_dma_probe()
985 dma->device_config = mpc_dma_device_config; in mpc_dma_probe()
986 dma->device_terminate_all = mpc_dma_device_terminate_all; in mpc_dma_probe()
988 INIT_LIST_HEAD(&dma->channels); in mpc_dma_probe()
989 dma_cap_set(DMA_MEMCPY, dma->cap_mask); in mpc_dma_probe()
990 dma_cap_set(DMA_SLAVE, dma->cap_mask); in mpc_dma_probe()
992 if (mdma->is_mpc8308) in mpc_dma_probe()
998 mchan = &mdma->channels[i]; in mpc_dma_probe()
1000 mchan->chan.device = dma; in mpc_dma_probe()
1001 dma_cookie_init(&mchan->chan); in mpc_dma_probe()
1003 INIT_LIST_HEAD(&mchan->free); in mpc_dma_probe()
1004 INIT_LIST_HEAD(&mchan->prepared); in mpc_dma_probe()
1005 INIT_LIST_HEAD(&mchan->queued); in mpc_dma_probe()
1006 INIT_LIST_HEAD(&mchan->active); in mpc_dma_probe()
1007 INIT_LIST_HEAD(&mchan->completed); in mpc_dma_probe()
1009 spin_lock_init(&mchan->lock); in mpc_dma_probe()
1010 list_add_tail(&mchan->chan.device_node, &dma->channels); in mpc_dma_probe()
1013 tasklet_setup(&mdma->tasklet, mpc_dma_tasklet); in mpc_dma_probe()
1017 * - Dynamic clock, in mpc_dma_probe()
1018 * - Round-robin group arbitration, in mpc_dma_probe()
1019 * - Round-robin channel arbitration. in mpc_dma_probe()
1021 if (mdma->is_mpc8308) { in mpc_dma_probe()
1023 out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_ERCA); in mpc_dma_probe()
1025 /* enable snooping */ in mpc_dma_probe()
1026 out_be32(&mdma->regs->dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE); in mpc_dma_probe()
1028 out_be32(&mdma->regs->dmaeeil, 0); in mpc_dma_probe()
1031 out_be32(&mdma->regs->dmaintl, 0xFFFF); in mpc_dma_probe()
1032 out_be32(&mdma->regs->dmaerrl, 0xFFFF); in mpc_dma_probe()
1034 out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_EDCG | in mpc_dma_probe()
1039 out_be32(&mdma->regs->dmaerqh, 0); in mpc_dma_probe()
1040 out_be32(&mdma->regs->dmaerql, 0); in mpc_dma_probe()
1043 out_be32(&mdma->regs->dmaeeih, 0); in mpc_dma_probe()
1044 out_be32(&mdma->regs->dmaeeil, 0); in mpc_dma_probe()
1047 out_be32(&mdma->regs->dmainth, 0xFFFFFFFF); in mpc_dma_probe()
1048 out_be32(&mdma->regs->dmaintl, 0xFFFFFFFF); in mpc_dma_probe()
1049 out_be32(&mdma->regs->dmaerrh, 0xFFFFFFFF); in mpc_dma_probe()
1050 out_be32(&mdma->regs->dmaerrl, 0xFFFFFFFF); in mpc_dma_probe()
1053 out_be32(&mdma->regs->dmaihsa, 0); in mpc_dma_probe()
1054 out_be32(&mdma->regs->dmailsa, 0); in mpc_dma_probe()
1064 if (dev->of_node) { in mpc_dma_probe()
1065 retval = of_dma_controller_register(dev->of_node, in mpc_dma_probe()
1074 if (mdma->is_mpc8308) in mpc_dma_probe()
1075 free_irq(mdma->irq2, mdma); in mpc_dma_probe()
1077 free_irq(mdma->irq, mdma); in mpc_dma_probe()
1079 if (mdma->is_mpc8308) in mpc_dma_probe()
1080 irq_dispose_mapping(mdma->irq2); in mpc_dma_probe()
1082 irq_dispose_mapping(mdma->irq); in mpc_dma_probe()
1089 struct device *dev = &op->dev; in mpc_dma_remove()
1092 if (dev->of_node) in mpc_dma_remove()
1093 of_dma_controller_free(dev->of_node); in mpc_dma_remove()
1094 dma_async_device_unregister(&mdma->dma); in mpc_dma_remove()
1095 if (mdma->is_mpc8308) { in mpc_dma_remove()
1096 free_irq(mdma->irq2, mdma); in mpc_dma_remove()
1097 irq_dispose_mapping(mdma->irq2); in mpc_dma_remove()
1099 free_irq(mdma->irq, mdma); in mpc_dma_remove()
1100 irq_dispose_mapping(mdma->irq); in mpc_dma_remove()
1101 tasklet_kill(&mdma->tasklet); in mpc_dma_remove()
1107 { .compatible = "fsl,mpc5121-dma", },
1108 { .compatible = "fsl,mpc8308-dma", },