Skip to contentSkip to conversation

: mx2_camera: Fix regression caused by clock conversion

PATCH Superseded Fabio Estevam 4 participants 6 messages Oct 8, 2012 – Oct 9, 2012 Media (V4L/DVB)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 2/2 : mx2_camera: Fix regression caused by clock conversion

From: Fabio Estevam <[email protected]>

Since mx27 transitioned to the commmon clock framework in 3.5, the correct way to acquire the csi clock is to get csi_ahb and csi_per clocks separately.

By not doing so the camera sensor does not probe correctly:

soc-camera-pdrv soc-camera-pdrv.0: Probing soc-camera-pdrv.0 mx2-camera mx2-camera.0: Camera driver attached to camera 0
ov2640 0-0030: Product ID error fb:fb
mx2-camera mx2-camera.0: Camera driver detached from camera 0 mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock frequency: 66500000

Adapt the mx2_camera driver to the new clock framework and make it functional again.

---
Changes since v1:
- Rebased against linux-next 20121008.

 drivers/media/platform/soc_camera/mx2_camera.c |   47 +++++++++++++++++-------
 1 file changed, 34 insertions(+), 13 deletions(-)
drivers/media/platform/soc_camera/mx2_camera.c +34 -13
index 403d7f1..9f8c5f0 100644
@@ -272,7 +272,8 @@ struct mx2_camera_dev {
 	struct device		*dev;
 	struct soc_camera_host	soc_host;
 	struct soc_camera_device *icd;
-	struct clk		*clk_csi, *clk_emma_ahb, *clk_emma_ipg;
+	struct clk		*clk_emma_ahb, *clk_emma_ipg;
+	struct clk		*clk_csi_ahb, *clk_csi_per;
 
 	void __iomem		*base_csi, *base_emma;
 
@@ -432,7 +433,8 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
 {
 	unsigned long flags;
 
-	clk_disable_unprepare(pcdev->clk_csi);
+	clk_disable_unprepare(pcdev->clk_csi_ahb);
+	clk_disable_unprepare(pcdev->clk_csi_per);
 	writel(0, pcdev->base_csi + CSICR1);
 	if (cpu_is_mx27()) {
 		writel(0, pcdev->base_emma + PRP_CNTL);
@@ -460,7 +462,11 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
 	if (pcdev->icd)
 		return -EBUSY;
 
-	ret = clk_prepare_enable(pcdev->clk_csi);
+	ret = clk_prepare_enable(pcdev->clk_csi_ahb);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_prepare_enable(pcdev->clk_csi_per);
 	if (ret < 0)
 		return ret;
 
@@ -1725,11 +1731,18 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
 		goto exit;
 	}
 
-	pcdev->clk_csi = devm_clk_get(&pdev->dev, "ahb");
-	if (IS_ERR(pcdev->clk_csi)) {
-		dev_err(&pdev->dev, "Could not get csi clock\n");
-		err = PTR_ERR(pcdev->clk_csi);
-		goto exit;
+	pcdev->clk_csi_ahb = devm_clk_get(&pdev->dev, "ahb");
+	if (IS_ERR(pcdev->clk_csi_ahb)) {
+		dev_err(&pdev->dev, "Could not get csi ahb clock\n");
+		err = PTR_ERR(pcdev->clk_csi_ahb);
+		goto exit;
+	}
+
+	pcdev->clk_csi_per = devm_clk_get(&pdev->dev, "per");
+	if (IS_ERR(pcdev->clk_csi_per)) {
+		dev_err(&pdev->dev, "Could not get csi per clock\n");
+		err = PTR_ERR(pcdev->clk_csi_per);
+		goto exit_csi_ahb;
 	}
 
 	pcdev->pdata = pdev->dev.platform_data;
@@ -1738,14 +1751,15 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
 
 		pcdev->platform_flags = pcdev->pdata->flags;
 
-		rate = clk_round_rate(pcdev->clk_csi, pcdev->pdata->clk * 2);
+		rate = clk_round_rate(pcdev->clk_csi_per,
+						pcdev->pdata->clk * 2);
 		if (rate <= 0) {
 			err = -ENODEV;
-			goto exit;
+			goto exit_csi_per;
 		}
-		err = clk_set_rate(pcdev->clk_csi, rate);
+		err = clk_set_rate(pcdev->clk_csi_per, rate);
 		if (err < 0)
-			goto exit;
+			goto exit_csi_per;
 	}
 
 	INIT_LIST_HEAD(&pcdev->capture);
@@ -1801,7 +1815,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
 		goto exit_free_emma;
 
 	dev_info(&pdev->dev, "MX2 Camera (CSI) driver probed, clock frequency: %ld\n",
-			clk_get_rate(pcdev->clk_csi));
+			clk_get_rate(pcdev->clk_csi_per));
 
 	return 0;
 
@@ -1812,6 +1826,10 @@ eallocctx:
 		clk_disable_unprepare(pcdev->clk_emma_ipg);
 		clk_disable_unprepare(pcdev->clk_emma_ahb);
 	}
