aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-streams.c
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2009-11-08 21:45:24 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:41:51 -0500
commit52fcb3ecc6707f52dfe4297f96b7609d4ba517fb (patch)
treefe8ecd66c20b10e8b2ba63c667a6afe78c23a2e1 /drivers/media/video/cx18/cx18-streams.c
parentfa655dda5ce6e5ac4a9b94fd451358edca2ddab8 (diff)
V4L/DVB (13429): cx18: Add Memory Descriptor List (MDL) layer to buffer handling
Add a Memory Descriptor List (MDL) layer to buffer handling to implement scatter-gather I/O. Currently there is still only 1 buffer per MDL. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18/cx18-streams.c')
-rw-r--r--drivers/media/video/cx18/cx18-streams.c50
1 files changed, 29 insertions, 21 deletions
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 10228c5ca5a0..9f8adda6f261 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -115,6 +115,9 @@ static void cx18_stream_init(struct cx18 *cx, int type)
115 s->dma = cx18_stream_info[type].dma; 115 s->dma = cx18_stream_info[type].dma;
116 s->buffers = cx->stream_buffers[type]; 116 s->buffers = cx->stream_buffers[type];
117 s->buf_size = cx->stream_buf_size[type]; 117 s->buf_size = cx->stream_buf_size[type];
118 INIT_LIST_HEAD(&s->buf_pool);
119 s->bufs_per_mdl = 1;
120 s->mdl_size = s->buf_size * s->bufs_per_mdl;
118 121
119 init_waitqueue_head(&s->waitq); 122 init_waitqueue_head(&s->waitq);
120 s->id = -1; 123 s->id = -1;
@@ -124,6 +127,8 @@ static void cx18_stream_init(struct cx18 *cx, int type)
124 cx18_queue_init(&s->q_busy); 127 cx18_queue_init(&s->q_busy);
125 spin_lock_init(&s->q_full.lock); 128 spin_lock_init(&s->q_full.lock);
126 cx18_queue_init(&s->q_full); 129 cx18_queue_init(&s->q_full);
130 spin_lock_init(&s->q_idle.lock);
131 cx18_queue_init(&s->q_idle);
127 132
128 INIT_WORK(&s->out_work_order, cx18_out_work_handler); 133 INIT_WORK(&s->out_work_order, cx18_out_work_handler);
129} 134}
@@ -441,8 +446,8 @@ static void cx18_vbi_setup(struct cx18_stream *s)
441} 446}
442 447
443static 448static
444struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s, 449struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
445 struct cx18_buffer *buf) 450 struct cx18_mdl *mdl)
446{ 451{
447 struct cx18 *cx = s->cx; 452 struct cx18 *cx = s->cx;
448 struct cx18_queue *q; 453 struct cx18_queue *q;
@@ -451,16 +456,16 @@ struct cx18_queue *_cx18_stream_put_buf_fw(struct cx18_stream *s,
451 if (s->handle == CX18_INVALID_TASK_HANDLE || 456 if (s->handle == CX18_INVALID_TASK_HANDLE ||
452 test_bit(CX18_F_S_STOPPING, &s->s_flags) || 457 test_bit(CX18_F_S_STOPPING, &s->s_flags) ||
453 !test_bit(CX18_F_S_STREAMING, &s->s_flags)) 458 !test_bit(CX18_F_S_STREAMING, &s->s_flags))
454 return cx18_enqueue(s, buf, &s->q_free); 459 return cx18_enqueue(s, mdl, &s->q_free);
455 460
456 q = cx18_enqueue(s, buf, &s->q_busy); 461 q = cx18_enqueue(s, mdl, &s->q_busy);
457 if (q != &s->q_busy) 462 if (q != &s->q_busy)
458 return q; /* The firmware has the max buffers it can handle */ 463 return q; /* The firmware has the max MDLs it can handle */
459 464
460 cx18_buf_sync_for_device(s, buf); 465 cx18_mdl_sync_for_device(s, mdl);
461 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, 466 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
462 (void __iomem *) &cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 467 (void __iomem *) &cx->scb->cpu_mdl[mdl->id] - cx->enc_mem,
463 1, buf->id, s->buf_size); 468 s->bufs_per_mdl, mdl->id, s->mdl_size);
464 return q; 469 return q;
465} 470}
466 471
@@ -468,7 +473,7 @@ static
468void _cx18_stream_load_fw_queue(struct cx18_stream *s) 473void _cx18_stream_load_fw_queue(struct cx18_stream *s)
469{ 474{
470 struct cx18_queue *q; 475 struct cx18_queue *q;
471 struct cx18_buffer *buf; 476 struct cx18_mdl *mdl;
472 477
473 if (atomic_read(&s->q_free.depth) == 0 || 478 if (atomic_read(&s->q_free.depth) == 0 ||
474 atomic_read(&s->q_busy.depth) >= CX18_MAX_FW_MDLS_PER_STREAM) 479 atomic_read(&s->q_busy.depth) >= CX18_MAX_FW_MDLS_PER_STREAM)
@@ -476,10 +481,10 @@ void _cx18_stream_load_fw_queue(struct cx18_stream *s)
476 481
477 /* Move from q_free to q_busy notifying the firmware, until the limit */ 482 /* Move from q_free to q_busy notifying the firmware, until the limit */
478 do { 483 do {
479 buf = cx18_dequeue(s, &s->q_free); 484 mdl = cx18_dequeue(s, &s->q_free);
480 if (buf == NULL) 485 if (mdl == NULL)
481 break; 486 break;
482 q = _cx18_stream_put_buf_fw(s, buf); 487 q = _cx18_stream_put_mdl_fw(s, mdl);
483 } while (atomic_read(&s->q_busy.depth) < CX18_MAX_FW_MDLS_PER_STREAM 488 } while (atomic_read(&s->q_busy.depth) < CX18_MAX_FW_MDLS_PER_STREAM
484 && q == &s->q_busy); 489 && q == &s->q_busy);
485} 490}
@@ -492,11 +497,21 @@ void cx18_out_work_handler(struct work_struct *work)
492 _cx18_stream_load_fw_queue(s); 497 _cx18_stream_load_fw_queue(s);
493} 498}
494 499
500static void cx18_stream_configure_mdls(struct cx18_stream *s)
501{
502 cx18_unload_queues(s);
503
504 /* For now */
505 s->bufs_per_mdl = 1;
506 s->mdl_size = s->buf_size * s->bufs_per_mdl;
507
508 cx18_load_queues(s);
509}
510
495int cx18_start_v4l2_encode_stream(struct cx18_stream *s) 511int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
496{ 512{
497 u32 data[MAX_MB_ARGUMENTS]; 513 u32 data[MAX_MB_ARGUMENTS];
498 struct cx18 *cx = s->cx; 514 struct cx18 *cx = s->cx;
499 struct cx18_buffer *buf;
500 int captype = 0; 515 int captype = 0;
501 struct cx18_api_func_private priv; 516 struct cx18_api_func_private priv;
502 517
@@ -619,14 +634,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
619 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem); 634 (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem);
620 635
621 /* Init all the cpu_mdls for this stream */ 636 /* Init all the cpu_mdls for this stream */
622 cx18_flush_queues(s); 637 cx18_stream_configure_mdls(s);
623 spin_lock(&s->q_free.lock);
624 list_for_each_entry(buf, &s->q_free.list, list) {
625 cx18_writel(cx, buf->dma_handle,
626 &cx->scb->cpu_mdl[buf->id].paddr);
627 cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length);
628 }
629 spin_unlock(&s->q_free.lock);
630 _cx18_stream_load_fw_queue(s); 638 _cx18_stream_load_fw_queue(s);
631 639
632 /* begin_capture */ 640 /* begin_capture */