Lines Matching +full:usb +full:- +full:dmac

1 // SPDX-License-Identifier: GPL-2.0
3 * Renesas USB DMA Controller Driver
7 * based on rcar-dmac.c
13 #include <linux/dma-mapping.h>
27 #include "../virt-dma.h"
30 * struct usb_dmac_sg - Descriptor for a hardware transfer
40 * struct usb_dmac_desc - USB DMA Transfer Descriptor
46 * @residue: residue after the DMAC completed a transfer
48 * @done_cookie: cookie after the DMAC completed a transfer
66 * struct usb_dmac_chan - USB DMA Controller Channel
74 * @desc_freed: freed descriptors after the DMAC completed a transfer
90 * struct usb_dmac - USB DMA Controller
95 * @channels: array of DMAC channels
108 /* -----------------------------------------------------------------------------
147 /* -----------------------------------------------------------------------------
151 static void usb_dmac_write(struct usb_dmac *dmac, u32 reg, u32 data) in usb_dmac_write() argument
153 writel(data, dmac->iomem + reg); in usb_dmac_write()
156 static u32 usb_dmac_read(struct usb_dmac *dmac, u32 reg) in usb_dmac_read() argument
158 return readl(dmac->iomem + reg); in usb_dmac_read()
163 return readl(chan->iomem + reg); in usb_dmac_chan_read()
168 writel(data, chan->iomem + reg); in usb_dmac_chan_write()
171 /* -----------------------------------------------------------------------------
188 return 0xffffffff << (32 - (size % USB_DMAC_XFER_SIZE ? : in usb_dmac_calc_tend()
196 struct usb_dmac_desc *desc = chan->desc; in usb_dmac_chan_start_sg()
197 struct usb_dmac_sg *sg = desc->sg + index; in usb_dmac_chan_start_sg()
202 if (desc->direction == DMA_DEV_TO_MEM) in usb_dmac_chan_start_sg()
203 dst_addr = sg->mem_addr; in usb_dmac_chan_start_sg()
205 src_addr = sg->mem_addr; in usb_dmac_chan_start_sg()
207 dev_dbg(chan->vc.chan.device->dev, in usb_dmac_chan_start_sg()
208 "chan%u: queue sg %p: %u@%pad -> %pad\n", in usb_dmac_chan_start_sg()
209 chan->index, sg, sg->size, &src_addr, &dst_addr); in usb_dmac_chan_start_sg()
214 DIV_ROUND_UP(sg->size, USB_DMAC_XFER_SIZE)); in usb_dmac_chan_start_sg()
215 usb_dmac_chan_write(chan, USB_DMATEND, usb_dmac_calc_tend(sg->size)); in usb_dmac_chan_start_sg()
226 vd = vchan_next_desc(&chan->vc); in usb_dmac_chan_start_desc()
228 chan->desc = NULL; in usb_dmac_chan_start_desc()
233 * Remove this request from vc->desc_issued. Otherwise, this driver in usb_dmac_chan_start_desc()
237 list_del(&vd->node); in usb_dmac_chan_start_desc()
239 chan->desc = to_usb_dmac_desc(vd); in usb_dmac_chan_start_desc()
240 chan->desc->sg_index = 0; in usb_dmac_chan_start_desc()
244 static int usb_dmac_init(struct usb_dmac *dmac) in usb_dmac_init() argument
248 /* Clear all channels and enable the DMAC globally. */ in usb_dmac_init()
249 usb_dmac_write(dmac, USB_DMAOR, USB_DMAOR_DME); in usb_dmac_init()
251 dmaor = usb_dmac_read(dmac, USB_DMAOR); in usb_dmac_init()
253 dev_warn(dmac->dev, "DMAOR initialization failed.\n"); in usb_dmac_init()
254 return -EIO; in usb_dmac_init()
260 /* -----------------------------------------------------------------------------
271 return -ENOMEM; in usb_dmac_desc_alloc()
273 desc->sg_allocated_len = sg_len; in usb_dmac_desc_alloc()
274 INIT_LIST_HEAD(&desc->node); in usb_dmac_desc_alloc()
276 spin_lock_irqsave(&chan->vc.lock, flags); in usb_dmac_desc_alloc()
277 list_add_tail(&desc->node, &chan->desc_freed); in usb_dmac_desc_alloc()
278 spin_unlock_irqrestore(&chan->vc.lock, flags); in usb_dmac_desc_alloc()
288 list_splice_init(&chan->desc_freed, &list); in usb_dmac_desc_free()
289 list_splice_init(&chan->desc_got, &list); in usb_dmac_desc_free()
292 list_del(&desc->node); in usb_dmac_desc_free()
295 chan->descs_allocated = 0; in usb_dmac_desc_free()
305 spin_lock_irqsave(&chan->vc.lock, flags); in usb_dmac_desc_get()
306 list_for_each_entry(desc, &chan->desc_freed, node) { in usb_dmac_desc_get()
307 if (sg_len <= desc->sg_allocated_len) { in usb_dmac_desc_get()
308 list_move_tail(&desc->node, &chan->desc_got); in usb_dmac_desc_get()
309 spin_unlock_irqrestore(&chan->vc.lock, flags); in usb_dmac_desc_get()
313 spin_unlock_irqrestore(&chan->vc.lock, flags); in usb_dmac_desc_get()
318 spin_lock_irqsave(&chan->vc.lock, flags); in usb_dmac_desc_get()
319 desc = list_last_entry(&chan->desc_freed, struct usb_dmac_desc, in usb_dmac_desc_get()
321 list_move_tail(&desc->node, &chan->desc_got); in usb_dmac_desc_get()
322 spin_unlock_irqrestore(&chan->vc.lock, flags); in usb_dmac_desc_get()
334 spin_lock_irqsave(&chan->vc.lock, flags); in usb_dmac_desc_put()
335 list_move_tail(&desc->node, &chan->desc_freed); in usb_dmac_desc_put()
336 spin_unlock_irqrestore(&chan->vc.lock, flags); in usb_dmac_desc_put()
339 /* -----------------------------------------------------------------------------
345 struct dma_chan *chan = &uchan->vc.chan; in usb_dmac_soft_reset()
346 struct usb_dmac *dmac = to_usb_dmac(chan->device); in usb_dmac_soft_reset() local
350 for (i = 0; i < dmac->n_channels; ++i) { in usb_dmac_soft_reset()
355 usb_dmac_write(dmac, USB_DMAOR, 0); in usb_dmac_soft_reset()
356 usb_dmac_write(dmac, USB_DMASWR, USB_DMASWR_SWR); in usb_dmac_soft_reset()
358 usb_dmac_write(dmac, USB_DMASWR, 0); in usb_dmac_soft_reset()
359 usb_dmac_write(dmac, USB_DMAOR, 1); in usb_dmac_soft_reset()
372 static void usb_dmac_stop(struct usb_dmac *dmac) in usb_dmac_stop() argument
374 usb_dmac_write(dmac, USB_DMAOR, 0); in usb_dmac_stop()
377 /* -----------------------------------------------------------------------------
386 while (uchan->descs_allocated < USB_DMAC_INITIAL_NR_DESC) { in usb_dmac_alloc_chan_resources()
393 uchan->descs_allocated++; in usb_dmac_alloc_chan_resources()
396 return pm_runtime_get_sync(chan->device->dev); in usb_dmac_alloc_chan_resources()
405 spin_lock_irqsave(&uchan->vc.lock, flags); in usb_dmac_free_chan_resources()
407 spin_unlock_irqrestore(&uchan->vc.lock, flags); in usb_dmac_free_chan_resources()
410 vchan_free_chan_resources(&uchan->vc); in usb_dmac_free_chan_resources()
412 pm_runtime_put(chan->device->dev); in usb_dmac_free_chan_resources()
426 dev_warn(chan->device->dev, in usb_dmac_prep_slave_sg()
435 desc->direction = dir; in usb_dmac_prep_slave_sg()
436 desc->sg_len = sg_len; in usb_dmac_prep_slave_sg()
438 desc->sg[i].mem_addr = sg_dma_address(sg); in usb_dmac_prep_slave_sg()
439 desc->sg[i].size = sg_dma_len(sg); in usb_dmac_prep_slave_sg()
442 return vchan_tx_prep(&uchan->vc, &desc->vd, dma_flags); in usb_dmac_prep_slave_sg()
453 spin_lock_irqsave(&uchan->vc.lock, flags); in usb_dmac_chan_terminate_all()
455 vchan_get_all_descriptors(&uchan->vc, &head); in usb_dmac_chan_terminate_all()
456 if (uchan->desc) in usb_dmac_chan_terminate_all()
457 uchan->desc = NULL; in usb_dmac_chan_terminate_all()
458 list_splice_init(&uchan->desc_got, &list); in usb_dmac_chan_terminate_all()
460 list_move_tail(&desc->node, &uchan->desc_freed); in usb_dmac_chan_terminate_all()
461 spin_unlock_irqrestore(&uchan->vc.lock, flags); in usb_dmac_chan_terminate_all()
462 vchan_dma_desc_free_list(&uchan->vc, &head); in usb_dmac_chan_terminate_all()
471 struct usb_dmac_sg *sg = desc->sg + sg_index; in usb_dmac_get_current_residue()
472 u32 mem_addr = sg->mem_addr & 0xffffffff; in usb_dmac_get_current_residue()
473 unsigned int residue = sg->size; in usb_dmac_get_current_residue()
479 if (desc->direction == DMA_DEV_TO_MEM) in usb_dmac_get_current_residue()
480 residue -= usb_dmac_chan_read(chan, USB_DMADAR) - mem_addr; in usb_dmac_get_current_residue()
482 residue -= usb_dmac_chan_read(chan, USB_DMASAR) - mem_addr; in usb_dmac_get_current_residue()
493 list_for_each_entry_reverse(desc, &chan->desc_freed, node) { in usb_dmac_chan_get_residue_if_complete()
494 if (desc->done_cookie == cookie) { in usb_dmac_chan_get_residue_if_complete()
495 residue = desc->residue; in usb_dmac_chan_get_residue_if_complete()
508 struct usb_dmac_desc *desc = chan->desc; in usb_dmac_chan_get_residue()
512 vd = vchan_find_desc(&chan->vc, cookie); in usb_dmac_chan_get_residue()
519 for (i = desc->sg_index + 1; i < desc->sg_len; i++) in usb_dmac_chan_get_residue()
520 residue += desc->sg[i].size; in usb_dmac_chan_get_residue()
523 residue += usb_dmac_get_current_residue(chan, desc, desc->sg_index); in usb_dmac_chan_get_residue()
542 spin_lock_irqsave(&uchan->vc.lock, flags); in usb_dmac_tx_status()
547 spin_unlock_irqrestore(&uchan->vc.lock, flags); in usb_dmac_tx_status()
559 spin_lock_irqsave(&uchan->vc.lock, flags); in usb_dmac_issue_pending()
560 if (vchan_issue_pending(&uchan->vc) && !uchan->desc) in usb_dmac_issue_pending()
562 spin_unlock_irqrestore(&uchan->vc.lock, flags); in usb_dmac_issue_pending()
568 struct usb_dmac_chan *chan = to_usb_dmac_chan(vd->tx.chan); in usb_dmac_virt_desc_free()
573 /* -----------------------------------------------------------------------------
579 struct usb_dmac_desc *desc = chan->desc; in usb_dmac_isr_transfer_end()
583 if (++desc->sg_index < desc->sg_len) { in usb_dmac_isr_transfer_end()
584 usb_dmac_chan_start_sg(chan, desc->sg_index); in usb_dmac_isr_transfer_end()
586 desc->residue = usb_dmac_get_current_residue(chan, desc, in usb_dmac_isr_transfer_end()
587 desc->sg_index - 1); in usb_dmac_isr_transfer_end()
588 desc->done_cookie = desc->vd.tx.cookie; in usb_dmac_isr_transfer_end()
589 desc->vd.tx_result.result = DMA_TRANS_NOERROR; in usb_dmac_isr_transfer_end()
590 desc->vd.tx_result.residue = desc->residue; in usb_dmac_isr_transfer_end()
591 vchan_cookie_complete(&desc->vd); in usb_dmac_isr_transfer_end()
606 spin_lock(&chan->vc.lock); in usb_dmac_isr_channel()
627 spin_unlock(&chan->vc.lock); in usb_dmac_isr_channel()
632 /* -----------------------------------------------------------------------------
641 /* USB-DMAC should be used with fixed usb controller's FIFO */ in usb_dmac_chan_filter()
642 if (uchan->index != dma_spec->args[0]) in usb_dmac_chan_filter()
654 if (dma_spec->args_count != 1) in usb_dmac_of_xlate()
662 ofdma->of_node); in usb_dmac_of_xlate()
669 /* -----------------------------------------------------------------------------
676 struct usb_dmac *dmac = dev_get_drvdata(dev); in usb_dmac_runtime_suspend() local
679 for (i = 0; i < dmac->n_channels; ++i) { in usb_dmac_runtime_suspend()
680 if (!dmac->channels[i].iomem) in usb_dmac_runtime_suspend()
682 usb_dmac_chan_halt(&dmac->channels[i]); in usb_dmac_runtime_suspend()
690 struct usb_dmac *dmac = dev_get_drvdata(dev); in usb_dmac_runtime_resume() local
692 return usb_dmac_init(dmac); in usb_dmac_runtime_resume()
703 /* -----------------------------------------------------------------------------
707 static int usb_dmac_chan_probe(struct usb_dmac *dmac, in usb_dmac_chan_probe() argument
711 struct platform_device *pdev = to_platform_device(dmac->dev); in usb_dmac_chan_probe()
716 uchan->index = index; in usb_dmac_chan_probe()
717 uchan->iomem = dmac->iomem + USB_DMAC_CHAN_OFFSET(index); in usb_dmac_chan_probe()
721 uchan->irq = platform_get_irq_byname(pdev, pdev_irqname); in usb_dmac_chan_probe()
722 if (uchan->irq < 0) in usb_dmac_chan_probe()
723 return -ENODEV; in usb_dmac_chan_probe()
725 irqname = devm_kasprintf(dmac->dev, GFP_KERNEL, "%s:%u", in usb_dmac_chan_probe()
726 dev_name(dmac->dev), index); in usb_dmac_chan_probe()
728 return -ENOMEM; in usb_dmac_chan_probe()
730 ret = devm_request_irq(dmac->dev, uchan->irq, usb_dmac_isr_channel, in usb_dmac_chan_probe()
733 dev_err(dmac->dev, "failed to request IRQ %u (%d)\n", in usb_dmac_chan_probe()
734 uchan->irq, ret); in usb_dmac_chan_probe()
738 uchan->vc.desc_free = usb_dmac_virt_desc_free; in usb_dmac_chan_probe()
739 vchan_init(&uchan->vc, &dmac->engine); in usb_dmac_chan_probe()
740 INIT_LIST_HEAD(&uchan->desc_freed); in usb_dmac_chan_probe()
741 INIT_LIST_HEAD(&uchan->desc_got); in usb_dmac_chan_probe()
746 static int usb_dmac_parse_of(struct device *dev, struct usb_dmac *dmac) in usb_dmac_parse_of() argument
748 struct device_node *np = dev->of_node; in usb_dmac_parse_of()
751 ret = of_property_read_u32(np, "dma-channels", &dmac->n_channels); in usb_dmac_parse_of()
753 dev_err(dev, "unable to read dma-channels property\n"); in usb_dmac_parse_of()
757 if (dmac->n_channels <= 0 || dmac->n_channels >= 100) { in usb_dmac_parse_of()
759 dmac->n_channels); in usb_dmac_parse_of()
760 return -EINVAL; in usb_dmac_parse_of()
770 struct usb_dmac *dmac; in usb_dmac_probe() local
774 dmac = devm_kzalloc(&pdev->dev, sizeof(*dmac), GFP_KERNEL); in usb_dmac_probe()
775 if (!dmac) in usb_dmac_probe()
776 return -ENOMEM; in usb_dmac_probe()
778 dmac->dev = &pdev->dev; in usb_dmac_probe()
779 platform_set_drvdata(pdev, dmac); in usb_dmac_probe()
781 ret = usb_dmac_parse_of(&pdev->dev, dmac); in usb_dmac_probe()
785 dmac->channels = devm_kcalloc(&pdev->dev, dmac->n_channels, in usb_dmac_probe()
786 sizeof(*dmac->channels), GFP_KERNEL); in usb_dmac_probe()
787 if (!dmac->channels) in usb_dmac_probe()
788 return -ENOMEM; in usb_dmac_probe()
791 dmac->iomem = devm_platform_ioremap_resource(pdev, 0); in usb_dmac_probe()
792 if (IS_ERR(dmac->iomem)) in usb_dmac_probe()
793 return PTR_ERR(dmac->iomem); in usb_dmac_probe()
796 pm_runtime_enable(&pdev->dev); in usb_dmac_probe()
797 ret = pm_runtime_get_sync(&pdev->dev); in usb_dmac_probe()
799 dev_err(&pdev->dev, "runtime PM get sync failed (%d)\n", ret); in usb_dmac_probe()
803 ret = usb_dmac_init(dmac); in usb_dmac_probe()
806 dev_err(&pdev->dev, "failed to reset device\n"); in usb_dmac_probe()
811 INIT_LIST_HEAD(&dmac->engine.channels); in usb_dmac_probe()
813 for (i = 0; i < dmac->n_channels; ++i) { in usb_dmac_probe()
814 ret = usb_dmac_chan_probe(dmac, &dmac->channels[i], i); in usb_dmac_probe()
819 /* Register the DMAC as a DMA provider for DT. */ in usb_dmac_probe()
820 ret = of_dma_controller_register(pdev->dev.of_node, usb_dmac_of_xlate, in usb_dmac_probe()
828 * Default transfer size of 32 bytes requires 32-byte alignment. in usb_dmac_probe()
830 engine = &dmac->engine; in usb_dmac_probe()
831 dma_cap_set(DMA_SLAVE, engine->cap_mask); in usb_dmac_probe()
833 engine->dev = &pdev->dev; in usb_dmac_probe()
835 engine->src_addr_widths = widths; in usb_dmac_probe()
836 engine->dst_addr_widths = widths; in usb_dmac_probe()
837 engine->directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM); in usb_dmac_probe()
838 engine->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; in usb_dmac_probe()
840 engine->device_alloc_chan_resources = usb_dmac_alloc_chan_resources; in usb_dmac_probe()
841 engine->device_free_chan_resources = usb_dmac_free_chan_resources; in usb_dmac_probe()
842 engine->device_prep_slave_sg = usb_dmac_prep_slave_sg; in usb_dmac_probe()
843 engine->device_terminate_all = usb_dmac_chan_terminate_all; in usb_dmac_probe()
844 engine->device_tx_status = usb_dmac_tx_status; in usb_dmac_probe()
845 engine->device_issue_pending = usb_dmac_issue_pending; in usb_dmac_probe()
851 pm_runtime_put(&pdev->dev); in usb_dmac_probe()
855 of_dma_controller_free(pdev->dev.of_node); in usb_dmac_probe()
857 pm_runtime_put(&pdev->dev); in usb_dmac_probe()
858 pm_runtime_disable(&pdev->dev); in usb_dmac_probe()
862 static void usb_dmac_chan_remove(struct usb_dmac *dmac, in usb_dmac_chan_remove() argument
866 devm_free_irq(dmac->dev, uchan->irq, uchan); in usb_dmac_chan_remove()
871 struct usb_dmac *dmac = platform_get_drvdata(pdev); in usb_dmac_remove() local
874 for (i = 0; i < dmac->n_channels; ++i) in usb_dmac_remove()
875 usb_dmac_chan_remove(dmac, &dmac->channels[i]); in usb_dmac_remove()
876 of_dma_controller_free(pdev->dev.of_node); in usb_dmac_remove()
877 dma_async_device_unregister(&dmac->engine); in usb_dmac_remove()
879 pm_runtime_disable(&pdev->dev); in usb_dmac_remove()
884 struct usb_dmac *dmac = platform_get_drvdata(pdev); in usb_dmac_shutdown() local
886 usb_dmac_stop(dmac); in usb_dmac_shutdown()
890 { .compatible = "renesas,usb-dmac", },
898 .name = "usb-dmac",
908 MODULE_DESCRIPTION("Renesas USB DMA Controller Driver");