+exit_csi_per:
+	clk_disable_unprepare(pcdev->clk_csi_per);
+exit_csi_ahb:
+	clk_disable_unprepare(pcdev->clk_csi_ahb);
 exit:
 	return err;
 }
@@ -1831,6 +1849,9 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev)
 		clk_disable_unprepare(pcdev->clk_emma_ahb);
 	}
 
+	clk_disable_unprepare(pcdev->clk_csi_per);
+	clk_disable_unprepare(pcdev->clk_csi_ahb);
+
 	dev_info(&pdev->dev, "MX2 Camera driver unloaded\n");
 
 	return 0;
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH v2 2/2 : mx2_camera: Fix regression caused by clock conversion

Quoted 136 lines · Fabio Estevam

From: Fabio Estevam <[email protected]>

Since mx27 transitioned to the commmon clock framework in 3.5, the correct way to acquire the csi clock is to get csi_ahb and csi_per clocks separately.

By not doing so the camera sensor does not probe correctly:

soc-camera-pdrv soc-camera-pdrv.0: Probing soc-camera-pdrv.0 mx2-camera mx2-camera.0: Camera driver attached to camera 0
ov2640 0-0030: Product ID error fb:fb
mx2-camera mx2-camera.0: Camera driver detached from camera 0 mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock frequency: 66500000

Adapt the mx2_camera driver to the new clock framework and make it functional again.

---
Changes since v1:
- Rebased against linux-next 20121008.

 drivers/media/platform/soc_camera/mx2_camera.c |   47 +++++++++++++++++-------
 1 file changed, 34 insertions(+), 13 deletions(-)
