Lines Matching +full:ahb +full:- +full:burst +full:- +full:config
1 // SPDX-License-Identifier: GPL-2.0-only
6 * Pierre-Yves Mordret <pierre-yves.mordret@st.com>
10 * Inspired by stm32-dma.c and dma-jz4780.c
17 #include <linux/dma-mapping.h>
33 #include "virt-dma.h"
265 return container_of(chan->vchan.chan.device, struct stm32_mdma_device, in stm32_mdma_get_dev()
281 return &chan->vchan.chan.dev->device; in chan2dev()
286 return mdma_dev->ddev.dev; in mdma2dev()
291 return readl_relaxed(dmadev->base + reg); in stm32_mdma_read()
296 writel_relaxed(val, dmadev->base + reg); in stm32_mdma_write()
302 void __iomem *addr = dmadev->base + reg; in stm32_mdma_set_bits()
310 void __iomem *addr = dmadev->base + reg; in stm32_mdma_clr_bits()
326 desc->node[i].hwdesc = in stm32_mdma_alloc_desc()
327 dma_pool_alloc(chan->desc_pool, GFP_NOWAIT, in stm32_mdma_alloc_desc()
328 &desc->node[i].hwdesc_phys); in stm32_mdma_alloc_desc()
329 if (!desc->node[i].hwdesc) in stm32_mdma_alloc_desc()
333 desc->count = count; in stm32_mdma_alloc_desc()
339 while (--i >= 0) in stm32_mdma_alloc_desc()
340 dma_pool_free(chan->desc_pool, desc->node[i].hwdesc, in stm32_mdma_alloc_desc()
341 desc->node[i].hwdesc_phys); in stm32_mdma_alloc_desc()
349 struct stm32_mdma_chan *chan = to_stm32_mdma_chan(vdesc->tx.chan); in stm32_mdma_desc_free()
352 for (i = 0; i < desc->count; i++) in stm32_mdma_desc_free()
353 dma_pool_free(chan->desc_pool, desc->node[i].hwdesc, in stm32_mdma_desc_free()
354 desc->node[i].hwdesc_phys); in stm32_mdma_desc_free()
366 return ffs(width) - 1; in stm32_mdma_get_width()
370 return -EINVAL; in stm32_mdma_get_width()
386 if ((((buf_len | addr) & (max_width - 1)) == 0) && in stm32_mdma_get_max_width()
411 id = chan->id; in stm32_mdma_disable_chan()
423 dmadev->base + STM32_MDMA_CISR(id), cisr, in stm32_mdma_disable_chan()
427 return -EBUSY; in stm32_mdma_disable_chan()
446 status = stm32_mdma_read(dmadev, STM32_MDMA_CISR(chan->id)); in stm32_mdma_stop()
450 stm32_mdma_set_bits(dmadev, STM32_MDMA_CIFCR(chan->id), status); in stm32_mdma_stop()
453 chan->busy = false; in stm32_mdma_stop()
462 /* Check if memory device is on AHB or AXI */ in stm32_mdma_set_bus()
465 for (i = 0; i < dmadev->nr_ahb_addr_masks; i++) { in stm32_mdma_set_bus()
466 if (mask == dmadev->ahb_addr_masks[i]) { in stm32_mdma_set_bus()
480 struct stm32_mdma_chan_config *chan_config = &chan->chan_config; in stm32_mdma_set_xfer_param()
487 src_addr_width = chan->dma_config.src_addr_width; in stm32_mdma_set_xfer_param()
488 dst_addr_width = chan->dma_config.dst_addr_width; in stm32_mdma_set_xfer_param()
489 src_maxburst = chan->dma_config.src_maxburst; in stm32_mdma_set_xfer_param()
490 dst_maxburst = chan->dma_config.dst_maxburst; in stm32_mdma_set_xfer_param()
492 ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & ~STM32_MDMA_CCR_EN; in stm32_mdma_set_xfer_param()
493 ctcr = stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id)); in stm32_mdma_set_xfer_param()
494 ctbr = stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id)); in stm32_mdma_set_xfer_param()
501 ctcr |= chan_config->transfer_config & STM32_MDMA_CTCR_CFG_MASK; in stm32_mdma_set_xfer_param()
505 * the number of bytes - 1 in CTCR register in stm32_mdma_set_xfer_param()
509 ctcr |= STM32_MDMA_CTCR_TLEN((tlen - 1)); in stm32_mdma_set_xfer_param()
514 /* Check burst size constraints */ in stm32_mdma_set_xfer_param()
518 "burst size * bus width higher than %d bytes\n", in stm32_mdma_set_xfer_param()
520 return -EINVAL; in stm32_mdma_set_xfer_param()
525 dev_err(chan2dev(chan), "burst size must be a power of 2\n"); in stm32_mdma_set_xfer_param()
526 return -EINVAL; in stm32_mdma_set_xfer_param()
531 * - Clear SW request as in this case this is a HW one in stm32_mdma_set_xfer_param()
532 * - Clear WEX, HEX and BEX bits in stm32_mdma_set_xfer_param()
533 * - Set priority level in stm32_mdma_set_xfer_param()
537 ccr |= STM32_MDMA_CCR_PL(chan_config->priority_level); in stm32_mdma_set_xfer_param()
541 ctbr |= STM32_MDMA_CTBR_TSEL(chan_config->request); in stm32_mdma_set_xfer_param()
545 dst_addr = chan->dma_config.dst_addr; in stm32_mdma_set_xfer_param()
548 if (chan_config->m2m_hw) in stm32_mdma_set_xfer_param()
556 if (chan_config->m2m_hw) { in stm32_mdma_set_xfer_param()
561 /* Set device burst value */ in stm32_mdma_set_xfer_param()
562 if (chan_config->m2m_hw) in stm32_mdma_set_xfer_param()
568 chan->mem_burst = dst_best_burst; in stm32_mdma_set_xfer_param()
574 chan->mem_width = src_addr_width; in stm32_mdma_set_xfer_param()
583 /* Set memory burst value */ in stm32_mdma_set_xfer_param()
588 chan->mem_burst = src_best_burst; in stm32_mdma_set_xfer_param()
600 stm32_mdma_write(dmadev, STM32_MDMA_CDAR(chan->id), dst_addr); in stm32_mdma_set_xfer_param()
604 src_addr = chan->dma_config.src_addr; in stm32_mdma_set_xfer_param()
607 if (chan_config->m2m_hw) in stm32_mdma_set_xfer_param()
616 if (chan_config->m2m_hw) { in stm32_mdma_set_xfer_param()
621 /* Set device burst value */ in stm32_mdma_set_xfer_param()
622 if (chan_config->m2m_hw) in stm32_mdma_set_xfer_param()
633 chan->mem_width = dst_addr_width; in stm32_mdma_set_xfer_param()
642 /* Set memory burst value */ in stm32_mdma_set_xfer_param()
658 stm32_mdma_write(dmadev, STM32_MDMA_CSAR(chan->id), src_addr); in stm32_mdma_set_xfer_param()
663 return -EINVAL; in stm32_mdma_set_xfer_param()
676 dev_dbg(chan2dev(chan), "hwdesc: %pad\n", &node->hwdesc_phys); in stm32_mdma_dump_hwdesc()
677 dev_dbg(chan2dev(chan), "CTCR: 0x%08x\n", node->hwdesc->ctcr); in stm32_mdma_dump_hwdesc()
678 dev_dbg(chan2dev(chan), "CBNDTR: 0x%08x\n", node->hwdesc->cbndtr); in stm32_mdma_dump_hwdesc()
679 dev_dbg(chan2dev(chan), "CSAR: 0x%08x\n", node->hwdesc->csar); in stm32_mdma_dump_hwdesc()
680 dev_dbg(chan2dev(chan), "CDAR: 0x%08x\n", node->hwdesc->cdar); in stm32_mdma_dump_hwdesc()
681 dev_dbg(chan2dev(chan), "CBRUR: 0x%08x\n", node->hwdesc->cbrur); in stm32_mdma_dump_hwdesc()
682 dev_dbg(chan2dev(chan), "CLAR: 0x%08x\n", node->hwdesc->clar); in stm32_mdma_dump_hwdesc()
683 dev_dbg(chan2dev(chan), "CTBR: 0x%08x\n", node->hwdesc->ctbr); in stm32_mdma_dump_hwdesc()
684 dev_dbg(chan2dev(chan), "CMAR: 0x%08x\n", node->hwdesc->cmar); in stm32_mdma_dump_hwdesc()
685 dev_dbg(chan2dev(chan), "CMDR: 0x%08x\n\n", node->hwdesc->cmdr); in stm32_mdma_dump_hwdesc()
695 struct stm32_mdma_chan_config *config = &chan->chan_config; in stm32_mdma_setup_hwdesc() local
699 hwdesc = desc->node[count].hwdesc; in stm32_mdma_setup_hwdesc()
700 hwdesc->ctcr = ctcr; in stm32_mdma_setup_hwdesc()
701 hwdesc->cbndtr &= ~(STM32_MDMA_CBNDTR_BRC_MK | in stm32_mdma_setup_hwdesc()
705 hwdesc->cbndtr |= STM32_MDMA_CBNDTR_BNDT(len); in stm32_mdma_setup_hwdesc()
706 hwdesc->csar = src_addr; in stm32_mdma_setup_hwdesc()
707 hwdesc->cdar = dst_addr; in stm32_mdma_setup_hwdesc()
708 hwdesc->cbrur = 0; in stm32_mdma_setup_hwdesc()
709 hwdesc->ctbr = ctbr; in stm32_mdma_setup_hwdesc()
710 hwdesc->cmar = config->mask_addr; in stm32_mdma_setup_hwdesc()
711 hwdesc->cmdr = config->mask_data; in stm32_mdma_setup_hwdesc()
715 hwdesc->clar = desc->node[0].hwdesc_phys; in stm32_mdma_setup_hwdesc()
717 hwdesc->clar = 0; in stm32_mdma_setup_hwdesc()
719 hwdesc->clar = desc->node[next].hwdesc_phys; in stm32_mdma_setup_hwdesc()
722 stm32_mdma_dump_hwdesc(chan, &desc->node[count]); in stm32_mdma_setup_hwdesc()
731 struct dma_slave_config *dma_config = &chan->dma_config; in stm32_mdma_setup_xfer()
732 struct stm32_mdma_chan_config *chan_config = &chan->chan_config; in stm32_mdma_setup_xfer()
738 if (chan_config->m2m_hw) in stm32_mdma_setup_xfer()
744 return -EINVAL; in stm32_mdma_setup_xfer()
749 dst_addr = dma_config->dst_addr; in stm32_mdma_setup_xfer()
750 if (chan_config->m2m_hw && (i & 1)) in stm32_mdma_setup_xfer()
758 src_addr = dma_config->src_addr; in stm32_mdma_setup_xfer()
759 if (chan_config->m2m_hw && (i & 1)) in stm32_mdma_setup_xfer()
774 i == sg_len - 1, i == 0, false); in stm32_mdma_setup_xfer()
780 desc->ccr = ccr; in stm32_mdma_setup_xfer()
791 struct stm32_mdma_chan_config *chan_config = &chan->chan_config; in stm32_mdma_prep_slave_sg()
800 if (chan->desc && chan->desc->cyclic) { in stm32_mdma_prep_slave_sg()
819 if (chan_config->m2m_hw && direction == DMA_MEM_TO_DEV) { in stm32_mdma_prep_slave_sg()
823 hwdesc = desc->node[i].hwdesc; in stm32_mdma_prep_slave_sg()
824 hwdesc->cmar = 0; in stm32_mdma_prep_slave_sg()
825 hwdesc->cmdr = 0; in stm32_mdma_prep_slave_sg()
829 desc->cyclic = false; in stm32_mdma_prep_slave_sg()
831 return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); in stm32_mdma_prep_slave_sg()
834 for (i = 0; i < desc->count; i++) in stm32_mdma_prep_slave_sg()
835 dma_pool_free(chan->desc_pool, desc->node[i].hwdesc, in stm32_mdma_prep_slave_sg()
836 desc->node[i].hwdesc_phys); in stm32_mdma_prep_slave_sg()
849 struct dma_slave_config *dma_config = &chan->dma_config; in stm32_mdma_prep_dma_cyclic()
850 struct stm32_mdma_chan_config *chan_config = &chan->chan_config; in stm32_mdma_prep_dma_cyclic()
861 if (chan->desc && chan->desc->cyclic) { in stm32_mdma_prep_dma_cyclic()
904 desc->ccr = ccr; in stm32_mdma_prep_dma_cyclic()
910 dst_addr = dma_config->dst_addr; in stm32_mdma_prep_dma_cyclic()
911 if (chan_config->m2m_hw && (i & 1)) in stm32_mdma_prep_dma_cyclic()
914 src_addr = dma_config->src_addr; in stm32_mdma_prep_dma_cyclic()
915 if (chan_config->m2m_hw && (i & 1)) in stm32_mdma_prep_dma_cyclic()
922 i == count - 1, i == 0, true); in stm32_mdma_prep_dma_cyclic()
925 desc->cyclic = true; in stm32_mdma_prep_dma_cyclic()
927 return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); in stm32_mdma_prep_dma_cyclic()
930 for (i = 0; i < desc->count; i++) in stm32_mdma_prep_dma_cyclic()
931 dma_pool_free(chan->desc_pool, desc->node[i].hwdesc, in stm32_mdma_prep_dma_cyclic()
932 desc->node[i].hwdesc_phys); in stm32_mdma_prep_dma_cyclic()
957 if (chan->desc && chan->desc->cyclic) { in stm32_mdma_prep_dma_memcpy()
968 ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & ~STM32_MDMA_CCR_EN; in stm32_mdma_prep_dma_memcpy()
969 ctcr = stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id)); in stm32_mdma_prep_dma_memcpy()
970 ctbr = stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id)); in stm32_mdma_prep_dma_memcpy()
971 cbndtr = stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id)); in stm32_mdma_prep_dma_memcpy()
1014 ctcr |= STM32_MDMA_CTCR_TLEN((tlen - 1)); in stm32_mdma_prep_dma_memcpy()
1016 /* Set source best burst size */ in stm32_mdma_prep_dma_memcpy()
1029 /* Set destination best burst size */ in stm32_mdma_prep_dma_memcpy()
1046 hwdesc = desc->node[0].hwdesc; in stm32_mdma_prep_dma_memcpy()
1047 hwdesc->ctcr = ctcr; in stm32_mdma_prep_dma_memcpy()
1048 hwdesc->cbndtr = cbndtr; in stm32_mdma_prep_dma_memcpy()
1049 hwdesc->csar = src; in stm32_mdma_prep_dma_memcpy()
1050 hwdesc->cdar = dest; in stm32_mdma_prep_dma_memcpy()
1051 hwdesc->cbrur = 0; in stm32_mdma_prep_dma_memcpy()
1052 hwdesc->clar = 0; in stm32_mdma_prep_dma_memcpy()
1053 hwdesc->ctbr = ctbr; in stm32_mdma_prep_dma_memcpy()
1054 hwdesc->cmar = 0; in stm32_mdma_prep_dma_memcpy()
1055 hwdesc->cmdr = 0; in stm32_mdma_prep_dma_memcpy()
1057 stm32_mdma_dump_hwdesc(chan, &desc->node[0]); in stm32_mdma_prep_dma_memcpy()
1061 STM32_MDMA_CTCR_TLEN((STM32_MDMA_MAX_BUF_LEN - 1)); in stm32_mdma_prep_dma_memcpy()
1067 xfer_count = min_t(size_t, len - offset, in stm32_mdma_prep_dma_memcpy()
1070 /* Set source best burst size */ in stm32_mdma_prep_dma_memcpy()
1084 /* Set destination best burst size */ in stm32_mdma_prep_dma_memcpy()
1105 i == count - 1, i == 0, false); in stm32_mdma_prep_dma_memcpy()
1109 desc->ccr = ccr; in stm32_mdma_prep_dma_memcpy()
1111 desc->cyclic = false; in stm32_mdma_prep_dma_memcpy()
1113 return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); in stm32_mdma_prep_dma_memcpy()
1121 stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id))); in stm32_mdma_dump_reg()
1123 stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id))); in stm32_mdma_dump_reg()
1125 stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id))); in stm32_mdma_dump_reg()
1127 stm32_mdma_read(dmadev, STM32_MDMA_CSAR(chan->id))); in stm32_mdma_dump_reg()
1129 stm32_mdma_read(dmadev, STM32_MDMA_CDAR(chan->id))); in stm32_mdma_dump_reg()
1131 stm32_mdma_read(dmadev, STM32_MDMA_CBRUR(chan->id))); in stm32_mdma_dump_reg()
1133 stm32_mdma_read(dmadev, STM32_MDMA_CLAR(chan->id))); in stm32_mdma_dump_reg()
1135 stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id))); in stm32_mdma_dump_reg()
1137 stm32_mdma_read(dmadev, STM32_MDMA_CMAR(chan->id))); in stm32_mdma_dump_reg()
1139 stm32_mdma_read(dmadev, STM32_MDMA_CMDR(chan->id))); in stm32_mdma_dump_reg()
1147 u32 id = chan->id; in stm32_mdma_start_transfer()
1150 vdesc = vchan_next_desc(&chan->vchan); in stm32_mdma_start_transfer()
1152 chan->desc = NULL; in stm32_mdma_start_transfer()
1156 list_del(&vdesc->node); in stm32_mdma_start_transfer()
1158 chan->desc = to_stm32_mdma_desc(vdesc); in stm32_mdma_start_transfer()
1159 hwdesc = chan->desc->node[0].hwdesc; in stm32_mdma_start_transfer()
1160 chan->curr_hwdesc = 0; in stm32_mdma_start_transfer()
1162 stm32_mdma_write(dmadev, STM32_MDMA_CCR(id), chan->desc->ccr); in stm32_mdma_start_transfer()
1163 stm32_mdma_write(dmadev, STM32_MDMA_CTCR(id), hwdesc->ctcr); in stm32_mdma_start_transfer()
1164 stm32_mdma_write(dmadev, STM32_MDMA_CBNDTR(id), hwdesc->cbndtr); in stm32_mdma_start_transfer()
1165 stm32_mdma_write(dmadev, STM32_MDMA_CSAR(id), hwdesc->csar); in stm32_mdma_start_transfer()
1166 stm32_mdma_write(dmadev, STM32_MDMA_CDAR(id), hwdesc->cdar); in stm32_mdma_start_transfer()
1167 stm32_mdma_write(dmadev, STM32_MDMA_CBRUR(id), hwdesc->cbrur); in stm32_mdma_start_transfer()
1168 stm32_mdma_write(dmadev, STM32_MDMA_CLAR(id), hwdesc->clar); in stm32_mdma_start_transfer()
1169 stm32_mdma_write(dmadev, STM32_MDMA_CTBR(id), hwdesc->ctbr); in stm32_mdma_start_transfer()
1170 stm32_mdma_write(dmadev, STM32_MDMA_CMAR(id), hwdesc->cmar); in stm32_mdma_start_transfer()
1171 stm32_mdma_write(dmadev, STM32_MDMA_CMDR(id), hwdesc->cmdr); in stm32_mdma_start_transfer()
1184 if (hwdesc->ctcr & STM32_MDMA_CTCR_SWRM) { in stm32_mdma_start_transfer()
1189 chan->busy = true; in stm32_mdma_start_transfer()
1191 dev_dbg(chan2dev(chan), "vchan %pK: started\n", &chan->vchan); in stm32_mdma_start_transfer()
1199 spin_lock_irqsave(&chan->vchan.lock, flags); in stm32_mdma_issue_pending()
1201 if (!vchan_issue_pending(&chan->vchan)) in stm32_mdma_issue_pending()
1204 dev_dbg(chan2dev(chan), "vchan %pK: issued\n", &chan->vchan); in stm32_mdma_issue_pending()
1206 if (!chan->desc && !chan->busy) in stm32_mdma_issue_pending()
1210 spin_unlock_irqrestore(&chan->vchan.lock, flags); in stm32_mdma_issue_pending()
1219 spin_lock_irqsave(&chan->vchan.lock, flags); in stm32_mdma_pause()
1221 spin_unlock_irqrestore(&chan->vchan.lock, flags); in stm32_mdma_pause()
1224 dev_dbg(chan2dev(chan), "vchan %pK: pause\n", &chan->vchan); in stm32_mdma_pause()
1238 if (!chan->desc || (stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & STM32_MDMA_CCR_EN)) in stm32_mdma_resume()
1239 return -EPERM; in stm32_mdma_resume()
1241 hwdesc = chan->desc->node[chan->curr_hwdesc].hwdesc; in stm32_mdma_resume()
1243 spin_lock_irqsave(&chan->vchan.lock, flags); in stm32_mdma_resume()
1245 /* Re-configure control register */ in stm32_mdma_resume()
1246 stm32_mdma_write(dmadev, STM32_MDMA_CCR(chan->id), chan->desc->ccr); in stm32_mdma_resume()
1249 status = stm32_mdma_read(dmadev, STM32_MDMA_CISR(chan->id)); in stm32_mdma_resume()
1251 stm32_mdma_set_bits(dmadev, STM32_MDMA_CIFCR(chan->id), status); in stm32_mdma_resume()
1255 /* Re-start DMA */ in stm32_mdma_resume()
1256 reg = STM32_MDMA_CCR(chan->id); in stm32_mdma_resume()
1260 if (hwdesc->ctcr & STM32_MDMA_CTCR_SWRM) in stm32_mdma_resume()
1263 spin_unlock_irqrestore(&chan->vchan.lock, flags); in stm32_mdma_resume()
1265 dev_dbg(chan2dev(chan), "vchan %pK: resume\n", &chan->vchan); in stm32_mdma_resume()
1276 spin_lock_irqsave(&chan->vchan.lock, flags); in stm32_mdma_terminate_all()
1277 if (chan->desc) { in stm32_mdma_terminate_all()
1278 vchan_terminate_vdesc(&chan->desc->vdesc); in stm32_mdma_terminate_all()
1279 if (chan->busy) in stm32_mdma_terminate_all()
1281 chan->desc = NULL; in stm32_mdma_terminate_all()
1283 vchan_get_all_descriptors(&chan->vchan, &head); in stm32_mdma_terminate_all()
1284 spin_unlock_irqrestore(&chan->vchan.lock, flags); in stm32_mdma_terminate_all()
1286 vchan_dma_desc_free_list(&chan->vchan, &head); in stm32_mdma_terminate_all()
1295 vchan_synchronize(&chan->vchan); in stm32_mdma_synchronize()
1299 struct dma_slave_config *config) in stm32_mdma_slave_config() argument
1303 memcpy(&chan->dma_config, config, sizeof(*config)); in stm32_mdma_slave_config()
1306 if (config->peripheral_size) { in stm32_mdma_slave_config()
1309 mdma_config = (struct stm32_mdma_dma_config *)chan->dma_config.peripheral_config; in stm32_mdma_slave_config()
1310 chan->chan_config.request = mdma_config->request; in stm32_mdma_slave_config()
1311 chan->chan_config.mask_addr = mdma_config->cmar; in stm32_mdma_slave_config()
1312 chan->chan_config.mask_data = mdma_config->cmdr; in stm32_mdma_slave_config()
1313 chan->chan_config.m2m_hw = true; in stm32_mdma_slave_config()
1329 cisr = stm32_mdma_read(dmadev, STM32_MDMA_CISR(chan->id)); in stm32_mdma_desc_residue()
1333 clar = stm32_mdma_read(dmadev, STM32_MDMA_CLAR(chan->id)); in stm32_mdma_desc_residue()
1334 for (i = desc->count - 1; i >= 0; i--) { in stm32_mdma_desc_residue()
1335 hwdesc = desc->node[i].hwdesc; in stm32_mdma_desc_residue()
1337 if (hwdesc->clar == clar) in stm32_mdma_desc_residue()
1341 residue += STM32_MDMA_CBNDTR_BNDT(hwdesc->cbndtr); in stm32_mdma_desc_residue()
1343 cbndtr = stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id)); in stm32_mdma_desc_residue()
1346 state->in_flight_bytes = 0; in stm32_mdma_desc_residue()
1347 if (chan->chan_config.m2m_hw && (cisr & STM32_MDMA_CISR_CRQA)) in stm32_mdma_desc_residue()
1348 state->in_flight_bytes = cbndtr & STM32_MDMA_CBNDTR_BNDT_MASK; in stm32_mdma_desc_residue()
1350 if (!chan->mem_burst) in stm32_mdma_desc_residue()
1353 burst_size = chan->mem_burst * chan->mem_width; in stm32_mdma_desc_residue()
1356 residue = residue - modulo + burst_size; in stm32_mdma_desc_residue()
1375 spin_lock_irqsave(&chan->vchan.lock, flags); in stm32_mdma_tx_status()
1377 vdesc = vchan_find_desc(&chan->vchan, cookie); in stm32_mdma_tx_status()
1378 if (chan->desc && cookie == chan->desc->vdesc.tx.cookie) in stm32_mdma_tx_status()
1379 residue = stm32_mdma_desc_residue(chan, chan->desc, chan->curr_hwdesc, state); in stm32_mdma_tx_status()
1385 spin_unlock_irqrestore(&chan->vchan.lock, flags); in stm32_mdma_tx_status()
1392 vchan_cookie_complete(&chan->desc->vdesc); in stm32_mdma_xfer_end()
1393 chan->desc = NULL; in stm32_mdma_xfer_end()
1394 chan->busy = false; in stm32_mdma_xfer_end()
1407 status = readl_relaxed(dmadev->base + STM32_MDMA_GISR0); in stm32_mdma_irq_handler()
1413 chan = &dmadev->chan[id]; in stm32_mdma_irq_handler()
1416 spin_lock(&chan->vchan.lock); in stm32_mdma_irq_handler()
1424 spin_unlock(&chan->vchan.lock); in stm32_mdma_irq_handler()
1425 if (chan->busy) in stm32_mdma_irq_handler()
1438 readl_relaxed(dmadev->base + STM32_MDMA_CESR(id))); in stm32_mdma_irq_handler()
1457 chan->curr_hwdesc++; in stm32_mdma_irq_handler()
1458 if (chan->desc && chan->desc->cyclic) { in stm32_mdma_irq_handler()
1459 if (chan->curr_hwdesc == chan->desc->count) in stm32_mdma_irq_handler()
1460 chan->curr_hwdesc = 0; in stm32_mdma_irq_handler()
1461 vchan_cyclic_callback(&chan->desc->vdesc); in stm32_mdma_irq_handler()
1477 spin_unlock(&chan->vchan.lock); in stm32_mdma_irq_handler()
1488 chan->desc_pool = dmam_pool_create(dev_name(&c->dev->device), in stm32_mdma_alloc_chan_resources()
1489 c->device->dev, in stm32_mdma_alloc_chan_resources()
1493 if (!chan->desc_pool) { in stm32_mdma_alloc_chan_resources()
1495 return -ENOMEM; in stm32_mdma_alloc_chan_resources()
1498 ret = pm_runtime_resume_and_get(dmadev->ddev.dev); in stm32_mdma_alloc_chan_resources()
1504 pm_runtime_put(dmadev->ddev.dev); in stm32_mdma_alloc_chan_resources()
1515 dev_dbg(chan2dev(chan), "Freeing channel %d\n", chan->id); in stm32_mdma_free_chan_resources()
1517 if (chan->busy) { in stm32_mdma_free_chan_resources()
1518 spin_lock_irqsave(&chan->vchan.lock, flags); in stm32_mdma_free_chan_resources()
1520 chan->desc = NULL; in stm32_mdma_free_chan_resources()
1521 spin_unlock_irqrestore(&chan->vchan.lock, flags); in stm32_mdma_free_chan_resources()
1524 pm_runtime_put(dmadev->ddev.dev); in stm32_mdma_free_chan_resources()
1526 dmam_pool_destroy(chan->desc_pool); in stm32_mdma_free_chan_resources()
1527 chan->desc_pool = NULL; in stm32_mdma_free_chan_resources()
1536 if (dmadev->chan_reserved & BIT(chan->id)) in stm32_mdma_filter_fn()
1545 struct stm32_mdma_device *dmadev = ofdma->of_dma_data; in stm32_mdma_of_xlate()
1546 dma_cap_mask_t mask = dmadev->ddev.cap_mask; in stm32_mdma_of_xlate()
1549 struct stm32_mdma_chan_config config; in stm32_mdma_of_xlate() local
1551 if (dma_spec->args_count < 5) { in stm32_mdma_of_xlate()
1556 memset(&config, 0, sizeof(config)); in stm32_mdma_of_xlate()
1557 config.request = dma_spec->args[0]; in stm32_mdma_of_xlate()
1558 config.priority_level = dma_spec->args[1]; in stm32_mdma_of_xlate()
1559 config.transfer_config = dma_spec->args[2]; in stm32_mdma_of_xlate()
1560 config.mask_addr = dma_spec->args[3]; in stm32_mdma_of_xlate()
1561 config.mask_data = dma_spec->args[4]; in stm32_mdma_of_xlate()
1563 if (config.request >= dmadev->nr_requests) { in stm32_mdma_of_xlate()
1568 if (config.priority_level > STM32_MDMA_VERY_HIGH_PRIORITY) { in stm32_mdma_of_xlate()
1573 c = __dma_request_channel(&mask, stm32_mdma_filter_fn, &config, ofdma->of_node); in stm32_mdma_of_xlate()
1580 chan->chan_config = config; in stm32_mdma_of_xlate()
1586 { .compatible = "st,stm32h7-mdma", },
1601 of_node = pdev->dev.of_node; in stm32_mdma_probe()
1603 return -ENODEV; in stm32_mdma_probe()
1605 ret = device_property_read_u32(&pdev->dev, "dma-channels", in stm32_mdma_probe()
1609 dev_warn(&pdev->dev, "MDMA defaulting on %i channels\n", in stm32_mdma_probe()
1613 ret = device_property_read_u32(&pdev->dev, "dma-requests", in stm32_mdma_probe()
1617 dev_warn(&pdev->dev, "MDMA defaulting on %i request lines\n", in stm32_mdma_probe()
1621 count = device_property_count_u32(&pdev->dev, "st,ahb-addr-masks"); in stm32_mdma_probe()
1625 dmadev = devm_kzalloc(&pdev->dev, in stm32_mdma_probe()
1629 return -ENOMEM; in stm32_mdma_probe()
1631 dmadev->nr_channels = nr_channels; in stm32_mdma_probe()
1632 dmadev->nr_requests = nr_requests; in stm32_mdma_probe()
1633 device_property_read_u32_array(&pdev->dev, "st,ahb-addr-masks", in stm32_mdma_probe()
1634 dmadev->ahb_addr_masks, in stm32_mdma_probe()
1636 dmadev->nr_ahb_addr_masks = count; in stm32_mdma_probe()
1638 dmadev->base = devm_platform_ioremap_resource(pdev, 0); in stm32_mdma_probe()
1639 if (IS_ERR(dmadev->base)) in stm32_mdma_probe()
1640 return PTR_ERR(dmadev->base); in stm32_mdma_probe()
1642 dmadev->clk = devm_clk_get(&pdev->dev, NULL); in stm32_mdma_probe()
1643 if (IS_ERR(dmadev->clk)) in stm32_mdma_probe()
1644 return dev_err_probe(&pdev->dev, PTR_ERR(dmadev->clk), in stm32_mdma_probe()
1647 ret = clk_prepare_enable(dmadev->clk); in stm32_mdma_probe()
1649 dev_err(&pdev->dev, "clk_prep_enable error: %d\n", ret); in stm32_mdma_probe()
1653 rst = devm_reset_control_get(&pdev->dev, NULL); in stm32_mdma_probe()
1656 if (ret == -EPROBE_DEFER) in stm32_mdma_probe()
1664 dd = &dmadev->ddev; in stm32_mdma_probe()
1665 dma_cap_set(DMA_SLAVE, dd->cap_mask); in stm32_mdma_probe()
1666 dma_cap_set(DMA_PRIVATE, dd->cap_mask); in stm32_mdma_probe()
1667 dma_cap_set(DMA_CYCLIC, dd->cap_mask); in stm32_mdma_probe()
1668 dma_cap_set(DMA_MEMCPY, dd->cap_mask); in stm32_mdma_probe()
1669 dd->device_alloc_chan_resources = stm32_mdma_alloc_chan_resources; in stm32_mdma_probe()
1670 dd->device_free_chan_resources = stm32_mdma_free_chan_resources; in stm32_mdma_probe()
1671 dd->device_tx_status = stm32_mdma_tx_status; in stm32_mdma_probe()
1672 dd->device_issue_pending = stm32_mdma_issue_pending; in stm32_mdma_probe()
1673 dd->device_prep_slave_sg = stm32_mdma_prep_slave_sg; in stm32_mdma_probe()
1674 dd->device_prep_dma_cyclic = stm32_mdma_prep_dma_cyclic; in stm32_mdma_probe()
1675 dd->device_prep_dma_memcpy = stm32_mdma_prep_dma_memcpy; in stm32_mdma_probe()
1676 dd->device_config = stm32_mdma_slave_config; in stm32_mdma_probe()
1677 dd->device_pause = stm32_mdma_pause; in stm32_mdma_probe()
1678 dd->device_resume = stm32_mdma_resume; in stm32_mdma_probe()
1679 dd->device_terminate_all = stm32_mdma_terminate_all; in stm32_mdma_probe()
1680 dd->device_synchronize = stm32_mdma_synchronize; in stm32_mdma_probe()
1681 dd->descriptor_reuse = true; in stm32_mdma_probe()
1683 dd->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | in stm32_mdma_probe()
1687 dd->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | in stm32_mdma_probe()
1691 dd->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV) | in stm32_mdma_probe()
1693 dd->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; in stm32_mdma_probe()
1694 dd->max_burst = STM32_MDMA_MAX_BURST; in stm32_mdma_probe()
1695 dd->dev = &pdev->dev; in stm32_mdma_probe()
1696 INIT_LIST_HEAD(&dd->channels); in stm32_mdma_probe()
1698 for (i = 0; i < dmadev->nr_channels; i++) { in stm32_mdma_probe()
1699 chan = &dmadev->chan[i]; in stm32_mdma_probe()
1700 chan->id = i; in stm32_mdma_probe()
1703 dmadev->chan_reserved |= BIT(i); in stm32_mdma_probe()
1705 chan->vchan.desc_free = stm32_mdma_desc_free; in stm32_mdma_probe()
1706 vchan_init(&chan->vchan, dd); in stm32_mdma_probe()
1709 dmadev->irq = platform_get_irq(pdev, 0); in stm32_mdma_probe()
1710 if (dmadev->irq < 0) { in stm32_mdma_probe()
1711 ret = dmadev->irq; in stm32_mdma_probe()
1715 ret = devm_request_irq(&pdev->dev, dmadev->irq, stm32_mdma_irq_handler, in stm32_mdma_probe()
1716 0, dev_name(&pdev->dev), dmadev); in stm32_mdma_probe()
1718 dev_err(&pdev->dev, "failed to request IRQ\n"); in stm32_mdma_probe()
1728 dev_err(&pdev->dev, in stm32_mdma_probe()
1734 pm_runtime_set_active(&pdev->dev); in stm32_mdma_probe()
1735 pm_runtime_enable(&pdev->dev); in stm32_mdma_probe()
1736 pm_runtime_get_noresume(&pdev->dev); in stm32_mdma_probe()
1737 pm_runtime_put(&pdev->dev); in stm32_mdma_probe()
1739 dev_info(&pdev->dev, "STM32 MDMA driver registered\n"); in stm32_mdma_probe()
1744 clk_disable_unprepare(dmadev->clk); in stm32_mdma_probe()
1754 clk_disable_unprepare(dmadev->clk); in stm32_mdma_runtime_suspend()
1764 ret = clk_prepare_enable(dmadev->clk); in stm32_mdma_runtime_resume()
1785 for (id = 0; id < dmadev->nr_channels; id++) { in stm32_mdma_pm_suspend()
1789 return -EBUSY; in stm32_mdma_pm_suspend()
1815 .name = "stm32-mdma",
1830 MODULE_AUTHOR("Pierre-Yves Mordret <pierre-yves.mordret@st.com>");