aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/ti-vpe/vpdma.c4
-rw-r--r--drivers/media/platform/ti-vpe/vpdma.h5
-rw-r--r--drivers/media/platform/ti-vpe/vpe.c53
3 files changed, 46 insertions, 16 deletions
diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index af0a5ffcaa98..f97253f6699f 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -602,7 +602,7 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect,
602 if (fmt->data_type == DATA_TYPE_C420) 602 if (fmt->data_type == DATA_TYPE_C420)
603 depth = 8; 603 depth = 8;
604 604
605 stride = (depth * c_rect->width) >> 3; 605 stride = ALIGN((depth * c_rect->width) >> 3, VPDMA_STRIDE_ALIGN);
606 dma_addr += (c_rect->left * depth) >> 3; 606 dma_addr += (c_rect->left * depth) >> 3;
607 607
608 dtd = list->next; 608 dtd = list->next;
@@ -655,7 +655,7 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width,
655 depth = 8; 655 depth = 8;
656 } 656 }
657 657
658 stride = (depth * c_rect->width) >> 3; 658 stride = ALIGN((depth * c_rect->width) >> 3, VPDMA_STRIDE_ALIGN);
659 dma_addr += (c_rect->left * depth) >> 3; 659 dma_addr += (c_rect->left * depth) >> 3;
660 660
661 dtd = list->next; 661 dtd = list->next;
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index eaa2a71a5db9..62dd14305e81 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -45,7 +45,10 @@ struct vpdma_data_format {
45}; 45};
46 46
47#define VPDMA_DESC_ALIGN 16 /* 16-byte descriptor alignment */ 47#define VPDMA_DESC_ALIGN 16 /* 16-byte descriptor alignment */
48 48#define VPDMA_STRIDE_ALIGN 16 /*
49 * line stride of source and dest
50 * buffers should be 16 byte aligned
51 */
49#define VPDMA_DTD_DESC_SIZE 32 /* 8 words */ 52#define VPDMA_DTD_DESC_SIZE 32 /* 8 words */
50#define VPDMA_CFD_CTD_DESC_SIZE 16 /* 4 words */ 53#define VPDMA_CFD_CTD_DESC_SIZE 16 /* 4 words */
51 54
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index f949ef57a54c..669777052a16 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -30,6 +30,7 @@
30#include <linux/sched.h> 30#include <linux/sched.h>
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/videodev2.h> 32#include <linux/videodev2.h>
33#include <linux/log2.h>
33 34
34#include <media/v4l2-common.h> 35#include <media/v4l2-common.h>
35#include <media/v4l2-ctrls.h> 36#include <media/v4l2-ctrls.h>
@@ -54,10 +55,6 @@
54/* required alignments */ 55/* required alignments */
55#define S_ALIGN 0 /* multiple of 1 */ 56#define S_ALIGN 0 /* multiple of 1 */
56#define H_ALIGN 1 /* multiple of 2 */ 57#define H_ALIGN 1 /* multiple of 2 */
57#define W_ALIGN 1 /* multiple of 2 */
58
59/* multiple of 128 bits, line stride, 16 bytes */
60#define L_ALIGN 4
61 58
62/* flags that indicate a format can be used for capture/output */ 59/* flags that indicate a format can be used for capture/output */
63#define VPE_FMT_TYPE_CAPTURE (1 << 0) 60#define VPE_FMT_TYPE_CAPTURE (1 << 0)
@@ -780,12 +777,21 @@ static int set_srcdst_params(struct vpe_ctx *ctx)
780 777
781 if ((s_q_data->flags & Q_DATA_INTERLACED) && 778 if ((s_q_data->flags & Q_DATA_INTERLACED) &&
782 !(d_q_data->flags & Q_DATA_INTERLACED)) { 779 !(d_q_data->flags & Q_DATA_INTERLACED)) {
780 int bytes_per_line;
783 const struct vpdma_data_format *mv = 781 const struct vpdma_data_format *mv =
784 &vpdma_misc_fmts[VPDMA_DATA_FMT_MV]; 782 &vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
785 783
786 ctx->deinterlacing = 1; 784 ctx->deinterlacing = 1;
787 mv_buf_size = 785 /*
788 (s_q_data->width * s_q_data->height * mv->depth) >> 3; 786 * we make sure that the source image has a 16 byte aligned
787 * stride, we need to do the same for the motion vector buffer
788 * by aligning it's stride to the next 16 byte boundry. this
789 * extra space will not be used by the de-interlacer, but will
790 * ensure that vpdma operates correctly
791 */
792 bytes_per_line = ALIGN((s_q_data->width * mv->depth) >> 3,
793 VPDMA_STRIDE_ALIGN);
794 mv_buf_size = bytes_per_line * s_q_data->height;
789 } else { 795 } else {
790 ctx->deinterlacing = 0; 796 ctx->deinterlacing = 0;
791 mv_buf_size = 0; 797 mv_buf_size = 0;
@@ -1352,7 +1358,8 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
1352{ 1358{
1353 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; 1359 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
1354 struct v4l2_plane_pix_format *plane_fmt; 1360 struct v4l2_plane_pix_format *plane_fmt;
1355 int i; 1361 unsigned int w_align;
1362 int i, depth, depth_bytes;
1356 1363
1357 if (!fmt || !(fmt->types & type)) { 1364 if (!fmt || !(fmt->types & type)) {
1358 vpe_err(ctx->dev, "Fourcc format (0x%08x) invalid.\n", 1365 vpe_err(ctx->dev, "Fourcc format (0x%08x) invalid.\n",
@@ -1363,7 +1370,31 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
1363 if (pix->field != V4L2_FIELD_NONE && pix->field != V4L2_FIELD_ALTERNATE) 1370 if (pix->field != V4L2_FIELD_NONE && pix->field != V4L2_FIELD_ALTERNATE)
1364 pix->field = V4L2_FIELD_NONE; 1371 pix->field = V4L2_FIELD_NONE;
1365 1372
1366 v4l_bound_align_image(&pix->width, MIN_W, MAX_W, W_ALIGN, 1373 depth = fmt->vpdma_fmt[VPE_LUMA]->depth;
1374
1375 /*
1376 * the line stride should 16 byte aligned for VPDMA to work, based on
1377 * the bytes per pixel, figure out how much the width should be aligned
1378 * to make sure line stride is 16 byte aligned
1379 */
1380 depth_bytes = depth >> 3;
1381
1382 if (depth_bytes == 3)
1383 /*
1384 * if bpp is 3(as in some RGB formats), the pixel width doesn't
1385 * really help in ensuring line stride is 16 byte aligned
1386 */
1387 w_align = 4;
1388 else
1389 /*
1390 * for the remainder bpp(4, 2 and 1), the pixel width alignment
1391 * can ensure a line stride alignment of 16 bytes. For example,
1392 * if bpp is 2, then the line stride can be 16 byte aligned if
1393 * the width is 8 byte aligned
1394 */
1395 w_align = order_base_2(VPDMA_DESC_ALIGN / depth_bytes);
1396
1397 v4l_bound_align_image(&pix->width, MIN_W, MAX_W, w_align,
1367 &pix->height, MIN_H, MAX_H, H_ALIGN, 1398 &pix->height, MIN_H, MAX_H, H_ALIGN,
1368 S_ALIGN); 1399 S_ALIGN);
1369 1400
@@ -1383,15 +1414,11 @@ static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
1383 } 1414 }
1384 1415
1385 for (i = 0; i < pix->num_planes; i++) { 1416 for (i = 0; i < pix->num_planes; i++) {
1386 int depth;
1387
1388 plane_fmt = &pix->plane_fmt[i]; 1417 plane_fmt = &pix->plane_fmt[i];
1389 depth = fmt->vpdma_fmt[i]->depth; 1418 depth = fmt->vpdma_fmt[i]->depth;
1390 1419
1391 if (i == VPE_LUMA) 1420 if (i == VPE_LUMA)
1392 plane_fmt->bytesperline = 1421 plane_fmt->bytesperline = (pix->width * depth) >> 3;
1393 round_up((pix->width * depth) >> 3,
1394 1 << L_ALIGN);
1395 else 1422 else
1396 plane_fmt->bytesperline = pix->width; 1423 plane_fmt->bytesperline = pix->width;
1397 1424