--- zzzz-none-000/linux-3.10.107/drivers/media/pci/cx88/cx88-mpeg.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/media/pci/cx88/cx88-mpeg.c 2021-02-04 17:41:59.000000000 +0000 @@ -86,21 +86,21 @@ static DEFINE_MUTEX(cx8802_mutex); /* ------------------------------------------------------------------ */ -static int cx8802_start_dma(struct cx8802_dev *dev, +int cx8802_start_dma(struct cx8802_dev *dev, struct cx88_dmaqueue *q, struct cx88_buffer *buf) { struct cx88_core *core = dev->core; dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n", - buf->vb.width, buf->vb.height, buf->vb.field); + core->width, core->height, core->field); /* setup fifo + format */ cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], dev->ts_packet_size, buf->risc.dma); /* write TS length to chip */ - cx_write(MO_TS_LNGTH, buf->vb.width); + cx_write(MO_TS_LNGTH, dev->ts_packet_size); /* FIXME: this needs a review. * also: move to cx88-blackbird + cx88-dvb source files? */ @@ -173,7 +173,7 @@ /* reset counter */ cx_write(MO_TS_GPCNTRL, GP_COUNT_CONTROL_RESET); - q->count = 1; + q->count = 0; /* enable irqs */ dprintk( 1, "setting the interrupt mask\n" ); @@ -210,83 +210,38 @@ dprintk( 1, "cx8802_restart_queue\n" ); if (list_empty(&q->active)) - { - struct cx88_buffer *prev; - prev = NULL; - - dprintk(1, "cx8802_restart_queue: queue is empty\n" ); - - for (;;) { - if (list_empty(&q->queued)) - return 0; - buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue); - if (NULL == prev) { - list_move_tail(&buf->vb.queue, &q->active); - cx8802_start_dma(dev, q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(1,"[%p/%d] restart_queue - first active\n", - buf,buf->vb.i); - - } else if (prev->vb.width == buf->vb.width && - prev->vb.height == buf->vb.height && - prev->fmt == buf->fmt) { - list_move_tail(&buf->vb.queue, &q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - dprintk(1,"[%p/%d] restart_queue - move to active\n", - buf,buf->vb.i); - } else { - return 0; - } - prev = buf; - } return 0; - } - buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); + buf = list_entry(q->active.next, struct cx88_buffer, list); dprintk(2,"restart_queue [%p/%d]: restart dma\n", - buf, buf->vb.i); + buf, buf->vb.vb2_buf.index); cx8802_start_dma(dev, q, buf); - list_for_each_entry(buf, &q->active, vb.queue) - buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); return 0; } /* ------------------------------------------------------------------ */ -int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev, - struct cx88_buffer *buf, enum v4l2_field field) +int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev, + struct cx88_buffer *buf) { int size = dev->ts_packet_size * dev->ts_packet_count; - struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); + struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb.vb2_buf, 0); + struct cx88_riscmem *risc = &buf->risc; int rc; - dprintk(1, "%s: %p\n", __func__, buf); - if (0 != buf->vb.baddr && buf->vb.bsize < size) + if (vb2_plane_size(&buf->vb.vb2_buf, 0) < size) return -EINVAL; + vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size); - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - buf->vb.width = dev->ts_packet_size; - buf->vb.height = dev->ts_packet_count; - buf->vb.size = size; - buf->vb.field = field /*V4L2_FIELD_TOP*/; - - if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL))) - goto fail; - cx88_risc_databuffer(dev->pci, &buf->risc, - dma->sglist, - buf->vb.width, buf->vb.height, 0); - } - buf->vb.state = VIDEOBUF_PREPARED; - return 0; - - fail: - cx88_free_buffer(q,buf); - return rc; + rc = cx88_risc_databuffer(dev->pci, risc, sgt->sgl, + dev->ts_packet_size, dev->ts_packet_count, 0); + if (rc) { + if (risc->cpu) + pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma); + memset(risc, 0, sizeof(*risc)); + return rc; + } + return 0; } void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) @@ -295,35 +250,31 @@ struct cx88_dmaqueue *cx88q = &dev->mpegq; dprintk( 1, "cx8802_buf_queue\n" ); - /* add jump to stopper */ - buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); - buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma); + /* add jump to start */ + buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 8); + buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC); + buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 8); if (list_empty(&cx88q->active)) { dprintk( 1, "queue is empty - first active\n" ); - list_add_tail(&buf->vb.queue,&cx88q->active); - cx8802_start_dma(dev, cx88q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = cx88q->count++; - mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT); + list_add_tail(&buf->list, &cx88q->active); dprintk(1,"[%p/%d] %s - first active\n", - buf, buf->vb.i, __func__); + buf, buf->vb.vb2_buf.index, __func__); } else { + buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1); dprintk( 1, "queue is not empty - append to active\n" ); - prev = list_entry(cx88q->active.prev, struct cx88_buffer, vb.queue); - list_add_tail(&buf->vb.queue,&cx88q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = cx88q->count++; + prev = list_entry(cx88q->active.prev, struct cx88_buffer, list); + list_add_tail(&buf->list, &cx88q->active); prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk( 1, "[%p/%d] %s - append to active\n", - buf, buf->vb.i, __func__); + buf, buf->vb.vb2_buf.index, __func__); } } /* ----------------------------------------------------------- */ -static void do_cancel_buffers(struct cx8802_dev *dev, const char *reason, int restart) +static void do_cancel_buffers(struct cx8802_dev *dev) { struct cx88_dmaqueue *q = &dev->mpegq; struct cx88_buffer *buf; @@ -331,41 +282,18 @@ spin_lock_irqsave(&dev->slock,flags); while (!list_empty(&q->active)) { - buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); - list_del(&buf->vb.queue); - buf->vb.state = VIDEOBUF_ERROR; - wake_up(&buf->vb.done); - dprintk(1,"[%p/%d] %s - dma=0x%08lx\n", - buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); - } - if (restart) - { - dprintk(1, "restarting queue\n" ); - cx8802_restart_queue(dev,q); + buf = list_entry(q->active.next, struct cx88_buffer, list); + list_del(&buf->list); + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); } spin_unlock_irqrestore(&dev->slock,flags); } void cx8802_cancel_buffers(struct cx8802_dev *dev) { - struct cx88_dmaqueue *q = &dev->mpegq; - dprintk( 1, "cx8802_cancel_buffers" ); - del_timer_sync(&q->timeout); - cx8802_stop_dma(dev); - do_cancel_buffers(dev,"cancel",0); -} - -static void cx8802_timeout(unsigned long data) -{ - struct cx8802_dev *dev = (struct cx8802_dev*)data; - - dprintk(1, "%s\n",__func__); - - if (debug) - cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); cx8802_stop_dma(dev); - do_cancel_buffers(dev,"timeout",1); + do_cancel_buffers(dev); } static const char * cx88_mpeg_irqs[32] = { @@ -411,19 +339,11 @@ spin_unlock(&dev->slock); } - /* risc2 y */ - if (status & 0x10) { - spin_lock(&dev->slock); - cx8802_restart_queue(dev,&dev->mpegq); - spin_unlock(&dev->slock); - } - /* other general errors */ if (status & 0x1f0100) { dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 ); spin_lock(&dev->slock); cx8802_stop_dma(dev); - cx8802_restart_queue(dev,&dev->mpegq); spin_unlock(&dev->slock); } } @@ -473,7 +393,8 @@ if (pci_enable_device(dev->pci)) return -EIO; pci_set_master(dev->pci); - if (!pci_dma_supported(dev->pci,DMA_BIT_MASK(32))) { + err = pci_set_dma_mask(dev->pci,DMA_BIT_MASK(32)); + if (err) { printk("%s/2: Oops: no 32bit PCI DMA ???\n",dev->core->name); return -EIO; } @@ -490,16 +411,10 @@ /* init dma queue */ INIT_LIST_HEAD(&dev->mpegq.active); - INIT_LIST_HEAD(&dev->mpegq.queued); - dev->mpegq.timeout.function = cx8802_timeout; - dev->mpegq.timeout.data = (unsigned long)dev; - init_timer(&dev->mpegq.timeout); - cx88_risc_stopper(dev->pci,&dev->mpegq.stopper, - MO_TS_DMACNTRL,0x11,0x00); /* get irq */ err = request_irq(dev->pci->irq, cx8802_irq, - IRQF_SHARED | IRQF_DISABLED, dev->core->name, dev); + IRQF_SHARED, dev->core->name, dev); if (err < 0) { printk(KERN_ERR "%s: can't get IRQ %d\n", dev->core->name, dev->pci->irq); @@ -520,10 +435,6 @@ /* unregister stuff */ free_irq(dev->pci->irq, dev); - pci_set_drvdata(dev->pci, NULL); - - /* free memory */ - btcx_riscmem_free(dev->pci,&dev->mpegq.stopper); } /* ----------------------------------------------------------- */ @@ -540,7 +451,6 @@ dprintk( 2, "suspend\n" ); printk("%s: suspend mpeg\n", core->name); cx8802_stop_dma(dev); - del_timer(&dev->mpegq.timeout); } spin_unlock_irqrestore(&dev->slock, flags); @@ -816,6 +726,11 @@ if (NULL == dev) goto fail_core; dev->pci = pci_dev; + dev->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev); + if (IS_ERR(dev->alloc_ctx)) { + err = PTR_ERR(dev->alloc_ctx); + goto fail_dev; + } dev->core = core; /* Maintain a reference so cx88-video can query the 8802 device. */ @@ -835,6 +750,8 @@ return 0; fail_free: + vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); + fail_dev: kfree(dev); fail_core: core->dvbdev = NULL; @@ -881,6 +798,7 @@ /* common */ cx8802_fini_common(dev); cx88_core_put(dev->core,dev->pci); + vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); kfree(dev); } @@ -903,31 +821,13 @@ .remove = cx8802_remove, }; -static int __init cx8802_init(void) -{ - printk(KERN_INFO "cx88/2: cx2388x MPEG-TS Driver Manager version %s loaded\n", - CX88_VERSION); - return pci_register_driver(&cx8802_pci_driver); -} - -static void __exit cx8802_fini(void) -{ - pci_unregister_driver(&cx8802_pci_driver); -} +module_pci_driver(cx8802_pci_driver); -module_init(cx8802_init); -module_exit(cx8802_fini); EXPORT_SYMBOL(cx8802_buf_prepare); EXPORT_SYMBOL(cx8802_buf_queue); EXPORT_SYMBOL(cx8802_cancel_buffers); +EXPORT_SYMBOL(cx8802_start_dma); EXPORT_SYMBOL(cx8802_register_driver); EXPORT_SYMBOL(cx8802_unregister_driver); EXPORT_SYMBOL(cx8802_get_driver); -/* ----------------------------------------------------------- */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off - */