Lines Matching +full:memcpy +full:- +full:channels
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2015 VanguardiaSur - www.vanguardiasur.com.ar
10 * -----
12 * 1. Under stress-testing, it has been observed that the PCIe link
14 * to allow device hot-unplugging.
17 * including: scatter-gather, field and frame modes. However,
22 * Therefore, driver implements a dma_mode called 'memcpy' which
28 * a timer to limit the rate at which DMA is reset on DMA channels error.
41 #include "tw686x-regs.h"
50 * users wanting fine-grain control over the interrupt rate should
62 return "memcpy"; in dma_mode_name()
86 return -EINVAL; in tw686x_dma_mode_set()
91 MODULE_PARM_DESC(dma_mode, "DMA operation mode (memcpy/contig/sg, default=memcpy)");
102 dev->pending_dma_en &= ~BIT(channel); in tw686x_disable_channel()
103 dev->pending_dma_cmd &= ~BIT(channel); in tw686x_disable_channel()
105 /* Stop DMA if no channels are enabled */ in tw686x_disable_channel()
117 dev->pending_dma_en |= dma_en | BIT(channel); in tw686x_enable_channel()
118 dev->pending_dma_cmd |= dma_cmd | DMA_CMD_ENABLE | BIT(channel); in tw686x_enable_channel()
123 * channels "too fast" which makes some TW686x devices very
131 spin_lock_irqsave(&dev->lock, flags); in tw686x_dma_delay()
133 reg_write(dev, DMA_CHANNEL_ENABLE, dev->pending_dma_en); in tw686x_dma_delay()
134 reg_write(dev, DMA_CMD, dev->pending_dma_cmd); in tw686x_dma_delay()
135 dev->pending_dma_en = 0; in tw686x_dma_delay()
136 dev->pending_dma_cmd = 0; in tw686x_dma_delay()
138 spin_unlock_irqrestore(&dev->lock, flags); in tw686x_dma_delay()
152 dev->pending_dma_en |= dma_en; in tw686x_reset_channels()
153 dev->pending_dma_cmd |= dma_cmd; in tw686x_reset_channels()
155 /* Disable the reset channels */ in tw686x_reset_channels()
159 dev_dbg(&dev->pci_dev->dev, "reset: stopping DMA\n"); in tw686x_reset_channels()
181 dev_dbg(&dev->pci_dev->dev, in tw686x_irq()
182 "DMA timeout. Resetting DMA for all channels\n"); in tw686x_irq()
187 spin_lock_irqsave(&dev->lock, flags); in tw686x_irq()
189 spin_unlock_irqrestore(&dev->lock, flags); in tw686x_irq()
196 /* Mask of channels with signal and FIFO errors */ in tw686x_irq()
214 spin_lock_irqsave(&dev->lock, flags); in tw686x_irq()
216 spin_unlock_irqrestore(&dev->lock, flags); in tw686x_irq()
217 mod_timer(&dev->dma_delay_timer, in tw686x_irq()
231 v4l2_ctrl_handler_free(&dev->video_channels[ch].ctrl_handler); in tw686x_dev_release()
233 v4l2_device_unregister(&dev->v4l2_dev); in tw686x_dev_release()
235 kfree(dev->audio_channels); in tw686x_dev_release()
236 kfree(dev->video_channels); in tw686x_dev_release()
248 return -ENOMEM; in tw686x_probe()
249 dev->type = pci_id->driver_data; in tw686x_probe()
250 dev->dma_mode = dma_mode; in tw686x_probe()
251 sprintf(dev->name, "tw%04X", pci_dev->device); in tw686x_probe()
253 dev->video_channels = kcalloc(max_channels(dev), in tw686x_probe()
254 sizeof(*dev->video_channels), GFP_KERNEL); in tw686x_probe()
255 if (!dev->video_channels) { in tw686x_probe()
256 err = -ENOMEM; in tw686x_probe()
260 dev->audio_channels = kcalloc(max_channels(dev), in tw686x_probe()
261 sizeof(*dev->audio_channels), GFP_KERNEL); in tw686x_probe()
262 if (!dev->audio_channels) { in tw686x_probe()
263 err = -ENOMEM; in tw686x_probe()
267 pr_info("%s: PCI %s, IRQ %d, MMIO 0x%lx (%s mode)\n", dev->name, in tw686x_probe()
268 pci_name(pci_dev), pci_dev->irq, in tw686x_probe()
272 dev->pci_dev = pci_dev; in tw686x_probe()
274 err = -EIO; in tw686x_probe()
279 err = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32)); in tw686x_probe()
281 dev_err(&pci_dev->dev, "32-bit PCI DMA not supported\n"); in tw686x_probe()
282 err = -EIO; in tw686x_probe()
286 err = pci_request_regions(pci_dev, dev->name); in tw686x_probe()
288 dev_err(&pci_dev->dev, "unable to request PCI region\n"); in tw686x_probe()
292 dev->mmio = pci_ioremap_bar(pci_dev, 0); in tw686x_probe()
293 if (!dev->mmio) { in tw686x_probe()
294 dev_err(&pci_dev->dev, "unable to remap PCI region\n"); in tw686x_probe()
295 err = -ENOMEM; in tw686x_probe()
316 spin_lock_init(&dev->lock); in tw686x_probe()
318 timer_setup(&dev->dma_delay_timer, tw686x_dma_delay, 0); in tw686x_probe()
325 dev->v4l2_dev.release = tw686x_dev_release; in tw686x_probe()
328 dev_err(&pci_dev->dev, "can't register video\n"); in tw686x_probe()
334 dev_warn(&pci_dev->dev, "can't register audio\n"); in tw686x_probe()
336 err = request_irq(pci_dev->irq, tw686x_irq, IRQF_SHARED, in tw686x_probe()
337 dev->name, dev); in tw686x_probe()
339 dev_err(&pci_dev->dev, "unable to request interrupt\n"); in tw686x_probe()
350 pci_iounmap(pci_dev, dev->mmio); in tw686x_probe()
356 kfree(dev->audio_channels); in tw686x_probe()
358 kfree(dev->video_channels); in tw686x_probe()
370 * which means we can kiss good-bye some resources. in tw686x_remove()
372 free_irq(pci_dev->irq, dev); in tw686x_remove()
376 del_timer_sync(&dev->dma_delay_timer); in tw686x_remove()
378 pci_iounmap(pci_dev, dev->mmio); in tw686x_remove()
385 * the device sometimes hot-unplugs itself as the result of a PCIe in tw686x_remove()
389 spin_lock_irqsave(&dev->lock, flags); in tw686x_remove()
390 dev->pci_dev = NULL; in tw686x_remove()
391 spin_unlock_irqrestore(&dev->lock, flags); in tw686x_remove()
397 v4l2_device_put(&dev->v4l2_dev); in tw686x_remove()
401 * On TW6864 and TW6868, all channels share the pair of video DMA SG tables,
402 * with 10-bit start_idx and end_idx determining start and end of frame buffer
404 * TW6868 with all its 8 channels would be problematic (only 127 SG entries per
405 * channel) but we support only 4 channels on this chip anyway (the first
406 * 4 channels are driven with internal video decoder, the other 4 would require
411 * (respectively 4 or 8-channel).
416 /* driver_data is number of A/V channels */
427 * TW6868 supports 8 A/V channels with an external TW2865 chip;