diff options
author | Javier Martin <javier.martin@vista-silicon.com> | 2012-02-22 14:59:34 +0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-03-08 17:04:10 +0400 |
commit | 560fab62fa0f4bc332e1a84fb2dfdb5ae5dc7581 (patch) | |
tree | 636e88cc89dbbeec9fbafc248a187783084f4fe8 /drivers/media/video/mx2_camera.c | |
parent | 8886a881e2379565808eacbadd129120967e3539 (diff) | |
download | linux-560fab62fa0f4bc332e1a84fb2dfdb5ae5dc7581.tar.xz |
[media] media: i.MX27 camera: more efficient discard buffer handling
Some elements of 'mx2_buffer' are grouped together in another
auxiliary structure. This way we don't need to have unused
'vb2_buffer' structures for both discard buffers.
Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/mx2_camera.c')
-rw-r--r-- | drivers/media/video/mx2_camera.c | 77 |
1 files changed, 45 insertions, 32 deletions
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 1f7e36c2116e..06675125f838 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -228,15 +228,18 @@ enum mx2_buffer_state { MX2_STATE_DONE, }; +struct mx2_buf_internal { + struct list_head queue; + int bufnum; + bool discard; +}; + /* buffer for one video frame */ struct mx2_buffer { /* common v4l buffer stuff -- must be first */ struct vb2_buffer vb; - struct list_head queue; enum mx2_buffer_state state; - - int bufnum; - bool discard; + struct mx2_buf_internal internal; }; struct mx2_camera_dev { @@ -266,7 +269,7 @@ struct mx2_camera_dev { u32 csicr1; - struct mx2_buffer buf_discard[2]; + struct mx2_buf_internal buf_discard[2]; void *discard_buffer; dma_addr_t discard_buffer_dma; size_t discard_size; @@ -275,6 +278,11 @@ struct mx2_camera_dev { struct vb2_alloc_ctx *alloc_ctx; }; +static struct mx2_buffer *mx2_ibuf_to_buf(struct mx2_buf_internal *int_buf) +{ + return container_of(int_buf, struct mx2_buffer, internal); +} + static struct mx2_fmt_cfg mx27_emma_prp_table[] = { /* * This is a generic configuration which is valid for most @@ -450,9 +458,9 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, writel(0, pcdev->base_csi + fb_reg); } else { buf = list_first_entry(&pcdev->capture, struct mx2_buffer, - queue); + internal.queue); vb = &buf->vb; - list_del(&buf->queue); + list_del(&buf->internal.queue); buf->state = MX2_STATE_ACTIVE; writel(vb2_dma_contig_plane_dma_addr(vb, 0), pcdev->base_csi + fb_reg); @@ -569,7 +577,7 @@ static void mx2_videobuf_queue(struct vb2_buffer *vb) spin_lock_irqsave(&pcdev->lock, flags); buf->state = MX2_STATE_QUEUED; - list_add_tail(&buf->queue, &pcdev->capture); + list_add_tail(&buf->internal.queue, &pcdev->capture); if (cpu_is_mx25()) { u32 csicr3, dma_inten = 0; @@ -587,7 +595,7 @@ static void mx2_videobuf_queue(struct vb2_buffer *vb) } if (dma_inten) { - list_del(&buf->queue); + list_del(&buf->internal.queue); buf->state = MX2_STATE_ACTIVE; csicr3 = readl(pcdev->base_csi + CSICR3); @@ -710,23 +718,23 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count) spin_lock_irqsave(&pcdev->lock, flags); buf = list_first_entry(&pcdev->capture, struct mx2_buffer, - queue); - buf->bufnum = 0; + internal.queue); + buf->internal.bufnum = 0; vb = &buf->vb; buf->state = MX2_STATE_ACTIVE; phys = vb2_dma_contig_plane_dma_addr(vb, 0); - mx27_update_emma_buf(pcdev, phys, buf->bufnum); + mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum); list_move_tail(pcdev->capture.next, &pcdev->active_bufs); buf = list_first_entry(&pcdev->capture, struct mx2_buffer, - queue); - buf->bufnum = 1; + internal.queue); + buf->internal.bufnum = 1; vb = &buf->vb; buf->state = MX2_STATE_ACTIVE; phys = vb2_dma_contig_plane_dma_addr(vb, 0); - mx27_update_emma_buf(pcdev, phys, buf->bufnum); + mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum); list_move_tail(pcdev->capture.next, &pcdev->active_bufs); bytesperline = soc_mbus_bytes_per_line(icd->user_width, @@ -1203,21 +1211,25 @@ static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev, #ifdef DEBUG struct mx2_fmt_cfg *prp = pcdev->emma_prp; #endif + struct mx2_buf_internal *ibuf; struct mx2_buffer *buf; struct vb2_buffer *vb; unsigned long phys; - buf = list_first_entry(&pcdev->active_bufs, struct mx2_buffer, queue); + ibuf = list_first_entry(&pcdev->active_bufs, struct mx2_buf_internal, + queue); - BUG_ON(buf->bufnum != bufnum); + BUG_ON(ibuf->bufnum != bufnum); - if (buf->discard) { + if (ibuf->discard) { /* * Discard buffer must not be returned to user space. * Just return it to the discard queue. */ list_move_tail(pcdev->active_bufs.next, &pcdev->discard); } else { + buf = mx2_ibuf_to_buf(ibuf); + vb = &buf->vb; #ifdef DEBUG phys = vb2_dma_contig_plane_dma_addr(vb, 0); @@ -1241,7 +1253,7 @@ static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); - list_del_init(&buf->queue); + list_del_init(&buf->internal.queue); do_gettimeofday(&vb->v4l2_buf.timestamp); vb->v4l2_buf.sequence = pcdev->frame_count; if (err) @@ -1259,18 +1271,19 @@ static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev, return; } - buf = list_first_entry(&pcdev->discard, struct mx2_buffer, - queue); - buf->bufnum = bufnum; + ibuf = list_first_entry(&pcdev->discard, + struct mx2_buf_internal, queue); + ibuf->bufnum = bufnum; list_move_tail(pcdev->discard.next, &pcdev->active_bufs); mx27_update_emma_buf(pcdev, pcdev->discard_buffer_dma, bufnum); return; } - buf = list_first_entry(&pcdev->capture, struct mx2_buffer, queue); + buf = list_first_entry(&pcdev->capture, struct mx2_buffer, + internal.queue); - buf->bufnum = bufnum; + buf->internal.bufnum = bufnum; list_move_tail(pcdev->capture.next, &pcdev->active_bufs); @@ -1285,7 +1298,7 @@ static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data) { struct mx2_camera_dev *pcdev = data; unsigned int status = readl(pcdev->base_emma + PRP_INTRSTATUS); - struct mx2_buffer *buf; + struct mx2_buf_internal *ibuf; spin_lock(&pcdev->lock); @@ -1305,10 +1318,10 @@ static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data) pcdev->base_emma + PRP_CNTL); writel(cntl, pcdev->base_emma + PRP_CNTL); - buf = list_first_entry(&pcdev->active_bufs, - struct mx2_buffer, queue); + ibuf = list_first_entry(&pcdev->active_bufs, + struct mx2_buf_internal, queue); mx27_camera_frame_done_emma(pcdev, - buf->bufnum, true); + ibuf->bufnum, true); status &= ~(1 << 7); } else if (((status & (3 << 5)) == (3 << 5)) || @@ -1317,10 +1330,10 @@ static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data) * Both buffers have triggered, process the one we're expecting * to first */ - buf = list_first_entry(&pcdev->active_bufs, struct mx2_buffer, - queue); - mx27_camera_frame_done_emma(pcdev, buf->bufnum, false); - status &= ~(1 << (6 - buf->bufnum)); /* mark processed */ + ibuf = list_first_entry(&pcdev->active_bufs, + struct mx2_buf_internal, queue); + mx27_camera_frame_done_emma(pcdev, ibuf->bufnum, false); + status &= ~(1 << (6 - ibuf->bufnum)); /* mark processed */ } else if ((status & (1 << 6)) || (status & (1 << 4))) { mx27_camera_frame_done_emma(pcdev, 0, false); } else if ((status & (1 << 5)) || (status & (1 << 3))) { |