aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRobert Jarzmik <robert.jarzmik@free.fr>2009-03-31 02:44:21 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-04-06 20:43:44 -0400
commit92a8337b380f0978ac81f096d6324d3ad689f83e (patch)
tree8a09a2d450f168a16e346167dd57d06c410049f1 /drivers
parentfedd73ccce8c77b677f8a9090feab8f8c6c9b03c (diff)
V4L/DVB (11319): pxa_camera: Enforce YUV422P frame sizes to be 16 multiples
Due to DMA constraints, the DMA chain always transfers bytes from the QCI fifos to memory in 8 bytes units. In planar formats, that could mean 0 padding between Y and U plane (and between U and V plane), which is against YUV422P standard. Therefore, a frame size is required to be a multiple of 16 (so U plane size is a multiple of 8). It is enforced in try_fmt() and set_fmt() primitives, be aligning height then width on 4 multiples as need be, to reach a 16 multiple. Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/pxa_camera.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index c522616ef38f..5f57e4018849 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -163,6 +163,13 @@
163 CICR0_EOFM | CICR0_FOM) 163 CICR0_EOFM | CICR0_FOM)
164 164
165/* 165/*
166 * YUV422P picture size should be a multiple of 16, so the heuristic aligns
167 * height, width on 4 byte boundaries to reach the 16 multiple for the size.
168 */
169#define YUV422P_X_Y_ALIGN 4
170#define YUV422P_SIZE_ALIGN YUV422P_X_Y_ALIGN * YUV422P_X_Y_ALIGN
171
172/*
166 * Structures 173 * Structures
167 */ 174 */
168enum pxa_camera_active_dma { 175enum pxa_camera_active_dma {
@@ -236,20 +243,11 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
236 unsigned int *size) 243 unsigned int *size)
237{ 244{
238 struct soc_camera_device *icd = vq->priv_data; 245 struct soc_camera_device *icd = vq->priv_data;
239 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
240 struct pxa_camera_dev *pcdev = ici->priv;
241 246
242 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); 247 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
243 248
244 /* planar capture requires Y, U and V buffers to be page aligned */ 249 *size = roundup(icd->width * icd->height *
245 if (pcdev->channels == 3) { 250 ((icd->current_fmt->depth + 7) >> 3), 8);
246 *size = PAGE_ALIGN(icd->width * icd->height); /* Y pages */
247 *size += PAGE_ALIGN(icd->width * icd->height / 2); /* U pages */
248 *size += PAGE_ALIGN(icd->width * icd->height / 2); /* V pages */
249 } else {
250 *size = icd->width * icd->height *
251 ((icd->current_fmt->depth + 7) >> 3);
252 }
253 251
254 if (0 == *count) 252 if (0 == *count)
255 *count = 32; 253 *count = 32;
@@ -1265,6 +1263,18 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1265 pix->width = 2048; 1263 pix->width = 2048;
1266 pix->width &= ~0x01; 1264 pix->width &= ~0x01;
1267 1265
1266 /*
1267 * YUV422P planar format requires images size to be a 16 bytes
1268 * multiple. If not, zeros will be inserted between Y and U planes, and
1269 * U and V planes, and YUV422P standard would be violated.
1270 */
1271 if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P) {
1272 if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN))
1273 pix->height = ALIGN(pix->height, YUV422P_X_Y_ALIGN);
1274 if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN))
1275 pix->width = ALIGN(pix->width, YUV422P_X_Y_ALIGN);
1276 }
1277
1268 pix->bytesperline = pix->width * 1278 pix->bytesperline = pix->width *
1269 DIV_ROUND_UP(xlate->host_fmt->depth, 8); 1279 DIV_ROUND_UP(xlate->host_fmt->depth, 8);
1270 pix->sizeimage = pix->height * pix->bytesperline; 1280 pix->sizeimage = pix->height * pix->bytesperline;