• Home
  • Raw
  • Download

Lines Matching +full:dma +full:- +full:maxburst

2  *  Copyright (C) 2013, Lars-Peter Clausen <lars@metafoo.de>
13 #include <linux/dma-mapping.h>
24 #include "virt-dma.h"
135 return container_of(chan->vchan.chan.device, struct jz4740_dma_dev, in jz4740_dma_chan_get_dev()
152 return readl(dmadev->base + reg); in jz4740_dma_read()
158 writel(val, dmadev->base + reg); in jz4740_dma_write()
192 static enum jz4740_dma_transfer_size jz4740_dma_maxburst(u32 maxburst) in jz4740_dma_maxburst() argument
194 if (maxburst <= 1) in jz4740_dma_maxburst()
196 else if (maxburst <= 3) in jz4740_dma_maxburst()
198 else if (maxburst <= 15) in jz4740_dma_maxburst()
200 else if (maxburst <= 31) in jz4740_dma_maxburst()
217 switch (config->direction) { in jz4740_dma_slave_config()
220 transfer_size = jz4740_dma_maxburst(config->dst_maxburst); in jz4740_dma_slave_config()
221 chan->fifo_addr = config->dst_addr; in jz4740_dma_slave_config()
225 transfer_size = jz4740_dma_maxburst(config->src_maxburst); in jz4740_dma_slave_config()
226 chan->fifo_addr = config->src_addr; in jz4740_dma_slave_config()
229 return -EINVAL; in jz4740_dma_slave_config()
232 src_width = jz4740_dma_width(config->src_addr_width); in jz4740_dma_slave_config()
233 dst_width = jz4740_dma_width(config->dst_addr_width); in jz4740_dma_slave_config()
237 chan->transfer_shift = 1; in jz4740_dma_slave_config()
240 chan->transfer_shift = 2; in jz4740_dma_slave_config()
243 chan->transfer_shift = 4; in jz4740_dma_slave_config()
246 chan->transfer_shift = 5; in jz4740_dma_slave_config()
249 chan->transfer_shift = 0; in jz4740_dma_slave_config()
260 jz4740_dma_write(dmadev, JZ_REG_DMA_CMD(chan->id), cmd); in jz4740_dma_slave_config()
261 jz4740_dma_write(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), 0); in jz4740_dma_slave_config()
262 jz4740_dma_write(dmadev, JZ_REG_DMA_REQ_TYPE(chan->id), in jz4740_dma_slave_config()
263 config->slave_id); in jz4740_dma_slave_config()
275 spin_lock_irqsave(&chan->vchan.lock, flags); in jz4740_dma_terminate_all()
276 jz4740_dma_write_mask(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), 0, in jz4740_dma_terminate_all()
278 chan->desc = NULL; in jz4740_dma_terminate_all()
279 vchan_get_all_descriptors(&chan->vchan, &head); in jz4740_dma_terminate_all()
280 spin_unlock_irqrestore(&chan->vchan.lock, flags); in jz4740_dma_terminate_all()
282 vchan_dma_desc_free_list(&chan->vchan, &head); in jz4740_dma_terminate_all()
294 jz4740_dma_write_mask(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), 0, in jz4740_dma_start_transfer()
297 if (!chan->desc) { in jz4740_dma_start_transfer()
298 vdesc = vchan_next_desc(&chan->vchan); in jz4740_dma_start_transfer()
301 chan->desc = to_jz4740_dma_desc(vdesc); in jz4740_dma_start_transfer()
302 chan->next_sg = 0; in jz4740_dma_start_transfer()
305 if (chan->next_sg == chan->desc->num_sgs) in jz4740_dma_start_transfer()
306 chan->next_sg = 0; in jz4740_dma_start_transfer()
308 sg = &chan->desc->sg[chan->next_sg]; in jz4740_dma_start_transfer()
310 if (chan->desc->direction == DMA_MEM_TO_DEV) { in jz4740_dma_start_transfer()
311 src_addr = sg->addr; in jz4740_dma_start_transfer()
312 dst_addr = chan->fifo_addr; in jz4740_dma_start_transfer()
314 src_addr = chan->fifo_addr; in jz4740_dma_start_transfer()
315 dst_addr = sg->addr; in jz4740_dma_start_transfer()
317 jz4740_dma_write(dmadev, JZ_REG_DMA_SRC_ADDR(chan->id), src_addr); in jz4740_dma_start_transfer()
318 jz4740_dma_write(dmadev, JZ_REG_DMA_DST_ADDR(chan->id), dst_addr); in jz4740_dma_start_transfer()
319 jz4740_dma_write(dmadev, JZ_REG_DMA_TRANSFER_COUNT(chan->id), in jz4740_dma_start_transfer()
320 sg->len >> chan->transfer_shift); in jz4740_dma_start_transfer()
322 chan->next_sg++; in jz4740_dma_start_transfer()
324 jz4740_dma_write_mask(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), in jz4740_dma_start_transfer()
338 spin_lock(&chan->vchan.lock); in jz4740_dma_chan_irq()
339 if (chan->desc) { in jz4740_dma_chan_irq()
340 if (chan->desc->cyclic) { in jz4740_dma_chan_irq()
341 vchan_cyclic_callback(&chan->desc->vdesc); in jz4740_dma_chan_irq()
343 if (chan->next_sg == chan->desc->num_sgs) { in jz4740_dma_chan_irq()
344 list_del(&chan->desc->vdesc.node); in jz4740_dma_chan_irq()
345 vchan_cookie_complete(&chan->desc->vdesc); in jz4740_dma_chan_irq()
346 chan->desc = NULL; in jz4740_dma_chan_irq()
351 spin_unlock(&chan->vchan.lock); in jz4740_dma_chan_irq()
360 irq_status = readl(dmadev->base + JZ_REG_DMA_IRQ); in jz4740_dma_irq()
369 jz4740_dma_chan_irq(&dmadev->chan[i]); in jz4740_dma_irq()
381 spin_lock_irqsave(&chan->vchan.lock, flags); in jz4740_dma_issue_pending()
382 if (vchan_issue_pending(&chan->vchan) && !chan->desc) in jz4740_dma_issue_pending()
384 spin_unlock_irqrestore(&chan->vchan.lock, flags); in jz4740_dma_issue_pending()
402 desc->sg[i].addr = sg_dma_address(sg); in jz4740_dma_prep_slave_sg()
403 desc->sg[i].len = sg_dma_len(sg); in jz4740_dma_prep_slave_sg()
406 desc->num_sgs = sg_len; in jz4740_dma_prep_slave_sg()
407 desc->direction = direction; in jz4740_dma_prep_slave_sg()
408 desc->cyclic = false; in jz4740_dma_prep_slave_sg()
410 return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); in jz4740_dma_prep_slave_sg()
432 desc->sg[i].addr = buf_addr; in jz4740_dma_prep_dma_cyclic()
433 desc->sg[i].len = period_len; in jz4740_dma_prep_dma_cyclic()
437 desc->num_sgs = num_periods; in jz4740_dma_prep_dma_cyclic()
438 desc->direction = direction; in jz4740_dma_prep_dma_cyclic()
439 desc->cyclic = true; in jz4740_dma_prep_dma_cyclic()
441 return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); in jz4740_dma_prep_dma_cyclic()
453 for (i = next_sg; i < desc->num_sgs; i++) in jz4740_dma_desc_residue()
454 residue += desc->sg[i].len; in jz4740_dma_desc_residue()
458 JZ_REG_DMA_TRANSFER_COUNT(chan->id)); in jz4740_dma_desc_residue()
459 residue += count << chan->transfer_shift; in jz4740_dma_desc_residue()
477 spin_lock_irqsave(&chan->vchan.lock, flags); in jz4740_dma_tx_status()
478 vdesc = vchan_find_desc(&chan->vchan, cookie); in jz4740_dma_tx_status()
479 if (cookie == chan->desc->vdesc.tx.cookie) { in jz4740_dma_tx_status()
480 state->residue = jz4740_dma_desc_residue(chan, chan->desc, in jz4740_dma_tx_status()
481 chan->next_sg); in jz4740_dma_tx_status()
483 state->residue = jz4740_dma_desc_residue(chan, in jz4740_dma_tx_status()
486 state->residue = 0; in jz4740_dma_tx_status()
488 spin_unlock_irqrestore(&chan->vchan.lock, flags); in jz4740_dma_tx_status()
516 dmadev = devm_kzalloc(&pdev->dev, sizeof(*dmadev), GFP_KERNEL); in jz4740_dma_probe()
518 return -EINVAL; in jz4740_dma_probe()
520 dd = &dmadev->ddev; in jz4740_dma_probe()
523 dmadev->base = devm_ioremap_resource(&pdev->dev, res); in jz4740_dma_probe()
524 if (IS_ERR(dmadev->base)) in jz4740_dma_probe()
525 return PTR_ERR(dmadev->base); in jz4740_dma_probe()
527 dmadev->clk = clk_get(&pdev->dev, "dma"); in jz4740_dma_probe()
528 if (IS_ERR(dmadev->clk)) in jz4740_dma_probe()
529 return PTR_ERR(dmadev->clk); in jz4740_dma_probe()
531 clk_prepare_enable(dmadev->clk); in jz4740_dma_probe()
533 dma_cap_set(DMA_SLAVE, dd->cap_mask); in jz4740_dma_probe()
534 dma_cap_set(DMA_CYCLIC, dd->cap_mask); in jz4740_dma_probe()
535 dd->device_free_chan_resources = jz4740_dma_free_chan_resources; in jz4740_dma_probe()
536 dd->device_tx_status = jz4740_dma_tx_status; in jz4740_dma_probe()
537 dd->device_issue_pending = jz4740_dma_issue_pending; in jz4740_dma_probe()
538 dd->device_prep_slave_sg = jz4740_dma_prep_slave_sg; in jz4740_dma_probe()
539 dd->device_prep_dma_cyclic = jz4740_dma_prep_dma_cyclic; in jz4740_dma_probe()
540 dd->device_config = jz4740_dma_slave_config; in jz4740_dma_probe()
541 dd->device_terminate_all = jz4740_dma_terminate_all; in jz4740_dma_probe()
542 dd->src_addr_widths = JZ4740_DMA_BUSWIDTHS; in jz4740_dma_probe()
543 dd->dst_addr_widths = JZ4740_DMA_BUSWIDTHS; in jz4740_dma_probe()
544 dd->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); in jz4740_dma_probe()
545 dd->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; in jz4740_dma_probe()
546 dd->dev = &pdev->dev; in jz4740_dma_probe()
547 INIT_LIST_HEAD(&dd->channels); in jz4740_dma_probe()
550 chan = &dmadev->chan[i]; in jz4740_dma_probe()
551 chan->id = i; in jz4740_dma_probe()
552 chan->vchan.desc_free = jz4740_dma_desc_free; in jz4740_dma_probe()
553 vchan_init(&chan->vchan, dd); in jz4740_dma_probe()
561 ret = request_irq(irq, jz4740_dma_irq, 0, dev_name(&pdev->dev), dmadev); in jz4740_dma_probe()
572 clk_disable_unprepare(dmadev->clk); in jz4740_dma_probe()
581 &dmadev->channels, vchan.chan.device_node) { in jz4740_cleanup_vchan()
582 list_del(&chan->vchan.chan.device_node); in jz4740_cleanup_vchan()
583 tasklet_kill(&chan->vchan.task); in jz4740_cleanup_vchan()
595 jz4740_cleanup_vchan(&dmadev->ddev); in jz4740_dma_remove()
596 dma_async_device_unregister(&dmadev->ddev); in jz4740_dma_remove()
597 clk_disable_unprepare(dmadev->clk); in jz4740_dma_remove()
606 .name = "jz4740-dma",
611 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
612 MODULE_DESCRIPTION("JZ4740 DMA driver");