cx88-mpeg.c (6f11adc6a5e3378aeb13d9a19c427cbec05805be) cx88-mpeg.c (0b6b6302d983236f8b5d6d6602b91a6d1e144896)
1/*
2 *
3 * Support for the mpeg transport stream transfers
4 * PCI function #2 of the cx2388x.
5 *
6 * (c) 2004 Jelle Foks <jelle@foks.us>
7 * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
8 * (c) 2004 Gerd Knorr <kraxel@bytesex.org>

--- 72 unchanged lines hidden (view full) ---

81#define flush_request_modules(dev)
82#endif /* CONFIG_MODULES */
83
84
85static LIST_HEAD(cx8802_devlist);
86static DEFINE_MUTEX(cx8802_mutex);
87/* ------------------------------------------------------------------ */
88
1/*
2 *
3 * Support for the mpeg transport stream transfers
4 * PCI function #2 of the cx2388x.
5 *
6 * (c) 2004 Jelle Foks <jelle@foks.us>
7 * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
8 * (c) 2004 Gerd Knorr <kraxel@bytesex.org>

--- 72 unchanged lines hidden (view full) ---

81#define flush_request_modules(dev)
82#endif /* CONFIG_MODULES */
83
84
85static LIST_HEAD(cx8802_devlist);
86static DEFINE_MUTEX(cx8802_mutex);
87/* ------------------------------------------------------------------ */
88
89static int cx8802_start_dma(struct cx8802_dev *dev,
89int cx8802_start_dma(struct cx8802_dev *dev,
90 struct cx88_dmaqueue *q,
91 struct cx88_buffer *buf)
92{
93 struct cx88_core *core = dev->core;
94
95 dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n",
90 struct cx88_dmaqueue *q,
91 struct cx88_buffer *buf)
92{
93 struct cx88_core *core = dev->core;
94
95 dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n",
96 buf->vb.width, buf->vb.height, buf->vb.field);
96 dev->width, dev->height, dev->field);
97
98 /* setup fifo + format */
99 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
100 dev->ts_packet_size, buf->risc.dma);
101
102 /* write TS length to chip */
97
98 /* setup fifo + format */
99 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
100 dev->ts_packet_size, buf->risc.dma);
101
102 /* write TS length to chip */
103 cx_write(MO_TS_LNGTH, buf->vb.width);
103 cx_write(MO_TS_LNGTH, dev->ts_packet_size);
104
105 /* FIXME: this needs a review.
106 * also: move to cx88-blackbird + cx88-dvb source files? */
107
108 dprintk( 1, "core->active_type_id = 0x%08x\n", core->active_type_id);
109
110 if ( (core->active_type_id == CX88_MPEG_DVB) &&
111 (core->board.mpeg & CX88_MPEG_DVB) ) {

--- 95 unchanged lines hidden (view full) ---

207 struct cx88_dmaqueue *q)
208{
209 struct cx88_buffer *buf;
210
211 dprintk( 1, "cx8802_restart_queue\n" );
212 if (list_empty(&q->active))
213 return 0;
214
104
105 /* FIXME: this needs a review.
106 * also: move to cx88-blackbird + cx88-dvb source files? */
107
108 dprintk( 1, "core->active_type_id = 0x%08x\n", core->active_type_id);
109
110 if ( (core->active_type_id == CX88_MPEG_DVB) &&
111 (core->board.mpeg & CX88_MPEG_DVB) ) {

--- 95 unchanged lines hidden (view full) ---

207 struct cx88_dmaqueue *q)
208{
209 struct cx88_buffer *buf;
210
211 dprintk( 1, "cx8802_restart_queue\n" );
212 if (list_empty(&q->active))
213 return 0;
214
215 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
215 buf = list_entry(q->active.next, struct cx88_buffer, list);
216 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
216 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
217 buf, buf->vb.i);
217 buf, buf->vb.v4l2_buf.index);
218 cx8802_start_dma(dev, q, buf);
218 cx8802_start_dma(dev, q, buf);
219 list_for_each_entry(buf, &q->active, vb.queue)
219 list_for_each_entry(buf, &q->active, list)
220 buf->count = q->count++;
220 buf->count = q->count++;
221 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
222 return 0;
223}
224
225/* ------------------------------------------------------------------ */
226
221 return 0;
222}
223
224/* ------------------------------------------------------------------ */
225
227int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev,
226int cx8802_buf_prepare(struct vb2_queue *q, struct cx8802_dev *dev,
228 struct cx88_buffer *buf, enum v4l2_field field)
229{
230 int size = dev->ts_packet_size * dev->ts_packet_count;
227 struct cx88_buffer *buf, enum v4l2_field field)
228{
229 int size = dev->ts_packet_size * dev->ts_packet_count;
231 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
230 struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb, 0);
232 int rc;
233
231 int rc;
232
234 dprintk(1, "%s: %p\n", __func__, buf);
235 if (0 != buf->vb.baddr && buf->vb.bsize < size)
233 if (vb2_plane_size(&buf->vb, 0) < size)
236 return -EINVAL;
234 return -EINVAL;
235 vb2_set_plane_payload(&buf->vb, 0, size);
237
236
238 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
239 buf->vb.width = dev->ts_packet_size;
240 buf->vb.height = dev->ts_packet_count;
241 buf->vb.size = size;
242 buf->vb.field = field /*V4L2_FIELD_TOP*/;
237 rc = dma_map_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
238 if (!rc)
239 return -EIO;
243
240
244 if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
245 goto fail;
246 cx88_risc_databuffer(dev->pci, &buf->risc,
247 dma->sglist,
248 buf->vb.width, buf->vb.height, 0);
249 }
250 buf->vb.state = VIDEOBUF_PREPARED;
241 cx88_risc_databuffer(dev->pci, &buf->risc, sgt->sgl,
242 dev->ts_packet_size, dev->ts_packet_count, 0);
251 return 0;
243 return 0;
252
253 fail:
254 cx88_free_buffer(q,buf);
255 return rc;
256}
257
258void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
259{
260 struct cx88_buffer *prev;
261 struct cx88_dmaqueue *cx88q = &dev->mpegq;
262
263 dprintk( 1, "cx8802_buf_queue\n" );
244}
245
246void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
247{
248 struct cx88_buffer *prev;
249 struct cx88_dmaqueue *cx88q = &dev->mpegq;
250
251 dprintk( 1, "cx8802_buf_queue\n" );
264 /* add jump to stopper */
265 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
266 buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma);
252 /* add jump to start */
253 buf->risc.cpu[1] = cpu_to_le32(buf->risc.dma + 8);
254 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_CNT_INC);
255 buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma + 8);
267
268 if (list_empty(&cx88q->active)) {
269 dprintk( 1, "queue is empty - first active\n" );
256
257 if (list_empty(&cx88q->active)) {
258 dprintk( 1, "queue is empty - first active\n" );
270 list_add_tail(&buf->vb.queue,&cx88q->active);
271 cx8802_start_dma(dev, cx88q, buf);
272 buf->vb.state = VIDEOBUF_ACTIVE;
259 list_add_tail(&buf->list, &cx88q->active);
273 buf->count = cx88q->count++;
260 buf->count = cx88q->count++;
274 mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT);
275 dprintk(1,"[%p/%d] %s - first active\n",
261 dprintk(1,"[%p/%d] %s - first active\n",
276 buf, buf->vb.i, __func__);
262 buf, buf->vb.v4l2_buf.index, __func__);
277
278 } else {
263
264 } else {
265 buf->risc.cpu[0] |= cpu_to_le32(RISC_IRQ1);
279 dprintk( 1, "queue is not empty - append to active\n" );
266 dprintk( 1, "queue is not empty - append to active\n" );
280 prev = list_entry(cx88q->active.prev, struct cx88_buffer, vb.queue);
281 list_add_tail(&buf->vb.queue,&cx88q->active);
282 buf->vb.state = VIDEOBUF_ACTIVE;
267 prev = list_entry(cx88q->active.prev, struct cx88_buffer, list);
268 list_add_tail(&buf->list, &cx88q->active);
283 buf->count = cx88q->count++;
284 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
285 dprintk( 1, "[%p/%d] %s - append to active\n",
269 buf->count = cx88q->count++;
270 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
271 dprintk( 1, "[%p/%d] %s - append to active\n",
286 buf, buf->vb.i, __func__);
272 buf, buf->vb.v4l2_buf.index, __func__);
287 }
288}
289
290/* ----------------------------------------------------------- */
291
273 }
274}
275
276/* ----------------------------------------------------------- */
277
292static void do_cancel_buffers(struct cx8802_dev *dev, const char *reason, int restart)
278static void do_cancel_buffers(struct cx8802_dev *dev)
293{
294 struct cx88_dmaqueue *q = &dev->mpegq;
295 struct cx88_buffer *buf;
296 unsigned long flags;
297
298 spin_lock_irqsave(&dev->slock,flags);
299 while (!list_empty(&q->active)) {
279{
280 struct cx88_dmaqueue *q = &dev->mpegq;
281 struct cx88_buffer *buf;
282 unsigned long flags;
283
284 spin_lock_irqsave(&dev->slock,flags);
285 while (!list_empty(&q->active)) {
300 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
301 list_del(&buf->vb.queue);
302 buf->vb.state = VIDEOBUF_ERROR;
303 wake_up(&buf->vb.done);
304 dprintk(1,"[%p/%d] %s - dma=0x%08lx\n",
305 buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
286 buf = list_entry(q->active.next, struct cx88_buffer, list);
287 list_del(&buf->list);
288 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
306 }
289 }
307 if (restart)
308 {
309 dprintk(1, "restarting queue\n" );
310 cx8802_restart_queue(dev,q);
311 }
312 spin_unlock_irqrestore(&dev->slock,flags);
313}
314
315void cx8802_cancel_buffers(struct cx8802_dev *dev)
316{
290 spin_unlock_irqrestore(&dev->slock,flags);
291}
292
293void cx8802_cancel_buffers(struct cx8802_dev *dev)
294{
317 struct cx88_dmaqueue *q = &dev->mpegq;
318
319 dprintk( 1, "cx8802_cancel_buffers" );
295 dprintk( 1, "cx8802_cancel_buffers" );
320 del_timer_sync(&q->timeout);
321 cx8802_stop_dma(dev);
296 cx8802_stop_dma(dev);
322 do_cancel_buffers(dev,"cancel",0);
297 do_cancel_buffers(dev);
323}
324
298}
299
325static void cx8802_timeout(unsigned long data)
326{
327 struct cx8802_dev *dev = (struct cx8802_dev*)data;
328
329 dprintk(1, "%s\n",__func__);
330
331 if (debug)
332 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
333 cx8802_stop_dma(dev);
334 do_cancel_buffers(dev,"timeout",1);
335}
336
337static const char * cx88_mpeg_irqs[32] = {
338 "ts_risci1", NULL, NULL, NULL,
339 "ts_risci2", NULL, NULL, NULL,
340 "ts_oflow", NULL, NULL, NULL,
341 "ts_sync", NULL, NULL, NULL,
342 "opc_err", "par_err", "rip_err", "pci_abort",
343 "ts_err?",
344};

--- 27 unchanged lines hidden (view full) ---

372 if (status & 0x01) {
373 dprintk( 1, "wake up\n" );
374 spin_lock(&dev->slock);
375 count = cx_read(MO_TS_GPCNT);
376 cx88_wakeup(dev->core, &dev->mpegq, count);
377 spin_unlock(&dev->slock);
378 }
379
300static const char * cx88_mpeg_irqs[32] = {
301 "ts_risci1", NULL, NULL, NULL,
302 "ts_risci2", NULL, NULL, NULL,
303 "ts_oflow", NULL, NULL, NULL,
304 "ts_sync", NULL, NULL, NULL,
305 "opc_err", "par_err", "rip_err", "pci_abort",
306 "ts_err?",
307};

--- 27 unchanged lines hidden (view full) ---

335 if (status & 0x01) {
336 dprintk( 1, "wake up\n" );
337 spin_lock(&dev->slock);
338 count = cx_read(MO_TS_GPCNT);
339 cx88_wakeup(dev->core, &dev->mpegq, count);
340 spin_unlock(&dev->slock);
341 }
342
380 /* risc2 y */
381 if (status & 0x10) {
382 spin_lock(&dev->slock);
383 cx8802_restart_queue(dev,&dev->mpegq);
384 spin_unlock(&dev->slock);
385 }
386
387 /* other general errors */
388 if (status & 0x1f0100) {
389 dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
390 spin_lock(&dev->slock);
391 cx8802_stop_dma(dev);
343 /* other general errors */
344 if (status & 0x1f0100) {
345 dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
346 spin_lock(&dev->slock);
347 cx8802_stop_dma(dev);
392 cx8802_restart_queue(dev,&dev->mpegq);
393 spin_unlock(&dev->slock);
394 }
395}
396
397#define MAX_IRQ_LOOP 10
398
399static irqreturn_t cx8802_irq(int irq, void *dev_id)
400{

--- 50 unchanged lines hidden (view full) ---

451 pci_name(dev->pci), dev->pci_rev, dev->pci->irq,
452 dev->pci_lat,(unsigned long long)pci_resource_start(dev->pci,0));
453
454 /* initialize driver struct */
455 spin_lock_init(&dev->slock);
456
457 /* init dma queue */
458 INIT_LIST_HEAD(&dev->mpegq.active);
348 spin_unlock(&dev->slock);
349 }
350}
351
352#define MAX_IRQ_LOOP 10
353
354static irqreturn_t cx8802_irq(int irq, void *dev_id)
355{

--- 50 unchanged lines hidden (view full) ---

406 pci_name(dev->pci), dev->pci_rev, dev->pci->irq,
407 dev->pci_lat,(unsigned long long)pci_resource_start(dev->pci,0));
408
409 /* initialize driver struct */
410 spin_lock_init(&dev->slock);
411
412 /* init dma queue */
413 INIT_LIST_HEAD(&dev->mpegq.active);
459 dev->mpegq.timeout.function = cx8802_timeout;
460 dev->mpegq.timeout.data = (unsigned long)dev;
461 init_timer(&dev->mpegq.timeout);
462 cx88_risc_stopper(dev->pci,&dev->mpegq.stopper,
463 MO_TS_DMACNTRL,0x11,0x00);
464
465 /* get irq */
466 err = request_irq(dev->pci->irq, cx8802_irq,
467 IRQF_SHARED, dev->core->name, dev);
468 if (err < 0) {
469 printk(KERN_ERR "%s: can't get IRQ %d\n",
470 dev->core->name, dev->pci->irq);
471 return err;

--- 8 unchanged lines hidden (view full) ---

480static void cx8802_fini_common(struct cx8802_dev *dev)
481{
482 dprintk( 2, "cx8802_fini_common\n" );
483 cx8802_stop_dma(dev);
484 pci_disable_device(dev->pci);
485
486 /* unregister stuff */
487 free_irq(dev->pci->irq, dev);
414
415 /* get irq */
416 err = request_irq(dev->pci->irq, cx8802_irq,
417 IRQF_SHARED, dev->core->name, dev);
418 if (err < 0) {
419 printk(KERN_ERR "%s: can't get IRQ %d\n",
420 dev->core->name, dev->pci->irq);
421 return err;

--- 8 unchanged lines hidden (view full) ---

430static void cx8802_fini_common(struct cx8802_dev *dev)
431{
432 dprintk( 2, "cx8802_fini_common\n" );
433 cx8802_stop_dma(dev);
434 pci_disable_device(dev->pci);
435
436 /* unregister stuff */
437 free_irq(dev->pci->irq, dev);
488
489 /* free memory */
490 btcx_riscmem_free(dev->pci,&dev->mpegq.stopper);
491}
492
493/* ----------------------------------------------------------- */
494
495static int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
496{
497 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
498 struct cx88_core *core = dev->core;
499 unsigned long flags;
500
501 /* stop mpeg dma */
502 spin_lock_irqsave(&dev->slock, flags);
503 if (!list_empty(&dev->mpegq.active)) {
504 dprintk( 2, "suspend\n" );
505 printk("%s: suspend mpeg\n", core->name);
506 cx8802_stop_dma(dev);
438}
439
440/* ----------------------------------------------------------- */
441
442static int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
443{
444 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
445 struct cx88_core *core = dev->core;
446 unsigned long flags;
447
448 /* stop mpeg dma */
449 spin_lock_irqsave(&dev->slock, flags);
450 if (!list_empty(&dev->mpegq.active)) {
451 dprintk( 2, "suspend\n" );
452 printk("%s: suspend mpeg\n", core->name);
453 cx8802_stop_dma(dev);
507 del_timer(&dev->mpegq.timeout);
508 }
509 spin_unlock_irqrestore(&dev->slock, flags);
510
511 /* FIXME -- shutdown device */
512 cx88_shutdown(dev->core);
513
514 pci_save_state(pci_dev);
515 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {

--- 351 unchanged lines hidden (view full) ---

867 .remove = cx8802_remove,
868};
869
870module_pci_driver(cx8802_pci_driver);
871
872EXPORT_SYMBOL(cx8802_buf_prepare);
873EXPORT_SYMBOL(cx8802_buf_queue);
874EXPORT_SYMBOL(cx8802_cancel_buffers);
454 }
455 spin_unlock_irqrestore(&dev->slock, flags);
456
457 /* FIXME -- shutdown device */
458 cx88_shutdown(dev->core);
459
460 pci_save_state(pci_dev);
461 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {

--- 351 unchanged lines hidden (view full) ---

813 .remove = cx8802_remove,
814};
815
816module_pci_driver(cx8802_pci_driver);
817
818EXPORT_SYMBOL(cx8802_buf_prepare);
819EXPORT_SYMBOL(cx8802_buf_queue);
820EXPORT_SYMBOL(cx8802_cancel_buffers);
821EXPORT_SYMBOL(cx8802_start_dma);
875
876EXPORT_SYMBOL(cx8802_register_driver);
877EXPORT_SYMBOL(cx8802_unregister_driver);
878EXPORT_SYMBOL(cx8802_get_driver);
879/* ----------------------------------------------------------- */
880/*
881 * Local variables:
882 * c-basic-offset: 8
883 * End:
884 * 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
885 */
822
823EXPORT_SYMBOL(cx8802_register_driver);
824EXPORT_SYMBOL(cx8802_unregister_driver);
825EXPORT_SYMBOL(cx8802_get_driver);
826/* ----------------------------------------------------------- */
827/*
828 * Local variables:
829 * c-basic-offset: 8
830 * End:
831 * 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
832 */