drivers/media/platform/soc_camera/mx2_camera.c +34 -14
index 403d7f1..9f8c5f0 100644
@@ -272,7 +272,8 @@ struct mx2_camera_dev {
        struct device           *dev;
        struct soc_camera_host  soc_host;
        struct soc_camera_device *icd;
-       struct clk              *clk_csi, *clk_emma_ahb, *clk_emma_ipg;
+       struct clk              *clk_emma_ahb, *clk_emma_ipg;
+       struct clk              *clk_csi_ahb, *clk_csi_per;
 
        void __iomem            *base_csi, *base_emma;
 
@@ -432,7 +433,8 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
 {
        unsigned long flags;
 
-       clk_disable_unprepare(pcdev->clk_csi);
+       clk_disable_unprepare(pcdev->clk_csi_ahb);
+       clk_disable_unprepare(pcdev->clk_csi_per);
        writel(0, pcdev->base_csi + CSICR1);
        if (cpu_is_mx27()) {
                writel(0, pcdev->base_emma + PRP_CNTL);
@@ -460,7 +462,11 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
        if (pcdev->icd)
                return -EBUSY;
 
-       ret = clk_prepare_enable(pcdev->clk_csi);
+       ret = clk_prepare_enable(pcdev->clk_csi_ahb);
+       if (ret < 0)
+               return ret;
+
+       ret = clk_prepare_enable(pcdev->clk_csi_per);
        if (ret < 0)
                return ret;
 
@@ -1725,11 +1731,18 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
                goto exit;
        }
 
-       pcdev->clk_csi = devm_clk_get(&pdev->dev, "ahb");
-       if (IS_ERR(pcdev->clk_csi)) {
-               dev_err(&pdev->dev, "Could not get csi clock\n");
-               err = PTR_ERR(pcdev->clk_csi);
-               goto exit;
+       pcdev->clk_csi_ahb = devm_clk_get(&pdev->dev, "ahb");
+       if (IS_ERR(pcdev->clk_csi_ahb)) {
+               dev_err(&pdev->dev, "Could not get csi ahb clock\n");
+               err = PTR_ERR(pcdev->clk_csi_ahb);
+               goto exit;
+       }
+
+       pcdev->clk_csi_per = devm_clk_get(&pdev->dev, "per");
+       if (IS_ERR(pcdev->clk_csi_per)) {
+               dev_err(&pdev->dev, "Could not get csi per clock\n");
+               err = PTR_ERR(pcdev->clk_csi_per);
+               goto exit_csi_ahb;
        }
 
        pcdev->pdata = pdev->dev.platform_data;
@@ -1738,14 +1751,15 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
 
                pcdev->platform_flags = pcdev->pdata->flags;
 
-               rate = clk_round_rate(pcdev->clk_csi, pcdev->pdata->clk * 2);
+               rate = clk_round_rate(pcdev->clk_csi_per,
+                                               pcdev->pdata->clk * 2);
                if (rate <= 0) {
                        err = -ENODEV;
-                       goto exit;
+                       goto exit_csi_per;
                }
-               err = clk_set_rate(pcdev->clk_csi, rate);
+               err = clk_set_rate(pcdev->clk_csi_per, rate);
                if (err < 0)
-                       goto exit;
+                       goto exit_csi_per;
        }
 
        INIT_LIST_HEAD(&pcdev->capture);
@@ -1801,7 +1815,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
                goto exit_free_emma;
 
        dev_info(&pdev->dev, "MX2 Camera (CSI) driver probed, clock frequency: %ld\n",
-                       clk_get_rate(pcdev->clk_csi));
+                       clk_get_rate(pcdev->clk_csi_per));
 
        return 0;
 
@@ -1812,6 +1826,10 @@ eallocctx:
                clk_disable_unprepare(pcdev->clk_emma_ipg);
                clk_disable_unprepare(pcdev->clk_emma_ahb);
        }
+exit_csi_per:
+       clk_disable_unprepare(pcdev->clk_csi_per);
+exit_csi_ahb:
+       clk_disable_unprepare(pcdev->clk_csi_ahb);
 exit:
        return err;
 }
@@ -1831,6 +1849,9 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev)
                clk_disable_unprepare(pcdev->clk_emma_ahb);
        }
 
+       clk_disable_unprepare(pcdev->clk_csi_per);
+       clk_disable_unprepare(pcdev->clk_csi_ahb);
+
        dev_info(&pdev->dev, "MX2 Camera driver unloaded\n");
 
        return 0;
--
Quoted 2 lines

1.7.9.5

This patch doesn't fix the BUG it claims to, since I have it working properly in our Visstrim M10 platform without it. Look:

soc-camera-pdrv soc-camera-pdrv.0: Probing soc-camera-pdrv.0 mx2-camera mx2-camera.0: Camera driver attached to camera 0 ov7670 0-0021: chip found @ 0x42 (imx-i2c)
[..]
mx2-camera mx2-camera.0: Camera driver detached from camera 0 mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock
frequency: 66500000

Furthermore, it's not correct, since there isn't such "per" clock for the CSI in 3.5 [1], 3.6 [2], linux-next-20121008[3], or next-20121009[4].

[1] http://lxr.linux.no/#linux+v3.5/arch/arm/mach-imx/clk-imx27.c#L226
[2] http://lxr.linux.no/#linux+v3.6/arch/arm/mach-imx/clk-imx27.c#L226
[3] http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=blob;f=arch/arm/mach-imx/clk-imx27.c;h=3b6b640eed247ea1b7848c7a7fa01801f0190cde;hb=cc925138a0dd9ae388135bb3cf11ee1729f9c4e9#l226
[4] http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=blob;f=arch/arm/mach-imx/clk-imx27.c;h=3b6b640eed247ea1b7848c7a7fa01801f0190cde;hb=b066f61482c7eac44e656499426a3c56d29c32ed#l226

