diff options
-rw-r--r-- | drivers/media/platform/ti-vpe/vpdma.c | 4 | ||||
-rw-r--r-- | drivers/media/platform/ti-vpe/vpdma.h | 5 | ||||
-rw-r--r-- | drivers/media/platform/ti-vpe/vpe.c | 53 |
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 | ||