aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-omap-psp-2.6.32/cam/0018-Fix-Moved-MCLK-setting-to-the-board-file.patch
blob: a47ee196fad7bd16f6ccb3c8e17a1f19f24d8f29 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
From 6e9a8ed420020b5692b511b3e8a7c2c1325e1ca2 Mon Sep 17 00:00:00 2001
From: Penda, Naveen <pnaveen@ti.com>
Date: Thu, 22 Oct 2009 06:07:01 +0530
Subject: [PATCH 18/75] Fix: Moved MCLK setting to the board file

This patch provides the flexibility to set  the MCLK frequency
 from the board file

Signed-off-by: Naveen Penda <pnaveen@ti.com>
Signed-off-by: Curran, Dominic <dcurran@ti.com>
---
 arch/arm/mach-omap2/board-zoom2-camera.c |   10 ++++++
 drivers/media/video/isp/isp.c            |   51 +++++++++++++++++++----------
 drivers/media/video/isp/isp.h            |    6 +++
 3 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/arch/arm/mach-omap2/board-zoom2-camera.c b/arch/arm/mach-omap2/board-zoom2-camera.c
index 1ba2982..8c035c4 100644
--- a/arch/arm/mach-omap2/board-zoom2-camera.c
+++ b/arch/arm/mach-omap2/board-zoom2-camera.c
@@ -41,6 +41,8 @@ static struct device *zoom2cam_dev;
 
 #define CAMZOOM2_USE_XCLKB  	1
 
+#define ISP_IMX046_MCLK		216000000
+
 /* Sensor specific GPIO signals */
 #define IMX046_RESET_GPIO  	98
 #define IMX046_STANDBY_GPIO	58
@@ -148,6 +150,7 @@ static struct isp_interface_config imx046_if_config = {
 	.shutter 		= 0x0,
 	.wenlog 		= ISPCCDC_CFG_WENLOG_AND,
 	.wait_hs_vs		= 2,
+	.cam_mclk		= ISP_IMX046_MCLK,
 	.u.csi.crc 		= 0x0,
 	.u.csi.mode 		= 0x0,
 	.u.csi.edge 		= 0x0,
@@ -264,6 +267,8 @@ static int imx046_sensor_power_set(struct v4l2_int_device *s, enum v4l2_power po
 #ifdef CONFIG_OMAP_PM_SRF
 		omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 0);
 #endif
+		if (previous_power != V4L2_POWER_OFF)
+			isp_disable_mclk(isp);
 		break;
 	case V4L2_POWER_STANDBY:
 		printk(KERN_DEBUG "imx046_sensor_power_set(STANDBY)\n");
@@ -272,9 +277,14 @@ static int imx046_sensor_power_set(struct v4l2_int_device *s, enum v4l2_power po
 #ifdef CONFIG_OMAP_PM_SRF
 		omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 0);
 #endif
+
+
+		isp_disable_mclk(isp);
+
 		break;
 	}
 
+
 	/* Save powerstate to know what was before calling POWER_ON. */
 	previous_power = power;
 	return err;
diff --git a/drivers/media/video/isp/isp.c b/drivers/media/video/isp/isp.c
index 9d46c01..cf68720 100644
--- a/drivers/media/video/isp/isp.c
+++ b/drivers/media/video/isp/isp.c
@@ -552,7 +552,7 @@ EXPORT_SYMBOL(isp_unset_callback);
  * Configures the specified MCLK divisor in the ISP timing control register
  * (TCTRL_CTRL) to generate the desired xclk clock value.
  *
- * Divisor = CM_CAM_MCLK_HZ / xclk
+ * Divisor = mclk / xclk
  *
  * Returns the final frequency that is actually being generated
  **/