Regards.

Signature · 7 lines
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
www.vista-silicon.com
#2 lore raw

PATCH v2 2/2 : mx2_camera: Fix regression caused by clock conversion

Hi Javier,

Quoted 2 lines · javier Martin

This patch doesn't fix the BUG it claims to, since I have it working properly in our Visstrim M10 platform without it. Look:

Yes, it does fix a real bug. Without this patch the ov2640 cannot be probed, as it fails to read the product/vendor ID via I2C. I measure with the scope and do not get mclk at all without this patch.

Again, camera probe does work fine on kernel 3.4.

Does the mx27 feed the mclk to your camera? Which frequency do you get if you measure it with a scope.

Quoted 8 lines

soc-camera-pdrv soc-camera-pdrv.0: Probing soc-camera-pdrv.0 mx2-camera mx2-camera.0: Camera driver attached to camera 0 ov7670 0-0021: chip found @ 0x42 (imx-i2c)
[..]
mx2-camera mx2-camera.0: Camera driver detached from camera 0 mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock
frequency: 66500000

This 66.5MHz is wrong.

Quoted 4 lines

Furthermore, it's not correct, since there isn't such "per" clock for the CSI in 3.5 [1], 3.6 [2], linux-next-20121008[3], or next-20121009[4].

Well, you are looking to all git trees after the conversion to the common clock framework.

Please look at 3.4 kernel instead and you will see that per4 is indeed used for csi.
"DEFINE_CLOCK1(csi_clk, 0, NULL, 0, parent, &csi_clk1, &per4_clk);"

In fact, the mx27 reference manual is the correct source for such information. Please check "Table 39-9. CSI Control Register 1 Field Descriptions (continued)":

"Sensor Master Clock (MCLK) Divider. This field contains the divisor MCLK. The MCLK is derived from the PERCLK4."

Can you let me know if this patch breaks things for you? Or what exactly you think is wrong with it?

It seems that you are camera works by pure luck without this patch. Maybe you are turning per4 in the bootloader or you get the clock to your camera from somewhere else.

Regards,

Fabio Estevam

#3 lore raw

PATCH v2 2/2 : mx2_camera: Fix regression caused by clock conversion

In reply to Fabio Estevam

Hi,

Quoted 127 lines · Fabio Estevam

From: Fabio Estevam <[email protected]>

Since mx27 transitioned to the commmon clock framework in 3.5, the correct way to acquire the csi clock is to get csi_ahb and csi_per clocks separately.

By not doing so the camera sensor does not probe correctly:

soc-camera-pdrv soc-camera-pdrv.0: Probing soc-camera-pdrv.0 mx2-camera mx2-camera.0: Camera driver attached to camera 0
ov2640 0-0030: Product ID error fb:fb
mx2-camera mx2-camera.0: Camera driver detached from camera 0 mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock frequency: 66500000

Adapt the mx2_camera driver to the new clock framework and make it functional again.

---
Changes since v1:
- Rebased against linux-next 20121008.

  drivers/media/platform/soc_camera/mx2_camera.c |   47 +++++++++++++++++-------
  1 file changed, 34 insertions(+), 13 deletions(-)
