• Home
  • Raw
  • Download

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
16 #include <linux/dma-mapping.h>
33 #include "virt-dma.h"
36 #define STM32_MDMA_SHIFT(n) (ffs(n) - 1)
285 return container_of(chan->vchan.chan.device, struct stm32_mdma_device, in stm32_mdma_get_dev()
301 return &chan->vchan.chan.dev->device; in chan2dev()
306 return mdma_dev->ddev.dev; in mdma2dev()
311 return readl_relaxed(dmadev->base + reg); in stm32_mdma_read()
316 writel_relaxed(val, dmadev->base + reg); in stm32_mdma_write()
322 void __iomem *addr = dmadev->base + reg; in stm32_mdma_set_bits()
330 void __iomem *addr = dmadev->base + reg; in stm32_mdma_clr_bits()
346 desc->node[i].hwdesc = in stm32_mdma_alloc_desc()
347 dma_pool_alloc(chan->desc_pool, GFP_NOWAIT, in stm32_mdma_alloc_desc()
348 &desc->node[i].hwdesc_phys); in stm32_mdma_alloc_desc()
349 if (!desc->node[i].hwdesc) in stm32_mdma_alloc_desc()
353 desc->count = count; in stm32_mdma_alloc_desc()
359 while (--i >= 0) in stm32_mdma_alloc_desc()
360 dma_pool_free(chan->desc_pool, desc->node[i].hwdesc, in stm32_mdma_alloc_desc()
361 desc->node[i].hwdesc_phys); in stm32_mdma_alloc_desc()
369 struct stm32_mdma_chan *chan = to_stm32_mdma_chan(vdesc->tx.chan); in stm32_mdma_desc_free()
372 for (i = 0; i < desc->count; i++) in stm32_mdma_desc_free()
373 dma_pool_free(chan->desc_pool, desc->node[i].hwdesc, in stm32_mdma_desc_free()
374 desc->node[i].hwdesc_phys); in stm32_mdma_desc_free()
386 return ffs(width) - 1; in stm32_mdma_get_width()
390 return -EINVAL; in stm32_mdma_get_width()
406 if ((((buf_len | addr) & (max_width - 1)) == 0) && in stm32_mdma_get_max_width()
431 id = chan->id; in stm32_mdma_disable_chan()
443 dmadev->base + STM32_MDMA_CISR(id), cisr, in stm32_mdma_disable_chan()
447 return -EBUSY; in stm32_mdma_disable_chan()
466 status = stm32_mdma_read(dmadev, STM32_MDMA_CISR(chan->id)); in stm32_mdma_stop()
470 stm32_mdma_set_bits(dmadev, STM32_MDMA_CIFCR(chan->id), status); in stm32_mdma_stop()
473 chan->busy = false; in stm32_mdma_stop()
482 /* Check if memory device is on AHB or AXI */ in stm32_mdma_set_bus()
485 for (i = 0; i < dmadev->nr_ahb_addr_masks; i++) { in stm32_mdma_set_bus()
486 if (mask == dmadev->ahb_addr_masks[i]) { in stm32_mdma_set_bus()
500 struct stm32_mdma_chan_config *chan_config = &chan->chan_config; in stm32_mdma_set_xfer_param()
507 src_addr_width = chan->dma_config.src_addr_width; in stm32_mdma_set_xfer_param()
508 dst_addr_width = chan->dma_config.dst_addr_width; in stm32_mdma_set_xfer_param()
509 src_maxburst = chan->dma_config.src_maxburst; in stm32_mdma_set_xfer_param()
510 dst_maxburst = chan->dma_config.dst_maxburst; in stm32_mdma_set_xfer_param()
512 ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & ~STM32_MDMA_CCR_EN; in stm32_mdma_set_xfer_param()
513 ctcr = stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id)); in stm32_mdma_set_xfer_param()
514 ctbr = stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id)); in stm32_mdma_set_xfer_param()
521 ctcr |= chan_config->transfer_config & STM32_MDMA_CTCR_CFG_MASK; in stm32_mdma_set_xfer_param()
525 * the number of bytes - 1 in CTCR register in stm32_mdma_set_xfer_param()
529 ctcr |= STM32_MDMA_CTCR_TLEN((tlen - 1)); in stm32_mdma_set_xfer_param()
534 /* Check burst size constraints */ in stm32_mdma_set_xfer_param()
538 "burst size * bus width higher than %d bytes\n", in stm32_mdma_set_xfer_param()
540 return -EINVAL; in stm32_mdma_set_xfer_param()
545 dev_err(chan2dev(chan), "burst size must be a power of 2\n"); in stm32_mdma_set_xfer_param()
546 return -EINVAL; in stm32_mdma_set_xfer_param()
551 * - Clear SW request as in this case this is a HW one in stm32_mdma_set_xfer_param()
552 * - Clear WEX, HEX and BEX bits in stm32_mdma_set_xfer_param()
553 * - Set priority level in stm32_mdma_set_xfer_param()
557 ccr |= STM32_MDMA_CCR_PL(chan_config->priority_level); in stm32_mdma_set_xfer_param()
561 ctbr |= STM32_MDMA_CTBR_TSEL(chan_config->request); in stm32_mdma_set_xfer_param()
565 dst_addr = chan->dma_config.dst_addr; in stm32_mdma_set_xfer_param()
574 /* Set device burst value */ in stm32_mdma_set_xfer_param()
578 chan->mem_burst = dst_best_burst; in stm32_mdma_set_xfer_param()
584 chan->mem_width = src_addr_width; in stm32_mdma_set_xfer_param()
593 /* Set memory burst value */ in stm32_mdma_set_xfer_param()
598 chan->mem_burst = src_best_burst; in stm32_mdma_set_xfer_param()
610 stm32_mdma_write(dmadev, STM32_MDMA_CDAR(chan->id), dst_addr); in stm32_mdma_set_xfer_param()
614 src_addr = chan->dma_config.src_addr; in stm32_mdma_set_xfer_param()
623 /* Set device burst value */ in stm32_mdma_set_xfer_param()
632 chan->mem_width = dst_addr_width; in stm32_mdma_set_xfer_param()
641 /* Set memory burst value */ in stm32_mdma_set_xfer_param()
657 stm32_mdma_write(dmadev, STM32_MDMA_CSAR(chan->id), src_addr); in stm32_mdma_set_xfer_param()
662 return -EINVAL; in stm32_mdma_set_xfer_param()
675 dev_dbg(chan2dev(chan), "hwdesc: %pad\n", &node->hwdesc_phys); in stm32_mdma_dump_hwdesc()
676 dev_dbg(chan2dev(chan), "CTCR: 0x%08x\n", node->hwdesc->ctcr); in stm32_mdma_dump_hwdesc()
677 dev_dbg(chan2dev(chan), "CBNDTR: 0x%08x\n", node->hwdesc->cbndtr); in stm32_mdma_dump_hwdesc()
678 dev_dbg(chan2dev(chan), "CSAR: 0x%08x\n", node->hwdesc->csar); in stm32_mdma_dump_hwdesc()
679 dev_dbg(chan2dev(chan), "CDAR: 0x%08x\n", node->hwdesc->cdar); in stm32_mdma_dump_hwdesc()
680 dev_dbg(chan2dev(chan), "CBRUR: 0x%08x\n", node->hwdesc->cbrur); in stm32_mdma_dump_hwdesc()
681 dev_dbg(chan2dev(chan), "CLAR: 0x%08x\n", node->hwdesc->clar); in stm32_mdma_dump_hwdesc()
682 dev_dbg(chan2dev(chan), "CTBR: 0x%08x\n", node->hwdesc->ctbr); in stm32_mdma_dump_hwdesc()
683 dev_dbg(chan2dev(chan), "CMAR: 0x%08x\n", node->hwdesc->cmar); in stm32_mdma_dump_hwdesc()
684 dev_dbg(chan2dev(chan), "CMDR: 0x%08x\n\n", node->hwdesc->cmdr); in stm32_mdma_dump_hwdesc()
694 struct stm32_mdma_chan_config *config = &chan->chan_config; in stm32_mdma_setup_hwdesc() local
698 hwdesc = desc->node[count].hwdesc; in stm32_mdma_setup_hwdesc()
699 hwdesc->ctcr = ctcr; in stm32_mdma_setup_hwdesc()
700 hwdesc->cbndtr &= ~(STM32_MDMA_CBNDTR_BRC_MK | in stm32_mdma_setup_hwdesc()
704 hwdesc->cbndtr |= STM32_MDMA_CBNDTR_BNDT(len); in stm32_mdma_setup_hwdesc()
705 hwdesc->csar = src_addr; in stm32_mdma_setup_hwdesc()
706 hwdesc->cdar = dst_addr; in stm32_mdma_setup_hwdesc()
707 hwdesc->cbrur = 0; in stm32_mdma_setup_hwdesc()
708 hwdesc->ctbr = ctbr; in stm32_mdma_setup_hwdesc()
709 hwdesc->cmar = config->mask_addr; in stm32_mdma_setup_hwdesc()
710 hwdesc->cmdr = config->mask_data; in stm32_mdma_setup_hwdesc()
714 hwdesc->clar = desc->node[0].hwdesc_phys; in stm32_mdma_setup_hwdesc()
716 hwdesc->clar = 0; in stm32_mdma_setup_hwdesc()
718 hwdesc->clar = desc->node[next].hwdesc_phys; in stm32_mdma_setup_hwdesc()
721 stm32_mdma_dump_hwdesc(chan, &desc->node[count]); in stm32_mdma_setup_hwdesc()
730 struct dma_slave_config *dma_config = &chan->dma_config; in stm32_mdma_setup_xfer()
739 return -EINVAL; in stm32_mdma_setup_xfer()
744 dst_addr = dma_config->dst_addr; in stm32_mdma_setup_xfer()
751 src_addr = dma_config->src_addr; in stm32_mdma_setup_xfer()
765 i == sg_len - 1, i == 0, false); in stm32_mdma_setup_xfer()
773 desc->ccr = ccr; in stm32_mdma_setup_xfer()
792 if (chan->desc && chan->desc->cyclic) { in stm32_mdma_prep_slave_sg()
806 desc->cyclic = false; in stm32_mdma_prep_slave_sg()
808 return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); in stm32_mdma_prep_slave_sg()
811 for (i = 0; i < desc->count; i++) in stm32_mdma_prep_slave_sg()
812 dma_pool_free(chan->desc_pool, desc->node[i].hwdesc, in stm32_mdma_prep_slave_sg()
813 desc->node[i].hwdesc_phys); in stm32_mdma_prep_slave_sg()
826 struct dma_slave_config *dma_config = &chan->dma_config; in stm32_mdma_prep_dma_cyclic()
837 if (chan->desc && chan->desc->cyclic) { in stm32_mdma_prep_dma_cyclic()
880 desc->ccr = ccr; in stm32_mdma_prep_dma_cyclic()
886 dst_addr = dma_config->dst_addr; in stm32_mdma_prep_dma_cyclic()
888 src_addr = dma_config->src_addr; in stm32_mdma_prep_dma_cyclic()
894 i == count - 1, i == 0, true); in stm32_mdma_prep_dma_cyclic()
897 desc->cyclic = true; in stm32_mdma_prep_dma_cyclic()
899 return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); in stm32_mdma_prep_dma_cyclic()
902 for (i = 0; i < desc->count; i++) in stm32_mdma_prep_dma_cyclic()
903 dma_pool_free(chan->desc_pool, desc->node[i].hwdesc, in stm32_mdma_prep_dma_cyclic()
904 desc->node[i].hwdesc_phys); in stm32_mdma_prep_dma_cyclic()
929 if (chan->desc && chan->desc->cyclic) { in stm32_mdma_prep_dma_memcpy()
940 ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & ~STM32_MDMA_CCR_EN; in stm32_mdma_prep_dma_memcpy()
941 ctcr = stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id)); in stm32_mdma_prep_dma_memcpy()
942 ctbr = stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id)); in stm32_mdma_prep_dma_memcpy()
943 cbndtr = stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id)); in stm32_mdma_prep_dma_memcpy()
986 ctcr |= STM32_MDMA_CTCR_TLEN((tlen - 1)); in stm32_mdma_prep_dma_memcpy()
988 /* Set source best burst size */ in stm32_mdma_prep_dma_memcpy()
1001 /* Set destination best burst size */ in stm32_mdma_prep_dma_memcpy()
1018 hwdesc = desc->node[0].hwdesc; in stm32_mdma_prep_dma_memcpy()
1019 hwdesc->ctcr = ctcr; in stm32_mdma_prep_dma_memcpy()
1020 hwdesc->cbndtr = cbndtr; in stm32_mdma_prep_dma_memcpy()
1021 hwdesc->csar = src; in stm32_mdma_prep_dma_memcpy()
1022 hwdesc->cdar = dest; in stm32_mdma_prep_dma_memcpy()
1023 hwdesc->cbrur = 0; in stm32_mdma_prep_dma_memcpy()
1024 hwdesc->clar = 0; in stm32_mdma_prep_dma_memcpy()
1025 hwdesc->ctbr = ctbr; in stm32_mdma_prep_dma_memcpy()
1026 hwdesc->cmar = 0; in stm32_mdma_prep_dma_memcpy()
1027 hwdesc->cmdr = 0; in stm32_mdma_prep_dma_memcpy()
1029 stm32_mdma_dump_hwdesc(chan, &desc->node[0]); in stm32_mdma_prep_dma_memcpy()
1033 STM32_MDMA_CTCR_TLEN((STM32_MDMA_MAX_BUF_LEN - 1)); in stm32_mdma_prep_dma_memcpy()
1039 xfer_count = min_t(size_t, len - offset, in stm32_mdma_prep_dma_memcpy()
1042 /* Set source best burst size */ in stm32_mdma_prep_dma_memcpy()
1056 /* Set destination best burst size */ in stm32_mdma_prep_dma_memcpy()
1077 i == count - 1, i == 0, false); in stm32_mdma_prep_dma_memcpy()
1081 desc->ccr = ccr; in stm32_mdma_prep_dma_memcpy()
1083 desc->cyclic = false; in stm32_mdma_prep_dma_memcpy()
1085 return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); in stm32_mdma_prep_dma_memcpy()
1093 stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id))); in stm32_mdma_dump_reg()
1095 stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id))); in stm32_mdma_dump_reg()
1097 stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id))); in stm32_mdma_dump_reg()
1099 stm32_mdma_read(dmadev, STM32_MDMA_CSAR(chan->id))); in stm32_mdma_dump_reg()
1101 stm32_mdma_read(dmadev, STM32_MDMA_CDAR(chan->id))); in stm32_mdma_dump_reg()
1103 stm32_mdma_read(dmadev, STM32_MDMA_CBRUR(chan->id))); in stm32_mdma_dump_reg()
1105 stm32_mdma_read(dmadev, STM32_MDMA_CLAR(chan->id))); in stm32_mdma_dump_reg()
1107 stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id))); in stm32_mdma_dump_reg()
1109 stm32_mdma_read(dmadev, STM32_MDMA_CMAR(chan->id))); in stm32_mdma_dump_reg()
1111 stm32_mdma_read(dmadev, STM32_MDMA_CMDR(chan->id))); in stm32_mdma_dump_reg()
1119 u32 id = chan->id; in stm32_mdma_start_transfer()
1122 vdesc = vchan_next_desc(&chan->vchan); in stm32_mdma_start_transfer()
1124 chan->desc = NULL; in stm32_mdma_start_transfer()
1128 list_del(&vdesc->node); in stm32_mdma_start_transfer()
1130 chan->desc = to_stm32_mdma_desc(vdesc); in stm32_mdma_start_transfer()
1131 hwdesc = chan->desc->node[0].hwdesc; in stm32_mdma_start_transfer()
1132 chan->curr_hwdesc = 0; in stm32_mdma_start_transfer()
1134 stm32_mdma_write(dmadev, STM32_MDMA_CCR(id), chan->desc->ccr); in stm32_mdma_start_transfer()
1135 stm32_mdma_write(dmadev, STM32_MDMA_CTCR(id), hwdesc->ctcr); in stm32_mdma_start_transfer()
1136 stm32_mdma_write(dmadev, STM32_MDMA_CBNDTR(id), hwdesc->cbndtr); in stm32_mdma_start_transfer()
1137 stm32_mdma_write(dmadev, STM32_MDMA_CSAR(id), hwdesc->csar); in stm32_mdma_start_transfer()
1138 stm32_mdma_write(dmadev, STM32_MDMA_CDAR(id), hwdesc->cdar); in stm32_mdma_start_transfer()
1139 stm32_mdma_write(dmadev, STM32_MDMA_CBRUR(id), hwdesc->cbrur); in stm32_mdma_start_transfer()
1140 stm32_mdma_write(dmadev, STM32_MDMA_CLAR(id), hwdesc->clar); in stm32_mdma_start_transfer()
1141 stm32_mdma_write(dmadev, STM32_MDMA_CTBR(id), hwdesc->ctbr); in stm32_mdma_start_transfer()
1142 stm32_mdma_write(dmadev, STM32_MDMA_CMAR(id), hwdesc->cmar); in stm32_mdma_start_transfer()
1143 stm32_mdma_write(dmadev, STM32_MDMA_CMDR(id), hwdesc->cmdr); in stm32_mdma_start_transfer()
1156 if (hwdesc->ctcr & STM32_MDMA_CTCR_SWRM) { in stm32_mdma_start_transfer()
1161 chan->busy = true; in stm32_mdma_start_transfer()
1163 dev_dbg(chan2dev(chan), "vchan %pK: started\n", &chan->vchan); in stm32_mdma_start_transfer()
1171 spin_lock_irqsave(&chan->vchan.lock, flags); in stm32_mdma_issue_pending()
1173 if (!vchan_issue_pending(&chan->vchan)) in stm32_mdma_issue_pending()
1176 dev_dbg(chan2dev(chan), "vchan %pK: issued\n", &chan->vchan); in stm32_mdma_issue_pending()
1178 if (!chan->desc && !chan->busy) in stm32_mdma_issue_pending()
1182 spin_unlock_irqrestore(&chan->vchan.lock, flags); in stm32_mdma_issue_pending()
1191 spin_lock_irqsave(&chan->vchan.lock, flags); in stm32_mdma_pause()
1193 spin_unlock_irqrestore(&chan->vchan.lock, flags); in stm32_mdma_pause()
1196 dev_dbg(chan2dev(chan), "vchan %pK: pause\n", &chan->vchan); in stm32_mdma_pause()
1210 if (!chan->desc || (stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & STM32_MDMA_CCR_EN)) in stm32_mdma_resume()
1211 return -EPERM; in stm32_mdma_resume()
1213 hwdesc = chan->desc->node[chan->curr_hwdesc].hwdesc; in stm32_mdma_resume()
1215 spin_lock_irqsave(&chan->vchan.lock, flags); in stm32_mdma_resume()
1217 /* Re-configure control register */ in stm32_mdma_resume()
1218 stm32_mdma_write(dmadev, STM32_MDMA_CCR(chan->id), chan->desc->ccr); in stm32_mdma_resume()
1221 status = stm32_mdma_read(dmadev, STM32_MDMA_CISR(chan->id)); in stm32_mdma_resume()
1223 stm32_mdma_set_bits(dmadev, STM32_MDMA_CIFCR(chan->id), status); in stm32_mdma_resume()
1227 /* Re-start DMA */ in stm32_mdma_resume()
1228 reg = STM32_MDMA_CCR(chan->id); in stm32_mdma_resume()
1232 if (hwdesc->ctcr & STM32_MDMA_CTCR_SWRM) in stm32_mdma_resume()
1235 spin_unlock_irqrestore(&chan->vchan.lock, flags); in stm32_mdma_resume()
1237 dev_dbg(chan2dev(chan), "vchan %pK: resume\n", &chan->vchan); in stm32_mdma_resume()
1248 spin_lock_irqsave(&chan->vchan.lock, flags); in stm32_mdma_terminate_all()
1249 if (chan->desc) { in stm32_mdma_terminate_all()
1250 vchan_terminate_vdesc(&chan->desc->vdesc); in stm32_mdma_terminate_all()
1251 if (chan->busy) in stm32_mdma_terminate_all()
1253 chan->desc = NULL; in stm32_mdma_terminate_all()
1255 vchan_get_all_descriptors(&chan->vchan, &head); in stm32_mdma_terminate_all()
1256 spin_unlock_irqrestore(&chan->vchan.lock, flags); in stm32_mdma_terminate_all()
1258 vchan_dma_desc_free_list(&chan->vchan, &head); in stm32_mdma_terminate_all()
1267 vchan_synchronize(&chan->vchan); in stm32_mdma_synchronize()
1271 struct dma_slave_config *config) in stm32_mdma_slave_config() argument
1275 memcpy(&chan->dma_config, config, sizeof(*config)); in stm32_mdma_slave_config()
1285 struct stm32_mdma_hwdesc *hwdesc = desc->node[0].hwdesc; in stm32_mdma_desc_residue()
1290 for (i = curr_hwdesc + 1; i < desc->count; i++) { in stm32_mdma_desc_residue()
1291 hwdesc = desc->node[i].hwdesc; in stm32_mdma_desc_residue()
1292 residue += STM32_MDMA_CBNDTR_BNDT(hwdesc->cbndtr); in stm32_mdma_desc_residue()
1294 cbndtr = stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id)); in stm32_mdma_desc_residue()
1297 if (!chan->mem_burst) in stm32_mdma_desc_residue()
1300 burst_size = chan->mem_burst * chan->mem_width; in stm32_mdma_desc_residue()
1303 residue = residue - modulo + burst_size; in stm32_mdma_desc_residue()
1322 spin_lock_irqsave(&chan->vchan.lock, flags); in stm32_mdma_tx_status()
1324 vdesc = vchan_find_desc(&chan->vchan, cookie); in stm32_mdma_tx_status()
1325 if (chan->desc && cookie == chan->desc->vdesc.tx.cookie) in stm32_mdma_tx_status()
1326 residue = stm32_mdma_desc_residue(chan, chan->desc, in stm32_mdma_tx_status()
1327 chan->curr_hwdesc); in stm32_mdma_tx_status()
1333 spin_unlock_irqrestore(&chan->vchan.lock, flags); in stm32_mdma_tx_status()
1340 vchan_cookie_complete(&chan->desc->vdesc); in stm32_mdma_xfer_end()
1341 chan->desc = NULL; in stm32_mdma_xfer_end()
1342 chan->busy = false; in stm32_mdma_xfer_end()
1355 status = readl_relaxed(dmadev->base + STM32_MDMA_GISR0); in stm32_mdma_irq_handler()
1362 chan = &dmadev->chan[id]; in stm32_mdma_irq_handler()
1369 spin_lock(&chan->vchan.lock); in stm32_mdma_irq_handler()
1377 spin_unlock(&chan->vchan.lock); in stm32_mdma_irq_handler()
1388 readl_relaxed(dmadev->base + STM32_MDMA_CESR(id))); in stm32_mdma_irq_handler()
1407 chan->curr_hwdesc++; in stm32_mdma_irq_handler()
1408 if (chan->desc && chan->desc->cyclic) { in stm32_mdma_irq_handler()
1409 if (chan->curr_hwdesc == chan->desc->count) in stm32_mdma_irq_handler()
1410 chan->curr_hwdesc = 0; in stm32_mdma_irq_handler()
1411 vchan_cyclic_callback(&chan->desc->vdesc); in stm32_mdma_irq_handler()
1427 spin_unlock(&chan->vchan.lock); in stm32_mdma_irq_handler()
1438 chan->desc_pool = dmam_pool_create(dev_name(&c->dev->device), in stm32_mdma_alloc_chan_resources()
1439 c->device->dev, in stm32_mdma_alloc_chan_resources()
1443 if (!chan->desc_pool) { in stm32_mdma_alloc_chan_resources()
1445 return -ENOMEM; in stm32_mdma_alloc_chan_resources()
1448 ret = pm_runtime_resume_and_get(dmadev->ddev.dev); in stm32_mdma_alloc_chan_resources()
1454 pm_runtime_put(dmadev->ddev.dev); in stm32_mdma_alloc_chan_resources()
1465 dev_dbg(chan2dev(chan), "Freeing channel %d\n", chan->id); in stm32_mdma_free_chan_resources()
1467 if (chan->busy) { in stm32_mdma_free_chan_resources()
1468 spin_lock_irqsave(&chan->vchan.lock, flags); in stm32_mdma_free_chan_resources()
1470 chan->desc = NULL; in stm32_mdma_free_chan_resources()
1471 spin_unlock_irqrestore(&chan->vchan.lock, flags); in stm32_mdma_free_chan_resources()
1474 pm_runtime_put(dmadev->ddev.dev); in stm32_mdma_free_chan_resources()
1476 dmam_pool_destroy(chan->desc_pool); in stm32_mdma_free_chan_resources()
1477 chan->desc_pool = NULL; in stm32_mdma_free_chan_resources()
1483 struct stm32_mdma_device *dmadev = ofdma->of_dma_data; in stm32_mdma_of_xlate()
1486 struct stm32_mdma_chan_config config; in stm32_mdma_of_xlate() local
1488 if (dma_spec->args_count < 5) { in stm32_mdma_of_xlate()
1493 config.request = dma_spec->args[0]; in stm32_mdma_of_xlate()
1494 config.priority_level = dma_spec->args[1]; in stm32_mdma_of_xlate()
1495 config.transfer_config = dma_spec->args[2]; in stm32_mdma_of_xlate()
1496 config.mask_addr = dma_spec->args[3]; in stm32_mdma_of_xlate()
1497 config.mask_data = dma_spec->args[4]; in stm32_mdma_of_xlate()
1499 if (config.request >= dmadev->nr_requests) { in stm32_mdma_of_xlate()
1504 if (config.priority_level > STM32_MDMA_VERY_HIGH_PRIORITY) { in stm32_mdma_of_xlate()
1509 c = dma_get_any_slave_channel(&dmadev->ddev); in stm32_mdma_of_xlate()
1516 chan->chan_config = config; in stm32_mdma_of_xlate()
1522 { .compatible = "st,stm32h7-mdma", },
1538 of_node = pdev->dev.of_node; in stm32_mdma_probe()
1540 return -ENODEV; in stm32_mdma_probe()
1542 ret = device_property_read_u32(&pdev->dev, "dma-channels", in stm32_mdma_probe()
1546 dev_warn(&pdev->dev, "MDMA defaulting on %i channels\n", in stm32_mdma_probe()
1550 ret = device_property_read_u32(&pdev->dev, "dma-requests", in stm32_mdma_probe()
1554 dev_warn(&pdev->dev, "MDMA defaulting on %i request lines\n", in stm32_mdma_probe()
1558 count = device_property_count_u32(&pdev->dev, "st,ahb-addr-masks"); in stm32_mdma_probe()
1562 dmadev = devm_kzalloc(&pdev->dev, sizeof(*dmadev) + sizeof(u32) * count, in stm32_mdma_probe()
1565 return -ENOMEM; in stm32_mdma_probe()
1567 dmadev->nr_channels = nr_channels; in stm32_mdma_probe()
1568 dmadev->nr_requests = nr_requests; in stm32_mdma_probe()
1569 device_property_read_u32_array(&pdev->dev, "st,ahb-addr-masks", in stm32_mdma_probe()
1570 dmadev->ahb_addr_masks, in stm32_mdma_probe()
1572 dmadev->nr_ahb_addr_masks = count; in stm32_mdma_probe()
1575 dmadev->base = devm_ioremap_resource(&pdev->dev, res); in stm32_mdma_probe()
1576 if (IS_ERR(dmadev->base)) in stm32_mdma_probe()
1577 return PTR_ERR(dmadev->base); in stm32_mdma_probe()
1579 dmadev->clk = devm_clk_get(&pdev->dev, NULL); in stm32_mdma_probe()
1580 if (IS_ERR(dmadev->clk)) in stm32_mdma_probe()
1581 return dev_err_probe(&pdev->dev, PTR_ERR(dmadev->clk), in stm32_mdma_probe()
1584 ret = clk_prepare_enable(dmadev->clk); in stm32_mdma_probe()
1586 dev_err(&pdev->dev, "clk_prep_enable error: %d\n", ret); in stm32_mdma_probe()
1590 rst = devm_reset_control_get(&pdev->dev, NULL); in stm32_mdma_probe()
1593 if (ret == -EPROBE_DEFER) in stm32_mdma_probe()
1601 dd = &dmadev->ddev; in stm32_mdma_probe()
1602 dma_cap_set(DMA_SLAVE, dd->cap_mask); in stm32_mdma_probe()
1603 dma_cap_set(DMA_PRIVATE, dd->cap_mask); in stm32_mdma_probe()
1604 dma_cap_set(DMA_CYCLIC, dd->cap_mask); in stm32_mdma_probe()
1605 dma_cap_set(DMA_MEMCPY, dd->cap_mask); in stm32_mdma_probe()
1606 dd->device_alloc_chan_resources = stm32_mdma_alloc_chan_resources; in stm32_mdma_probe()
1607 dd->device_free_chan_resources = stm32_mdma_free_chan_resources; in stm32_mdma_probe()
1608 dd->device_tx_status = stm32_mdma_tx_status; in stm32_mdma_probe()
1609 dd->device_issue_pending = stm32_mdma_issue_pending; in stm32_mdma_probe()
1610 dd->device_prep_slave_sg = stm32_mdma_prep_slave_sg; in stm32_mdma_probe()
1611 dd->device_prep_dma_cyclic = stm32_mdma_prep_dma_cyclic; in stm32_mdma_probe()
1612 dd->device_prep_dma_memcpy = stm32_mdma_prep_dma_memcpy; in stm32_mdma_probe()
1613 dd->device_config = stm32_mdma_slave_config; in stm32_mdma_probe()
1614 dd->device_pause = stm32_mdma_pause; in stm32_mdma_probe()
1615 dd->device_resume = stm32_mdma_resume; in stm32_mdma_probe()
1616 dd->device_terminate_all = stm32_mdma_terminate_all; in stm32_mdma_probe()
1617 dd->device_synchronize = stm32_mdma_synchronize; in stm32_mdma_probe()
1618 dd->descriptor_reuse = true; in stm32_mdma_probe()
1620 dd->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | in stm32_mdma_probe()
1624 dd->dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | in stm32_mdma_probe()
1628 dd->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV) | in stm32_mdma_probe()
1630 dd->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; in stm32_mdma_probe()
1631 dd->max_burst = STM32_MDMA_MAX_BURST; in stm32_mdma_probe()
1632 dd->dev = &pdev->dev; in stm32_mdma_probe()
1633 INIT_LIST_HEAD(&dd->channels); in stm32_mdma_probe()
1635 for (i = 0; i < dmadev->nr_channels; i++) { in stm32_mdma_probe()
1636 chan = &dmadev->chan[i]; in stm32_mdma_probe()
1637 chan->id = i; in stm32_mdma_probe()
1638 chan->vchan.desc_free = stm32_mdma_desc_free; in stm32_mdma_probe()
1639 vchan_init(&chan->vchan, dd); in stm32_mdma_probe()
1642 dmadev->irq = platform_get_irq(pdev, 0); in stm32_mdma_probe()
1643 if (dmadev->irq < 0) { in stm32_mdma_probe()
1644 ret = dmadev->irq; in stm32_mdma_probe()
1648 ret = devm_request_irq(&pdev->dev, dmadev->irq, stm32_mdma_irq_handler, in stm32_mdma_probe()
1649 0, dev_name(&pdev->dev), dmadev); in stm32_mdma_probe()
1651 dev_err(&pdev->dev, "failed to request IRQ\n"); in stm32_mdma_probe()
1661 dev_err(&pdev->dev, in stm32_mdma_probe()
1667 pm_runtime_set_active(&pdev->dev); in stm32_mdma_probe()
1668 pm_runtime_enable(&pdev->dev); in stm32_mdma_probe()
1669 pm_runtime_get_noresume(&pdev->dev); in stm32_mdma_probe()
1670 pm_runtime_put(&pdev->dev); in stm32_mdma_probe()
1672 dev_info(&pdev->dev, "STM32 MDMA driver registered\n"); in stm32_mdma_probe()
1677 clk_disable_unprepare(dmadev->clk); in stm32_mdma_probe()
1687 clk_disable_unprepare(dmadev->clk); in stm32_mdma_runtime_suspend()
1697 ret = clk_prepare_enable(dmadev->clk); in stm32_mdma_runtime_resume()
1718 for (id = 0; id < dmadev->nr_channels; id++) { in stm32_mdma_pm_suspend()
1722 return -EBUSY; in stm32_mdma_pm_suspend()
1748 .name = "stm32-mdma",
1763 MODULE_AUTHOR("Pierre-Yves Mordret <pierre-yves.mordret@st.com>");