linux/drivers/media/pci/tw686x/tw686x-core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2015 VanguardiaSur - www.vanguardiasur.com.ar
   4 *
   5 * Based on original driver by Krzysztof Ha?asa:
   6 * Copyright (C) 2015 Industrial Research Institute for Automation
   7 * and Measurements PIAP
   8 *
   9 * Notes
  10 * -----
  11 *
  12 * 1. Under stress-testing, it has been observed that the PCIe link
  13 * goes down, without reason. Therefore, the driver takes special care
  14 * to allow device hot-unplugging.
  15 *
  16 * 2. TW686X devices are capable of setting a few different DMA modes,
  17 * including: scatter-gather, field and frame modes. However,
  18 * under stress testings it has been found that the machine can
  19 * freeze completely if DMA registers are programmed while streaming
  20 * is active.
  21 *
  22 * Therefore, driver implements a dma_mode called 'memcpy' which
  23 * avoids cycling the DMA buffers, and insteads allocates extra DMA buffers
  24 * and then copies into vmalloc'ed user buffers.
  25 *
  26 * In addition to this, when streaming is on, the driver tries to access
  27 * hardware registers as infrequently as possible. This is done by using
  28 * a timer to limit the rate at which DMA is reset on DMA channels error.
  29 */
  30
  31#include <linux/init.h>
  32#include <linux/interrupt.h>
  33#include <linux/delay.h>
  34#include <linux/kernel.h>
  35#include <linux/module.h>
  36#include <linux/pci_ids.h>
  37#include <linux/slab.h>
  38#include <linux/timer.h>
  39
  40#include "tw686x.h"
  41#include "tw686x-regs.h"
  42
  43/*
  44 * This module parameter allows to control the DMA_TIMER_INTERVAL value.
  45 * The DMA_TIMER_INTERVAL register controls the minimum DMA interrupt
  46 * time span (iow, the maximum DMA interrupt rate) thus allowing for
  47 * IRQ coalescing.
  48 *
  49 * The chip datasheet does not mention a time unit for this value, so
  50 * users wanting fine-grain control over the interrupt rate should
  51 * determine the desired value through testing.
  52 */
  53static u32 dma_interval = 0x00098968;
  54module_param(dma_interval, int, 0444);
  55MODULE_PARM_DESC(dma_interval, "Minimum time span for DMA interrupting host");
  56
  57static unsigned int dma_mode = TW686X_DMA_MODE_MEMCPY;
  58static const char *dma_mode_name(unsigned int mode)
  59{
  60        switch (mode) {
  61        case TW686X_DMA_MODE_MEMCPY:
  62                return "memcpy";
  63        case TW686X_DMA_MODE_CONTIG:
  64                return "contig";
  65        case TW686X_DMA_MODE_SG:
  66                return "sg";
  67        default:
  68                return "unknown";
  69        }
  70}
  71
  72static int tw686x_dma_mode_get(char *buffer, const struct kernel_param *kp)
  73{
  74        return sprintf(buffer, "%s", dma_mode_name(dma_mode));
  75}
  76
  77static int tw686x_dma_mode_set(const char *val, const struct kernel_param *kp)
  78{
  79        if (!strcasecmp(val, dma_mode_name(TW686X_DMA_MODE_MEMCPY)))
  80                dma_mode = TW686X_DMA_MODE_MEMCPY;
  81        else if (!strcasecmp(val, dma_mode_name(TW686X_DMA_MODE_CONTIG)))
  82                dma_mode = TW686X_DMA_MODE_CONTIG;
  83        else if (!strcasecmp(val, dma_mode_name(TW686X_DMA_MODE_SG)))
  84                dma_mode = TW686X_DMA_MODE_SG;
  85        else
  86                return -EINVAL;
  87        return 0;
  88}
  89module_param_call(dma_mode, tw686x_dma_mode_set, tw686x_dma_mode_get,
  90                  &dma_mode, S_IRUGO|S_IWUSR);
  91MODULE_PARM_DESC(dma_mode, "DMA operation mode (memcpy/contig/sg, default=memcpy)");
  92
  93void tw686x_disable_channel(struct tw686x_dev *dev, unsigned int channel)
  94{
  95        u32 dma_en = reg_read(dev, DMA_CHANNEL_ENABLE);
  96        u32 dma_cmd = reg_read(dev, DMA_CMD);
  97
  98        dma_en &= ~BIT(channel);
  99        dma_cmd &= ~BIT(channel);
 100
 101        /* Must remove it from pending too */
 102        dev->pending_dma_en &= ~BIT(channel);
 103        dev->pending_dma_cmd &= ~BIT(channel);
 104
 105        /* Stop DMA if no channels are enabled */
 106        if (!dma_en)
 107                dma_cmd = 0;
 108        reg_write(dev, DMA_CHANNEL_ENABLE, dma_en);
 109        reg_write(dev, DMA_CMD, dma_cmd);
 110}
 111
 112void tw686x_enable_channel(struct tw686x_dev *dev, unsigned int channel)
 113{
 114        u32 dma_en = reg_read(dev, DMA_CHANNEL_ENABLE);
 115        u32 dma_cmd = reg_read(dev, DMA_CMD);
 116
 117        dev->pending_dma_en |= dma_en | BIT(channel);
 118        dev->pending_dma_cmd |= dma_cmd | DMA_CMD_ENABLE | BIT(channel);
 119}
 120
 121/*
 122 * The purpose of this awful hack is to avoid enabling the DMA
 123 * channels "too fast" which makes some TW686x devices very
 124 * angry and freeze the CPU (see note 1).
 125 */
 126static void tw686x_dma_delay(struct timer_list *t)
 127{
 128        struct tw686x_dev *dev = from_timer(dev, t, dma_delay_timer);
 129        unsigned long flags;
 130
 131        spin_lock_irqsave(&dev->lock, flags);
 132
 133        reg_write(dev, DMA_CHANNEL_ENABLE, dev->pending_dma_en);
 134        reg_write(dev, DMA_CMD, dev->pending_dma_cmd);
 135        dev->pending_dma_en = 0;
 136        dev->pending_dma_cmd = 0;
 137
 138        spin_unlock_irqrestore(&dev->lock, flags);
 139}
 140
 141static void tw686x_reset_channels(struct tw686x_dev *dev, unsigned int ch_mask)
 142{
 143        u32 dma_en, dma_cmd;
 144
 145        dma_en = reg_read(dev, DMA_CHANNEL_ENABLE);
 146        dma_cmd = reg_read(dev, DMA_CMD);
 147
 148        /*
 149         * Save pending register status, the timer will
 150         * restore them.
 151         */
 152        dev->pending_dma_en |= dma_en;
 153        dev->pending_dma_cmd |= dma_cmd;
 154
 155        /* Disable the reset channels */
 156        reg_write(dev, DMA_CHANNEL_ENABLE, dma_en & ~ch_mask);
 157
 158        if ((dma_en & ~ch_mask) == 0) {
 159                dev_dbg(&dev->pci_dev->dev, "reset: stopping DMA\n");
 160                dma_cmd &= ~DMA_CMD_ENABLE;
 161        }
 162        reg_write(dev, DMA_CMD, dma_cmd & ~ch_mask);
 163}
 164
 165static irqreturn_t tw686x_irq(int irq, void *dev_id)
 166{
 167        struct tw686x_dev *dev = (struct tw686x_dev *)dev_id;
 168        unsigned int video_requests, audio_requests, reset_ch;
 169        u32 fifo_status, fifo_signal, fifo_ov, fifo_bad, fifo_errors;
 170        u32 int_status, dma_en, video_en, pb_status;
 171        unsigned long flags;
 172
 173        int_status = reg_read(dev, INT_STATUS); /* cleared on read */
 174        fifo_status = reg_read(dev, VIDEO_FIFO_STATUS);
 175
 176        /* INT_STATUS does not include FIFO_STATUS errors! */
 177        if (!int_status && !TW686X_FIFO_ERROR(fifo_status))
 178                return IRQ_NONE;
 179
 180        if (int_status & INT_STATUS_DMA_TOUT) {
 181                dev_dbg(&dev->pci_dev->dev,
 182                        "DMA timeout. Resetting DMA for all channels\n");
 183                reset_ch = ~0;
 184                goto reset_channels;
 185        }
 186
 187        spin_lock_irqsave(&dev->lock, flags);
 188        dma_en = reg_read(dev, DMA_CHANNEL_ENABLE);
 189        spin_unlock_irqrestore(&dev->lock, flags);
 190
 191        video_en = dma_en & 0xff;
 192        fifo_signal = ~(fifo_status & 0xff) & video_en;
 193        fifo_ov = fifo_status >> 24;
 194        fifo_bad = fifo_status >> 16;
 195
 196        /* Mask of channels with signal and FIFO errors */
 197        fifo_errors = fifo_signal & (fifo_ov | fifo_bad);
 198
 199        reset_ch = 0;
 200        pb_status = reg_read(dev, PB_STATUS);
 201
 202        /* Coalesce video frame/error events */
 203        video_requests = (int_status & video_en) | fifo_errors;
 204        audio_requests = (int_status & dma_en) >> 8;
 205
 206        if (video_requests)
 207                tw686x_video_irq(dev, video_requests, pb_status,
 208                                 fifo_status, &reset_ch);
 209        if (audio_requests)
 210                tw686x_audio_irq(dev, audio_requests, pb_status);
 211
 212reset_channels:
 213        if (reset_ch) {
 214                spin_lock_irqsave(&dev->lock, flags);
 215                tw686x_reset_channels(dev, reset_ch);
 216                spin_unlock_irqrestore(&dev->lock, flags);
 217                mod_timer(&dev->dma_delay_timer,
 218                          jiffies + msecs_to_jiffies(100));
 219        }
 220
 221        return IRQ_HANDLED;
 222}
 223
 224static void tw686x_dev_release(struct v4l2_device *v4l2_dev)
 225{
 226        struct tw686x_dev *dev = container_of(v4l2_dev, struct tw686x_dev,
 227                                              v4l2_dev);
 228        unsigned int ch;
 229
 230        for (ch = 0; ch < max_channels(dev); ch++)
 231                v4l2_ctrl_handler_free(&dev->video_channels[ch].ctrl_handler);
 232
 233        v4l2_device_unregister(&dev->v4l2_dev);
 234
 235        kfree(dev->audio_channels);
 236        kfree(dev->video_channels);
 237        kfree(dev);
 238}
 239
 240static int tw686x_probe(struct pci_dev *pci_dev,
 241                        const struct pci_device_id *pci_id)
 242{
 243        struct tw686x_dev *dev;
 244        int err;
 245
 246        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 247        if (!dev)
 248                return -ENOMEM;
 249        dev->type = pci_id->driver_data;
 250        dev->dma_mode = dma_mode;
 251        sprintf(dev->name, "tw%04X", pci_dev->device);
 252
 253        dev->video_channels = kcalloc(max_channels(dev),
 254                sizeof(*dev->video_channels), GFP_KERNEL);
 255        if (!dev->video_channels) {
 256                err = -ENOMEM;
 257                goto free_dev;
 258        }
 259
 260        dev->audio_channels = kcalloc(max_channels(dev),
 261                sizeof(*dev->audio_channels), GFP_KERNEL);
 262        if (!dev->audio_channels) {
 263                err = -ENOMEM;
 264                goto free_video;
 265        }
 266
 267        pr_info("%s: PCI %s, IRQ %d, MMIO 0x%lx (%s mode)\n", dev->name,
 268                pci_name(pci_dev), pci_dev->irq,
 269                (unsigned long)pci_resource_start(pci_dev, 0),
 270                dma_mode_name(dma_mode));
 271
 272        dev->pci_dev = pci_dev;
 273        if (pci_enable_device(pci_dev)) {
 274                err = -EIO;
 275                goto free_audio;
 276        }
 277
 278        pci_set_master(pci_dev);
 279        err = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32));
 280        if (err) {
 281                dev_err(&pci_dev->dev, "32-bit PCI DMA not supported\n");
 282                err = -EIO;
 283                goto disable_pci;
 284        }
 285
 286        err = pci_request_regions(pci_dev, dev->name);
 287        if (err) {
 288                dev_err(&pci_dev->dev, "unable to request PCI region\n");
 289                goto disable_pci;
 290        }
 291
 292        dev->mmio = pci_ioremap_bar(pci_dev, 0);
 293        if (!dev->mmio) {
 294                dev_err(&pci_dev->dev, "unable to remap PCI region\n");
 295                err = -ENOMEM;
 296                goto free_region;
 297        }
 298
 299        /* Reset all subsystems */
 300        reg_write(dev, SYS_SOFT_RST, 0x0f);
 301        mdelay(1);
 302
 303        reg_write(dev, SRST[0], 0x3f);
 304        if (max_channels(dev) > 4)
 305                reg_write(dev, SRST[1], 0x3f);
 306
 307        /* Disable the DMA engine */
 308        reg_write(dev, DMA_CMD, 0);
 309        reg_write(dev, DMA_CHANNEL_ENABLE, 0);
 310
 311        /* Enable DMA FIFO overflow and pointer check */
 312        reg_write(dev, DMA_CONFIG, 0xffffff04);
 313        reg_write(dev, DMA_CHANNEL_TIMEOUT, 0x140c8584);
 314        reg_write(dev, DMA_TIMER_INTERVAL, dma_interval);
 315
 316        spin_lock_init(&dev->lock);
 317
 318        err = request_irq(pci_dev->irq, tw686x_irq, IRQF_SHARED,
 319                          dev->name, dev);
 320        if (err < 0) {
 321                dev_err(&pci_dev->dev, "unable to request interrupt\n");
 322                goto iounmap;
 323        }
 324
 325        timer_setup(&dev->dma_delay_timer, tw686x_dma_delay, 0);
 326
 327        /*
 328         * This must be set right before initializing v4l2_dev.
 329         * It's used to release resources after the last handle
 330         * held is released.
 331         */
 332        dev->v4l2_dev.release = tw686x_dev_release;
 333        err = tw686x_video_init(dev);
 334        if (err) {
 335                dev_err(&pci_dev->dev, "can't register video\n");
 336                goto free_irq;
 337        }
 338
 339        err = tw686x_audio_init(dev);
 340        if (err)
 341                dev_warn(&pci_dev->dev, "can't register audio\n");
 342
 343        pci_set_drvdata(pci_dev, dev);
 344        return 0;
 345
 346free_irq:
 347        free_irq(pci_dev->irq, dev);
 348iounmap:
 349        pci_iounmap(pci_dev, dev->mmio);
 350free_region:
 351        pci_release_regions(pci_dev);
 352disable_pci:
 353        pci_disable_device(pci_dev);
 354free_audio:
 355        kfree(dev->audio_channels);
 356free_video:
 357        kfree(dev->video_channels);
 358free_dev:
 359        kfree(dev);
 360        return err;
 361}
 362
 363static void tw686x_remove(struct pci_dev *pci_dev)
 364{
 365        struct tw686x_dev *dev = pci_get_drvdata(pci_dev);
 366        unsigned long flags;
 367
 368        /* This guarantees the IRQ handler is no longer running,
 369         * which means we can kiss good-bye some resources.
 370         */
 371        free_irq(pci_dev->irq, dev);
 372
 373        tw686x_video_free(dev);
 374        tw686x_audio_free(dev);
 375        del_timer_sync(&dev->dma_delay_timer);
 376
 377        pci_iounmap(pci_dev, dev->mmio);
 378        pci_release_regions(pci_dev);
 379        pci_disable_device(pci_dev);
 380
 381        /*
 382         * Setting pci_dev to NULL allows to detect hardware is no longer
 383         * available and will be used by vb2_ops. This is required because
 384         * the device sometimes hot-unplugs itself as the result of a PCIe
 385         * link down.
 386         * The lock is really important here.
 387         */
 388        spin_lock_irqsave(&dev->lock, flags);
 389        dev->pci_dev = NULL;
 390        spin_unlock_irqrestore(&dev->lock, flags);
 391
 392        /*
 393         * This calls tw686x_dev_release if it's the last reference.
 394         * Otherwise, release is postponed until there are no users left.
 395         */
 396        v4l2_device_put(&dev->v4l2_dev);
 397}
 398
 399/*
 400 * On TW6864 and TW6868, all channels share the pair of video DMA SG tables,
 401 * with 10-bit start_idx and end_idx determining start and end of frame buffer
 402 * for particular channel.
 403 * TW6868 with all its 8 channels would be problematic (only 127 SG entries per
 404 * channel) but we support only 4 channels on this chip anyway (the first
 405 * 4 channels are driven with internal video decoder, the other 4 would require
 406 * an external TW286x part).
 407 *
 408 * On TW6865 and TW6869, each channel has its own DMA SG table, with indexes
 409 * starting with 0. Both chips have complete sets of internal video decoders
 410 * (respectively 4 or 8-channel).
 411 *
 412 * All chips have separate SG tables for two video frames.
 413 */
 414
 415/* driver_data is number of A/V channels */
 416static const struct pci_device_id tw686x_pci_tbl[] = {
 417        {
 418                PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, 0x6864),
 419                .driver_data = 4
 420        },
 421        {
 422                PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, 0x6865), /* not tested */
 423                .driver_data = 4 | TYPE_SECOND_GEN
 424        },
 425        /*
 426         * TW6868 supports 8 A/V channels with an external TW2865 chip;
 427         * not supported by the driver.
 428         */
 429        {
 430                PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, 0x6868), /* not tested */
 431                .driver_data = 4
 432        },
 433        {
 434                PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, 0x6869),
 435                .driver_data = 8 | TYPE_SECOND_GEN},
 436        {}
 437};
 438MODULE_DEVICE_TABLE(pci, tw686x_pci_tbl);
 439
 440static struct pci_driver tw686x_pci_driver = {
 441        .name = "tw686x",
 442        .id_table = tw686x_pci_tbl,
 443        .probe = tw686x_probe,
 444        .remove = tw686x_remove,
 445};
 446module_pci_driver(tw686x_pci_driver);
 447
 448MODULE_DESCRIPTION("Driver for video frame grabber cards based on Intersil/Techwell TW686[4589]");
 449MODULE_AUTHOR("Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>");
 450MODULE_AUTHOR("Krzysztof Ha?asa <khalasa@piap.pl>");
 451MODULE_LICENSE("GPL v2");
 452