drivers/media/platform/soc_camera/mx2_camera.c +31 -13
index 403d7f1..9f8c5f0 100644
@@ -272,7 +272,8 @@ struct mx2_camera_dev {
  	struct device		*dev;
  	struct soc_camera_host	soc_host;
  	struct soc_camera_device *icd;
-	struct clk		*clk_csi, *clk_emma_ahb, *clk_emma_ipg;
+	struct clk		*clk_emma_ahb, *clk_emma_ipg;
+	struct clk		*clk_csi_ahb, *clk_csi_per;
 
  	void __iomem		*base_csi, *base_emma;
 
@@ -432,7 +433,8 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
  {
  	unsigned long flags;
 
-	clk_disable_unprepare(pcdev->clk_csi);
+	clk_disable_unprepare(pcdev->clk_csi_ahb);
+	clk_disable_unprepare(pcdev->clk_csi_per);
  	writel(0, pcdev->base_csi + CSICR1);
  	if (cpu_is_mx27()) {
  		writel(0, pcdev->base_emma + PRP_CNTL);
@@ -460,7 +462,11 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
  	if (pcdev->icd)
  		return -EBUSY;
 
-	ret = clk_prepare_enable(pcdev->clk_csi);
+	ret = clk_prepare_enable(pcdev->clk_csi_ahb);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_prepare_enable(pcdev->clk_csi_per);
  	if (ret < 0)
  		return ret;
 
@@ -1725,11 +1731,18 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
  		goto exit;
  	}
 
-	pcdev->clk_csi = devm_clk_get(&pdev->dev, "ahb");
-	if (IS_ERR(pcdev->clk_csi)) {
-		dev_err(&pdev->dev, "Could not get csi clock\n");
-		err = PTR_ERR(pcdev->clk_csi);
-		goto exit;
+	pcdev->clk_csi_ahb = devm_clk_get(&pdev->dev, "ahb");
+	if (IS_ERR(pcdev->clk_csi_ahb)) {
+		dev_err(&pdev->dev, "Could not get csi ahb clock\n");
+		err = PTR_ERR(pcdev->clk_csi_ahb);
+		goto exit;
+	}
+
+	pcdev->clk_csi_per = devm_clk_get(&pdev->dev, "per");
+	if (IS_ERR(pcdev->clk_csi_per)) {
+		dev_err(&pdev->dev, "Could not get csi per clock\n");
+		err = PTR_ERR(pcdev->clk_csi_per);
+		goto exit_csi_ahb;
  	}
 
  	pcdev->pdata = pdev->dev.platform_data;
@@ -1738,14 +1751,15 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
 
  		pcdev->platform_flags = pcdev->pdata->flags;
 
-		rate = clk_round_rate(pcdev->clk_csi, pcdev->pdata->clk * 2);
+		rate = clk_round_rate(pcdev->clk_csi_per,
+						pcdev->pdata->clk * 2);
  		if (rate <= 0) {
  			err = -ENODEV;
-			goto exit;
+			goto exit_csi_per;
  		}
-		err = clk_set_rate(pcdev->clk_csi, rate);
+		err = clk_set_rate(pcdev->clk_csi_per, rate);
  		if (err < 0)
-			goto exit;
+			goto exit_csi_per;
  	}
 
  	INIT_LIST_HEAD(&pcdev->capture);
@@ -1801,7 +1815,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
  		goto exit_free_emma;
 
  	dev_info(&pdev->dev, "MX2 Camera (CSI) driver probed, clock frequency: %ld\n",
-			clk_get_rate(pcdev->clk_csi));
+			clk_get_rate(pcdev->clk_csi_per));
 
  	return 0;
 
@@ -1812,6 +1826,10 @@ eallocctx:
  		clk_disable_unprepare(pcdev->clk_emma_ipg);
  		clk_disable_unprepare(pcdev->clk_emma_ahb);
  	}
+exit_csi_per:
+	clk_disable_unprepare(pcdev->clk_csi_per);
+exit_csi_ahb:
+	clk_disable_unprepare(pcdev->clk_csi_ahb);
  exit:
  	return err;
  }

drivers/media/platform/soc_camera/mx2_camera.c static int __devexit mx2_camera_remove(struct platform_device *pdev) · line 1857

Quoted 9 lines
drivers/media/platform/soc_camera/mx2_camera.c +3 -0
@@ -1831,6 +1849,9 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev)
  		clk_disable_unprepare(pcdev->clk_emma_ahb);
  	}
 
+	clk_disable_unprepare(pcdev->clk_csi_per);
+	clk_disable_unprepare(pcdev->clk_csi_ahb);
+
  	dev_info(&pdev->dev, "MX2 Camera driver unloaded\n");
 
  	return 0;

