aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorJavier Martin <javier.martin@vista-silicon.com>2012-02-22 05:59:34 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-03-08 08:04:10 -0500
commit560fab62fa0f4bc332e1a84fb2dfdb5ae5dc7581 (patch)
tree636e88cc89dbbeec9fbafc248a187783084f4fe8 /drivers/media
parent8886a881e2379565808eacbadd129120967e3539 (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>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/mx2_camera.c77
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
231struct 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 */
232struct mx2_buffer { 238struct 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
242struct mx2_camera_dev { 245struct 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
281static 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
278static struct mx2_fmt_cfg mx27_emma_prp_table[] = { 286static 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))) {