@@ -560,15 +560,16 @@ u32 isp_set_xclk(struct device *dev, u32 xclk, u8 xclksel)
 {
 	u32 divisor;
 	u32 currentxclk;
+	struct isp_device *isp = dev_get_drvdata(dev);
 
-	if (xclk >= CM_CAM_MCLK_HZ) {
+	if (xclk >= isp->mclk) {
 		divisor = ISPTCTRL_CTRL_DIV_BYPASS;
-		currentxclk = CM_CAM_MCLK_HZ;
+		currentxclk = isp->mclk;
 	} else if (xclk >= 2) {
-		divisor = CM_CAM_MCLK_HZ / xclk;
+		divisor = isp->mclk / xclk;
 		if (divisor >= ISPTCTRL_CTRL_DIV_BYPASS)
 			divisor = ISPTCTRL_CTRL_DIV_BYPASS - 1;
-		currentxclk = CM_CAM_MCLK_HZ / divisor;
+		currentxclk = isp->mclk / divisor;
 	} else {
 		divisor = xclk;
 		currentxclk = 0;
@@ -874,6 +875,8 @@ int isp_configure_interface(struct device *dev,
 	/* Set sensor specific fields in CCDC and Previewer module. */
 	ispccdc_set_wenlog(&isp->isp_ccdc, config->wenlog);
 
+	isp->mclk = config->cam_mclk;
+	isp_enable_mclk(dev);
 	/* FIXME: this should be set in ispccdc_config_vp() */
 	fmtcfg = isp_reg_readl(dev, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG);
 	fmtcfg &= ISPCCDC_FMTCFG_VPIF_FRQ_MASK;
@@ -2333,16 +2336,6 @@ static int isp_enable_clocks(struct device *dev)
 		dev_err(dev, "clk_enable cam_ick failed\n");
 		goto out_clk_enable_ick;
 	}
-	r = clk_set_rate(isp->dpll4_m5_ck, CM_CAM_MCLK_HZ/2);
-	if (r) {
-		dev_err(dev, "clk_set_rate for dpll4_m5_ck failed\n");
-		goto out_clk_enable_mclk;
-	}
-	r = clk_enable(isp->cam_mclk);
-	if (r) {
-		dev_err(dev, "clk_enable cam_mclk failed\n");
-		goto out_clk_enable_mclk;
-	}
 	r = clk_enable(isp->csi2_fck);
 	if (r) {
 		dev_err(dev, "clk_enable csi2_fck failed\n");
@@ -2351,13 +2344,34 @@ static int isp_enable_clocks(struct device *dev)
 	return 0;
 
 out_clk_enable_csi2_fclk:
-	clk_disable(isp->cam_mclk);
-out_clk_enable_mclk:
 	clk_disable(isp->cam_ick);
 out_clk_enable_ick:
 	return r;
 }
 
+int isp_enable_mclk(struct device *dev)
+{
+	struct isp_device *isp = dev_get_drvdata(dev);
+	int r;
+
+	r = clk_set_rate(isp->dpll4_m5_ck, isp->mclk);
+		if (r) {
+			dev_err(dev, "clk_set_rate for dpll4_m5_ck failed\n");
+			return r;
+	}
+	r = clk_enable(isp->cam_mclk);
+	if (r) {
+		dev_err(dev, "clk_enable cam_mclk failed\n");
+		return r;
+	}
+	return 0;
+}
+
+void isp_disable_mclk(struct isp_device *isp)
+{
+	clk_disable(isp->cam_mclk);
+}
+
 /**
  * isp_disable_clocks - Disable ISP clocks
  * @dev: Device pointer specific to the OMAP3 ISP.
@@ -2367,7 +2381,6 @@ static void isp_disable_clocks(struct device *dev)
 	struct isp_device *isp = dev_get_drvdata(dev);
 
 	clk_disable(isp->cam_ick);
-	clk_disable(isp->cam_mclk);
 	clk_disable(isp->csi2_fck);
 }
 
@@ -2668,6 +2681,8 @@ static int isp_probe(struct platform_device *pdev)
 		goto out_free_mmio;
 	}
 
+	isp->mclk = CM_CAM_MCLK_HZ / 2;
+
 	isp->cam_ick = clk_get(&camera_dev, "cam_ick");
 	if (IS_ERR(isp->cam_ick)) {
 		dev_err(isp->dev, "clk_get cam_ick failed\n");
diff --git a/drivers/media/video/isp/isp.h b/drivers/media/video/isp/isp.h
index 6b100b6..85c3fa9 100644
--- a/drivers/media/video/isp/isp.h
+++ b/drivers/media/video/isp/isp.h
@@ -199,6 +199,7 @@ struct isp_interface_config {
 	u32 prev_slv;
 	u32 wenlog;
 	int wait_hs_vs;
+	u32 cam_mclk;
 	unsigned int pixelclk;
 	union {
 		struct par {
@@ -425,6 +426,7 @@ struct isp_device {
 	struct isp_irq irq;
 	struct isp_pipeline pipeline;
 	u32 interrupts;
+	u32 mclk;
 	enum isp_running running;
 	int current_field;
 	int bt656ifen;
@@ -489,6 +491,10 @@ struct device *isp_get(void);
 
 int isp_put(void);
 
+int isp_enable_mclk(struct device *dev);
+
+void isp_disable_mclk(struct isp_device *dev);
+
 int isp_queryctrl(struct v4l2_queryctrl *a);
 
 int isp_querymenu(struct v4l2_querymenu *a);
-- 
1.6.6.1