diff options
author | Javier Martin <javier.martin@vista-silicon.com> | 2012-02-22 05:59:34 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-03-08 08:04:10 -0500 |
commit | 560fab62fa0f4bc332e1a84fb2dfdb5ae5dc7581 (patch) | |
tree | 636e88cc89dbbeec9fbafc248a187783084f4fe8 | |
parent | 8886a881e2379565808eacbadd129120967e3539 (diff) |
[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>
-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 { | |||
228 | MX2_STATE_DONE, | 228 | MX2_STATE_DONE, |
229 | }; | 229 | }; |
230 | 230 | ||
231 | struct mx2_buf_internal { | ||
232 | struct list_head queue; | ||
233 | int bufnum; | ||
234 | bool discard; | ||
235 | }; | ||
236 | |||
231 | /* buffer for one video frame */ | 237 | /* buffer for one video frame */ |
232 | struct mx2_buffer { | 238 | struct mx2_buffer { |
233 | /* common v4l buffer stuff -- must be first */ | 239 | /* common v4l buffer stuff -- must be first */ |
234 | struct vb2_buffer vb; | 240 | struct vb2_buffer vb; |
235 | struct list_head queue; | ||
236 | enum mx2_buffer_state state; | 241 | enum mx2_buffer_state state; |
237 | 242 | struct mx2_buf_internal internal; | |
238 | int bufnum; | ||
239 | bool discard; | ||
240 | }; | 243 | }; |
241 | 244 | ||
242 | struct mx2_camera_dev { | 245 | struct mx2_camera_dev { |
@@ -266,7 +269,7 @@ struct mx2_camera_dev { | |||
266 | 269 | ||
267 | u32 csicr1; | 270 | u32 csicr1; |
268 | 271 | ||
269 | struct mx2_buffer buf_discard[2]; | 272 | struct mx2_buf_internal buf_discard[2]; |
270 | void *discard_buffer; | 273 | void *discard_buffer; |
271 | dma_addr_t discard_buffer_dma; | 274 | dma_addr_t discard_buffer_dma; |
272 | size_t discard_size; | 275 | size_t discard_size; |
@@ -275,6 +278,11 @@ struct mx2_camera_dev { | |||
275 | struct vb2_alloc_ctx *alloc_ctx; | 278 | struct vb2_alloc_ctx *alloc_ctx; |
276 | }; | 279 | }; |
277 | 280 | ||
281 | static struct mx2_buffer *mx2_ibuf_to_buf(struct mx2_buf_internal *int_buf) | ||
282 | { | ||
283 | return container_of(int_buf, struct mx2_buffer, internal); | ||
284 | } | ||
285 | |||
278 | static struct mx2_fmt_cfg mx27_emma_prp_table[] = { | 286 | static struct mx2_fmt_cfg mx27_emma_prp_table[] = { |
279 | /* | 287 | /* |
280 | * This is a generic configuration which is valid for most | 288 | * 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, | |||
450 | writel(0, pcdev->base_csi + fb_reg); | 458 | writel(0, pcdev->base_csi + fb_reg); |
451 | } else { | 459 | } else { |
452 | buf = list_first_entry(&pcdev->capture, struct mx2_buffer, | 460 | buf = list_first_entry(&pcdev->capture, struct mx2_buffer, |
453 | queue); | 461 | internal.queue); |
454 | vb = &buf->vb; | 462 | vb = &buf->vb; |
455 | list_del(&buf->queue); | 463 | list_del(&buf->internal.queue); |
456 | buf->state = MX2_STATE_ACTIVE; | 464 | buf->state = MX2_STATE_ACTIVE; |
457 | writel(vb2_dma_contig_plane_dma_addr(vb, 0), | 465 | writel(vb2_dma_contig_plane_dma_addr(vb, 0), |
458 | pcdev->base_csi + fb_reg); | 466 | pcdev->base_csi + fb_reg); |
@@ -569,7 +577,7 @@ static void mx2_videobuf_queue(struct vb2_buffer *vb) | |||
569 | spin_lock_irqsave(&pcdev->lock, flags); | 577 | spin_lock_irqsave(&pcdev->lock, flags); |
570 | 578 | ||
571 | buf->state = MX2_STATE_QUEUED; | 579 | buf->state = MX2_STATE_QUEUED; |
572 | list_add_tail(&buf->queue, &pcdev->capture); | 580 | list_add_tail(&buf->internal.queue, &pcdev->capture); |
573 | 581 | ||
574 | if (cpu_is_mx25()) { | 582 | if (cpu_is_mx25()) { |
575 | u32 csicr3, dma_inten = 0; | 583 | u32 csicr3, dma_inten = 0; |
@@ -587,7 +595,7 @@ static void mx2_videobuf_queue(struct vb2_buffer *vb) | |||
587 | } | 595 | } |
588 | 596 | ||
589 | if (dma_inten) { | 597 | if (dma_inten) { |
590 | list_del(&buf->queue); | 598 | list_del(&buf->internal.queue); |
591 | buf->state = MX2_STATE_ACTIVE; | 599 | buf->state = MX2_STATE_ACTIVE; |
592 | 600 | ||
593 | csicr3 = readl(pcdev->base_csi + CSICR3); | 601 | csicr3 = readl(pcdev->base_csi + CSICR3); |
@@ -710,23 +718,23 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count) | |||
710 | spin_lock_irqsave(&pcdev->lock, flags); | 718 | spin_lock_irqsave(&pcdev->lock, flags); |
711 | 719 | ||
712 | buf = list_first_entry(&pcdev->capture, struct mx2_buffer, | 720 | buf = list_first_entry(&pcdev->capture, struct mx2_buffer, |
713 | queue); | 721 | internal.queue); |
714 | buf->bufnum = 0; | 722 | buf->internal.bufnum = 0; |
715 | vb = &buf->vb; | 723 | vb = &buf->vb; |
716 | buf->state = MX2_STATE_ACTIVE; | 724 | buf->state = MX2_STATE_ACTIVE; |
717 | 725 | ||
718 | phys = vb2_dma_contig_plane_dma_addr(vb, 0); | 726 | phys = vb2_dma_contig_plane_dma_addr(vb, 0); |
719 | mx27_update_emma_buf(pcdev, phys, buf->bufnum); | 727 | mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum); |
720 | list_move_tail(pcdev->capture.next, &pcdev->active_bufs); | 728 | list_move_tail(pcdev->capture.next, &pcdev->active_bufs); |
721 | 729 | ||
722 | buf = list_first_entry(&pcdev->capture, struct mx2_buffer, | 730 | buf = list_first_entry(&pcdev->capture, struct mx2_buffer, |
723 | queue); | 731 | internal.queue); |
724 | buf->bufnum = 1; | 732 | buf->internal.bufnum = 1; |
725 | vb = &buf->vb; | 733 | vb = &buf->vb; |
726 | buf->state = MX2_STATE_ACTIVE; | 734 | buf->state = MX2_STATE_ACTIVE; |
727 | 735 | ||
728 | phys = vb2_dma_contig_plane_dma_addr(vb, 0); | 736 | phys = vb2_dma_contig_plane_dma_addr(vb, 0); |
729 | mx27_update_emma_buf(pcdev, phys, buf->bufnum); | 737 | mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum); |
730 | list_move_tail(pcdev->capture.next, &pcdev->active_bufs); | 738 | list_move_tail(pcdev->capture.next, &pcdev->active_bufs); |
731 | 739 | ||
732 | bytesperline = soc_mbus_bytes_per_line(icd->user_width, | 740 | 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, | |||
1203 | #ifdef DEBUG | 1211 | #ifdef DEBUG |
1204 | struct mx2_fmt_cfg *prp = pcdev->emma_prp; | 1212 | struct mx2_fmt_cfg *prp = pcdev->emma_prp; |
1205 | #endif | 1213 | #endif |
1214 | struct mx2_buf_internal *ibuf; | ||
1206 | struct mx2_buffer *buf; | 1215 | struct mx2_buffer *buf; |
1207 | struct vb2_buffer *vb; | 1216 | struct vb2_buffer *vb; |
1208 | unsigned long phys; | 1217 | unsigned long phys; |
1209 | 1218 | ||
1210 | buf = list_first_entry(&pcdev->active_bufs, struct mx2_buffer, queue); | 1219 | ibuf = list_first_entry(&pcdev->active_bufs, struct mx2_buf_internal, |
1220 | queue); | ||
1211 | 1221 | ||
1212 | BUG_ON(buf->bufnum != bufnum); | 1222 | BUG_ON(ibuf->bufnum != bufnum); |
1213 | 1223 | ||
1214 | if (buf->discard) { | 1224 | if (ibuf->discard) { |
1215 | /* | 1225 | /* |
1216 | * Discard buffer must not be returned to user space. | 1226 | * Discard buffer must not be returned to user space. |
1217 | * Just return it to the discard queue. | 1227 | * Just return it to the discard queue. |
1218 | */ | 1228 | */ |
1219 | list_move_tail(pcdev->active_bufs.next, &pcdev->discard); | 1229 | list_move_tail(pcdev->active_bufs.next, &pcdev->discard); |
1220 | } else { | 1230 | } else { |
1231 | buf = mx2_ibuf_to_buf(ibuf); | ||
1232 | |||
1221 | vb = &buf->vb; | 1233 | vb = &buf->vb; |
1222 | #ifdef DEBUG | 1234 | #ifdef DEBUG |
1223 | phys = vb2_dma_contig_plane_dma_addr(vb, 0); | 1235 | 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, | |||
1241 | vb2_plane_vaddr(vb, 0), | 1253 | vb2_plane_vaddr(vb, 0), |
1242 | vb2_get_plane_payload(vb, 0)); | 1254 | vb2_get_plane_payload(vb, 0)); |
1243 | 1255 | ||
1244 | list_del_init(&buf->queue); | 1256 | list_del_init(&buf->internal.queue); |
1245 | do_gettimeofday(&vb->v4l2_buf.timestamp); | 1257 | do_gettimeofday(&vb->v4l2_buf.timestamp); |
1246 | vb->v4l2_buf.sequence = pcdev->frame_count; | 1258 | vb->v4l2_buf.sequence = pcdev->frame_count; |
1247 | if (err) | 1259 | if (err) |
@@ -1259,18 +1271,19 @@ static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev, | |||
1259 | return; | 1271 | return; |
1260 | } | 1272 | } |
1261 | 1273 | ||
1262 | buf = list_first_entry(&pcdev->discard, struct mx2_buffer, | 1274 | ibuf = list_first_entry(&pcdev->discard, |
1263 | queue); | 1275 | struct mx2_buf_internal, queue); |
1264 | buf->bufnum = bufnum; | 1276 | ibuf->bufnum = bufnum; |
1265 | 1277 | ||
1266 | list_move_tail(pcdev->discard.next, &pcdev->active_bufs); | 1278 | list_move_tail(pcdev->discard.next, &pcdev->active_bufs); |
1267 | mx27_update_emma_buf(pcdev, pcdev->discard_buffer_dma, bufnum); | 1279 | mx27_update_emma_buf(pcdev, pcdev->discard_buffer_dma, bufnum); |
1268 | return; | 1280 | return; |
1269 | } | 1281 | } |
1270 | 1282 | ||
1271 | buf = list_first_entry(&pcdev->capture, struct mx2_buffer, queue); | 1283 | buf = list_first_entry(&pcdev->capture, struct mx2_buffer, |
1284 | internal.queue); | ||
1272 | 1285 | ||
1273 | buf->bufnum = bufnum; | 1286 | buf->internal.bufnum = bufnum; |
1274 | 1287 | ||
1275 | list_move_tail(pcdev->capture.next, &pcdev->active_bufs); | 1288 | list_move_tail(pcdev->capture.next, &pcdev->active_bufs); |
1276 | 1289 | ||
@@ -1285,7 +1298,7 @@ static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data) | |||
1285 | { | 1298 | { |
1286 | struct mx2_camera_dev *pcdev = data; | 1299 | struct mx2_camera_dev *pcdev = data; |
1287 | unsigned int status = readl(pcdev->base_emma + PRP_INTRSTATUS); | 1300 | unsigned int status = readl(pcdev->base_emma + PRP_INTRSTATUS); |
1288 | struct mx2_buffer *buf; | 1301 | struct mx2_buf_internal *ibuf; |
1289 | 1302 | ||
1290 | spin_lock(&pcdev->lock); | 1303 | spin_lock(&pcdev->lock); |
1291 | 1304 | ||
@@ -1305,10 +1318,10 @@ static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data) | |||
1305 | pcdev->base_emma + PRP_CNTL); | 1318 | pcdev->base_emma + PRP_CNTL); |
1306 | writel(cntl, pcdev->base_emma + PRP_CNTL); | 1319 | writel(cntl, pcdev->base_emma + PRP_CNTL); |
1307 | 1320 | ||
1308 | buf = list_first_entry(&pcdev->active_bufs, | 1321 | ibuf = list_first_entry(&pcdev->active_bufs, |
1309 | struct mx2_buffer, queue); | 1322 | struct mx2_buf_internal, queue); |
1310 | mx27_camera_frame_done_emma(pcdev, | 1323 | mx27_camera_frame_done_emma(pcdev, |
1311 | buf->bufnum, true); | 1324 | ibuf->bufnum, true); |
1312 | 1325 | ||
1313 | status &= ~(1 << 7); | 1326 | status &= ~(1 << 7); |
1314 | } else if (((status & (3 << 5)) == (3 << 5)) || | 1327 | } else if (((status & (3 << 5)) == (3 << 5)) || |
@@ -1317,10 +1330,10 @@ static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data) | |||
1317 | * Both buffers have triggered, process the one we're expecting | 1330 | * Both buffers have triggered, process the one we're expecting |
1318 | * to first | 1331 | * to first |
1319 | */ | 1332 | */ |
1320 | buf = list_first_entry(&pcdev->active_bufs, struct mx2_buffer, | 1333 | ibuf = list_first_entry(&pcdev->active_bufs, |
1321 | queue); | 1334 | struct mx2_buf_internal, queue); |
1322 | mx27_camera_frame_done_emma(pcdev, buf->bufnum, false); | 1335 | mx27_camera_frame_done_emma(pcdev, ibuf->bufnum, false); |
1323 | status &= ~(1 << (6 - buf->bufnum)); /* mark processed */ | 1336 | status &= ~(1 << (6 - ibuf->bufnum)); /* mark processed */ |
1324 | } else if ((status & (1 << 6)) || (status & (1 << 4))) { | 1337 | } else if ((status & (1 << 6)) || (status & (1 << 4))) { |
1325 | mx27_camera_frame_done_emma(pcdev, 0, false); | 1338 | mx27_camera_frame_done_emma(pcdev, 0, false); |
1326 | } else if ((status & (1 << 5)) || (status & (1 << 3))) { | 1339 | } else if ((status & (1 << 5)) || (status & (1 << 3))) { |