diff options
author | Javier Martin <javier.martin@vista-silicon.com> | 2012-10-30 10:28:59 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-01-04 22:47:16 -0500 |
commit | 9b556953224080d81754bfe764ab1899fc069edc (patch) | |
tree | bb8f259adb6b594b8842e87dd361cfa52db3ba70 | |
parent | 70e176a5a9839ea22f0fbcfa21d1c8ae952a0dd2 (diff) |
[media] mx2_camera: Remove i.mx25 support
i.MX25 support has been broken for several releases
now and nobody seems to care about it.
Signed-off-by: Javier Martin <javier.martin@vista-silicon.com>
[g.liakhovetski@gmx.de: rebased on top of cpu_is_mx27() removal]
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/platform/soc_camera/Kconfig | 7 | ||||
-rw-r--r-- | drivers/media/platform/soc_camera/mx2_camera.c | 476 |
2 files changed, 115 insertions, 368 deletions
diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig index cb6791e62bd4..b139b525bb16 100644 --- a/drivers/media/platform/soc_camera/Kconfig +++ b/drivers/media/platform/soc_camera/Kconfig | |||
@@ -70,13 +70,12 @@ config VIDEO_MX2_HOSTSUPPORT | |||
70 | bool | 70 | bool |
71 | 71 | ||
72 | config VIDEO_MX2 | 72 | config VIDEO_MX2 |
73 | tristate "i.MX27/i.MX25 Camera Sensor Interface driver" | 73 | tristate "i.MX27 Camera Sensor Interface driver" |
74 | depends on VIDEO_DEV && SOC_CAMERA && (MACH_MX27 || (ARCH_MX25 && BROKEN)) | 74 | depends on VIDEO_DEV && SOC_CAMERA && MACH_MX27 |
75 | select VIDEOBUF2_DMA_CONTIG | 75 | select VIDEOBUF2_DMA_CONTIG |
76 | select VIDEO_MX2_HOSTSUPPORT | 76 | select VIDEO_MX2_HOSTSUPPORT |
77 | ---help--- | 77 | ---help--- |
78 | This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor | 78 | This is a v4l2 driver for the i.MX27 Camera Sensor Interface |
79 | Interface | ||
80 | 79 | ||
81 | config VIDEO_ATMEL_ISI | 80 | config VIDEO_ATMEL_ISI |
82 | tristate "ATMEL Image Sensor Interface (ISI) support" | 81 | tristate "ATMEL Image Sensor Interface (ISI) support" |
diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index bf2740f7c4d1..c0511c001be1 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * V4L2 Driver for i.MX27/i.MX25 camera host | 2 | * V4L2 Driver for i.MX27 camera host |
3 | * | 3 | * |
4 | * Copyright (C) 2008, Sascha Hauer, Pengutronix | 4 | * Copyright (C) 2008, Sascha Hauer, Pengutronix |
5 | * Copyright (C) 2010, Baruch Siach, Orex Computed Radiography | 5 | * Copyright (C) 2010, Baruch Siach, Orex Computed Radiography |
@@ -63,9 +63,7 @@ | |||
63 | #define CSICR1_RF_OR_INTEN (1 << 24) | 63 | #define CSICR1_RF_OR_INTEN (1 << 24) |
64 | #define CSICR1_STATFF_LEVEL (3 << 22) | 64 | #define CSICR1_STATFF_LEVEL (3 << 22) |
65 | #define CSICR1_STATFF_INTEN (1 << 21) | 65 | #define CSICR1_STATFF_INTEN (1 << 21) |
66 | #define CSICR1_RXFF_LEVEL(l) (((l) & 3) << 19) /* MX27 */ | 66 | #define CSICR1_RXFF_LEVEL(l) (((l) & 3) << 19) |
67 | #define CSICR1_FB2_DMA_INTEN (1 << 20) /* MX25 */ | ||
68 | #define CSICR1_FB1_DMA_INTEN (1 << 19) /* MX25 */ | ||
69 | #define CSICR1_RXFF_INTEN (1 << 18) | 67 | #define CSICR1_RXFF_INTEN (1 << 18) |
70 | #define CSICR1_SOF_POL (1 << 17) | 68 | #define CSICR1_SOF_POL (1 << 17) |
71 | #define CSICR1_SOF_INTEN (1 << 16) | 69 | #define CSICR1_SOF_INTEN (1 << 16) |
@@ -87,45 +85,15 @@ | |||
87 | #define SHIFT_RXFF_LEVEL 19 | 85 | #define SHIFT_RXFF_LEVEL 19 |
88 | #define SHIFT_MCLKDIV 12 | 86 | #define SHIFT_MCLKDIV 12 |
89 | 87 | ||
90 | /* control reg 3 */ | ||
91 | #define CSICR3_FRMCNT (0xFFFF << 16) | ||
92 | #define CSICR3_FRMCNT_RST (1 << 15) | ||
93 | #define CSICR3_DMA_REFLASH_RFF (1 << 14) | ||
94 | #define CSICR3_DMA_REFLASH_SFF (1 << 13) | ||
95 | #define CSICR3_DMA_REQ_EN_RFF (1 << 12) | ||
96 | #define CSICR3_DMA_REQ_EN_SFF (1 << 11) | ||
97 | #define CSICR3_RXFF_LEVEL(l) (((l) & 7) << 4) /* MX25 */ | ||
98 | #define CSICR3_CSI_SUP (1 << 3) | ||
99 | #define CSICR3_ZERO_PACK_EN (1 << 2) | ||
100 | #define CSICR3_ECC_INT_EN (1 << 1) | ||
101 | #define CSICR3_ECC_AUTO_EN (1 << 0) | ||
102 | |||
103 | #define SHIFT_FRMCNT 16 | 88 | #define SHIFT_FRMCNT 16 |
104 | 89 | ||
105 | /* csi status reg */ | ||
106 | #define CSISR_SFF_OR_INT (1 << 25) | ||
107 | #define CSISR_RFF_OR_INT (1 << 24) | ||
108 | #define CSISR_STATFF_INT (1 << 21) | ||
109 | #define CSISR_DMA_TSF_FB2_INT (1 << 20) /* MX25 */ | ||
110 | #define CSISR_DMA_TSF_FB1_INT (1 << 19) /* MX25 */ | ||
111 | #define CSISR_RXFF_INT (1 << 18) | ||
112 | #define CSISR_EOF_INT (1 << 17) | ||
113 | #define CSISR_SOF_INT (1 << 16) | ||
114 | #define CSISR_F2_INT (1 << 15) | ||
115 | #define CSISR_F1_INT (1 << 14) | ||
116 | #define CSISR_COF_INT (1 << 13) | ||
117 | #define CSISR_ECC_INT (1 << 1) | ||
118 | #define CSISR_DRDY (1 << 0) | ||
119 | |||
120 | #define CSICR1 0x00 | 90 | #define CSICR1 0x00 |
121 | #define CSICR2 0x04 | 91 | #define CSICR2 0x04 |
122 | #define CSISR_IMX25 0x18 | 92 | #define CSISR 0x08 |
123 | #define CSISR_IMX27 0x08 | ||
124 | #define CSISTATFIFO 0x0c | 93 | #define CSISTATFIFO 0x0c |
125 | #define CSIRFIFO 0x10 | 94 | #define CSIRFIFO 0x10 |
126 | #define CSIRXCNT 0x14 | 95 | #define CSIRXCNT 0x14 |
127 | #define CSICR3_IMX25 0x08 | 96 | #define CSICR3 0x1c |
128 | #define CSICR3_IMX27 0x1c | ||
129 | #define CSIDMASA_STATFIFO 0x20 | 97 | #define CSIDMASA_STATFIFO 0x20 |
130 | #define CSIDMATA_STATFIFO 0x24 | 98 | #define CSIDMATA_STATFIFO 0x24 |
131 | #define CSIDMASA_FB1 0x28 | 99 | #define CSIDMASA_FB1 0x28 |
@@ -269,7 +237,6 @@ struct mx2_buffer { | |||
269 | }; | 237 | }; |
270 | 238 | ||
271 | enum mx2_camera_type { | 239 | enum mx2_camera_type { |
272 | IMX25_CAMERA, | ||
273 | IMX27_CAMERA, | 240 | IMX27_CAMERA, |
274 | }; | 241 | }; |
275 | 242 | ||
@@ -297,8 +264,6 @@ struct mx2_camera_dev { | |||
297 | struct mx2_buffer *fb2_active; | 264 | struct mx2_buffer *fb2_active; |
298 | 265 | ||
299 | u32 csicr1; | 266 | u32 csicr1; |
300 | u32 reg_csisr; | ||
301 | u32 reg_csicr3; | ||
302 | enum mx2_camera_type devtype; | 267 | enum mx2_camera_type devtype; |
303 | 268 | ||
304 | struct mx2_buf_internal buf_discard[2]; | 269 | struct mx2_buf_internal buf_discard[2]; |
@@ -314,9 +279,6 @@ struct mx2_camera_dev { | |||
314 | 279 | ||
315 | static struct platform_device_id mx2_camera_devtype[] = { | 280 | static struct platform_device_id mx2_camera_devtype[] = { |
316 | { | 281 | { |
317 | .name = "imx25-camera", | ||
318 | .driver_data = IMX25_CAMERA, | ||
319 | }, { | ||
320 | .name = "imx27-camera", | 282 | .name = "imx27-camera", |
321 | .driver_data = IMX27_CAMERA, | 283 | .driver_data = IMX27_CAMERA, |
322 | }, { | 284 | }, { |
@@ -325,16 +287,6 @@ static struct platform_device_id mx2_camera_devtype[] = { | |||
325 | }; | 287 | }; |
326 | MODULE_DEVICE_TABLE(platform, mx2_camera_devtype); | 288 | MODULE_DEVICE_TABLE(platform, mx2_camera_devtype); |
327 | 289 | ||
328 | static inline int is_imx25_camera(struct mx2_camera_dev *pcdev) | ||
329 | { | ||
330 | return pcdev->devtype == IMX25_CAMERA; | ||
331 | } | ||
332 | |||
333 | static inline int is_imx27_camera(struct mx2_camera_dev *pcdev) | ||
334 | { | ||
335 | return pcdev->devtype == IMX27_CAMERA; | ||
336 | } | ||
337 | |||
338 | static struct mx2_buffer *mx2_ibuf_to_buf(struct mx2_buf_internal *int_buf) | 290 | static struct mx2_buffer *mx2_ibuf_to_buf(struct mx2_buf_internal *int_buf) |
339 | { | 291 | { |
340 | return container_of(int_buf, struct mx2_buffer, internal); | 292 | return container_of(int_buf, struct mx2_buffer, internal); |
@@ -462,21 +414,10 @@ static void mx27_update_emma_buf(struct mx2_camera_dev *pcdev, | |||
462 | 414 | ||
463 | static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev) | 415 | static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev) |
464 | { | 416 | { |
465 | unsigned long flags; | ||
466 | |||
467 | clk_disable_unprepare(pcdev->clk_csi_ahb); | 417 | clk_disable_unprepare(pcdev->clk_csi_ahb); |
468 | clk_disable_unprepare(pcdev->clk_csi_per); | 418 | clk_disable_unprepare(pcdev->clk_csi_per); |
469 | writel(0, pcdev->base_csi + CSICR1); | 419 | writel(0, pcdev->base_csi + CSICR1); |
470 | if (is_imx27_camera(pcdev)) { | 420 | writel(0, pcdev->base_emma + PRP_CNTL); |
471 | writel(0, pcdev->base_emma + PRP_CNTL); | ||
472 | } else if (is_imx25_camera(pcdev)) { | ||
473 | spin_lock_irqsave(&pcdev->lock, flags); | ||
474 | pcdev->fb1_active = NULL; | ||
475 | pcdev->fb2_active = NULL; | ||
476 | writel(0, pcdev->base_csi + CSIDMASA_FB1); | ||
477 | writel(0, pcdev->base_csi + CSIDMASA_FB2); | ||
478 | spin_unlock_irqrestore(&pcdev->lock, flags); | ||
479 | } | ||
480 | } | 421 | } |
481 | 422 | ||
482 | /* | 423 | /* |
@@ -501,11 +442,8 @@ static int mx2_camera_add_device(struct soc_camera_device *icd) | |||
501 | if (ret < 0) | 442 | if (ret < 0) |
502 | goto exit_csi_ahb; | 443 | goto exit_csi_ahb; |
503 | 444 | ||
504 | csicr1 = CSICR1_MCLKEN; | 445 | csicr1 = CSICR1_MCLKEN | CSICR1_PRP_IF_EN | CSICR1_FCC | |
505 | 446 | CSICR1_RXFF_LEVEL(0); | |
506 | if (is_imx27_camera(pcdev)) | ||
507 | csicr1 |= CSICR1_PRP_IF_EN | CSICR1_FCC | | ||
508 | CSICR1_RXFF_LEVEL(0); | ||
509 | 447 | ||
510 | pcdev->csicr1 = csicr1; | 448 | pcdev->csicr1 = csicr1; |
511 | writel(pcdev->csicr1, pcdev->base_csi + CSICR1); | 449 | writel(pcdev->csicr1, pcdev->base_csi + CSICR1); |
@@ -539,65 +477,6 @@ static void mx2_camera_remove_device(struct soc_camera_device *icd) | |||
539 | pcdev->icd = NULL; | 477 | pcdev->icd = NULL; |
540 | } | 478 | } |
541 | 479 | ||
542 | static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, | ||
543 | int state) | ||
544 | { | ||
545 | struct vb2_buffer *vb; | ||
546 | struct mx2_buffer *buf; | ||
547 | struct mx2_buffer **fb_active = fb == 1 ? &pcdev->fb1_active : | ||
548 | &pcdev->fb2_active; | ||
549 | u32 fb_reg = fb == 1 ? CSIDMASA_FB1 : CSIDMASA_FB2; | ||
550 | unsigned long flags; | ||
551 | |||
552 | spin_lock_irqsave(&pcdev->lock, flags); | ||
553 | |||
554 | if (*fb_active == NULL) | ||
555 | goto out; | ||
556 | |||
557 | vb = &(*fb_active)->vb; | ||
558 | dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__, | ||
559 | vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); | ||
560 | |||
561 | v4l2_get_timestamp(&vb->v4l2_buf.timestamp); | ||
562 | vb->v4l2_buf.sequence++; | ||
563 | vb2_buffer_done(vb, VB2_BUF_STATE_DONE); | ||
564 | |||
565 | if (list_empty(&pcdev->capture)) { | ||
566 | buf = NULL; | ||
567 | writel(0, pcdev->base_csi + fb_reg); | ||
568 | } else { | ||
569 | buf = list_first_entry(&pcdev->capture, struct mx2_buffer, | ||
570 | internal.queue); | ||
571 | vb = &buf->vb; | ||
572 | list_del(&buf->internal.queue); | ||
573 | buf->state = MX2_STATE_ACTIVE; | ||
574 | writel(vb2_dma_contig_plane_dma_addr(vb, 0), | ||
575 | pcdev->base_csi + fb_reg); | ||
576 | } | ||
577 | |||
578 | *fb_active = buf; | ||
579 | |||
580 | out: | ||
581 | spin_unlock_irqrestore(&pcdev->lock, flags); | ||
582 | } | ||
583 | |||
584 | static irqreturn_t mx25_camera_irq(int irq_csi, void *data) | ||
585 | { | ||
586 | struct mx2_camera_dev *pcdev = data; | ||
587 | u32 status = readl(pcdev->base_csi + pcdev->reg_csisr); | ||
588 | |||
589 | if (status & CSISR_DMA_TSF_FB1_INT) | ||
590 | mx25_camera_frame_done(pcdev, 1, MX2_STATE_DONE); | ||
591 | else if (status & CSISR_DMA_TSF_FB2_INT) | ||
592 | mx25_camera_frame_done(pcdev, 2, MX2_STATE_DONE); | ||
593 | |||
594 | /* FIXME: handle CSISR_RFF_OR_INT */ | ||
595 | |||
596 | writel(status, pcdev->base_csi + pcdev->reg_csisr); | ||
597 | |||
598 | return IRQ_HANDLED; | ||
599 | } | ||
600 | |||
601 | /* | 480 | /* |
602 | * Videobuf operations | 481 | * Videobuf operations |
603 | */ | 482 | */ |
@@ -678,54 +557,17 @@ static void mx2_videobuf_queue(struct vb2_buffer *vb) | |||
678 | buf->state = MX2_STATE_QUEUED; | 557 | buf->state = MX2_STATE_QUEUED; |
679 | list_add_tail(&buf->internal.queue, &pcdev->capture); | 558 | list_add_tail(&buf->internal.queue, &pcdev->capture); |
680 | 559 | ||
681 | if (is_imx25_camera(pcdev)) { | ||
682 | u32 csicr3, dma_inten = 0; | ||
683 | |||
684 | if (pcdev->fb1_active == NULL) { | ||
685 | writel(vb2_dma_contig_plane_dma_addr(vb, 0), | ||
686 | pcdev->base_csi + CSIDMASA_FB1); | ||
687 | pcdev->fb1_active = buf; | ||
688 | dma_inten = CSICR1_FB1_DMA_INTEN; | ||
689 | } else if (pcdev->fb2_active == NULL) { | ||
690 | writel(vb2_dma_contig_plane_dma_addr(vb, 0), | ||
691 | pcdev->base_csi + CSIDMASA_FB2); | ||
692 | pcdev->fb2_active = buf; | ||
693 | dma_inten = CSICR1_FB2_DMA_INTEN; | ||
694 | } | ||
695 | |||
696 | if (dma_inten) { | ||
697 | list_del(&buf->internal.queue); | ||
698 | buf->state = MX2_STATE_ACTIVE; | ||
699 | |||
700 | csicr3 = readl(pcdev->base_csi + pcdev->reg_csicr3); | ||
701 | |||
702 | /* Reflash DMA */ | ||
703 | writel(csicr3 | CSICR3_DMA_REFLASH_RFF, | ||
704 | pcdev->base_csi + pcdev->reg_csicr3); | ||
705 | |||
706 | /* clear & enable interrupts */ | ||
707 | writel(dma_inten, pcdev->base_csi + pcdev->reg_csisr); | ||
708 | pcdev->csicr1 |= dma_inten; | ||
709 | writel(pcdev->csicr1, pcdev->base_csi + CSICR1); | ||
710 | |||
711 | /* enable DMA */ | ||
712 | csicr3 |= CSICR3_DMA_REQ_EN_RFF | CSICR3_RXFF_LEVEL(1); | ||
713 | writel(csicr3, pcdev->base_csi + pcdev->reg_csicr3); | ||
714 | } | ||
715 | } | ||
716 | |||
717 | spin_unlock_irqrestore(&pcdev->lock, flags); | 560 | spin_unlock_irqrestore(&pcdev->lock, flags); |
718 | } | 561 | } |
719 | 562 | ||
720 | static void mx2_videobuf_release(struct vb2_buffer *vb) | 563 | static void mx2_videobuf_release(struct vb2_buffer *vb) |
721 | { | 564 | { |
565 | #ifdef DEBUG | ||
722 | struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); | 566 | struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); |
723 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 567 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
724 | struct mx2_camera_dev *pcdev = ici->priv; | 568 | struct mx2_camera_dev *pcdev = ici->priv; |
725 | struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb); | 569 | struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb); |
726 | unsigned long flags; | ||
727 | 570 | ||
728 | #ifdef DEBUG | ||
729 | dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, | 571 | dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, |
730 | vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); | 572 | vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); |
731 | 573 | ||
@@ -744,29 +586,11 @@ static void mx2_videobuf_release(struct vb2_buffer *vb) | |||
744 | #endif | 586 | #endif |
745 | 587 | ||
746 | /* | 588 | /* |
747 | * Terminate only queued but inactive buffers. Active buffers are | ||
748 | * released when they become inactive after videobuf_waiton(). | ||
749 | * | ||
750 | * FIXME: implement forced termination of active buffers for mx27 and | 589 | * FIXME: implement forced termination of active buffers for mx27 and |
751 | * mx27 eMMA, so that the user won't get stuck in an uninterruptible | 590 | * mx27 eMMA, so that the user won't get stuck in an uninterruptible |
752 | * state. This requires a specific handling for each of the these DMA | 591 | * state. This requires a specific handling for each of the these DMA |
753 | * types. | 592 | * types. |
754 | */ | 593 | */ |
755 | |||
756 | spin_lock_irqsave(&pcdev->lock, flags); | ||
757 | if (is_imx25_camera(pcdev) && buf->state == MX2_STATE_ACTIVE) { | ||
758 | if (pcdev->fb1_active == buf) { | ||
759 | pcdev->csicr1 &= ~CSICR1_FB1_DMA_INTEN; | ||
760 | writel(0, pcdev->base_csi + CSIDMASA_FB1); | ||
761 | pcdev->fb1_active = NULL; | ||
762 | } else if (pcdev->fb2_active == buf) { | ||
763 | pcdev->csicr1 &= ~CSICR1_FB2_DMA_INTEN; | ||
764 | writel(0, pcdev->base_csi + CSIDMASA_FB2); | ||
765 | pcdev->fb2_active = NULL; | ||
766 | } | ||
767 | writel(pcdev->csicr1, pcdev->base_csi + CSICR1); | ||
768 | } | ||
769 | spin_unlock_irqrestore(&pcdev->lock, flags); | ||
770 | } | 594 | } |
771 | 595 | ||
772 | static void mx27_camera_emma_buf_init(struct soc_camera_device *icd, | 596 | static void mx27_camera_emma_buf_init(struct soc_camera_device *icd, |
@@ -876,91 +700,89 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count) | |||
876 | struct mx2_buffer *buf; | 700 | struct mx2_buffer *buf; |
877 | unsigned long phys; | 701 | unsigned long phys; |
878 | int bytesperline; | 702 | int bytesperline; |
703 | unsigned long flags; | ||
879 | 704 | ||
880 | if (is_imx27_camera(pcdev)) { | 705 | if (count < 2) |
881 | unsigned long flags; | 706 | return -EINVAL; |
882 | if (count < 2) | ||
883 | return -EINVAL; | ||
884 | 707 | ||
885 | spin_lock_irqsave(&pcdev->lock, flags); | 708 | spin_lock_irqsave(&pcdev->lock, flags); |
886 | 709 | ||
887 | buf = list_first_entry(&pcdev->capture, struct mx2_buffer, | 710 | buf = list_first_entry(&pcdev->capture, struct mx2_buffer, |
888 | internal.queue); | 711 | internal.queue); |
889 | buf->internal.bufnum = 0; | 712 | buf->internal.bufnum = 0; |
890 | vb = &buf->vb; | 713 | vb = &buf->vb; |
891 | buf->state = MX2_STATE_ACTIVE; | 714 | buf->state = MX2_STATE_ACTIVE; |
892 | 715 | ||
893 | phys = vb2_dma_contig_plane_dma_addr(vb, 0); | 716 | phys = vb2_dma_contig_plane_dma_addr(vb, 0); |
894 | mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum); | 717 | mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum); |
895 | list_move_tail(pcdev->capture.next, &pcdev->active_bufs); | 718 | list_move_tail(pcdev->capture.next, &pcdev->active_bufs); |
896 | 719 | ||
897 | buf = list_first_entry(&pcdev->capture, struct mx2_buffer, | 720 | buf = list_first_entry(&pcdev->capture, struct mx2_buffer, |
898 | internal.queue); | 721 | internal.queue); |
899 | buf->internal.bufnum = 1; | 722 | buf->internal.bufnum = 1; |
900 | vb = &buf->vb; | 723 | vb = &buf->vb; |
901 | buf->state = MX2_STATE_ACTIVE; | 724 | buf->state = MX2_STATE_ACTIVE; |
902 | 725 | ||
903 | phys = vb2_dma_contig_plane_dma_addr(vb, 0); | 726 | phys = vb2_dma_contig_plane_dma_addr(vb, 0); |
904 | mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum); | 727 | mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum); |
905 | list_move_tail(pcdev->capture.next, &pcdev->active_bufs); | 728 | list_move_tail(pcdev->capture.next, &pcdev->active_bufs); |
906 | |||
907 | bytesperline = soc_mbus_bytes_per_line(icd->user_width, | ||
908 | icd->current_fmt->host_fmt); | ||
909 | if (bytesperline < 0) { | ||
910 | spin_unlock_irqrestore(&pcdev->lock, flags); | ||
911 | return bytesperline; | ||
912 | } | ||
913 | 729 | ||
914 | /* | 730 | bytesperline = soc_mbus_bytes_per_line(icd->user_width, |
915 | * I didn't manage to properly enable/disable the prp | 731 | icd->current_fmt->host_fmt); |
916 | * on a per frame basis during running transfers, | 732 | if (bytesperline < 0) { |
917 | * thus we allocate a buffer here and use it to | 733 | spin_unlock_irqrestore(&pcdev->lock, flags); |
918 | * discard frames when no buffer is available. | 734 | return bytesperline; |
919 | * Feel free to work on this ;) | 735 | } |
920 | */ | ||
921 | pcdev->discard_size = icd->user_height * bytesperline; | ||
922 | pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev, | ||
923 | pcdev->discard_size, &pcdev->discard_buffer_dma, | ||
924 | GFP_ATOMIC); | ||
925 | if (!pcdev->discard_buffer) { | ||
926 | spin_unlock_irqrestore(&pcdev->lock, flags); | ||
927 | return -ENOMEM; | ||
928 | } | ||
929 | 736 | ||
930 | pcdev->buf_discard[0].discard = true; | 737 | /* |
931 | list_add_tail(&pcdev->buf_discard[0].queue, | 738 | * I didn't manage to properly enable/disable the prp |
932 | &pcdev->discard); | 739 | * on a per frame basis during running transfers, |
740 | * thus we allocate a buffer here and use it to | ||
741 | * discard frames when no buffer is available. | ||
742 | * Feel free to work on this ;) | ||
743 | */ | ||
744 | pcdev->discard_size = icd->user_height * bytesperline; | ||
745 | pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev, | ||
746 | pcdev->discard_size, | ||
747 | &pcdev->discard_buffer_dma, GFP_ATOMIC); | ||
748 | if (!pcdev->discard_buffer) { | ||
749 | spin_unlock_irqrestore(&pcdev->lock, flags); | ||
750 | return -ENOMEM; | ||
751 | } | ||
933 | 752 | ||
934 | pcdev->buf_discard[1].discard = true; | 753 | pcdev->buf_discard[0].discard = true; |
935 | list_add_tail(&pcdev->buf_discard[1].queue, | 754 | list_add_tail(&pcdev->buf_discard[0].queue, |
936 | &pcdev->discard); | 755 | &pcdev->discard); |
937 | 756 | ||
938 | mx2_prp_resize_commit(pcdev); | 757 | pcdev->buf_discard[1].discard = true; |
758 | list_add_tail(&pcdev->buf_discard[1].queue, | ||
759 | &pcdev->discard); | ||
939 | 760 | ||
940 | mx27_camera_emma_buf_init(icd, bytesperline); | 761 | mx2_prp_resize_commit(pcdev); |
941 | 762 | ||
942 | if (prp->cfg.channel == 1) { | 763 | mx27_camera_emma_buf_init(icd, bytesperline); |
943 | writel(PRP_CNTL_CH1EN | | 764 | |
944 | PRP_CNTL_CSIEN | | 765 | if (prp->cfg.channel == 1) { |
945 | prp->cfg.in_fmt | | 766 | writel(PRP_CNTL_CH1EN | |
946 | prp->cfg.out_fmt | | 767 | PRP_CNTL_CSIEN | |
947 | PRP_CNTL_CH1_LEN | | 768 | prp->cfg.in_fmt | |
948 | PRP_CNTL_CH1BYP | | 769 | prp->cfg.out_fmt | |
949 | PRP_CNTL_CH1_TSKIP(0) | | 770 | PRP_CNTL_CH1_LEN | |
950 | PRP_CNTL_IN_TSKIP(0), | 771 | PRP_CNTL_CH1BYP | |
951 | pcdev->base_emma + PRP_CNTL); | 772 | PRP_CNTL_CH1_TSKIP(0) | |
952 | } else { | 773 | PRP_CNTL_IN_TSKIP(0), |
953 | writel(PRP_CNTL_CH2EN | | 774 | pcdev->base_emma + PRP_CNTL); |
954 | PRP_CNTL_CSIEN | | 775 | } else { |
955 | prp->cfg.in_fmt | | 776 | writel(PRP_CNTL_CH2EN | |
956 | prp->cfg.out_fmt | | 777 | PRP_CNTL_CSIEN | |
957 | PRP_CNTL_CH2_LEN | | 778 | prp->cfg.in_fmt | |
958 | PRP_CNTL_CH2_TSKIP(0) | | 779 | prp->cfg.out_fmt | |
959 | PRP_CNTL_IN_TSKIP(0), | 780 | PRP_CNTL_CH2_LEN | |
960 | pcdev->base_emma + PRP_CNTL); | 781 | PRP_CNTL_CH2_TSKIP(0) | |
961 | } | 782 | PRP_CNTL_IN_TSKIP(0), |
962 | spin_unlock_irqrestore(&pcdev->lock, flags); | 783 | pcdev->base_emma + PRP_CNTL); |
963 | } | 784 | } |
785 | spin_unlock_irqrestore(&pcdev->lock, flags); | ||
964 | 786 | ||
965 | return 0; | 787 | return 0; |
966 | } | 788 | } |
@@ -976,29 +798,27 @@ static int mx2_stop_streaming(struct vb2_queue *q) | |||
976 | void *b; | 798 | void *b; |
977 | u32 cntl; | 799 | u32 cntl; |
978 | 800 | ||
979 | if (is_imx27_camera(pcdev)) { | 801 | spin_lock_irqsave(&pcdev->lock, flags); |
980 | spin_lock_irqsave(&pcdev->lock, flags); | ||
981 | 802 | ||
982 | cntl = readl(pcdev->base_emma + PRP_CNTL); | 803 | cntl = readl(pcdev->base_emma + PRP_CNTL); |
983 | if (prp->cfg.channel == 1) { | 804 | if (prp->cfg.channel == 1) { |
984 | writel(cntl & ~PRP_CNTL_CH1EN, | 805 | writel(cntl & ~PRP_CNTL_CH1EN, |
985 | pcdev->base_emma + PRP_CNTL); | 806 | pcdev->base_emma + PRP_CNTL); |
986 | } else { | 807 | } else { |
987 | writel(cntl & ~PRP_CNTL_CH2EN, | 808 | writel(cntl & ~PRP_CNTL_CH2EN, |
988 | pcdev->base_emma + PRP_CNTL); | 809 | pcdev->base_emma + PRP_CNTL); |
989 | } | 810 | } |
990 | INIT_LIST_HEAD(&pcdev->capture); | 811 | INIT_LIST_HEAD(&pcdev->capture); |
991 | INIT_LIST_HEAD(&pcdev->active_bufs); | 812 | INIT_LIST_HEAD(&pcdev->active_bufs); |
992 | INIT_LIST_HEAD(&pcdev->discard); | 813 | INIT_LIST_HEAD(&pcdev->discard); |
993 | 814 | ||
994 | b = pcdev->discard_buffer; | 815 | b = pcdev->discard_buffer; |
995 | pcdev->discard_buffer = NULL; | 816 | pcdev->discard_buffer = NULL; |
996 | 817 | ||
997 | spin_unlock_irqrestore(&pcdev->lock, flags); | 818 | spin_unlock_irqrestore(&pcdev->lock, flags); |
998 | 819 | ||
999 | dma_free_coherent(ici->v4l2_dev.dev, | 820 | dma_free_coherent(ici->v4l2_dev.dev, |
1000 | pcdev->discard_size, b, pcdev->discard_buffer_dma); | 821 | pcdev->discard_size, b, pcdev->discard_buffer_dma); |
1001 | } | ||
1002 | 822 | ||
1003 | return 0; | 823 | return 0; |
1004 | } | 824 | } |
@@ -1128,16 +948,9 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) | |||
1128 | if (bytesperline < 0) | 948 | if (bytesperline < 0) |
1129 | return bytesperline; | 949 | return bytesperline; |
1130 | 950 | ||
1131 | if (is_imx27_camera(pcdev)) { | 951 | ret = mx27_camera_emma_prp_reset(pcdev); |
1132 | ret = mx27_camera_emma_prp_reset(pcdev); | 952 | if (ret) |
1133 | if (ret) | 953 | return ret; |
1134 | return ret; | ||
1135 | } else if (is_imx25_camera(pcdev)) { | ||
1136 | writel((bytesperline * icd->user_height) >> 2, | ||
1137 | pcdev->base_csi + CSIRXCNT); | ||
1138 | writel((bytesperline << 16) | icd->user_height, | ||
1139 | pcdev->base_csi + CSIIMAG_PARA); | ||
1140 | } | ||
1141 | 954 | ||
1142 | writel(pcdev->csicr1, pcdev->base_csi + CSICR1); | 955 | writel(pcdev->csicr1, pcdev->base_csi + CSICR1); |
1143 | 956 | ||
@@ -1424,7 +1237,6 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd, | |||
1424 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 1237 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
1425 | struct mx2_camera_dev *pcdev = ici->priv; | 1238 | struct mx2_camera_dev *pcdev = ici->priv; |
1426 | struct mx2_fmt_cfg *emma_prp; | 1239 | struct mx2_fmt_cfg *emma_prp; |
1427 | unsigned int width_limit; | ||
1428 | int ret; | 1240 | int ret; |
1429 | 1241 | ||
1430 | dev_dbg(icd->parent, "%s: requested params: width = %d, height = %d\n", | 1242 | dev_dbg(icd->parent, "%s: requested params: width = %d, height = %d\n", |
@@ -1436,44 +1248,11 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd, | |||
1436 | return -EINVAL; | 1248 | return -EINVAL; |
1437 | } | 1249 | } |
1438 | 1250 | ||
1439 | /* limit to MX25 hardware capabilities */ | 1251 | /* |
1440 | if (is_imx25_camera(pcdev)) { | 1252 | * limit to MX27 hardware capabilities: width must be a multiple of 8 as |
1441 | if (xlate->host_fmt->bits_per_sample <= 8) | 1253 | * requested by the CSI. (Table 39-2 in the i.MX27 Reference Manual). |
1442 | width_limit = 0xffff * 4; | 1254 | */ |
1443 | else | 1255 | pix->width &= ~0x7; |
1444 | width_limit = 0xffff * 2; | ||
1445 | /* CSIIMAG_PARA limit */ | ||
1446 | if (pix->width > width_limit) | ||
1447 | pix->width = width_limit; | ||
1448 | if (pix->height > 0xffff) | ||
1449 | pix->height = 0xffff; | ||
1450 | |||
1451 | pix->bytesperline = soc_mbus_bytes_per_line(pix->width, | ||
1452 | xlate->host_fmt); | ||
1453 | if (pix->bytesperline < 0) | ||
1454 | return pix->bytesperline; | ||
1455 | pix->sizeimage = soc_mbus_image_size(xlate->host_fmt, | ||
1456 | pix->bytesperline, pix->height); | ||
1457 | /* Check against the CSIRXCNT limit */ | ||
1458 | if (pix->sizeimage > 4 * 0x3ffff) { | ||
1459 | /* Adjust geometry, preserve aspect ratio */ | ||
1460 | unsigned int new_height = int_sqrt(div_u64(0x3ffffULL * | ||
1461 | 4 * pix->height, pix->bytesperline)); | ||
1462 | pix->width = new_height * pix->width / pix->height; | ||
1463 | pix->height = new_height; | ||
1464 | pix->bytesperline = soc_mbus_bytes_per_line(pix->width, | ||
1465 | xlate->host_fmt); | ||
1466 | BUG_ON(pix->bytesperline < 0); | ||
1467 | pix->sizeimage = soc_mbus_image_size(xlate->host_fmt, | ||
1468 | pix->bytesperline, pix->height); | ||
1469 | } | ||
1470 | } else { | ||
1471 | /* | ||
1472 | * Width must be a multiple of 8 as requested by the CSI. | ||
1473 | * (Table 39-2 in the i.MX27 Reference Manual). | ||
1474 | */ | ||
1475 | pix->width &= ~0x7; | ||
1476 | } | ||
1477 | 1256 | ||
1478 | /* limit to sensor capabilities */ | 1257 | /* limit to sensor capabilities */ |
1479 | mf.width = pix->width; | 1258 | mf.width = pix->width; |
@@ -1491,7 +1270,7 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd, | |||
1491 | 1270 | ||
1492 | /* If the sensor does not support image size try PrP resizing */ | 1271 | /* If the sensor does not support image size try PrP resizing */ |
1493 | emma_prp = mx27_emma_prp_get_format(xlate->code, | 1272 | emma_prp = mx27_emma_prp_get_format(xlate->code, |
1494 | xlate->host_fmt->fourcc); | 1273 | xlate->host_fmt->fourcc); |
1495 | 1274 | ||
1496 | if ((mf.width != pix->width || mf.height != pix->height) && | 1275 | if ((mf.width != pix->width || mf.height != pix->height) && |
1497 | emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) { | 1276 | emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) { |
@@ -1777,20 +1556,6 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev) | |||
1777 | goto exit; | 1556 | goto exit; |
1778 | } | 1557 | } |
1779 | 1558 | ||
1780 | pcdev->devtype = pdev->id_entry->driver_data; | ||
1781 | switch (pcdev->devtype) { | ||
1782 | case IMX25_CAMERA: | ||
1783 | pcdev->reg_csisr = CSISR_IMX25; | ||
1784 | pcdev->reg_csicr3 = CSICR3_IMX25; | ||
1785 | break; | ||
1786 | case IMX27_CAMERA: | ||
1787 | pcdev->reg_csisr = CSISR_IMX27; | ||
1788 | pcdev->reg_csicr3 = CSICR3_IMX27; | ||
1789 | break; | ||
1790 | default: | ||
1791 | break; | ||
1792 | } | ||
1793 | |||
1794 | pcdev->clk_csi_ahb = devm_clk_get(&pdev->dev, "ahb"); | 1559 | pcdev->clk_csi_ahb = devm_clk_get(&pdev->dev, "ahb"); |
1795 | if (IS_ERR(pcdev->clk_csi_ahb)) { | 1560 | if (IS_ERR(pcdev->clk_csi_ahb)) { |
1796 | dev_err(&pdev->dev, "Could not get csi ahb clock\n"); | 1561 | dev_err(&pdev->dev, "Could not get csi ahb clock\n"); |
@@ -1836,20 +1601,9 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev) | |||
1836 | pcdev->dev = &pdev->dev; | 1601 | pcdev->dev = &pdev->dev; |
1837 | platform_set_drvdata(pdev, pcdev); | 1602 | platform_set_drvdata(pdev, pcdev); |
1838 | 1603 | ||
1839 | if (is_imx25_camera(pcdev)) { | 1604 | err = mx27_camera_emma_init(pdev); |
1840 | err = devm_request_irq(&pdev->dev, irq_csi, mx25_camera_irq, 0, | 1605 | if (err) |
1841 | MX2_CAM_DRV_NAME, pcdev); | 1606 | goto exit; |
1842 | if (err) { | ||
1843 | dev_err(pcdev->dev, "Camera interrupt register failed \n"); | ||
1844 | goto exit; | ||
1845 | } | ||
1846 | } | ||
1847 | |||
1848 | if (is_imx27_camera(pcdev)) { | ||
1849 | err = mx27_camera_emma_init(pdev); | ||
1850 | if (err) | ||
1851 | goto exit; | ||
1852 | } | ||
1853 | 1607 | ||
1854 | /* | 1608 | /* |
1855 | * We're done with drvdata here. Clear the pointer so that | 1609 | * We're done with drvdata here. Clear the pointer so that |
@@ -1862,8 +1616,6 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev) | |||
1862 | pcdev->soc_host.priv = pcdev; | 1616 | pcdev->soc_host.priv = pcdev; |
1863 | pcdev->soc_host.v4l2_dev.dev = &pdev->dev; | 1617 | pcdev->soc_host.v4l2_dev.dev = &pdev->dev; |
1864 | pcdev->soc_host.nr = pdev->id; | 1618 | pcdev->soc_host.nr = pdev->id; |
1865 | if (is_imx25_camera(pcdev)) | ||
1866 | pcdev->soc_host.capabilities = SOCAM_HOST_CAP_STRIDE; | ||
1867 | 1619 | ||
1868 | pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); | 1620 | pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); |
1869 | if (IS_ERR(pcdev->alloc_ctx)) { | 1621 | if (IS_ERR(pcdev->alloc_ctx)) { |
@@ -1882,10 +1634,8 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev) | |||
1882 | exit_free_emma: | 1634 | exit_free_emma: |
1883 | vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); | 1635 | vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); |
1884 | eallocctx: | 1636 | eallocctx: |
1885 | if (is_imx27_camera(pcdev)) { | 1637 | clk_disable_unprepare(pcdev->clk_emma_ipg); |
1886 | clk_disable_unprepare(pcdev->clk_emma_ipg); | 1638 | clk_disable_unprepare(pcdev->clk_emma_ahb); |
1887 | clk_disable_unprepare(pcdev->clk_emma_ahb); | ||
1888 | } | ||
1889 | exit: | 1639 | exit: |
1890 | return err; | 1640 | return err; |
1891 | } | 1641 | } |
@@ -1900,10 +1650,8 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev) | |||
1900 | 1650 | ||
1901 | vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); | 1651 | vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); |
1902 | 1652 | ||
1903 | if (is_imx27_camera(pcdev)) { | 1653 | clk_disable_unprepare(pcdev->clk_emma_ipg); |
1904 | clk_disable_unprepare(pcdev->clk_emma_ipg); | 1654 | clk_disable_unprepare(pcdev->clk_emma_ahb); |
1905 | clk_disable_unprepare(pcdev->clk_emma_ahb); | ||
1906 | } | ||
1907 | 1655 | ||
1908 | dev_info(&pdev->dev, "MX2 Camera driver unloaded\n"); | 1656 | dev_info(&pdev->dev, "MX2 Camera driver unloaded\n"); |
1909 | 1657 | ||
@@ -1932,7 +1680,7 @@ static void __exit mx2_camera_exit(void) | |||
1932 | module_init(mx2_camera_init); | 1680 | module_init(mx2_camera_init); |
1933 | module_exit(mx2_camera_exit); | 1681 | module_exit(mx2_camera_exit); |
1934 | 1682 | ||
1935 | MODULE_DESCRIPTION("i.MX27/i.MX25 SoC Camera Host driver"); | 1683 | MODULE_DESCRIPTION("i.MX27 SoC Camera Host driver"); |
1936 | MODULE_AUTHOR("Sascha Hauer <sha@pengutronix.de>"); | 1684 | MODULE_AUTHOR("Sascha Hauer <sha@pengutronix.de>"); |
1937 | MODULE_LICENSE("GPL"); | 1685 | MODULE_LICENSE("GPL"); |
1938 | MODULE_VERSION(MX2_CAM_VERSION); | 1686 | MODULE_VERSION(MX2_CAM_VERSION); |