Lines Matching +full:spi +full:- +full:src +full:- +full:clk
1 // SPDX-License-Identifier: GPL-2.0-or-later
9 #include <linux/clk.h>
10 #include <linux/dma-mapping.h>
20 #include "virt-dma.h"
75 #define SUN4I_DDMA_PARA_DST_DATA_BLK_SIZE(n) (((n) - 1) << 24)
76 #define SUN4I_DDMA_PARA_DST_WAIT_CYCLES(n) (((n) - 1) << 16)
77 #define SUN4I_DDMA_PARA_SRC_DATA_BLK_SIZE(n) (((n) - 1) << 8)
78 #define SUN4I_DDMA_PARA_SRC_WAIT_CYCLES(n) (((n) - 1) << 0)
113 #define SUN4I_NDMA_NR_MAX_VCHANS (29 * 2 - 1)
119 * working with the SPI driver and seem to make it behave correctly */
157 dma_addr_t src; member
178 struct clk *clk; member
200 return &chan->dev->device; in chan2dev()
206 return -EINVAL; in convert_burst()
208 /* 1 -> 0, 4 -> 1, 8 -> 2 */ in convert_burst()
215 return -EINVAL; in convert_buswidth()
217 /* 8 (1 byte) -> 0, 16 (2 bytes) -> 1, 32 (4 bytes) -> 2 */ in convert_buswidth()
225 vchan_free_chan_resources(&vchan->vc); in sun4i_dma_free_chan_resources()
231 struct sun4i_dma_pchan *pchan = NULL, *pchans = priv->pchans; in find_and_use_pchan()
236 * pchans 0-SUN4I_NDMA_NR_MAX_CHANNELS are normal, and in find_and_use_pchan()
239 if (vchan->is_dedicated) { in find_and_use_pchan()
247 spin_lock_irqsave(&priv->lock, flags); in find_and_use_pchan()
248 for_each_clear_bit_from(i, priv->pchans_used, max) { in find_and_use_pchan()
250 pchan->vchan = vchan; in find_and_use_pchan()
251 set_bit(i, priv->pchans_used); in find_and_use_pchan()
254 spin_unlock_irqrestore(&priv->lock, flags); in find_and_use_pchan()
263 int nr = pchan - priv->pchans; in release_pchan()
265 spin_lock_irqsave(&priv->lock, flags); in release_pchan()
267 pchan->vchan = NULL; in release_pchan()
268 clear_bit(nr, priv->pchans_used); in release_pchan()
270 spin_unlock_irqrestore(&priv->lock, flags); in release_pchan()
280 if (pchan->is_dedicated) { in configure_pchan()
281 writel_relaxed(d->src, pchan->base + SUN4I_DDMA_SRC_ADDR_REG); in configure_pchan()
282 writel_relaxed(d->dst, pchan->base + SUN4I_DDMA_DST_ADDR_REG); in configure_pchan()
283 writel_relaxed(d->len, pchan->base + SUN4I_DDMA_BYTE_COUNT_REG); in configure_pchan()
284 writel_relaxed(d->para, pchan->base + SUN4I_DDMA_PARA_REG); in configure_pchan()
285 writel_relaxed(d->cfg, pchan->base + SUN4I_DDMA_CFG_REG); in configure_pchan()
287 writel_relaxed(d->src, pchan->base + SUN4I_NDMA_SRC_ADDR_REG); in configure_pchan()
288 writel_relaxed(d->dst, pchan->base + SUN4I_NDMA_DST_ADDR_REG); in configure_pchan()
289 writel_relaxed(d->len, pchan->base + SUN4I_NDMA_BYTE_COUNT_REG); in configure_pchan()
290 writel_relaxed(d->cfg, pchan->base + SUN4I_NDMA_CFG_REG); in configure_pchan()
299 int pchan_number = pchan - priv->pchans; in set_pchan_interrupt()
302 spin_lock_irqsave(&priv->lock, flags); in set_pchan_interrupt()
304 reg = readl_relaxed(priv->base + SUN4I_DMA_IRQ_ENABLE_REG); in set_pchan_interrupt()
316 writel_relaxed(reg, priv->base + SUN4I_DMA_IRQ_ENABLE_REG); in set_pchan_interrupt()
318 spin_unlock_irqrestore(&priv->lock, flags); in set_pchan_interrupt()
328 * This function must be called with &vchan->vc.lock held.
339 lockdep_assert_held(&vchan->vc.lock); in __execute_vchan_pending()
344 return -EBUSY; in __execute_vchan_pending()
350 if (vchan->processing) { in __execute_vchan_pending()
351 dev_dbg(chan2dev(&vchan->vc.chan), in __execute_vchan_pending()
353 ret = -EBUSY; in __execute_vchan_pending()
359 vd = vchan_next_desc(&vchan->vc); in __execute_vchan_pending()
361 dev_dbg(chan2dev(&vchan->vc.chan), in __execute_vchan_pending()
368 if (list_empty(&contract->demands)) { in __execute_vchan_pending()
370 list_del(&contract->vd.node); in __execute_vchan_pending()
371 vchan_cookie_complete(&contract->vd); in __execute_vchan_pending()
372 dev_dbg(chan2dev(&vchan->vc.chan), in __execute_vchan_pending()
375 } while (list_empty(&contract->demands)); in __execute_vchan_pending()
378 promise = list_first_entry(&contract->demands, in __execute_vchan_pending()
380 vchan->processing = promise; in __execute_vchan_pending()
384 vchan->contract = contract; in __execute_vchan_pending()
385 vchan->pchan = pchan; in __execute_vchan_pending()
386 set_pchan_interrupt(priv, pchan, contract->use_half_int, 1); in __execute_vchan_pending()
402 if ((sconfig->dst_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) || in sanitize_config()
403 !sconfig->dst_maxburst) in sanitize_config()
404 return -EINVAL; in sanitize_config()
406 if (sconfig->src_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) in sanitize_config()
407 sconfig->src_addr_width = sconfig->dst_addr_width; in sanitize_config()
409 if (!sconfig->src_maxburst) in sanitize_config()
410 sconfig->src_maxburst = sconfig->dst_maxburst; in sanitize_config()
415 if ((sconfig->src_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) || in sanitize_config()
416 !sconfig->src_maxburst) in sanitize_config()
417 return -EINVAL; in sanitize_config()
419 if (sconfig->dst_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) in sanitize_config()
420 sconfig->dst_addr_width = sconfig->src_addr_width; in sanitize_config()
422 if (!sconfig->dst_maxburst) in sanitize_config()
423 sconfig->dst_maxburst = sconfig->src_maxburst; in sanitize_config()
437 * normal part of the DMA Engine and get data copied. A non-executed
443 generate_ndma_promise(struct dma_chan *chan, dma_addr_t src, dma_addr_t dest, in generate_ndma_promise() argument
458 promise->src = src; in generate_ndma_promise()
459 promise->dst = dest; in generate_ndma_promise()
460 promise->len = len; in generate_ndma_promise()
461 promise->cfg = SUN4I_DMA_CFG_LOADING | in generate_ndma_promise()
465 "src burst %d, dst burst %d, src buswidth %d, dst buswidth %d", in generate_ndma_promise()
466 sconfig->src_maxburst, sconfig->dst_maxburst, in generate_ndma_promise()
467 sconfig->src_addr_width, sconfig->dst_addr_width); in generate_ndma_promise()
470 ret = convert_burst(sconfig->src_maxburst); in generate_ndma_promise()
473 promise->cfg |= SUN4I_DMA_CFG_SRC_BURST_LENGTH(ret); in generate_ndma_promise()
476 ret = convert_burst(sconfig->dst_maxburst); in generate_ndma_promise()
479 promise->cfg |= SUN4I_DMA_CFG_DST_BURST_LENGTH(ret); in generate_ndma_promise()
482 ret = convert_buswidth(sconfig->src_addr_width); in generate_ndma_promise()
485 promise->cfg |= SUN4I_DMA_CFG_SRC_DATA_WIDTH(ret); in generate_ndma_promise()
488 ret = convert_buswidth(sconfig->dst_addr_width); in generate_ndma_promise()
491 promise->cfg |= SUN4I_DMA_CFG_DST_DATA_WIDTH(ret); in generate_ndma_promise()
504 * Dedicated part of the DMA Engine and get data copied. A non-executed
510 generate_ddma_promise(struct dma_chan *chan, dma_addr_t src, dma_addr_t dest, in generate_ddma_promise() argument
520 promise->src = src; in generate_ddma_promise()
521 promise->dst = dest; in generate_ddma_promise()
522 promise->len = len; in generate_ddma_promise()
523 promise->cfg = SUN4I_DMA_CFG_LOADING | in generate_ddma_promise()
527 ret = convert_burst(sconfig->src_maxburst); in generate_ddma_promise()
530 promise->cfg |= SUN4I_DMA_CFG_SRC_BURST_LENGTH(ret); in generate_ddma_promise()
533 ret = convert_burst(sconfig->dst_maxburst); in generate_ddma_promise()
536 promise->cfg |= SUN4I_DMA_CFG_DST_BURST_LENGTH(ret); in generate_ddma_promise()
539 ret = convert_buswidth(sconfig->src_addr_width); in generate_ddma_promise()
542 promise->cfg |= SUN4I_DMA_CFG_SRC_DATA_WIDTH(ret); in generate_ddma_promise()
545 ret = convert_buswidth(sconfig->dst_addr_width); in generate_ddma_promise()
548 promise->cfg |= SUN4I_DMA_CFG_DST_DATA_WIDTH(ret); in generate_ddma_promise()
573 INIT_LIST_HEAD(&contract->demands); in generate_dma_contract()
574 INIT_LIST_HEAD(&contract->completed_demands); in generate_dma_contract()
591 promise = list_first_entry_or_null(&contract->demands, in get_next_cyclic_promise()
594 list_splice_init(&contract->completed_demands, in get_next_cyclic_promise()
595 &contract->demands); in get_next_cyclic_promise()
596 promise = list_first_entry(&contract->demands, in get_next_cyclic_promise()
612 list_for_each_entry_safe(promise, tmp, &contract->demands, list) in sun4i_dma_free_contract()
615 list_for_each_entry_safe(promise, tmp, &contract->completed_demands, list) in sun4i_dma_free_contract()
623 dma_addr_t src, size_t len, unsigned long flags) in sun4i_dma_prep_dma_memcpy() argument
626 struct dma_slave_config *sconfig = &vchan->cfg; in sun4i_dma_prep_dma_memcpy()
639 sconfig->src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; in sun4i_dma_prep_dma_memcpy()
640 sconfig->dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; in sun4i_dma_prep_dma_memcpy()
641 sconfig->src_maxburst = 8; in sun4i_dma_prep_dma_memcpy()
642 sconfig->dst_maxburst = 8; in sun4i_dma_prep_dma_memcpy()
644 if (vchan->is_dedicated) in sun4i_dma_prep_dma_memcpy()
645 promise = generate_ddma_promise(chan, src, dest, len, sconfig); in sun4i_dma_prep_dma_memcpy()
647 promise = generate_ndma_promise(chan, src, dest, len, sconfig, in sun4i_dma_prep_dma_memcpy()
656 if (vchan->is_dedicated) { in sun4i_dma_prep_dma_memcpy()
657 promise->cfg |= SUN4I_DMA_CFG_SRC_DRQ_TYPE(SUN4I_DDMA_DRQ_TYPE_SDRAM) | in sun4i_dma_prep_dma_memcpy()
660 promise->cfg |= SUN4I_DMA_CFG_SRC_DRQ_TYPE(SUN4I_NDMA_DRQ_TYPE_SDRAM) | in sun4i_dma_prep_dma_memcpy()
665 list_add_tail(&promise->list, &contract->demands); in sun4i_dma_prep_dma_memcpy()
668 return vchan_tx_prep(&vchan->vc, &contract->vd, flags); in sun4i_dma_prep_dma_memcpy()
677 struct dma_slave_config *sconfig = &vchan->cfg; in sun4i_dma_prep_dma_cyclic()
680 dma_addr_t src, dest; in sun4i_dma_prep_dma_cyclic() local
694 contract->is_cyclic = 1; in sun4i_dma_prep_dma_cyclic()
696 if (vchan->is_dedicated) { in sun4i_dma_prep_dma_cyclic()
707 src = buf; in sun4i_dma_prep_dma_cyclic()
708 dest = sconfig->dst_addr; in sun4i_dma_prep_dma_cyclic()
709 endpoints = SUN4I_DMA_CFG_DST_DRQ_TYPE(vchan->endpoint) | in sun4i_dma_prep_dma_cyclic()
714 src = sconfig->src_addr; in sun4i_dma_prep_dma_cyclic()
718 SUN4I_DMA_CFG_SRC_DRQ_TYPE(vchan->endpoint) | in sun4i_dma_prep_dma_cyclic()
729 * The engine can interrupt on half-transfer, so we can use in sun4i_dma_prep_dma_cyclic()
738 * |---|---|---|---| (periods / promises) in sun4i_dma_prep_dma_cyclic()
743 * |-------|-------| (promises as configured on hw) in sun4i_dma_prep_dma_cyclic()
744 * |---|---|---|---| (periods) in sun4i_dma_prep_dma_cyclic()
754 if (vchan->is_dedicated || period_len <= SUN4I_NDMA_MAX_SEG_SIZE / 2) { in sun4i_dma_prep_dma_cyclic()
756 contract->use_half_int = 1; in sun4i_dma_prep_dma_cyclic()
763 plength = min((len - offset), period_len); in sun4i_dma_prep_dma_cyclic()
765 src = buf + offset; in sun4i_dma_prep_dma_cyclic()
770 if (vchan->is_dedicated) in sun4i_dma_prep_dma_cyclic()
771 promise = generate_ddma_promise(chan, src, dest, in sun4i_dma_prep_dma_cyclic()
774 promise = generate_ndma_promise(chan, src, dest, in sun4i_dma_prep_dma_cyclic()
781 promise->cfg |= endpoints; in sun4i_dma_prep_dma_cyclic()
784 list_add_tail(&promise->list, &contract->demands); in sun4i_dma_prep_dma_cyclic()
788 return vchan_tx_prep(&vchan->vc, &contract->vd, flags); in sun4i_dma_prep_dma_cyclic()
797 struct dma_slave_config *sconfig = &vchan->cfg; in sun4i_dma_prep_slave_sg()
818 if (vchan->is_dedicated) { in sun4i_dma_prep_slave_sg()
829 endpoints = SUN4I_DMA_CFG_DST_DRQ_TYPE(vchan->endpoint) | in sun4i_dma_prep_slave_sg()
836 SUN4I_DMA_CFG_SRC_DRQ_TYPE(vchan->endpoint) | in sun4i_dma_prep_slave_sg()
843 dstaddr = sconfig->dst_addr; in sun4i_dma_prep_slave_sg()
845 srcaddr = sconfig->src_addr; in sun4i_dma_prep_slave_sg()
850 * These are the magic DMA engine timings that keep SPI going. in sun4i_dma_prep_slave_sg()
861 if (vchan->is_dedicated) in sun4i_dma_prep_slave_sg()
873 promise->cfg |= endpoints; in sun4i_dma_prep_slave_sg()
874 promise->para = para; in sun4i_dma_prep_slave_sg()
877 list_add_tail(&promise->list, &contract->demands); in sun4i_dma_prep_slave_sg()
884 return vchan_tx_prep(&vchan->vc, &contract->vd, flags); in sun4i_dma_prep_slave_sg()
889 struct sun4i_dma_dev *priv = to_sun4i_dma_dev(chan->device); in sun4i_dma_terminate_all()
891 struct sun4i_dma_pchan *pchan = vchan->pchan; in sun4i_dma_terminate_all()
895 spin_lock_irqsave(&vchan->vc.lock, flags); in sun4i_dma_terminate_all()
896 vchan_get_all_descriptors(&vchan->vc, &head); in sun4i_dma_terminate_all()
897 spin_unlock_irqrestore(&vchan->vc.lock, flags); in sun4i_dma_terminate_all()
904 if (pchan->is_dedicated) in sun4i_dma_terminate_all()
905 writel(0, pchan->base + SUN4I_DDMA_CFG_REG); in sun4i_dma_terminate_all()
907 writel(0, pchan->base + SUN4I_NDMA_CFG_REG); in sun4i_dma_terminate_all()
912 spin_lock_irqsave(&vchan->vc.lock, flags); in sun4i_dma_terminate_all()
914 vchan->processing = NULL; in sun4i_dma_terminate_all()
915 vchan->pchan = NULL; in sun4i_dma_terminate_all()
916 spin_unlock_irqrestore(&vchan->vc.lock, flags); in sun4i_dma_terminate_all()
918 vchan_dma_desc_free_list(&vchan->vc, &head); in sun4i_dma_terminate_all()
928 memcpy(&vchan->cfg, config, sizeof(*config)); in sun4i_dma_config()
936 struct sun4i_dma_dev *priv = ofdma->of_dma_data; in sun4i_dma_of_xlate()
939 u8 is_dedicated = dma_spec->args[0]; in sun4i_dma_of_xlate()
940 u8 endpoint = dma_spec->args[1]; in sun4i_dma_of_xlate()
951 chan = dma_get_any_slave_channel(&priv->slave); in sun4i_dma_of_xlate()
957 vchan->is_dedicated = is_dedicated; in sun4i_dma_of_xlate()
958 vchan->endpoint = endpoint; in sun4i_dma_of_xlate()
968 struct sun4i_dma_pchan *pchan = vchan->pchan; in sun4i_dma_tx_status()
980 spin_lock_irqsave(&vchan->vc.lock, flags); in sun4i_dma_tx_status()
981 vd = vchan_find_desc(&vchan->vc, cookie); in sun4i_dma_tx_status()
986 list_for_each_entry(promise, &contract->demands, list) in sun4i_dma_tx_status()
987 bytes += promise->len; in sun4i_dma_tx_status()
994 promise = list_first_entry_or_null(&contract->demands, in sun4i_dma_tx_status()
997 bytes -= promise->len; in sun4i_dma_tx_status()
998 if (pchan->is_dedicated) in sun4i_dma_tx_status()
999 bytes += readl(pchan->base + SUN4I_DDMA_BYTE_COUNT_REG); in sun4i_dma_tx_status()
1001 bytes += readl(pchan->base + SUN4I_NDMA_BYTE_COUNT_REG); in sun4i_dma_tx_status()
1007 spin_unlock_irqrestore(&vchan->vc.lock, flags); in sun4i_dma_tx_status()
1014 struct sun4i_dma_dev *priv = to_sun4i_dma_dev(chan->device); in sun4i_dma_issue_pending()
1018 spin_lock_irqsave(&vchan->vc.lock, flags); in sun4i_dma_issue_pending()
1024 if (vchan_issue_pending(&vchan->vc)) in sun4i_dma_issue_pending()
1027 spin_unlock_irqrestore(&vchan->vc.lock, flags); in sun4i_dma_issue_pending()
1033 struct sun4i_dma_pchan *pchans = priv->pchans, *pchan; in sun4i_dma_interrupt()
1040 pendirq = readl_relaxed(priv->base + SUN4I_DMA_IRQ_PENDING_STATUS_REG); in sun4i_dma_interrupt()
1049 vchan = pchan->vchan; in sun4i_dma_interrupt()
1052 contract = vchan->contract; in sun4i_dma_interrupt()
1059 spin_lock(&vchan->vc.lock); in sun4i_dma_interrupt()
1065 list_move_tail(&vchan->processing->list, in sun4i_dma_interrupt()
1066 &contract->completed_demands); in sun4i_dma_interrupt()
1070 * - There's always something we can dispatch in sun4i_dma_interrupt()
1071 * - We need to run the callback in sun4i_dma_interrupt()
1072 * - Latency is very important, as this is used by audio in sun4i_dma_interrupt()
1077 * For non-cyclic transfers we need to look around, in sun4i_dma_interrupt()
1081 if (contract->is_cyclic) { in sun4i_dma_interrupt()
1083 vchan->processing = promise; in sun4i_dma_interrupt()
1085 vchan_cyclic_callback(&contract->vd); in sun4i_dma_interrupt()
1087 vchan->processing = NULL; in sun4i_dma_interrupt()
1088 vchan->pchan = NULL; in sun4i_dma_interrupt()
1095 spin_unlock(&vchan->vc.lock); in sun4i_dma_interrupt()
1098 if (contract->is_cyclic) in sun4i_dma_interrupt()
1099 vchan_cyclic_callback(&contract->vd); in sun4i_dma_interrupt()
1106 spin_lock(&priv->lock); in sun4i_dma_interrupt()
1107 irqs = readl_relaxed(priv->base + SUN4I_DMA_IRQ_ENABLE_REG); in sun4i_dma_interrupt()
1109 priv->base + SUN4I_DMA_IRQ_ENABLE_REG); in sun4i_dma_interrupt()
1110 spin_unlock(&priv->lock); in sun4i_dma_interrupt()
1113 writel_relaxed(pendirq, priv->base + SUN4I_DMA_IRQ_PENDING_STATUS_REG); in sun4i_dma_interrupt()
1121 vchan = &priv->vchans[i]; in sun4i_dma_interrupt()
1122 spin_lock(&vchan->vc.lock); in sun4i_dma_interrupt()
1124 spin_unlock(&vchan->vc.lock); in sun4i_dma_interrupt()
1133 pendirq = readl_relaxed(priv->base + in sun4i_dma_interrupt()
1149 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in sun4i_dma_probe()
1151 return -ENOMEM; in sun4i_dma_probe()
1153 priv->base = devm_platform_ioremap_resource(pdev, 0); in sun4i_dma_probe()
1154 if (IS_ERR(priv->base)) in sun4i_dma_probe()
1155 return PTR_ERR(priv->base); in sun4i_dma_probe()
1157 priv->irq = platform_get_irq(pdev, 0); in sun4i_dma_probe()
1158 if (priv->irq < 0) in sun4i_dma_probe()
1159 return priv->irq; in sun4i_dma_probe()
1161 priv->clk = devm_clk_get(&pdev->dev, NULL); in sun4i_dma_probe()
1162 if (IS_ERR(priv->clk)) { in sun4i_dma_probe()
1163 dev_err(&pdev->dev, "No clock specified\n"); in sun4i_dma_probe()
1164 return PTR_ERR(priv->clk); in sun4i_dma_probe()
1168 spin_lock_init(&priv->lock); in sun4i_dma_probe()
1170 dma_set_max_seg_size(&pdev->dev, SUN4I_DMA_MAX_SEG_SIZE); in sun4i_dma_probe()
1172 dma_cap_zero(priv->slave.cap_mask); in sun4i_dma_probe()
1173 dma_cap_set(DMA_PRIVATE, priv->slave.cap_mask); in sun4i_dma_probe()
1174 dma_cap_set(DMA_MEMCPY, priv->slave.cap_mask); in sun4i_dma_probe()
1175 dma_cap_set(DMA_CYCLIC, priv->slave.cap_mask); in sun4i_dma_probe()
1176 dma_cap_set(DMA_SLAVE, priv->slave.cap_mask); in sun4i_dma_probe()
1178 INIT_LIST_HEAD(&priv->slave.channels); in sun4i_dma_probe()
1179 priv->slave.device_free_chan_resources = sun4i_dma_free_chan_resources; in sun4i_dma_probe()
1180 priv->slave.device_tx_status = sun4i_dma_tx_status; in sun4i_dma_probe()
1181 priv->slave.device_issue_pending = sun4i_dma_issue_pending; in sun4i_dma_probe()
1182 priv->slave.device_prep_slave_sg = sun4i_dma_prep_slave_sg; in sun4i_dma_probe()
1183 priv->slave.device_prep_dma_memcpy = sun4i_dma_prep_dma_memcpy; in sun4i_dma_probe()
1184 priv->slave.device_prep_dma_cyclic = sun4i_dma_prep_dma_cyclic; in sun4i_dma_probe()
1185 priv->slave.device_config = sun4i_dma_config; in sun4i_dma_probe()
1186 priv->slave.device_terminate_all = sun4i_dma_terminate_all; in sun4i_dma_probe()
1187 priv->slave.copy_align = 2; in sun4i_dma_probe()
1188 priv->slave.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | in sun4i_dma_probe()
1191 priv->slave.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | in sun4i_dma_probe()
1194 priv->slave.directions = BIT(DMA_DEV_TO_MEM) | in sun4i_dma_probe()
1196 priv->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; in sun4i_dma_probe()
1198 priv->slave.dev = &pdev->dev; in sun4i_dma_probe()
1200 priv->pchans = devm_kcalloc(&pdev->dev, SUN4I_DMA_NR_MAX_CHANNELS, in sun4i_dma_probe()
1202 priv->vchans = devm_kcalloc(&pdev->dev, SUN4I_DMA_NR_MAX_VCHANS, in sun4i_dma_probe()
1204 if (!priv->vchans || !priv->pchans) in sun4i_dma_probe()
1205 return -ENOMEM; in sun4i_dma_probe()
1213 priv->pchans[i].base = priv->base + in sun4i_dma_probe()
1217 priv->pchans[i].base = priv->base + in sun4i_dma_probe()
1219 priv->pchans[i].is_dedicated = 1; in sun4i_dma_probe()
1223 struct sun4i_dma_vchan *vchan = &priv->vchans[i]; in sun4i_dma_probe()
1225 spin_lock_init(&vchan->vc.lock); in sun4i_dma_probe()
1226 vchan->vc.desc_free = sun4i_dma_free_contract; in sun4i_dma_probe()
1227 vchan_init(&vchan->vc, &priv->slave); in sun4i_dma_probe()
1230 ret = clk_prepare_enable(priv->clk); in sun4i_dma_probe()
1232 dev_err(&pdev->dev, "Couldn't enable the clock\n"); in sun4i_dma_probe()
1240 writel(0, priv->base + SUN4I_DMA_IRQ_ENABLE_REG); in sun4i_dma_probe()
1241 writel(0xFFFFFFFF, priv->base + SUN4I_DMA_IRQ_PENDING_STATUS_REG); in sun4i_dma_probe()
1243 ret = devm_request_irq(&pdev->dev, priv->irq, sun4i_dma_interrupt, in sun4i_dma_probe()
1244 0, dev_name(&pdev->dev), priv); in sun4i_dma_probe()
1246 dev_err(&pdev->dev, "Cannot request IRQ\n"); in sun4i_dma_probe()
1250 ret = dma_async_device_register(&priv->slave); in sun4i_dma_probe()
1252 dev_warn(&pdev->dev, "Failed to register DMA engine device\n"); in sun4i_dma_probe()
1256 ret = of_dma_controller_register(pdev->dev.of_node, sun4i_dma_of_xlate, in sun4i_dma_probe()
1259 dev_err(&pdev->dev, "of_dma_controller_register failed\n"); in sun4i_dma_probe()
1263 dev_dbg(&pdev->dev, "Successfully probed SUN4I_DMA\n"); in sun4i_dma_probe()
1268 dma_async_device_unregister(&priv->slave); in sun4i_dma_probe()
1270 clk_disable_unprepare(priv->clk); in sun4i_dma_probe()
1279 disable_irq(priv->irq); in sun4i_dma_remove()
1281 of_dma_controller_free(pdev->dev.of_node); in sun4i_dma_remove()
1282 dma_async_device_unregister(&priv->slave); in sun4i_dma_remove()
1284 clk_disable_unprepare(priv->clk); in sun4i_dma_remove()
1288 { .compatible = "allwinner,sun4i-a10-dma" },
1297 .name = "sun4i-dma",