aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/ti-vpe
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2014-03-13 07:44:08 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-23 13:32:18 -0400
commit928bf2ba2f0e65a971a60e940c69af0b02ae4a57 (patch)
tree74ca04e73ac14f5a50dcfb09588ae88d54254b48 /drivers/media/platform/ti-vpe
parentf472c0b59f4e06c62d855a6158b9afb313ec6400 (diff)
[media] v4l: ti-vpe: Fix some params in VPE data descriptors
Some parameters of the VPE descriptors were understood incorrectly. They are now fixed. The fixes are explained as follows: - When adding an inbound data descriptor to the VPDMA descriptor list, we intend to use c_rect as the cropped region fetched by VPDMA. Therefore, c_rect->width shouldn't be used to calculate the line stride, the original image width should be used for that. We add a 'width' argument which gives the buffer width in memory. - frame_width and frame_height describe the complete width and height of the client to which the channel is connected. If there are multiple channels fetching data and providing to the same client, the above 2 arguments should be the width and height of the region covered by all the channels. In the case where there is only one channel providing pixel data to the client (like in VPE), frame_width and frame_height should be the cropped width and cropped height respectively. The calculation of these params is done in the vpe driver now. - start_h and start_v is also used in the case of multiple channels to describe where each channel should start filling pixel data. We don't use this in VPE, and pass 0s to the vpdma_add_in_dtd() helper. - Some minor changes are made to the vpdma_add_out_dtd() helper. The c_rect param is used for specifying the 'composition' target, and 'width' is added to calculate the line stride. Signed-off-by: Archit Taneja <archit@ti.com> Acked-by: Kamil Debski <k.debski@samsung.com> Signed-off-by: Kamil Debski <k.debski@samsung.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/platform/ti-vpe')
-rw-r--r--drivers/media/platform/ti-vpe/vpdma.c60
-rw-r--r--drivers/media/platform/ti-vpe/vpdma.h10
-rw-r--r--drivers/media/platform/ti-vpe/vpe.c18
3 files changed, 64 insertions, 24 deletions
diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index 73dd38eab582..a51a01359805 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -614,8 +614,17 @@ static void dump_dtd(struct vpdma_dtd *dtd)
614/* 614/*
615 * append an outbound data transfer descriptor to the given descriptor list, 615 * append an outbound data transfer descriptor to the given descriptor list,
616 * this sets up a 'client to memory' VPDMA transfer for the given VPDMA channel 616 * this sets up a 'client to memory' VPDMA transfer for the given VPDMA channel
617 *
618 * @list: vpdma desc list to which we add this decriptor
619 * @width: width of the image in pixels in memory
620 * @c_rect: compose params of output image
621 * @fmt: vpdma data format of the buffer
622 * dma_addr: dma address as seen by VPDMA
623 * chan: VPDMA channel
624 * flags: VPDMA flags to configure some descriptor fileds
617 */ 625 */
618void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect, 626void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
627 const struct v4l2_rect *c_rect,
619 const struct vpdma_data_format *fmt, dma_addr_t dma_addr, 628 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
620 enum vpdma_channel chan, u32 flags) 629 enum vpdma_channel chan, u32 flags)
621{ 630{
@@ -623,6 +632,7 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect,
623 int field = 0; 632 int field = 0;
624 int notify = 1; 633 int notify = 1;
625 int channel, next_chan; 634 int channel, next_chan;
635 struct v4l2_rect rect = *c_rect;
626 int depth = fmt->depth; 636 int depth = fmt->depth;
627 int stride; 637 int stride;
628 struct vpdma_dtd *dtd; 638 struct vpdma_dtd *dtd;
@@ -630,11 +640,15 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect,
630 channel = next_chan = chan_info[chan].num; 640 channel = next_chan = chan_info[chan].num;
631 641
632 if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV && 642 if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV &&
633 fmt->data_type == DATA_TYPE_C420) 643 fmt->data_type == DATA_TYPE_C420) {
644 rect.height >>= 1;
645 rect.top >>= 1;
634 depth = 8; 646 depth = 8;
647 }
635 648
636 stride = ALIGN((depth * c_rect->width) >> 3, VPDMA_STRIDE_ALIGN); 649 stride = ALIGN((depth * width) >> 3, VPDMA_STRIDE_ALIGN);
637 dma_addr += (c_rect->left * depth) >> 3; 650
651 dma_addr += rect.top * stride + (rect.left * depth >> 3);
638 652
639 dtd = list->next; 653 dtd = list->next;
640 WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size)); 654 WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size));
@@ -664,31 +678,48 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect,
664/* 678/*
665 * append an inbound data transfer descriptor to the given descriptor list, 679 * append an inbound data transfer descriptor to the given descriptor list,
666 * this sets up a 'memory to client' VPDMA transfer for the given VPDMA channel 680 * this sets up a 'memory to client' VPDMA transfer for the given VPDMA channel
681 *
682 * @list: vpdma desc list to which we add this decriptor
683 * @width: width of the image in pixels in memory(not the cropped width)
684 * @c_rect: crop params of input image
685 * @fmt: vpdma data format of the buffer
686 * dma_addr: dma address as seen by VPDMA
687 * chan: VPDMA channel
688 * field: top or bottom field info of the input image
689 * flags: VPDMA flags to configure some descriptor fileds
690 * frame_width/height: the complete width/height of the image presented to the
691 * client (this makes sense when multiple channels are
692 * connected to the same client, forming a larger frame)
693 * start_h, start_v: position where the given channel starts providing pixel
694 * data to the client (makes sense when multiple channels
695 * contribute to the client)
667 */ 696 */
668void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width, 697void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
669 int frame_height, struct v4l2_rect *c_rect, 698 const struct v4l2_rect *c_rect,
670 const struct vpdma_data_format *fmt, dma_addr_t dma_addr, 699 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
671 enum vpdma_channel chan, int field, u32 flags) 700 enum vpdma_channel chan, int field, u32 flags, int frame_width,
701 int frame_height, int start_h, int start_v)
672{ 702{
673 int priority = 0; 703 int priority = 0;
674 int notify = 1; 704 int notify = 1;
675 int depth = fmt->depth; 705 int depth = fmt->depth;
676 int channel, next_chan; 706 int channel, next_chan;
707 struct v4l2_rect rect = *c_rect;
677 int stride; 708 int stride;
678 int height = c_rect->height;
679 struct vpdma_dtd *dtd; 709 struct vpdma_dtd *dtd;
680 710
681 channel = next_chan = chan_info[chan].num; 711 channel = next_chan = chan_info[chan].num;
682 712
683 if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV && 713 if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV &&
684 fmt->data_type == DATA_TYPE_C420) { 714 fmt->data_type == DATA_TYPE_C420) {
685 height >>= 1; 715 rect.height >>= 1;
686 frame_height >>= 1; 716 rect.top >>= 1;
687 depth = 8; 717 depth = 8;
688 } 718 }
689 719
690 stride = ALIGN((depth * c_rect->width) >> 3, VPDMA_STRIDE_ALIGN); 720 stride = ALIGN((depth * width) >> 3, VPDMA_STRIDE_ALIGN);
691 dma_addr += (c_rect->left * depth) >> 3; 721
722 dma_addr += rect.top * stride + (rect.left * depth >> 3);
692 723
693 dtd = list->next; 724 dtd = list->next;
694 WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size)); 725 WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size));
@@ -701,13 +732,14 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width,
701 !!(flags & VPDMA_DATA_ODD_LINE_SKIP), 732 !!(flags & VPDMA_DATA_ODD_LINE_SKIP),
702 stride); 733 stride);
703 734
704 dtd->xfer_length_height = dtd_xfer_length_height(c_rect->width, height); 735 dtd->xfer_length_height = dtd_xfer_length_height(rect.width,
736 rect.height);
705 dtd->start_addr = (u32) dma_addr; 737 dtd->start_addr = (u32) dma_addr;
706 dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED), 738 dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED),
707 DTD_DIR_IN, channel, priority, next_chan); 739 DTD_DIR_IN, channel, priority, next_chan);
708 dtd->frame_width_height = dtd_frame_width_height(frame_width, 740 dtd->frame_width_height = dtd_frame_width_height(frame_width,
709 frame_height); 741 frame_height);
710 dtd->start_h_v = dtd_start_h_v(c_rect->left, c_rect->top); 742 dtd->start_h_v = dtd_start_h_v(start_h, start_v);
711 dtd->client_attr0 = 0; 743 dtd->client_attr0 = 0;
712 dtd->client_attr1 = 0; 744 dtd->client_attr1 = 0;
713 745
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
index bf5f8bbcf917..2bd8fb050381 100644
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ b/drivers/media/platform/ti-vpe/vpdma.h
@@ -186,13 +186,15 @@ void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client,
186 struct vpdma_buf *adb); 186 struct vpdma_buf *adb);
187void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list, 187void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
188 enum vpdma_channel chan); 188 enum vpdma_channel chan);
189void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect, 189void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
190 const struct v4l2_rect *c_rect,
190 const struct vpdma_data_format *fmt, dma_addr_t dma_addr, 191 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
191 enum vpdma_channel chan, u32 flags); 192 enum vpdma_channel chan, u32 flags);
192void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width, 193void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
193 int frame_height, struct v4l2_rect *c_rect, 194 const struct v4l2_rect *c_rect,
194 const struct vpdma_data_format *fmt, dma_addr_t dma_addr, 195 const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
195 enum vpdma_channel chan, int field, u32 flags); 196 enum vpdma_channel chan, int field, u32 flags, int frame_width,
197 int frame_height, int start_h, int start_v);
196 198
197/* vpdma list interrupt management */ 199/* vpdma list interrupt management */
198void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num, 200void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num,
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index b3cea49d6279..1c9e57c278e9 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -986,7 +986,6 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port)
986 struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_DST]; 986 struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_DST];
987 const struct vpe_port_data *p_data = &port_data[port]; 987 const struct vpe_port_data *p_data = &port_data[port];
988 struct vb2_buffer *vb = ctx->dst_vb; 988 struct vb2_buffer *vb = ctx->dst_vb;
989 struct v4l2_rect *c_rect = &q_data->c_rect;
990 struct vpe_fmt *fmt = q_data->fmt; 989 struct vpe_fmt *fmt = q_data->fmt;
991 const struct vpdma_data_format *vpdma_fmt; 990 const struct vpdma_data_format *vpdma_fmt;
992 int mv_buf_selector = !ctx->src_mv_buf_selector; 991 int mv_buf_selector = !ctx->src_mv_buf_selector;
@@ -1015,8 +1014,8 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port)
1015 if (q_data->flags & Q_DATA_MODE_TILED) 1014 if (q_data->flags & Q_DATA_MODE_TILED)
1016 flags |= VPDMA_DATA_MODE_TILED; 1015 flags |= VPDMA_DATA_MODE_TILED;
1017 1016
1018 vpdma_add_out_dtd(&ctx->desc_list, c_rect, vpdma_fmt, dma_addr, 1017 vpdma_add_out_dtd(&ctx->desc_list, q_data->width, &q_data->c_rect,
1019 p_data->channel, flags); 1018 vpdma_fmt, dma_addr, p_data->channel, flags);
1020} 1019}
1021 1020
1022static void add_in_dtd(struct vpe_ctx *ctx, int port) 1021static void add_in_dtd(struct vpe_ctx *ctx, int port)
@@ -1024,11 +1023,11 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port)
1024 struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_SRC]; 1023 struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_SRC];
1025 const struct vpe_port_data *p_data = &port_data[port]; 1024 const struct vpe_port_data *p_data = &port_data[port];
1026 struct vb2_buffer *vb = ctx->src_vbs[p_data->vb_index]; 1025 struct vb2_buffer *vb = ctx->src_vbs[p_data->vb_index];
1027 struct v4l2_rect *c_rect = &q_data->c_rect;
1028 struct vpe_fmt *fmt = q_data->fmt; 1026 struct vpe_fmt *fmt = q_data->fmt;
1029 const struct vpdma_data_format *vpdma_fmt; 1027 const struct vpdma_data_format *vpdma_fmt;
1030 int mv_buf_selector = ctx->src_mv_buf_selector; 1028 int mv_buf_selector = ctx->src_mv_buf_selector;
1031 int field = vb->v4l2_buf.field == V4L2_FIELD_BOTTOM; 1029 int field = vb->v4l2_buf.field == V4L2_FIELD_BOTTOM;
1030 int frame_width, frame_height;
1032 dma_addr_t dma_addr; 1031 dma_addr_t dma_addr;
1033 u32 flags = 0; 1032 u32 flags = 0;
1034 1033
@@ -1055,8 +1054,15 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port)
1055 if (q_data->flags & Q_DATA_MODE_TILED) 1054 if (q_data->flags & Q_DATA_MODE_TILED)
1056 flags |= VPDMA_DATA_MODE_TILED; 1055 flags |= VPDMA_DATA_MODE_TILED;
1057 1056
1058 vpdma_add_in_dtd(&ctx->desc_list, q_data->width, q_data->height, 1057 frame_width = q_data->c_rect.width;
1059 c_rect, vpdma_fmt, dma_addr, p_data->channel, field, flags); 1058 frame_height = q_data->c_rect.height;
1059
1060 if (p_data->vb_part && fmt->fourcc == V4L2_PIX_FMT_NV12)
1061 frame_height /= 2;
1062
1063 vpdma_add_in_dtd(&ctx->desc_list, q_data->width, &q_data->c_rect,
1064 vpdma_fmt, dma_addr, p_data->channel, field, flags, frame_width,
1065 frame_height, 0, 0);
1060} 1066}
1061 1067
1062/* 1068/*