Lines Matching +full:common +full:- +full:mode +full:- +full:channel
1 // SPDX-License-Identifier: GPL-2.0-or-later
9 #include <linux/dma-mapping.h>
19 #include <linux/io-64-nonatomic-lo-hi.h>
25 #define ZYNQMP_DMA_ISR (chan->irq_offset + 0x100)
26 #define ZYNQMP_DMA_IMR (chan->irq_offset + 0x104)
27 #define ZYNQMP_DMA_IER (chan->irq_offset + 0x108)
28 #define ZYNQMP_DMA_IDS (chan->irq_offset + 0x10c)
118 /* Max number of descriptors per channel */
141 #define ZYNQMP_DMA_DESC_SIZE(chan) (chan->desc_size)
144 common)
152 * struct zynqmp_dma_desc_ll - Hw linked list descriptor
168 * struct zynqmp_dma_desc_sw - Per Transaction structure
169 * @src: Source address for simple mode dma
170 * @dst: Destination address for simple mode dma
171 * @len: Transfer length for simple mode dma
172 * @node: Node in the channel descriptor list
194 * struct zynqmp_dma_chan - Driver specific DMA channel structure
203 * @common: DMA common channel
208 * @irq: Channel IRQ
211 * @idle : Channel status;
213 * @err: Channel has errors
228 struct dma_chan common; member
246 * struct zynqmp_dma_device - DMA device structure
248 * @common: DMA device structure
249 * @chan: Driver specific DMA channel
255 struct dma_device common; member
272 lo_hi_writeq(value, chan->regs + reg); in zynqmp_dma_writeq()
276 * zynqmp_dma_update_desc_to_ctrlr - Updates descriptor to the controller
277 * @chan: ZynqMP DMA DMA channel pointer
285 addr = desc->src_p; in zynqmp_dma_update_desc_to_ctrlr()
287 addr = desc->dst_p; in zynqmp_dma_update_desc_to_ctrlr()
292 * zynqmp_dma_desc_config_eod - Mark the descriptor as end descriptor
293 * @chan: ZynqMP DMA channel pointer
301 hw->ctrl |= ZYNQMP_DMA_DESC_CTRL_STOP; in zynqmp_dma_desc_config_eod()
303 hw->ctrl |= ZYNQMP_DMA_DESC_CTRL_COMP_INT | ZYNQMP_DMA_DESC_CTRL_STOP; in zynqmp_dma_desc_config_eod()
307 * zynqmp_dma_config_sg_ll_desc - Configure the linked list descriptor
308 * @chan: ZynqMP DMA channel pointer
322 sdesc->size = ddesc->size = len; in zynqmp_dma_config_sg_ll_desc()
323 sdesc->addr = src; in zynqmp_dma_config_sg_ll_desc()
324 ddesc->addr = dst; in zynqmp_dma_config_sg_ll_desc()
326 sdesc->ctrl = ddesc->ctrl = ZYNQMP_DMA_DESC_CTRL_SIZE_256; in zynqmp_dma_config_sg_ll_desc()
327 if (chan->is_dmacoherent) { in zynqmp_dma_config_sg_ll_desc()
328 sdesc->ctrl |= ZYNQMP_DMA_DESC_CTRL_COHRNT; in zynqmp_dma_config_sg_ll_desc()
329 ddesc->ctrl |= ZYNQMP_DMA_DESC_CTRL_COHRNT; in zynqmp_dma_config_sg_ll_desc()
333 dma_addr_t addr = chan->desc_pool_p + in zynqmp_dma_config_sg_ll_desc()
334 ((uintptr_t)sdesc - (uintptr_t)chan->desc_pool_v); in zynqmp_dma_config_sg_ll_desc()
336 prev->nxtdscraddr = addr; in zynqmp_dma_config_sg_ll_desc()
337 ddesc->nxtdscraddr = addr + ZYNQMP_DMA_DESC_SIZE(chan); in zynqmp_dma_config_sg_ll_desc()
342 * zynqmp_dma_init - Initialize the channel
343 * @chan: ZynqMP DMA channel pointer
349 writel(ZYNQMP_DMA_IDS_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IDS); in zynqmp_dma_init()
350 val = readl(chan->regs + ZYNQMP_DMA_ISR); in zynqmp_dma_init()
351 writel(val, chan->regs + ZYNQMP_DMA_ISR); in zynqmp_dma_init()
353 if (chan->is_dmacoherent) { in zynqmp_dma_init()
357 writel(val, chan->regs + ZYNQMP_DMA_DSCR_ATTR); in zynqmp_dma_init()
360 val = readl(chan->regs + ZYNQMP_DMA_DATA_ATTR); in zynqmp_dma_init()
361 if (chan->is_dmacoherent) { in zynqmp_dma_init()
367 writel(val, chan->regs + ZYNQMP_DMA_DATA_ATTR); in zynqmp_dma_init()
370 val = readl(chan->regs + ZYNQMP_DMA_IRQ_SRC_ACCT); in zynqmp_dma_init()
371 val = readl(chan->regs + ZYNQMP_DMA_IRQ_DST_ACCT); in zynqmp_dma_init()
373 chan->idle = true; in zynqmp_dma_init()
377 * zynqmp_dma_tx_submit - Submit DMA transaction
384 struct zynqmp_dma_chan *chan = to_chan(tx->chan); in zynqmp_dma_tx_submit()
390 spin_lock_irqsave(&chan->lock, irqflags); in zynqmp_dma_tx_submit()
393 if (!list_empty(&chan->pending_list)) { in zynqmp_dma_tx_submit()
394 desc = list_last_entry(&chan->pending_list, in zynqmp_dma_tx_submit()
396 if (!list_empty(&desc->tx_list)) in zynqmp_dma_tx_submit()
397 desc = list_last_entry(&desc->tx_list, in zynqmp_dma_tx_submit()
399 desc->src_v->nxtdscraddr = new->src_p; in zynqmp_dma_tx_submit()
400 desc->src_v->ctrl &= ~ZYNQMP_DMA_DESC_CTRL_STOP; in zynqmp_dma_tx_submit()
401 desc->dst_v->nxtdscraddr = new->dst_p; in zynqmp_dma_tx_submit()
402 desc->dst_v->ctrl &= ~ZYNQMP_DMA_DESC_CTRL_STOP; in zynqmp_dma_tx_submit()
405 list_add_tail(&new->node, &chan->pending_list); in zynqmp_dma_tx_submit()
406 spin_unlock_irqrestore(&chan->lock, irqflags); in zynqmp_dma_tx_submit()
412 * zynqmp_dma_get_descriptor - Get the sw descriptor from the pool
413 * @chan: ZynqMP DMA channel pointer
423 spin_lock_irqsave(&chan->lock, irqflags); in zynqmp_dma_get_descriptor()
424 desc = list_first_entry(&chan->free_list, in zynqmp_dma_get_descriptor()
426 list_del(&desc->node); in zynqmp_dma_get_descriptor()
427 spin_unlock_irqrestore(&chan->lock, irqflags); in zynqmp_dma_get_descriptor()
429 INIT_LIST_HEAD(&desc->tx_list); in zynqmp_dma_get_descriptor()
431 memset((void *)desc->src_v, 0, ZYNQMP_DMA_DESC_SIZE(chan)); in zynqmp_dma_get_descriptor()
432 memset((void *)desc->dst_v, 0, ZYNQMP_DMA_DESC_SIZE(chan)); in zynqmp_dma_get_descriptor()
438 * zynqmp_dma_free_descriptor - Issue pending transactions
439 * @chan: ZynqMP DMA channel pointer
447 chan->desc_free_cnt++; in zynqmp_dma_free_descriptor()
448 list_move_tail(&sdesc->node, &chan->free_list); in zynqmp_dma_free_descriptor()
449 list_for_each_entry_safe(child, next, &sdesc->tx_list, node) { in zynqmp_dma_free_descriptor()
450 chan->desc_free_cnt++; in zynqmp_dma_free_descriptor()
451 list_move_tail(&child->node, &chan->free_list); in zynqmp_dma_free_descriptor()
456 * zynqmp_dma_free_desc_list - Free descriptors list
457 * @chan: ZynqMP DMA channel pointer
470 * zynqmp_dma_alloc_chan_resources - Allocate channel resources
471 * @dchan: DMA channel
481 ret = pm_runtime_resume_and_get(chan->dev); in zynqmp_dma_alloc_chan_resources()
485 chan->sw_desc_pool = kcalloc(ZYNQMP_DMA_NUM_DESCS, sizeof(*desc), in zynqmp_dma_alloc_chan_resources()
487 if (!chan->sw_desc_pool) in zynqmp_dma_alloc_chan_resources()
488 return -ENOMEM; in zynqmp_dma_alloc_chan_resources()
490 chan->idle = true; in zynqmp_dma_alloc_chan_resources()
491 chan->desc_free_cnt = ZYNQMP_DMA_NUM_DESCS; in zynqmp_dma_alloc_chan_resources()
493 INIT_LIST_HEAD(&chan->free_list); in zynqmp_dma_alloc_chan_resources()
496 desc = chan->sw_desc_pool + i; in zynqmp_dma_alloc_chan_resources()
497 dma_async_tx_descriptor_init(&desc->async_tx, &chan->common); in zynqmp_dma_alloc_chan_resources()
498 desc->async_tx.tx_submit = zynqmp_dma_tx_submit; in zynqmp_dma_alloc_chan_resources()
499 list_add_tail(&desc->node, &chan->free_list); in zynqmp_dma_alloc_chan_resources()
502 chan->desc_pool_v = dma_alloc_coherent(chan->dev, in zynqmp_dma_alloc_chan_resources()
505 &chan->desc_pool_p, GFP_KERNEL); in zynqmp_dma_alloc_chan_resources()
506 if (!chan->desc_pool_v) in zynqmp_dma_alloc_chan_resources()
507 return -ENOMEM; in zynqmp_dma_alloc_chan_resources()
510 desc = chan->sw_desc_pool + i; in zynqmp_dma_alloc_chan_resources()
511 desc->src_v = (struct zynqmp_dma_desc_ll *) (chan->desc_pool_v + in zynqmp_dma_alloc_chan_resources()
513 desc->dst_v = (struct zynqmp_dma_desc_ll *) (desc->src_v + 1); in zynqmp_dma_alloc_chan_resources()
514 desc->src_p = chan->desc_pool_p + in zynqmp_dma_alloc_chan_resources()
516 desc->dst_p = desc->src_p + ZYNQMP_DMA_DESC_SIZE(chan); in zynqmp_dma_alloc_chan_resources()
523 * zynqmp_dma_start - Start DMA channel
524 * @chan: ZynqMP DMA channel pointer
528 writel(ZYNQMP_DMA_INT_EN_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IER); in zynqmp_dma_start()
529 writel(0, chan->regs + ZYNQMP_DMA_TOTAL_BYTE); in zynqmp_dma_start()
530 chan->idle = false; in zynqmp_dma_start()
531 writel(ZYNQMP_DMA_ENABLE, chan->regs + ZYNQMP_DMA_CTRL2); in zynqmp_dma_start()
535 * zynqmp_dma_handle_ovfl_int - Process the overflow interrupt
536 * @chan: ZynqMP DMA channel pointer
542 writel(0, chan->regs + ZYNQMP_DMA_TOTAL_BYTE); in zynqmp_dma_handle_ovfl_int()
544 readl(chan->regs + ZYNQMP_DMA_IRQ_DST_ACCT); in zynqmp_dma_handle_ovfl_int()
546 readl(chan->regs + ZYNQMP_DMA_IRQ_SRC_ACCT); in zynqmp_dma_handle_ovfl_int()
553 val = readl(chan->regs + ZYNQMP_DMA_CTRL0); in zynqmp_dma_config()
555 writel(val, chan->regs + ZYNQMP_DMA_CTRL0); in zynqmp_dma_config()
557 val = readl(chan->regs + ZYNQMP_DMA_DATA_ATTR); in zynqmp_dma_config()
558 burst_val = __ilog2_u32(chan->src_burst_len); in zynqmp_dma_config()
561 burst_val = __ilog2_u32(chan->dst_burst_len); in zynqmp_dma_config()
564 writel(val, chan->regs + ZYNQMP_DMA_DATA_ATTR); in zynqmp_dma_config()
568 * zynqmp_dma_device_config - Zynqmp dma device configuration
569 * @dchan: DMA channel
579 chan->src_burst_len = clamp(config->src_maxburst, 1U, in zynqmp_dma_device_config()
581 chan->dst_burst_len = clamp(config->dst_maxburst, 1U, in zynqmp_dma_device_config()
588 * zynqmp_dma_start_transfer - Initiate the new transfer
589 * @chan: ZynqMP DMA channel pointer
595 if (!chan->idle) in zynqmp_dma_start_transfer()
600 desc = list_first_entry_or_null(&chan->pending_list, in zynqmp_dma_start_transfer()
605 list_splice_tail_init(&chan->pending_list, &chan->active_list); in zynqmp_dma_start_transfer()
612 * zynqmp_dma_chan_desc_cleanup - Cleanup the completed descriptors
613 * @chan: ZynqMP DMA channel
620 spin_lock_irqsave(&chan->lock, irqflags); in zynqmp_dma_chan_desc_cleanup()
622 list_for_each_entry_safe(desc, next, &chan->done_list, node) { in zynqmp_dma_chan_desc_cleanup()
625 dmaengine_desc_get_callback(&desc->async_tx, &cb); in zynqmp_dma_chan_desc_cleanup()
627 spin_unlock_irqrestore(&chan->lock, irqflags); in zynqmp_dma_chan_desc_cleanup()
629 spin_lock_irqsave(&chan->lock, irqflags); in zynqmp_dma_chan_desc_cleanup()
636 spin_unlock_irqrestore(&chan->lock, irqflags); in zynqmp_dma_chan_desc_cleanup()
640 * zynqmp_dma_complete_descriptor - Mark the active descriptor as complete
641 * @chan: ZynqMP DMA channel pointer
647 desc = list_first_entry_or_null(&chan->active_list, in zynqmp_dma_complete_descriptor()
651 list_del(&desc->node); in zynqmp_dma_complete_descriptor()
652 dma_cookie_complete(&desc->async_tx); in zynqmp_dma_complete_descriptor()
653 list_add_tail(&desc->node, &chan->done_list); in zynqmp_dma_complete_descriptor()
657 * zynqmp_dma_issue_pending - Issue pending transactions
658 * @dchan: DMA channel pointer
665 spin_lock_irqsave(&chan->lock, irqflags); in zynqmp_dma_issue_pending()
667 spin_unlock_irqrestore(&chan->lock, irqflags); in zynqmp_dma_issue_pending()
671 * zynqmp_dma_free_descriptors - Free channel descriptors
672 * @chan: ZynqMP DMA channel pointer
678 spin_lock_irqsave(&chan->lock, irqflags); in zynqmp_dma_free_descriptors()
679 zynqmp_dma_free_desc_list(chan, &chan->active_list); in zynqmp_dma_free_descriptors()
680 zynqmp_dma_free_desc_list(chan, &chan->pending_list); in zynqmp_dma_free_descriptors()
681 zynqmp_dma_free_desc_list(chan, &chan->done_list); in zynqmp_dma_free_descriptors()
682 spin_unlock_irqrestore(&chan->lock, irqflags); in zynqmp_dma_free_descriptors()
686 * zynqmp_dma_free_chan_resources - Free channel resources
687 * @dchan: DMA channel pointer
694 dma_free_coherent(chan->dev, in zynqmp_dma_free_chan_resources()
696 chan->desc_pool_v, chan->desc_pool_p); in zynqmp_dma_free_chan_resources()
697 kfree(chan->sw_desc_pool); in zynqmp_dma_free_chan_resources()
698 pm_runtime_mark_last_busy(chan->dev); in zynqmp_dma_free_chan_resources()
699 pm_runtime_put_autosuspend(chan->dev); in zynqmp_dma_free_chan_resources()
703 * zynqmp_dma_reset - Reset the channel
704 * @chan: ZynqMP DMA channel pointer
710 writel(ZYNQMP_DMA_IDS_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IDS); in zynqmp_dma_reset()
712 spin_lock_irqsave(&chan->lock, irqflags); in zynqmp_dma_reset()
714 spin_unlock_irqrestore(&chan->lock, irqflags); in zynqmp_dma_reset()
722 * zynqmp_dma_irq_handler - ZynqMP DMA Interrupt handler
724 * @data: Pointer to the ZynqMP DMA channel structure
734 isr = readl(chan->regs + ZYNQMP_DMA_ISR); in zynqmp_dma_irq_handler()
735 imr = readl(chan->regs + ZYNQMP_DMA_IMR); in zynqmp_dma_irq_handler()
738 writel(isr, chan->regs + ZYNQMP_DMA_ISR); in zynqmp_dma_irq_handler()
740 tasklet_schedule(&chan->tasklet); in zynqmp_dma_irq_handler()
745 chan->idle = true; in zynqmp_dma_irq_handler()
748 chan->err = true; in zynqmp_dma_irq_handler()
749 tasklet_schedule(&chan->tasklet); in zynqmp_dma_irq_handler()
750 dev_err(chan->dev, "Channel %p has errors\n", chan); in zynqmp_dma_irq_handler()
756 dev_dbg(chan->dev, "Channel %p overflow interrupt\n", chan); in zynqmp_dma_irq_handler()
764 * zynqmp_dma_do_tasklet - Schedule completion tasklet
765 * @t: Pointer to the ZynqMP DMA channel structure
773 if (chan->err) { in zynqmp_dma_do_tasklet()
775 chan->err = false; in zynqmp_dma_do_tasklet()
779 spin_lock_irqsave(&chan->lock, irqflags); in zynqmp_dma_do_tasklet()
780 count = readl(chan->regs + ZYNQMP_DMA_IRQ_DST_ACCT); in zynqmp_dma_do_tasklet()
783 count--; in zynqmp_dma_do_tasklet()
785 spin_unlock_irqrestore(&chan->lock, irqflags); in zynqmp_dma_do_tasklet()
789 if (chan->idle) { in zynqmp_dma_do_tasklet()
790 spin_lock_irqsave(&chan->lock, irqflags); in zynqmp_dma_do_tasklet()
792 spin_unlock_irqrestore(&chan->lock, irqflags); in zynqmp_dma_do_tasklet()
797 * zynqmp_dma_device_terminate_all - Aborts all transfers on a channel
798 * @dchan: DMA channel pointer
806 writel(ZYNQMP_DMA_IDS_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IDS); in zynqmp_dma_device_terminate_all()
813 * zynqmp_dma_synchronize - Synchronizes the termination of a transfers to the current context.
814 * @dchan: DMA channel pointer
820 tasklet_kill(&chan->tasklet); in zynqmp_dma_synchronize()
824 * zynqmp_dma_prep_memcpy - prepare descriptors for memcpy transaction
825 * @dchan: DMA channel
848 spin_lock_irqsave(&chan->lock, irqflags); in zynqmp_dma_prep_memcpy()
849 if (desc_cnt > chan->desc_free_cnt) { in zynqmp_dma_prep_memcpy()
850 spin_unlock_irqrestore(&chan->lock, irqflags); in zynqmp_dma_prep_memcpy()
851 dev_dbg(chan->dev, "chan %p descs are not available\n", chan); in zynqmp_dma_prep_memcpy()
854 chan->desc_free_cnt = chan->desc_free_cnt - desc_cnt; in zynqmp_dma_prep_memcpy()
855 spin_unlock_irqrestore(&chan->lock, irqflags); in zynqmp_dma_prep_memcpy()
862 desc = (struct zynqmp_dma_desc_ll *)new->src_v; in zynqmp_dma_prep_memcpy()
866 len -= copy; in zynqmp_dma_prep_memcpy()
872 list_add_tail(&new->node, &first->tx_list); in zynqmp_dma_prep_memcpy()
876 async_tx_ack(&first->async_tx); in zynqmp_dma_prep_memcpy()
877 first->async_tx.flags = (enum dma_ctrl_flags)flags; in zynqmp_dma_prep_memcpy()
878 return &first->async_tx; in zynqmp_dma_prep_memcpy()
882 * zynqmp_dma_chan_remove - Channel remove function
883 * @chan: ZynqMP DMA channel pointer
890 if (chan->irq) in zynqmp_dma_chan_remove()
891 devm_free_irq(chan->zdev->dev, chan->irq, chan); in zynqmp_dma_chan_remove()
892 tasklet_kill(&chan->tasklet); in zynqmp_dma_chan_remove()
893 list_del(&chan->common.device_node); in zynqmp_dma_chan_remove()
897 * zynqmp_dma_chan_probe - Per Channel Probing
907 struct device_node *node = pdev->dev.of_node; in zynqmp_dma_chan_probe()
911 chan = devm_kzalloc(zdev->dev, sizeof(*chan), GFP_KERNEL); in zynqmp_dma_chan_probe()
913 return -ENOMEM; in zynqmp_dma_chan_probe()
914 chan->dev = zdev->dev; in zynqmp_dma_chan_probe()
915 chan->zdev = zdev; in zynqmp_dma_chan_probe()
917 chan->regs = devm_platform_ioremap_resource(pdev, 0); in zynqmp_dma_chan_probe()
918 if (IS_ERR(chan->regs)) in zynqmp_dma_chan_probe()
919 return PTR_ERR(chan->regs); in zynqmp_dma_chan_probe()
921 chan->bus_width = ZYNQMP_DMA_BUS_WIDTH_64; in zynqmp_dma_chan_probe()
922 chan->dst_burst_len = ZYNQMP_DMA_MAX_DST_BURST_LEN; in zynqmp_dma_chan_probe()
923 chan->src_burst_len = ZYNQMP_DMA_MAX_SRC_BURST_LEN; in zynqmp_dma_chan_probe()
924 err = of_property_read_u32(node, "xlnx,bus-width", &chan->bus_width); in zynqmp_dma_chan_probe()
926 dev_err(&pdev->dev, "missing xlnx,bus-width property\n"); in zynqmp_dma_chan_probe()
930 if (chan->bus_width != ZYNQMP_DMA_BUS_WIDTH_64 && in zynqmp_dma_chan_probe()
931 chan->bus_width != ZYNQMP_DMA_BUS_WIDTH_128) { in zynqmp_dma_chan_probe()
932 dev_err(zdev->dev, "invalid bus-width value"); in zynqmp_dma_chan_probe()
933 return -EINVAL; in zynqmp_dma_chan_probe()
936 match_data = of_device_get_match_data(&pdev->dev); in zynqmp_dma_chan_probe()
938 chan->irq_offset = match_data->offset; in zynqmp_dma_chan_probe()
940 chan->is_dmacoherent = of_property_read_bool(node, "dma-coherent"); in zynqmp_dma_chan_probe()
941 zdev->chan = chan; in zynqmp_dma_chan_probe()
942 tasklet_setup(&chan->tasklet, zynqmp_dma_do_tasklet); in zynqmp_dma_chan_probe()
943 spin_lock_init(&chan->lock); in zynqmp_dma_chan_probe()
944 INIT_LIST_HEAD(&chan->active_list); in zynqmp_dma_chan_probe()
945 INIT_LIST_HEAD(&chan->pending_list); in zynqmp_dma_chan_probe()
946 INIT_LIST_HEAD(&chan->done_list); in zynqmp_dma_chan_probe()
947 INIT_LIST_HEAD(&chan->free_list); in zynqmp_dma_chan_probe()
949 dma_cookie_init(&chan->common); in zynqmp_dma_chan_probe()
950 chan->common.device = &zdev->common; in zynqmp_dma_chan_probe()
951 list_add_tail(&chan->common.device_node, &zdev->common.channels); in zynqmp_dma_chan_probe()
954 chan->irq = platform_get_irq(pdev, 0); in zynqmp_dma_chan_probe()
955 if (chan->irq < 0) in zynqmp_dma_chan_probe()
956 return -ENXIO; in zynqmp_dma_chan_probe()
957 err = devm_request_irq(&pdev->dev, chan->irq, zynqmp_dma_irq_handler, 0, in zynqmp_dma_chan_probe()
958 "zynqmp-dma", chan); in zynqmp_dma_chan_probe()
962 chan->desc_size = sizeof(struct zynqmp_dma_desc_ll); in zynqmp_dma_chan_probe()
963 chan->idle = true; in zynqmp_dma_chan_probe()
968 * of_zynqmp_dma_xlate - Translation function
972 * Return: DMA channel pointer on success and NULL on error
977 struct zynqmp_dma_device *zdev = ofdma->of_dma_data; in of_zynqmp_dma_xlate()
979 return dma_get_slave_channel(&zdev->chan->common); in of_zynqmp_dma_xlate()
983 * zynqmp_dma_suspend - Suspend method for the driver
986 * Put the driver into low power mode.
998 * zynqmp_dma_resume - Resume from suspend
1013 * zynqmp_dma_runtime_suspend - Runtime suspend method for the driver
1016 * Put the driver into low power mode.
1023 clk_disable_unprepare(zdev->clk_main); in zynqmp_dma_runtime_suspend()
1024 clk_disable_unprepare(zdev->clk_apb); in zynqmp_dma_runtime_suspend()
1030 * zynqmp_dma_runtime_resume - Runtime suspend method for the driver
1033 * Put the driver into low power mode.
1041 err = clk_prepare_enable(zdev->clk_main); in zynqmp_dma_runtime_resume()
1047 err = clk_prepare_enable(zdev->clk_apb); in zynqmp_dma_runtime_resume()
1050 clk_disable_unprepare(zdev->clk_main); in zynqmp_dma_runtime_resume()
1064 * zynqmp_dma_probe - Driver probe function
1075 zdev = devm_kzalloc(&pdev->dev, sizeof(*zdev), GFP_KERNEL); in zynqmp_dma_probe()
1077 return -ENOMEM; in zynqmp_dma_probe()
1079 zdev->dev = &pdev->dev; in zynqmp_dma_probe()
1080 INIT_LIST_HEAD(&zdev->common.channels); in zynqmp_dma_probe()
1082 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44)); in zynqmp_dma_probe()
1084 dev_err(&pdev->dev, "DMA not available for address range\n"); in zynqmp_dma_probe()
1087 dma_cap_set(DMA_MEMCPY, zdev->common.cap_mask); in zynqmp_dma_probe()
1089 p = &zdev->common; in zynqmp_dma_probe()
1090 p->device_prep_dma_memcpy = zynqmp_dma_prep_memcpy; in zynqmp_dma_probe()
1091 p->device_terminate_all = zynqmp_dma_device_terminate_all; in zynqmp_dma_probe()
1092 p->device_synchronize = zynqmp_dma_synchronize; in zynqmp_dma_probe()
1093 p->device_issue_pending = zynqmp_dma_issue_pending; in zynqmp_dma_probe()
1094 p->device_alloc_chan_resources = zynqmp_dma_alloc_chan_resources; in zynqmp_dma_probe()
1095 p->device_free_chan_resources = zynqmp_dma_free_chan_resources; in zynqmp_dma_probe()
1096 p->device_tx_status = dma_cookie_status; in zynqmp_dma_probe()
1097 p->device_config = zynqmp_dma_device_config; in zynqmp_dma_probe()
1098 p->dev = &pdev->dev; in zynqmp_dma_probe()
1100 zdev->clk_main = devm_clk_get(&pdev->dev, "clk_main"); in zynqmp_dma_probe()
1101 if (IS_ERR(zdev->clk_main)) in zynqmp_dma_probe()
1102 return dev_err_probe(&pdev->dev, PTR_ERR(zdev->clk_main), in zynqmp_dma_probe()
1105 zdev->clk_apb = devm_clk_get(&pdev->dev, "clk_apb"); in zynqmp_dma_probe()
1106 if (IS_ERR(zdev->clk_apb)) in zynqmp_dma_probe()
1107 return dev_err_probe(&pdev->dev, PTR_ERR(zdev->clk_apb), in zynqmp_dma_probe()
1111 pm_runtime_set_autosuspend_delay(zdev->dev, ZDMA_PM_TIMEOUT); in zynqmp_dma_probe()
1112 pm_runtime_use_autosuspend(zdev->dev); in zynqmp_dma_probe()
1113 pm_runtime_enable(zdev->dev); in zynqmp_dma_probe()
1114 ret = pm_runtime_resume_and_get(zdev->dev); in zynqmp_dma_probe()
1116 dev_err(&pdev->dev, "device wakeup failed.\n"); in zynqmp_dma_probe()
1117 pm_runtime_disable(zdev->dev); in zynqmp_dma_probe()
1119 if (!pm_runtime_enabled(zdev->dev)) { in zynqmp_dma_probe()
1120 ret = zynqmp_dma_runtime_resume(zdev->dev); in zynqmp_dma_probe()
1127 dev_err_probe(&pdev->dev, ret, "Probing channel failed\n"); in zynqmp_dma_probe()
1131 p->dst_addr_widths = BIT(zdev->chan->bus_width / 8); in zynqmp_dma_probe()
1132 p->src_addr_widths = BIT(zdev->chan->bus_width / 8); in zynqmp_dma_probe()
1134 ret = dma_async_device_register(&zdev->common); in zynqmp_dma_probe()
1136 dev_err(zdev->dev, "failed to register the dma device\n"); in zynqmp_dma_probe()
1140 ret = of_dma_controller_register(pdev->dev.of_node, in zynqmp_dma_probe()
1143 dev_err_probe(&pdev->dev, ret, "Unable to register DMA to DT\n"); in zynqmp_dma_probe()
1144 dma_async_device_unregister(&zdev->common); in zynqmp_dma_probe()
1148 pm_runtime_mark_last_busy(zdev->dev); in zynqmp_dma_probe()
1149 pm_runtime_put_sync_autosuspend(zdev->dev); in zynqmp_dma_probe()
1154 zynqmp_dma_chan_remove(zdev->chan); in zynqmp_dma_probe()
1156 if (!pm_runtime_enabled(zdev->dev)) in zynqmp_dma_probe()
1157 zynqmp_dma_runtime_suspend(zdev->dev); in zynqmp_dma_probe()
1158 pm_runtime_disable(zdev->dev); in zynqmp_dma_probe()
1163 * zynqmp_dma_remove - Driver remove function
1172 of_dma_controller_free(pdev->dev.of_node); in zynqmp_dma_remove()
1173 dma_async_device_unregister(&zdev->common); in zynqmp_dma_remove()
1175 zynqmp_dma_chan_remove(zdev->chan); in zynqmp_dma_remove()
1176 pm_runtime_disable(zdev->dev); in zynqmp_dma_remove()
1177 if (!pm_runtime_enabled(zdev->dev)) in zynqmp_dma_remove()
1178 zynqmp_dma_runtime_suspend(zdev->dev); in zynqmp_dma_remove()
1182 { .compatible = "amd,versal2-dma-1.0", .data = &versal2_dma_config },
1183 { .compatible = "xlnx,zynqmp-dma-1.0", },
1190 .name = "xilinx-zynqmp-dma",