2 * Copyright (C) 2015 VanguardiaSur - www.vanguardiasur.com.ar
4 * Based on original driver by Krzysztof Ha?asa:
5 * Copyright (C) 2015 Industrial Research Institute for Automation
6 * and Measurements PIAP
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License
10 * as published by the Free Software Foundation.
15 * 1. Under stress-testing, it has been observed that the PCIe link
16 * goes down, without reason. Therefore, the driver takes special care
17 * to allow device hot-unplugging.
19 * 2. TW686X devices are capable of setting a few different DMA modes,
20 * including: scatter-gather, field and frame modes. However,
21 * under stress testings it has been found that the machine can
22 * freeze completely if DMA registers are programmed while streaming
25 * Therefore, driver implements a dma_mode called 'memcpy' which
26 * avoids cycling the DMA buffers, and insteads allocates extra DMA buffers
27 * and then copies into vmalloc'ed user buffers.
29 * In addition to this, when streaming is on, the driver tries to access
30 * hardware registers as infrequently as possible. This is done by using
31 * a timer to limit the rate at which DMA is reset on DMA channels error.
34 #include <linux/init.h>
35 #include <linux/interrupt.h>
36 #include <linux/delay.h>
37 #include <linux/kernel.h>
38 #include <linux/module.h>
39 #include <linux/pci_ids.h>
40 #include <linux/slab.h>
41 #include <linux/timer.h>
44 #include "tw686x-regs.h"
47 * This module parameter allows to control the DMA_TIMER_INTERVAL value.
48 * The DMA_TIMER_INTERVAL register controls the minimum DMA interrupt
49 * time span (iow, the maximum DMA interrupt rate) thus allowing for
52 * The chip datasheet does not mention a time unit for this value, so
53 * users wanting fine-grain control over the interrupt rate should
54 * determine the desired value through testing.
56 static u32 dma_interval
= 0x00098968;
57 module_param(dma_interval
, int, 0444);
58 MODULE_PARM_DESC(dma_interval
, "Minimum time span for DMA interrupting host");
60 static unsigned int dma_mode
= TW686X_DMA_MODE_MEMCPY
;
61 static const char *dma_mode_name(unsigned int mode
)
64 case TW686X_DMA_MODE_MEMCPY
:
66 case TW686X_DMA_MODE_CONTIG
:
68 case TW686X_DMA_MODE_SG
:
75 static int tw686x_dma_mode_get(char *buffer
, struct kernel_param
*kp
)
77 return sprintf(buffer
, dma_mode_name(dma_mode
));
80 static int tw686x_dma_mode_set(const char *val
, struct kernel_param
*kp
)
82 if (!strcasecmp(val
, dma_mode_name(TW686X_DMA_MODE_MEMCPY
)))
83 dma_mode
= TW686X_DMA_MODE_MEMCPY
;
84 else if (!strcasecmp(val
, dma_mode_name(TW686X_DMA_MODE_CONTIG
)))
85 dma_mode
= TW686X_DMA_MODE_CONTIG
;
86 else if (!strcasecmp(val
, dma_mode_name(TW686X_DMA_MODE_SG
)))
87 dma_mode
= TW686X_DMA_MODE_SG
;
92 module_param_call(dma_mode
, tw686x_dma_mode_set
, tw686x_dma_mode_get
,
93 &dma_mode
, S_IRUGO
|S_IWUSR
);
94 MODULE_PARM_DESC(dma_mode
, "DMA operation mode (memcpy/contig/sg, default=memcpy)");
96 void tw686x_disable_channel(struct tw686x_dev
*dev
, unsigned int channel
)
98 u32 dma_en
= reg_read(dev
, DMA_CHANNEL_ENABLE
);
99 u32 dma_cmd
= reg_read(dev
, DMA_CMD
);
101 dma_en
&= ~BIT(channel
);
102 dma_cmd
&= ~BIT(channel
);
104 /* Must remove it from pending too */
105 dev
->pending_dma_en
&= ~BIT(channel
);
106 dev
->pending_dma_cmd
&= ~BIT(channel
);
108 /* Stop DMA if no channels are enabled */
111 reg_write(dev
, DMA_CHANNEL_ENABLE
, dma_en
);
112 reg_write(dev
, DMA_CMD
, dma_cmd
);
115 void tw686x_enable_channel(struct tw686x_dev
*dev
, unsigned int channel
)
117 u32 dma_en
= reg_read(dev
, DMA_CHANNEL_ENABLE
);
118 u32 dma_cmd
= reg_read(dev
, DMA_CMD
);
120 dev
->pending_dma_en
|= dma_en
| BIT(channel
);
121 dev
->pending_dma_cmd
|= dma_cmd
| DMA_CMD_ENABLE
| BIT(channel
);
125 * The purpose of this awful hack is to avoid enabling the DMA
126 * channels "too fast" which makes some TW686x devices very
127 * angry and freeze the CPU (see note 1).
129 static void tw686x_dma_delay(unsigned long data
)
131 struct tw686x_dev
*dev
= (struct tw686x_dev
*)data
;
134 spin_lock_irqsave(&dev
->lock
, flags
);
136 reg_write(dev
, DMA_CHANNEL_ENABLE
, dev
->pending_dma_en
);
137 reg_write(dev
, DMA_CMD
, dev
->pending_dma_cmd
);
138 dev
->pending_dma_en
= 0;
139 dev
->pending_dma_cmd
= 0;
141 spin_unlock_irqrestore(&dev
->lock
, flags
);
144 static void tw686x_reset_channels(struct tw686x_dev
*dev
, unsigned int ch_mask
)
148 dma_en
= reg_read(dev
, DMA_CHANNEL_ENABLE
);
149 dma_cmd
= reg_read(dev
, DMA_CMD
);
152 * Save pending register status, the timer will
155 dev
->pending_dma_en
|= dma_en
;
156 dev
->pending_dma_cmd
|= dma_cmd
;
158 /* Disable the reset channels */
159 reg_write(dev
, DMA_CHANNEL_ENABLE
, dma_en
& ~ch_mask
);
161 if ((dma_en
& ~ch_mask
) == 0) {
162 dev_dbg(&dev
->pci_dev
->dev
, "reset: stopping DMA\n");
163 dma_cmd
&= ~DMA_CMD_ENABLE
;
165 reg_write(dev
, DMA_CMD
, dma_cmd
& ~ch_mask
);
168 static irqreturn_t
tw686x_irq(int irq
, void *dev_id
)
170 struct tw686x_dev
*dev
= (struct tw686x_dev
*)dev_id
;
171 unsigned int video_requests
, audio_requests
, reset_ch
;
172 u32 fifo_status
, fifo_signal
, fifo_ov
, fifo_bad
, fifo_errors
;
173 u32 int_status
, dma_en
, video_en
, pb_status
;
176 int_status
= reg_read(dev
, INT_STATUS
); /* cleared on read */
177 fifo_status
= reg_read(dev
, VIDEO_FIFO_STATUS
);
179 /* INT_STATUS does not include FIFO_STATUS errors! */
180 if (!int_status
&& !TW686X_FIFO_ERROR(fifo_status
))
183 if (int_status
& INT_STATUS_DMA_TOUT
) {
184 dev_dbg(&dev
->pci_dev
->dev
,
185 "DMA timeout. Resetting DMA for all channels\n");
190 spin_lock_irqsave(&dev
->lock
, flags
);
191 dma_en
= reg_read(dev
, DMA_CHANNEL_ENABLE
);
192 spin_unlock_irqrestore(&dev
->lock
, flags
);
194 video_en
= dma_en
& 0xff;
195 fifo_signal
= ~(fifo_status
& 0xff) & video_en
;
196 fifo_ov
= fifo_status
>> 24;
197 fifo_bad
= fifo_status
>> 16;
199 /* Mask of channels with signal and FIFO errors */
200 fifo_errors
= fifo_signal
& (fifo_ov
| fifo_bad
);
203 pb_status
= reg_read(dev
, PB_STATUS
);
205 /* Coalesce video frame/error events */
206 video_requests
= (int_status
& video_en
) | fifo_errors
;
207 audio_requests
= (int_status
& dma_en
) >> 8;
210 tw686x_video_irq(dev
, video_requests
, pb_status
,
211 fifo_status
, &reset_ch
);
213 tw686x_audio_irq(dev
, audio_requests
, pb_status
);
217 spin_lock_irqsave(&dev
->lock
, flags
);
218 tw686x_reset_channels(dev
, reset_ch
);
219 spin_unlock_irqrestore(&dev
->lock
, flags
);
220 mod_timer(&dev
->dma_delay_timer
,
221 jiffies
+ msecs_to_jiffies(100));
227 static void tw686x_dev_release(struct v4l2_device
*v4l2_dev
)
229 struct tw686x_dev
*dev
= container_of(v4l2_dev
, struct tw686x_dev
,
233 for (ch
= 0; ch
< max_channels(dev
); ch
++)
234 v4l2_ctrl_handler_free(&dev
->video_channels
[ch
].ctrl_handler
);
236 v4l2_device_unregister(&dev
->v4l2_dev
);
238 kfree(dev
->audio_channels
);
239 kfree(dev
->video_channels
);
243 static int tw686x_probe(struct pci_dev
*pci_dev
,
244 const struct pci_device_id
*pci_id
)
246 struct tw686x_dev
*dev
;
249 dev
= kzalloc(sizeof(*dev
), GFP_KERNEL
);
252 dev
->type
= pci_id
->driver_data
;
253 dev
->dma_mode
= dma_mode
;
254 sprintf(dev
->name
, "tw%04X", pci_dev
->device
);
256 dev
->video_channels
= kcalloc(max_channels(dev
),
257 sizeof(*dev
->video_channels
), GFP_KERNEL
);
258 if (!dev
->video_channels
) {
263 dev
->audio_channels
= kcalloc(max_channels(dev
),
264 sizeof(*dev
->audio_channels
), GFP_KERNEL
);
265 if (!dev
->audio_channels
) {
270 pr_info("%s: PCI %s, IRQ %d, MMIO 0x%lx (%s mode)\n", dev
->name
,
271 pci_name(pci_dev
), pci_dev
->irq
,
272 (unsigned long)pci_resource_start(pci_dev
, 0),
273 dma_mode_name(dma_mode
));
275 dev
->pci_dev
= pci_dev
;
276 if (pci_enable_device(pci_dev
)) {
281 pci_set_master(pci_dev
);
282 err
= pci_set_dma_mask(pci_dev
, DMA_BIT_MASK(32));
284 dev_err(&pci_dev
->dev
, "32-bit PCI DMA not supported\n");
289 err
= pci_request_regions(pci_dev
, dev
->name
);
291 dev_err(&pci_dev
->dev
, "unable to request PCI region\n");
295 dev
->mmio
= pci_ioremap_bar(pci_dev
, 0);
297 dev_err(&pci_dev
->dev
, "unable to remap PCI region\n");
302 /* Reset all subsystems */
303 reg_write(dev
, SYS_SOFT_RST
, 0x0f);
306 reg_write(dev
, SRST
[0], 0x3f);
307 if (max_channels(dev
) > 4)
308 reg_write(dev
, SRST
[1], 0x3f);
310 /* Disable the DMA engine */
311 reg_write(dev
, DMA_CMD
, 0);
312 reg_write(dev
, DMA_CHANNEL_ENABLE
, 0);
314 /* Enable DMA FIFO overflow and pointer check */
315 reg_write(dev
, DMA_CONFIG
, 0xffffff04);
316 reg_write(dev
, DMA_CHANNEL_TIMEOUT
, 0x140c8584);
317 reg_write(dev
, DMA_TIMER_INTERVAL
, dma_interval
);
319 spin_lock_init(&dev
->lock
);
321 err
= request_irq(pci_dev
->irq
, tw686x_irq
, IRQF_SHARED
,
324 dev_err(&pci_dev
->dev
, "unable to request interrupt\n");
328 setup_timer(&dev
->dma_delay_timer
,
329 tw686x_dma_delay
, (unsigned long) dev
);
332 * This must be set right before initializing v4l2_dev.
333 * It's used to release resources after the last handle
336 dev
->v4l2_dev
.release
= tw686x_dev_release
;
337 err
= tw686x_video_init(dev
);
339 dev_err(&pci_dev
->dev
, "can't register video\n");
343 err
= tw686x_audio_init(dev
);
345 dev_warn(&pci_dev
->dev
, "can't register audio\n");
347 pci_set_drvdata(pci_dev
, dev
);
351 free_irq(pci_dev
->irq
, dev
);
353 pci_iounmap(pci_dev
, dev
->mmio
);
355 pci_release_regions(pci_dev
);
357 pci_disable_device(pci_dev
);
359 kfree(dev
->audio_channels
);
361 kfree(dev
->video_channels
);
367 static void tw686x_remove(struct pci_dev
*pci_dev
)
369 struct tw686x_dev
*dev
= pci_get_drvdata(pci_dev
);
372 /* This guarantees the IRQ handler is no longer running,
373 * which means we can kiss good-bye some resources.
375 free_irq(pci_dev
->irq
, dev
);
377 tw686x_video_free(dev
);
378 tw686x_audio_free(dev
);
379 del_timer_sync(&dev
->dma_delay_timer
);
381 pci_iounmap(pci_dev
, dev
->mmio
);
382 pci_release_regions(pci_dev
);
383 pci_disable_device(pci_dev
);
386 * Setting pci_dev to NULL allows to detect hardware is no longer
387 * available and will be used by vb2_ops. This is required because
388 * the device sometimes hot-unplugs itself as the result of a PCIe
390 * The lock is really important here.
392 spin_lock_irqsave(&dev
->lock
, flags
);
394 spin_unlock_irqrestore(&dev
->lock
, flags
);
397 * This calls tw686x_dev_release if it's the last reference.
398 * Otherwise, release is postponed until there are no users left.
400 v4l2_device_put(&dev
->v4l2_dev
);
404 * On TW6864 and TW6868, all channels share the pair of video DMA SG tables,
405 * with 10-bit start_idx and end_idx determining start and end of frame buffer
406 * for particular channel.
407 * TW6868 with all its 8 channels would be problematic (only 127 SG entries per
408 * channel) but we support only 4 channels on this chip anyway (the first
409 * 4 channels are driven with internal video decoder, the other 4 would require
410 * an external TW286x part).
412 * On TW6865 and TW6869, each channel has its own DMA SG table, with indexes
413 * starting with 0. Both chips have complete sets of internal video decoders
414 * (respectively 4 or 8-channel).
416 * All chips have separate SG tables for two video frames.
419 /* driver_data is number of A/V channels */
420 static const struct pci_device_id tw686x_pci_tbl
[] = {
422 PCI_DEVICE(PCI_VENDOR_ID_TECHWELL
, 0x6864),
426 PCI_DEVICE(PCI_VENDOR_ID_TECHWELL
, 0x6865), /* not tested */
427 .driver_data
= 4 | TYPE_SECOND_GEN
430 * TW6868 supports 8 A/V channels with an external TW2865 chip;
431 * not supported by the driver.
434 PCI_DEVICE(PCI_VENDOR_ID_TECHWELL
, 0x6868), /* not tested */
438 PCI_DEVICE(PCI_VENDOR_ID_TECHWELL
, 0x6869),
439 .driver_data
= 8 | TYPE_SECOND_GEN
},
442 MODULE_DEVICE_TABLE(pci
, tw686x_pci_tbl
);
444 static struct pci_driver tw686x_pci_driver
= {
446 .id_table
= tw686x_pci_tbl
,
447 .probe
= tw686x_probe
,
448 .remove
= tw686x_remove
,
450 module_pci_driver(tw686x_pci_driver
);
452 MODULE_DESCRIPTION("Driver for video frame grabber cards based on Intersil/Techwell TW686[4589]");
453 MODULE_AUTHOR("Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>");
454 MODULE_AUTHOR("Krzysztof Ha?asa <khalasa@piap.pl>");
455 MODULE_LICENSE("GPL v2");