summaryrefslogtreecommitdiff
path: root/drivers/media/video/cx18
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2009-11-11 02:28:30 (GMT)
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 20:41:52 (GMT)
commit1047a83844a4d894a068d94aca2d3efe54ac7a9c (patch)
treeb701e53e5db83b79f608eb6f515195d0cd403679 /drivers/media/video/cx18
parent22dce188ef3e1e058ceabe3b3072640d7568f764 (diff)
downloadlinux-fsl-qoriq-1047a83844a4d894a068d94aca2d3efe54ac7a9c.tar.xz
V4L/DVB (13431): cx18: Adjust an MDL's final buffer size to force encoder transfer size
The encoder was not honoring the MDL size sent in DE_SET_MDL mailbox commands. This change adjusts the size of the last buffer in an MDL, as reported to the firmware, so that the encoder will send the exact amount of bytes we specify per MDL transfer. This eliminates tearing in YUV playback when using non-default YUV buffer sizes. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18')
-rw-r--r--drivers/media/video/cx18/cx18-queue.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 98cbf00..f2d539f 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -280,6 +280,7 @@ void cx18_load_queues(struct cx18_stream *s)
struct cx18_buffer *buf;
int mdl_id;
int i;
+ u32 partial_buf_size;
/*
* Attach buffers to MDLs, give the MDLs ids, and add MDLs to q_free
@@ -308,10 +309,24 @@ void cx18_load_queues(struct cx18_stream *s)
&cx->scb->cpu_mdl[mdl_id + i].length);
}
- if (i == s->bufs_per_mdl)
+ if (i == s->bufs_per_mdl) {
+ /*
+ * The encoder doesn't honor s->mdl_size. So in the
+ * case of a non-integral number of buffers to meet
+ * mdl_size, we lie about the size of the last buffer
+ * in the MDL to get the encoder to really only send
+ * us mdl_size bytes per MDL transfer.
+ */
+ partial_buf_size = s->mdl_size % s->buf_size;
+ if (partial_buf_size) {
+ cx18_writel(cx, partial_buf_size,
+ &cx->scb->cpu_mdl[mdl_id + i - 1].length);
+ }
cx18_enqueue(s, mdl, &s->q_free);
- else
- cx18_push(s, mdl, &s->q_idle); /* not enough buffers */
+ } else {
+ /* Not enough buffers for this MDL; we won't use it */
+ cx18_push(s, mdl, &s->q_idle);
+ }
mdl_id += i;
}
}