I only test detection at kernel boot not streaming using Gstreamer due to lack of time.

On imx27_3ds board with ov2640 sensor:
ov2640 0-0030: ov2640 Product ID 26:42 Manufacturer ID 7f:a2 mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock
frequency: 44333333

On clone imx27_3ds board with mt9v111 sensor (draft driver):
mt9v111 0-0048: Detected a MT9V111 chip ID 823a mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock
frequency: 44333333

#4 lore raw

PATCH v2 2/2 : mx2_camera: Fix regression caused by clock conversion

Quoted 161 lines · Ga?tan Carlier

Hi,

Quoted 148 lines · Fabio Estevam

From: Fabio Estevam <[email protected]>

Since mx27 transitioned to the commmon clock framework in 3.5, the correct way
to acquire the csi clock is to get csi_ahb and csi_per clocks separately.

By not doing so the camera sensor does not probe correctly:

soc-camera-pdrv soc-camera-pdrv.0: Probing soc-camera-pdrv.0 mx2-camera mx2-camera.0: Camera driver attached to camera 0 ov2640 0-0030: Product ID error fb:fb
mx2-camera mx2-camera.0: Camera driver detached from camera 0 mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock frequency:
66500000

Adapt the mx2_camera driver to the new clock framework and make it functional
again.

---
Changes since v1:
- Rebased against linux-next 20121008.

  drivers/media/platform/soc_camera/mx2_camera.c |   47
+++++++++++++++++-------
  1 file changed, 34 insertions(+), 13 deletions(-)
drivers/media/platform/soc_camera/mx2_camera.c +4 -2
index 403d7f1..9f8c5f0 100644
@@ -272,7 +272,8 @@ struct mx2_camera_dev {
        struct device           *dev;
        struct soc_camera_host  soc_host;
        struct soc_camera_device *icd;
-       struct clk              *clk_csi, *clk_emma_ahb, *clk_emma_ipg;
+       struct clk              *clk_emma_ahb, *clk_emma_ipg;
+       struct clk              *clk_csi_ahb, *clk_csi_per;
 
        void __iomem            *base_csi, *base_emma;
 
@@ -432,7 +433,8 @@ static void mx2_camera_deactivate(struct
 mx2_camera_dev *pcdev)
  {
        unsigned long flags;
 
-       clk_disable_unprepare(pcdev->clk_csi);
+       clk_disable_unprepare(pcdev->clk_csi_ahb);
+       clk_disable_unprepare(pcdev->clk_csi_per);
        writel(0, pcdev->base_csi + CSICR1);
        if (cpu_is_mx27()) {
                writel(0, pcdev->base_emma + PRP_CNTL);
drivers/media/platform/soc_camera/mx2_camera.c +17 -6
@@ -460,7 +462,11 @@ static int mx2_camera_add_device(struct
 soc_camera_device *icd)
        if (pcdev->icd)
                return -EBUSY;
 
-       ret = clk_prepare_enable(pcdev->clk_csi);
+       ret = clk_prepare_enable(pcdev->clk_csi_ahb);
+       if (ret < 0)
+               return ret;
+
+       ret = clk_prepare_enable(pcdev->clk_csi_per);
        if (ret < 0)
                return ret;
@@ -1725,11 +1731,18 @@ static int __devinit mx2_camera_probe(struct
 platform_device *pdev)
                goto exit;
        }
 
-       pcdev->clk_csi = devm_clk_get(&pdev->dev, "ahb");
-       if (IS_ERR(pcdev->clk_csi)) {
-               dev_err(&pdev->dev, "Could not get csi clock\n");
-               err = PTR_ERR(pcdev->clk_csi);
-               goto exit;
+       pcdev->clk_csi_ahb = devm_clk_get(&pdev->dev, "ahb");
+       if (IS_ERR(pcdev->clk_csi_ahb)) {
+               dev_err(&pdev->dev, "Could not get csi ahb clock\n");
+               err = PTR_ERR(pcdev->clk_csi_ahb);
+               goto exit;
+       }
+
+       pcdev->clk_csi_per = devm_clk_get(&pdev->dev, "per");
+       if (IS_ERR(pcdev->clk_csi_per)) {
+               dev_err(&pdev->dev, "Could not get csi per clock\n");
+               err = PTR_ERR(pcdev->clk_csi_per);
+               goto exit_csi_ahb;
        }
 
        pcdev->pdata = pdev->dev.platform_data;
drivers/media/platform/soc_camera/mx2_camera.c +5 -4
@@ -1738,14 +1751,15 @@ static int __devinit mx2_camera_probe(struct
 platform_device *pdev)
 
                pcdev->platform_flags = pcdev->pdata->flags;
 
-               rate = clk_round_rate(pcdev->clk_csi, pcdev->pdata->clk *
 2);
+               rate = clk_round_rate(pcdev->clk_csi_per,
+                                               pcdev->pdata->clk * 2);
                if (rate <= 0) {
                        err = -ENODEV;
-                       goto exit;
+                       goto exit_csi_per;
                }
-               err = clk_set_rate(pcdev->clk_csi, rate);
+               err = clk_set_rate(pcdev->clk_csi_per, rate);
                if (err < 0)
-                       goto exit;
+                       goto exit_csi_per;
        }
        INIT_LIST_HEAD(&pcdev->capture);
drivers/media/platform/soc_camera/mx2_camera.c +1 -1
@@ -1801,7 +1815,7 @@ static int __devinit mx2_camera_probe(struct
 platform_device *pdev)
                goto exit_free_emma;
 
        dev_info(&pdev->dev, "MX2 Camera (CSI) driver probed, clock
 frequency: %ld\n",
-                       clk_get_rate(pcdev->clk_csi));
+                       clk_get_rate(pcdev->clk_csi_per));
 
        return 0;
drivers/media/platform/soc_camera/mx2_camera.c +7 -0
@@ -1812,6 +1826,10 @@ eallocctx:
                clk_disable_unprepare(pcdev->clk_emma_ipg);
                clk_disable_unprepare(pcdev->clk_emma_ahb);
        }
