diff options
author | Jonathan Corbet <corbet@lwn.net> | 2011-06-30 16:05:27 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-07-27 16:53:35 -0400 |
commit | cbc4f3a277ce52c217457ce08f433d8e9ad4925f (patch) | |
tree | 5c5d19d197131b80210784751159a172b175a4ec | |
parent | 60c0732244164f14e376cfae493dba368f761514 (diff) |
[media] marvell-cam: Working s/g DMA
The core Marvell camera driver can now do scatter/gather DMA on controllers
which support that functionality.
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/marvell-ccic/Kconfig | 3 | ||||
-rw-r--r-- | drivers/media/video/marvell-ccic/mcam-core.c | 289 | ||||
-rw-r--r-- | drivers/media/video/marvell-ccic/mcam-core.h | 16 |
3 files changed, 266 insertions, 42 deletions
diff --git a/drivers/media/video/marvell-ccic/Kconfig b/drivers/media/video/marvell-ccic/Kconfig index 22314a0fa23..5be66e2e859 100644 --- a/drivers/media/video/marvell-ccic/Kconfig +++ b/drivers/media/video/marvell-ccic/Kconfig | |||
@@ -3,6 +3,8 @@ config VIDEO_CAFE_CCIC | |||
3 | depends on PCI && I2C && VIDEO_V4L2 | 3 | depends on PCI && I2C && VIDEO_V4L2 |
4 | select VIDEO_OV7670 | 4 | select VIDEO_OV7670 |
5 | select VIDEOBUF2_VMALLOC | 5 | select VIDEOBUF2_VMALLOC |
6 | select VIDEOBUF2_DMA_CONTIG | ||
7 | select VIDEOBUF2_DMA_SG | ||
6 | ---help--- | 8 | ---help--- |
7 | This is a video4linux2 driver for the Marvell 88ALP01 integrated | 9 | This is a video4linux2 driver for the Marvell 88ALP01 integrated |
8 | CMOS camera controller. This is the controller found on first- | 10 | CMOS camera controller. This is the controller found on first- |
@@ -15,6 +17,7 @@ config VIDEO_MMP_CAMERA | |||
15 | select I2C_GPIO | 17 | select I2C_GPIO |
16 | select VIDEOBUF2_VMALLOC | 18 | select VIDEOBUF2_VMALLOC |
17 | select VIDEOBUF2_DMA_CONTIG | 19 | select VIDEOBUF2_DMA_CONTIG |
20 | select VIDEOBUF2_DMA_SG | ||
18 | ---help--- | 21 | ---help--- |
19 | This is a Video4Linux2 driver for the integrated camera | 22 | This is a Video4Linux2 driver for the integrated camera |
20 | controller found on Marvell Armada 610 application | 23 | controller found on Marvell Armada 610 application |
diff --git a/drivers/media/video/marvell-ccic/mcam-core.c b/drivers/media/video/marvell-ccic/mcam-core.c index 419b4e5f698..af5faa6d7bc 100644 --- a/drivers/media/video/marvell-ccic/mcam-core.c +++ b/drivers/media/video/marvell-ccic/mcam-core.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <media/ov7670.h> | 26 | #include <media/ov7670.h> |
27 | #include <media/videobuf2-vmalloc.h> | 27 | #include <media/videobuf2-vmalloc.h> |
28 | #include <media/videobuf2-dma-contig.h> | 28 | #include <media/videobuf2-dma-contig.h> |
29 | #include <media/videobuf2-dma-sg.h> | ||
29 | 30 | ||
30 | #include "mcam-core.h" | 31 | #include "mcam-core.h" |
31 | 32 | ||
@@ -106,6 +107,7 @@ MODULE_PARM_DESC(buffer_mode, | |||
106 | #define CF_DMA_ACTIVE 3 /* A frame is incoming */ | 107 | #define CF_DMA_ACTIVE 3 /* A frame is incoming */ |
107 | #define CF_CONFIG_NEEDED 4 /* Must configure hardware */ | 108 | #define CF_CONFIG_NEEDED 4 /* Must configure hardware */ |
108 | #define CF_SINGLE_BUFFER 5 /* Running with a single buffer */ | 109 | #define CF_SINGLE_BUFFER 5 /* Running with a single buffer */ |
110 | #define CF_SG_RESTART 6 /* SG restart needed */ | ||
109 | 111 | ||
110 | #define sensor_call(cam, o, f, args...) \ | 112 | #define sensor_call(cam, o, f, args...) \ |
111 | v4l2_subdev_call(cam->sensor, o, f, ##args) | 113 | v4l2_subdev_call(cam->sensor, o, f, ##args) |
@@ -180,6 +182,17 @@ static void mcam_set_config_needed(struct mcam_camera *cam, int needed) | |||
180 | } | 182 | } |
181 | 183 | ||
182 | /* | 184 | /* |
185 | * The two-word DMA descriptor format used by the Armada 610 and like. There | ||
186 | * Is a three-word format as well (set C1_DESC_3WORD) where the third | ||
187 | * word is a pointer to the next descriptor, but we don't use it. Two-word | ||
188 | * descriptors have to be contiguous in memory. | ||
189 | */ | ||
190 | struct mcam_dma_desc { | ||
191 | u32 dma_addr; | ||
192 | u32 segment_len; | ||
193 | }; | ||
194 | |||
195 | /* | ||
183 | * Our buffer type for working with videobuf2. Note that the vb2 | 196 | * Our buffer type for working with videobuf2. Note that the vb2 |
184 | * developers have decreed that struct vb2_buffer must be at the | 197 | * developers have decreed that struct vb2_buffer must be at the |
185 | * beginning of this structure. | 198 | * beginning of this structure. |
@@ -187,6 +200,9 @@ static void mcam_set_config_needed(struct mcam_camera *cam, int needed) | |||
187 | struct mcam_vb_buffer { | 200 | struct mcam_vb_buffer { |
188 | struct vb2_buffer vb_buf; | 201 | struct vb2_buffer vb_buf; |
189 | struct list_head queue; | 202 | struct list_head queue; |
203 | struct mcam_dma_desc *dma_desc; /* Descriptor virtual address */ | ||
204 | dma_addr_t dma_desc_pa; /* Descriptor physical address */ | ||
205 | int dma_desc_nent; /* Number of mapped descriptors */ | ||
190 | }; | 206 | }; |
191 | 207 | ||
192 | static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_buffer *vb) | 208 | static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_buffer *vb) |
@@ -268,6 +284,9 @@ static void mcam_set_contig_buffer(struct mcam_camera *cam, int frame) | |||
268 | clear_bit(CF_SINGLE_BUFFER, &cam->flags); | 284 | clear_bit(CF_SINGLE_BUFFER, &cam->flags); |
269 | } | 285 | } |
270 | 286 | ||
287 | /* | ||
288 | * Initial B_DMA_contig setup. | ||
289 | */ | ||
271 | static void mcam_ctlr_dma_contig(struct mcam_camera *cam) | 290 | static void mcam_ctlr_dma_contig(struct mcam_camera *cam) |
272 | { | 291 | { |
273 | mcam_reg_set_bit(cam, REG_CTRL1, C1_TWOBUFS); | 292 | mcam_reg_set_bit(cam, REG_CTRL1, C1_TWOBUFS); |
@@ -277,14 +296,38 @@ static void mcam_ctlr_dma_contig(struct mcam_camera *cam) | |||
277 | } | 296 | } |
278 | 297 | ||
279 | 298 | ||
280 | static void mcam_ctlr_dma(struct mcam_camera *cam) | 299 | /* |
300 | * Set up the next buffer for S/G I/O; caller should be sure that | ||
301 | * the controller is stopped and a buffer is available. | ||
302 | */ | ||
303 | static void mcam_sg_next_buffer(struct mcam_camera *cam) | ||
281 | { | 304 | { |
282 | if (cam->buffer_mode == B_DMA_contig) | 305 | struct mcam_vb_buffer *buf; |
283 | mcam_ctlr_dma_contig(cam); | 306 | |
284 | else | 307 | buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, queue); |
285 | mcam_ctlr_dma_vmalloc(cam); | 308 | list_del_init(&buf->queue); |
309 | mcam_reg_write(cam, REG_DMA_DESC_Y, buf->dma_desc_pa); | ||
310 | mcam_reg_write(cam, REG_DESC_LEN_Y, | ||
311 | buf->dma_desc_nent*sizeof(struct mcam_dma_desc)); | ||
312 | mcam_reg_write(cam, REG_DESC_LEN_U, 0); | ||
313 | mcam_reg_write(cam, REG_DESC_LEN_V, 0); | ||
314 | cam->vb_bufs[0] = buf; | ||
286 | } | 315 | } |
287 | 316 | ||
317 | /* | ||
318 | * Initial B_DMA_sg setup | ||
319 | */ | ||
320 | static void mcam_ctlr_dma_sg(struct mcam_camera *cam) | ||
321 | { | ||
322 | mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_3WORD); | ||
323 | mcam_sg_next_buffer(cam); | ||
324 | mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA); | ||
325 | cam->nbufs = 3; | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * Image format setup, independent of DMA scheme. | ||
330 | */ | ||
288 | static void mcam_ctlr_image(struct mcam_camera *cam) | 331 | static void mcam_ctlr_image(struct mcam_camera *cam) |
289 | { | 332 | { |
290 | int imgsz; | 333 | int imgsz; |
@@ -341,9 +384,20 @@ static int mcam_ctlr_configure(struct mcam_camera *cam) | |||
341 | unsigned long flags; | 384 | unsigned long flags; |
342 | 385 | ||
343 | spin_lock_irqsave(&cam->dev_lock, flags); | 386 | spin_lock_irqsave(&cam->dev_lock, flags); |
344 | mcam_ctlr_dma(cam); | 387 | switch (cam->buffer_mode) { |
388 | case B_vmalloc: | ||
389 | mcam_ctlr_dma_vmalloc(cam); | ||
390 | break; | ||
391 | case B_DMA_contig: | ||
392 | mcam_ctlr_dma_contig(cam); | ||
393 | break; | ||
394 | case B_DMA_sg: | ||
395 | mcam_ctlr_dma_sg(cam); | ||
396 | break; | ||
397 | } | ||
345 | mcam_ctlr_image(cam); | 398 | mcam_ctlr_image(cam); |
346 | mcam_set_config_needed(cam, 0); | 399 | mcam_set_config_needed(cam, 0); |
400 | clear_bit(CF_SG_RESTART, &cam->flags); | ||
347 | spin_unlock_irqrestore(&cam->dev_lock, flags); | 401 | spin_unlock_irqrestore(&cam->dev_lock, flags); |
348 | return 0; | 402 | return 0; |
349 | } | 403 | } |
@@ -379,6 +433,19 @@ static void mcam_ctlr_stop(struct mcam_camera *cam) | |||
379 | mcam_reg_clear_bit(cam, REG_CTRL0, C0_ENABLE); | 433 | mcam_reg_clear_bit(cam, REG_CTRL0, C0_ENABLE); |
380 | } | 434 | } |
381 | 435 | ||
436 | /* | ||
437 | * Scatter/gather mode requires stopping the controller between | ||
438 | * frames so we can put in a new DMA descriptor array. If no new | ||
439 | * buffer exists at frame completion, the controller is left stopped; | ||
440 | * this function is charged with gettig things going again. | ||
441 | */ | ||
442 | static void mcam_sg_restart(struct mcam_camera *cam) | ||
443 | { | ||
444 | mcam_ctlr_dma_sg(cam); | ||
445 | mcam_ctlr_start(cam); | ||
446 | clear_bit(CF_SG_RESTART, &cam->flags); | ||
447 | } | ||
448 | |||
382 | static void mcam_ctlr_init(struct mcam_camera *cam) | 449 | static void mcam_ctlr_init(struct mcam_camera *cam) |
383 | { | 450 | { |
384 | unsigned long flags; | 451 | unsigned long flags; |
@@ -416,14 +483,15 @@ static void mcam_ctlr_stop_dma(struct mcam_camera *cam) | |||
416 | * interrupt, then wait until no DMA is active. | 483 | * interrupt, then wait until no DMA is active. |
417 | */ | 484 | */ |
418 | spin_lock_irqsave(&cam->dev_lock, flags); | 485 | spin_lock_irqsave(&cam->dev_lock, flags); |
486 | clear_bit(CF_SG_RESTART, &cam->flags); | ||
419 | mcam_ctlr_stop(cam); | 487 | mcam_ctlr_stop(cam); |
488 | cam->state = S_IDLE; | ||
420 | spin_unlock_irqrestore(&cam->dev_lock, flags); | 489 | spin_unlock_irqrestore(&cam->dev_lock, flags); |
421 | msleep(10); | 490 | msleep(40); |
422 | if (test_bit(CF_DMA_ACTIVE, &cam->flags)) | 491 | if (test_bit(CF_DMA_ACTIVE, &cam->flags)) |
423 | cam_err(cam, "Timeout waiting for DMA to end\n"); | 492 | cam_err(cam, "Timeout waiting for DMA to end\n"); |
424 | /* This would be bad news - what now? */ | 493 | /* This would be bad news - what now? */ |
425 | spin_lock_irqsave(&cam->dev_lock, flags); | 494 | spin_lock_irqsave(&cam->dev_lock, flags); |
426 | cam->state = S_IDLE; | ||
427 | mcam_ctlr_irq_disable(cam); | 495 | mcam_ctlr_irq_disable(cam); |
428 | spin_unlock_irqrestore(&cam->dev_lock, flags); | 496 | spin_unlock_irqrestore(&cam->dev_lock, flags); |
429 | } | 497 | } |
@@ -540,9 +608,8 @@ static int mcam_cam_configure(struct mcam_camera *cam) | |||
540 | * DMA buffer management. These functions need s_mutex held. | 608 | * DMA buffer management. These functions need s_mutex held. |
541 | */ | 609 | */ |
542 | 610 | ||
543 | /* FIXME: this is inefficient as hell, since dma_alloc_coherent just | 611 | /* |
544 | * does a get_free_pages() call, and we waste a good chunk of an orderN | 612 | * Allocate in-kernel DMA buffers for vmalloc mode. |
545 | * allocation. Should try to allocate the whole set in one chunk. | ||
546 | */ | 613 | */ |
547 | static int mcam_alloc_dma_bufs(struct mcam_camera *cam, int loadtime) | 614 | static int mcam_alloc_dma_bufs(struct mcam_camera *cam, int loadtime) |
548 | { | 615 | { |
@@ -650,24 +717,56 @@ static int mcam_vb_queue_setup(struct vb2_queue *vq, unsigned int *nbufs, | |||
650 | void *alloc_ctxs[]) | 717 | void *alloc_ctxs[]) |
651 | { | 718 | { |
652 | struct mcam_camera *cam = vb2_get_drv_priv(vq); | 719 | struct mcam_camera *cam = vb2_get_drv_priv(vq); |
720 | int minbufs = (cam->buffer_mode == B_DMA_contig) ? 3 : 2; | ||
653 | 721 | ||
654 | sizes[0] = cam->pix_format.sizeimage; | 722 | sizes[0] = cam->pix_format.sizeimage; |
655 | *num_planes = 1; /* Someday we have to support planar formats... */ | 723 | *num_planes = 1; /* Someday we have to support planar formats... */ |
656 | if (*nbufs < 3 || *nbufs > 32) | 724 | if (*nbufs < minbufs) |
657 | *nbufs = 3; /* semi-arbitrary numbers */ | 725 | *nbufs = minbufs; |
658 | if (cam->buffer_mode == B_DMA_contig) | 726 | if (cam->buffer_mode == B_DMA_contig) |
659 | alloc_ctxs[0] = cam->vb_alloc_ctx; | 727 | alloc_ctxs[0] = cam->vb_alloc_ctx; |
660 | return 0; | 728 | return 0; |
661 | } | 729 | } |
662 | 730 | ||
663 | static int mcam_vb_buf_init(struct vb2_buffer *vb) | 731 | /* DMA_sg only */ |
732 | static int mcam_vb_sg_buf_init(struct vb2_buffer *vb) | ||
733 | { | ||
734 | struct mcam_vb_buffer *mvb = vb_to_mvb(vb); | ||
735 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); | ||
736 | int ndesc = cam->pix_format.sizeimage/PAGE_SIZE + 1; | ||
737 | |||
738 | mvb->dma_desc = dma_alloc_coherent(cam->dev, | ||
739 | ndesc * sizeof(struct mcam_dma_desc), | ||
740 | &mvb->dma_desc_pa, GFP_KERNEL); | ||
741 | if (mvb->dma_desc == NULL) { | ||
742 | cam_err(cam, "Unable to get DMA descriptor array\n"); | ||
743 | return -ENOMEM; | ||
744 | } | ||
745 | return 0; | ||
746 | } | ||
747 | |||
748 | static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb) | ||
664 | { | 749 | { |
665 | struct mcam_vb_buffer *mvb = vb_to_mvb(vb); | 750 | struct mcam_vb_buffer *mvb = vb_to_mvb(vb); |
751 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); | ||
752 | struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0); | ||
753 | struct mcam_dma_desc *desc = mvb->dma_desc; | ||
754 | struct scatterlist *sg; | ||
755 | int i; | ||
666 | 756 | ||
667 | INIT_LIST_HEAD(&mvb->queue); | 757 | mvb->dma_desc_nent = dma_map_sg(cam->dev, sgd->sglist, sgd->num_pages, |
758 | DMA_FROM_DEVICE); | ||
759 | if (mvb->dma_desc_nent <= 0) | ||
760 | return -EIO; /* Not sure what's right here */ | ||
761 | for_each_sg(sgd->sglist, sg, mvb->dma_desc_nent, i) { | ||
762 | desc->dma_addr = sg_dma_address(sg); | ||
763 | desc->segment_len = sg_dma_len(sg); | ||
764 | desc++; | ||
765 | } | ||
668 | return 0; | 766 | return 0; |
669 | } | 767 | } |
670 | 768 | ||
769 | |||
671 | static void mcam_vb_buf_queue(struct vb2_buffer *vb) | 770 | static void mcam_vb_buf_queue(struct vb2_buffer *vb) |
672 | { | 771 | { |
673 | struct mcam_vb_buffer *mvb = vb_to_mvb(vb); | 772 | struct mcam_vb_buffer *mvb = vb_to_mvb(vb); |
@@ -678,11 +777,34 @@ static void mcam_vb_buf_queue(struct vb2_buffer *vb) | |||
678 | spin_lock_irqsave(&cam->dev_lock, flags); | 777 | spin_lock_irqsave(&cam->dev_lock, flags); |
679 | start = (cam->state == S_BUFWAIT) && !list_empty(&cam->buffers); | 778 | start = (cam->state == S_BUFWAIT) && !list_empty(&cam->buffers); |
680 | list_add(&mvb->queue, &cam->buffers); | 779 | list_add(&mvb->queue, &cam->buffers); |
780 | if (test_bit(CF_SG_RESTART, &cam->flags)) | ||
781 | mcam_sg_restart(cam); | ||
681 | spin_unlock_irqrestore(&cam->dev_lock, flags); | 782 | spin_unlock_irqrestore(&cam->dev_lock, flags); |
682 | if (start) | 783 | if (start) |
683 | mcam_read_setup(cam); | 784 | mcam_read_setup(cam); |
684 | } | 785 | } |
685 | 786 | ||
787 | |||
788 | static int mcam_vb_sg_buf_finish(struct vb2_buffer *vb) | ||
789 | { | ||
790 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); | ||
791 | struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0); | ||
792 | |||
793 | dma_unmap_sg(cam->dev, sgd->sglist, sgd->num_pages, DMA_FROM_DEVICE); | ||
794 | return 0; | ||
795 | } | ||
796 | |||
797 | static void mcam_vb_sg_buf_cleanup(struct vb2_buffer *vb) | ||
798 | { | ||
799 | struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue); | ||
800 | struct mcam_vb_buffer *mvb = vb_to_mvb(vb); | ||
801 | int ndesc = cam->pix_format.sizeimage/PAGE_SIZE + 1; | ||
802 | |||
803 | dma_free_coherent(cam->dev, ndesc * sizeof(struct mcam_dma_desc), | ||
804 | mvb->dma_desc, mvb->dma_desc_pa); | ||
805 | } | ||
806 | |||
807 | |||
686 | /* | 808 | /* |
687 | * vb2 uses these to release the mutex when waiting in dqbuf. I'm | 809 | * vb2 uses these to release the mutex when waiting in dqbuf. I'm |
688 | * not actually sure we need to do this (I'm not sure that vb2_dqbuf() needs | 810 | * not actually sure we need to do this (I'm not sure that vb2_dqbuf() needs |
@@ -752,7 +874,6 @@ static int mcam_vb_stop_streaming(struct vb2_queue *vq) | |||
752 | 874 | ||
753 | static const struct vb2_ops mcam_vb2_ops = { | 875 | static const struct vb2_ops mcam_vb2_ops = { |
754 | .queue_setup = mcam_vb_queue_setup, | 876 | .queue_setup = mcam_vb_queue_setup, |
755 | .buf_init = mcam_vb_buf_init, | ||
756 | .buf_queue = mcam_vb_buf_queue, | 877 | .buf_queue = mcam_vb_buf_queue, |
757 | .start_streaming = mcam_vb_start_streaming, | 878 | .start_streaming = mcam_vb_start_streaming, |
758 | .stop_streaming = mcam_vb_stop_streaming, | 879 | .stop_streaming = mcam_vb_stop_streaming, |
@@ -760,22 +881,49 @@ static const struct vb2_ops mcam_vb2_ops = { | |||
760 | .wait_finish = mcam_vb_wait_finish, | 881 | .wait_finish = mcam_vb_wait_finish, |
761 | }; | 882 | }; |
762 | 883 | ||
884 | /* | ||
885 | * Scatter/gather mode complicates things somewhat. | ||
886 | */ | ||
887 | static const struct vb2_ops mcam_vb2_sg_ops = { | ||
888 | .queue_setup = mcam_vb_queue_setup, | ||
889 | .buf_init = mcam_vb_sg_buf_init, | ||
890 | .buf_prepare = mcam_vb_sg_buf_prepare, | ||
891 | .buf_queue = mcam_vb_buf_queue, | ||
892 | .buf_finish = mcam_vb_sg_buf_finish, | ||
893 | .buf_cleanup = mcam_vb_sg_buf_cleanup, | ||
894 | .start_streaming = mcam_vb_start_streaming, | ||
895 | .stop_streaming = mcam_vb_stop_streaming, | ||
896 | .wait_prepare = mcam_vb_wait_prepare, | ||
897 | .wait_finish = mcam_vb_wait_finish, | ||
898 | }; | ||
899 | |||
763 | static int mcam_setup_vb2(struct mcam_camera *cam) | 900 | static int mcam_setup_vb2(struct mcam_camera *cam) |
764 | { | 901 | { |
765 | struct vb2_queue *vq = &cam->vb_queue; | 902 | struct vb2_queue *vq = &cam->vb_queue; |
766 | 903 | ||
767 | memset(vq, 0, sizeof(*vq)); | 904 | memset(vq, 0, sizeof(*vq)); |
768 | vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 905 | vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
769 | vq->io_modes = VB2_MMAP; /* Add userptr */ | ||
770 | vq->drv_priv = cam; | 906 | vq->drv_priv = cam; |
771 | vq->ops = &mcam_vb2_ops; | 907 | INIT_LIST_HEAD(&cam->buffers); |
772 | if (cam->buffer_mode == B_DMA_contig) { | 908 | switch (cam->buffer_mode) { |
909 | case B_DMA_contig: | ||
910 | vq->ops = &mcam_vb2_ops; | ||
773 | vq->mem_ops = &vb2_dma_contig_memops; | 911 | vq->mem_ops = &vb2_dma_contig_memops; |
774 | cam->vb_alloc_ctx = vb2_dma_contig_init_ctx(cam->dev); | 912 | cam->vb_alloc_ctx = vb2_dma_contig_init_ctx(cam->dev); |
775 | } else | 913 | vq->io_modes = VB2_MMAP | VB2_USERPTR; |
914 | break; | ||
915 | case B_DMA_sg: | ||
916 | vq->ops = &mcam_vb2_sg_ops; | ||
917 | vq->mem_ops = &vb2_dma_sg_memops; | ||
918 | vq->io_modes = VB2_MMAP | VB2_USERPTR; | ||
919 | break; | ||
920 | case B_vmalloc: | ||
921 | vq->ops = &mcam_vb2_ops; | ||
776 | vq->mem_ops = &vb2_vmalloc_memops; | 922 | vq->mem_ops = &vb2_vmalloc_memops; |
777 | vq->buf_struct_size = sizeof(struct mcam_vb_buffer); | 923 | vq->buf_struct_size = sizeof(struct mcam_vb_buffer); |
778 | 924 | vq->io_modes = VB2_MMAP; | |
925 | break; | ||
926 | } | ||
779 | return vb2_queue_init(vq); | 927 | return vb2_queue_init(vq); |
780 | } | 928 | } |
781 | 929 | ||
@@ -1313,8 +1461,6 @@ static void mcam_buffer_done(struct mcam_camera *cam, int frame, | |||
1313 | { | 1461 | { |
1314 | vbuf->v4l2_buf.bytesused = cam->pix_format.sizeimage; | 1462 | vbuf->v4l2_buf.bytesused = cam->pix_format.sizeimage; |
1315 | vbuf->v4l2_buf.sequence = cam->buf_seq[frame]; | 1463 | vbuf->v4l2_buf.sequence = cam->buf_seq[frame]; |
1316 | vbuf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; | ||
1317 | vbuf->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; | ||
1318 | vb2_set_plane_payload(vbuf, 0, cam->pix_format.sizeimage); | 1464 | vb2_set_plane_payload(vbuf, 0, cam->pix_format.sizeimage); |
1319 | vb2_buffer_done(vbuf, VB2_BUF_STATE_DONE); | 1465 | vb2_buffer_done(vbuf, VB2_BUF_STATE_DONE); |
1320 | } | 1466 | } |
@@ -1363,7 +1509,7 @@ static void mcam_frame_tasklet(unsigned long data) | |||
1363 | /* | 1509 | /* |
1364 | * For direct DMA, mark the buffer ready and set up another one. | 1510 | * For direct DMA, mark the buffer ready and set up another one. |
1365 | */ | 1511 | */ |
1366 | static void mcam_dma_complete(struct mcam_camera *cam, int frame) | 1512 | static void mcam_dma_contig_done(struct mcam_camera *cam, int frame) |
1367 | { | 1513 | { |
1368 | struct mcam_vb_buffer *buf = cam->vb_bufs[frame]; | 1514 | struct mcam_vb_buffer *buf = cam->vb_bufs[frame]; |
1369 | 1515 | ||
@@ -1374,6 +1520,52 @@ static void mcam_dma_complete(struct mcam_camera *cam, int frame) | |||
1374 | mcam_set_contig_buffer(cam, frame); | 1520 | mcam_set_contig_buffer(cam, frame); |
1375 | } | 1521 | } |
1376 | 1522 | ||
1523 | /* | ||
1524 | * Frame completion with S/G is trickier. We can't muck with | ||
1525 | * a descriptor chain on the fly, since the controller buffers it | ||
1526 | * internally. So we have to actually stop and restart; Marvell | ||
1527 | * says this is the way to do it. | ||
1528 | * | ||
1529 | * Of course, stopping is easier said than done; experience shows | ||
1530 | * that the controller can start a frame *after* C0_ENABLE has been | ||
1531 | * cleared. So when running in S/G mode, the controller is "stopped" | ||
1532 | * on receipt of the start-of-frame interrupt. That means we can | ||
1533 | * safely change the DMA descriptor array here and restart things | ||
1534 | * (assuming there's another buffer waiting to go). | ||
1535 | */ | ||
1536 | static void mcam_dma_sg_done(struct mcam_camera *cam, int frame) | ||
1537 | { | ||
1538 | struct mcam_vb_buffer *buf = cam->vb_bufs[0]; | ||
1539 | |||
1540 | /* | ||
1541 | * Very Bad Not Good Things happen if you don't clear | ||
1542 | * C1_DESC_ENA before making any descriptor changes. | ||
1543 | */ | ||
1544 | mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA); | ||
1545 | /* | ||
1546 | * If we have another buffer available, put it in and | ||
1547 | * restart the engine. | ||
1548 | */ | ||
1549 | if (!list_empty(&cam->buffers)) { | ||
1550 | mcam_sg_next_buffer(cam); | ||
1551 | mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA); | ||
1552 | mcam_ctlr_start(cam); | ||
1553 | /* | ||
1554 | * Otherwise set CF_SG_RESTART and the controller will | ||
1555 | * be restarted once another buffer shows up. | ||
1556 | */ | ||
1557 | } else { | ||
1558 | set_bit(CF_SG_RESTART, &cam->flags); | ||
1559 | singles++; | ||
1560 | } | ||
1561 | /* | ||
1562 | * Now we can give the completed frame back to user space. | ||
1563 | */ | ||
1564 | delivered++; | ||
1565 | mcam_buffer_done(cam, frame, &buf->vb_buf); | ||
1566 | } | ||
1567 | |||
1568 | |||
1377 | 1569 | ||
1378 | static void mcam_frame_complete(struct mcam_camera *cam, int frame) | 1570 | static void mcam_frame_complete(struct mcam_camera *cam, int frame) |
1379 | { | 1571 | { |
@@ -1385,22 +1577,25 @@ static void mcam_frame_complete(struct mcam_camera *cam, int frame) | |||
1385 | cam->next_buf = frame; | 1577 | cam->next_buf = frame; |
1386 | cam->buf_seq[frame] = ++(cam->sequence); | 1578 | cam->buf_seq[frame] = ++(cam->sequence); |
1387 | cam->last_delivered = frame; | 1579 | cam->last_delivered = frame; |
1388 | |||
1389 | frames++; | 1580 | frames++; |
1390 | switch (cam->state) { | ||
1391 | /* | 1581 | /* |
1392 | * We're streaming and have a ready frame, hand it back | 1582 | * "This should never happen" |
1393 | */ | 1583 | */ |
1394 | case S_STREAMING: | 1584 | if (cam->state != S_STREAMING) |
1395 | if (cam->buffer_mode == B_vmalloc) | 1585 | return; |
1396 | tasklet_schedule(&cam->s_tasklet); | 1586 | /* |
1397 | else | 1587 | * Process the frame and set up the next one. |
1398 | mcam_dma_complete(cam, frame); | 1588 | */ |
1399 | break; | 1589 | switch (cam->buffer_mode) { |
1400 | 1590 | case B_vmalloc: | |
1401 | default: | 1591 | tasklet_schedule(&cam->s_tasklet); |
1402 | cam_err(cam, "Frame interrupt in non-operational state\n"); | 1592 | break; |
1403 | break; | 1593 | case B_DMA_contig: |
1594 | mcam_dma_contig_done(cam, frame); | ||
1595 | break; | ||
1596 | case B_DMA_sg: | ||
1597 | mcam_dma_sg_done(cam, frame); | ||
1598 | break; | ||
1404 | } | 1599 | } |
1405 | } | 1600 | } |
1406 | 1601 | ||
@@ -1416,6 +1611,11 @@ int mccic_irq(struct mcam_camera *cam, unsigned int irqs) | |||
1416 | * Handle any frame completions. There really should | 1611 | * Handle any frame completions. There really should |
1417 | * not be more than one of these, or we have fallen | 1612 | * not be more than one of these, or we have fallen |
1418 | * far behind. | 1613 | * far behind. |
1614 | * | ||
1615 | * When running in S/G mode, the frame number lacks any | ||
1616 | * real meaning - there's only one descriptor array - but | ||
1617 | * the controller still picks a different one to signal | ||
1618 | * each time. | ||
1419 | */ | 1619 | */ |
1420 | for (frame = 0; frame < cam->nbufs; frame++) | 1620 | for (frame = 0; frame < cam->nbufs; frame++) |
1421 | if (irqs & (IRQ_EOF0 << frame)) { | 1621 | if (irqs & (IRQ_EOF0 << frame)) { |
@@ -1430,6 +1630,8 @@ int mccic_irq(struct mcam_camera *cam, unsigned int irqs) | |||
1430 | if (irqs & (IRQ_SOF0 | IRQ_SOF1 | IRQ_SOF2)) { | 1630 | if (irqs & (IRQ_SOF0 | IRQ_SOF1 | IRQ_SOF2)) { |
1431 | set_bit(CF_DMA_ACTIVE, &cam->flags); | 1631 | set_bit(CF_DMA_ACTIVE, &cam->flags); |
1432 | handled = 1; | 1632 | handled = 1; |
1633 | if (cam->buffer_mode == B_DMA_sg) | ||
1634 | mcam_ctlr_stop(cam); | ||
1433 | } | 1635 | } |
1434 | return handled; | 1636 | return handled; |
1435 | } | 1637 | } |
@@ -1480,8 +1682,15 @@ int mccic_register(struct mcam_camera *cam) | |||
1480 | cam->buffer_mode = B_vmalloc; | 1682 | cam->buffer_mode = B_vmalloc; |
1481 | else if (buffer_mode == 1) | 1683 | else if (buffer_mode == 1) |
1482 | cam->buffer_mode = B_DMA_contig; | 1684 | cam->buffer_mode = B_DMA_contig; |
1483 | else if (buffer_mode != -1) | 1685 | else if (buffer_mode == 2) { |
1484 | printk(KERN_ERR "marvel-cam: " | 1686 | if (cam->chip_id == V4L2_IDENT_ARMADA610) |
1687 | cam->buffer_mode = B_DMA_sg; | ||
1688 | else { | ||
1689 | printk(KERN_ERR "marvell-cam: Cafe can't do S/G I/O\n"); | ||
1690 | cam->buffer_mode = B_vmalloc; | ||
1691 | } | ||
1692 | } else if (buffer_mode != -1) | ||
1693 | printk(KERN_ERR "marvell-cam: " | ||
1485 | "Strange module buffer mode %d - ignoring\n", | 1694 | "Strange module buffer mode %d - ignoring\n", |
1486 | buffer_mode); | 1695 | buffer_mode); |
1487 | mcam_ctlr_init(cam); | 1696 | mcam_ctlr_init(cam); |
diff --git a/drivers/media/video/marvell-ccic/mcam-core.h b/drivers/media/video/marvell-ccic/mcam-core.h index 2e667a05620..55fd07823ae 100644 --- a/drivers/media/video/marvell-ccic/mcam-core.h +++ b/drivers/media/video/marvell-ccic/mcam-core.h | |||
@@ -38,7 +38,8 @@ enum mcam_state { | |||
38 | */ | 38 | */ |
39 | enum mcam_buffer_mode { | 39 | enum mcam_buffer_mode { |
40 | B_vmalloc = 0, | 40 | B_vmalloc = 0, |
41 | B_DMA_contig | 41 | B_DMA_contig, |
42 | B_DMA_sg | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | /* | 45 | /* |
@@ -250,8 +251,11 @@ int mccic_resume(struct mcam_camera *cam); | |||
250 | #define C0_SIF_HVSYNC 0x00000000 /* Use H/VSYNC */ | 251 | #define C0_SIF_HVSYNC 0x00000000 /* Use H/VSYNC */ |
251 | #define CO_SOF_NOSYNC 0x40000000 /* Use inband active signaling */ | 252 | #define CO_SOF_NOSYNC 0x40000000 /* Use inband active signaling */ |
252 | 253 | ||
253 | 254 | /* Bits below C1_444ALPHA are not present in Cafe */ | |
254 | #define REG_CTRL1 0x40 /* Control 1 */ | 255 | #define REG_CTRL1 0x40 /* Control 1 */ |
256 | #define C1_CLKGATE 0x00000001 /* Sensor clock gate */ | ||
257 | #define C1_DESC_ENA 0x00000100 /* DMA descriptor enable */ | ||
258 | #define C1_DESC_3WORD 0x00000200 /* Three-word descriptors used */ | ||
255 | #define C1_444ALPHA 0x00f00000 /* Alpha field in RGB444 */ | 259 | #define C1_444ALPHA 0x00f00000 /* Alpha field in RGB444 */ |
256 | #define C1_ALPHA_SHFT 20 | 260 | #define C1_ALPHA_SHFT 20 |
257 | #define C1_DMAB32 0x00000000 /* 32-byte DMA burst */ | 261 | #define C1_DMAB32 0x00000000 /* 32-byte DMA burst */ |
@@ -267,6 +271,14 @@ int mccic_resume(struct mcam_camera *cam); | |||
267 | /* This appears to be a Cafe-only register */ | 271 | /* This appears to be a Cafe-only register */ |
268 | #define REG_UBAR 0xc4 /* Upper base address register */ | 272 | #define REG_UBAR 0xc4 /* Upper base address register */ |
269 | 273 | ||
274 | /* Armada 610 DMA descriptor registers */ | ||
275 | #define REG_DMA_DESC_Y 0x200 | ||
276 | #define REG_DMA_DESC_U 0x204 | ||
277 | #define REG_DMA_DESC_V 0x208 | ||
278 | #define REG_DESC_LEN_Y 0x20c /* Lengths are in bytes */ | ||
279 | #define REG_DESC_LEN_U 0x210 | ||
280 | #define REG_DESC_LEN_V 0x214 | ||
281 | |||
270 | /* | 282 | /* |
271 | * Useful stuff that probably belongs somewhere global. | 283 | * Useful stuff that probably belongs somewhere global. |
272 | */ | 284 | */ |