+exit_csi_per:
+       clk_disable_unprepare(pcdev->clk_csi_per);
+exit_csi_ahb:
+       clk_disable_unprepare(pcdev->clk_csi_ahb);
  exit:
        return err;
  }
@@ -1831,6 +1849,9 @@ static int __devexit mx2_camera_remove(struct
 platform_device *pdev)
                clk_disable_unprepare(pcdev->clk_emma_ahb);
        }
 
+       clk_disable_unprepare(pcdev->clk_csi_per);
+       clk_disable_unprepare(pcdev->clk_csi_ahb);
+
        dev_info(&pdev->dev, "MX2 Camera driver unloaded\n");
 
Quoted 2 lines
        return 0;

I only test detection at kernel boot not streaming using Gstreamer due to lack of time.

On imx27_3ds board with ov2640 sensor:
ov2640 0-0030: ov2640 Product ID 26:42 Manufacturer ID 7f:a2 mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock frequency:
44333333

Quoted 6 lines

On clone imx27_3ds board with mt9v111 sensor (draft driver):
mt9v111 0-0048: Detected a MT9V111 chip ID 823a
mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock frequency:
44333333

Sorry I missed patch 1/2. Both patches are correct:

Signature · 7 lines
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
www.vista-silicon.com
#5 lore raw

PATCH v2 2/2 : mx2_camera: Fix regression caused by clock conversion

In reply to Fabio Estevam
Quoted 13 lines · Fabio Estevam
drivers/media/platform/soc_camera/mx2_camera.c +5 -1
@@ -460,7 +462,11 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
 	if (pcdev->icd)
 		return -EBUSY;
 
-	ret = clk_prepare_enable(pcdev->clk_csi);
+	ret = clk_prepare_enable(pcdev->clk_csi_ahb);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_prepare_enable(pcdev->clk_csi_per);
 	if (ret < 0)
 		return ret;
 
Quoted 1 line

From the point of view of error cleanup, this looks buggy to me. If

the prepare_enable for the per clock fails, what cleans up the ahb clock?