summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-omap2-git/omap3evm/0003-ARM-OMAP-SmartReflex-driver.patch
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-kernel/linux/linux-omap2-git/omap3evm/0003-ARM-OMAP-SmartReflex-driver.patch
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadpoky-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap2-git/omap3evm/0003-ARM-OMAP-SmartReflex-driver.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-omap2-git/omap3evm/0003-ARM-OMAP-SmartReflex-driver.patch1001
1 files changed, 1001 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap2-git/omap3evm/0003-ARM-OMAP-SmartReflex-driver.patch b/meta/recipes-kernel/linux/linux-omap2-git/omap3evm/0003-ARM-OMAP-SmartReflex-driver.patch
new file mode 100644
index 0000000000..40d5790367
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-omap2-git/omap3evm/0003-ARM-OMAP-SmartReflex-driver.patch
@@ -0,0 +1,1001 @@
1From: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
2To: linux-omap@vger.kernel.org
3Cc: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
4Subject: [PATCH 3/3] ARM: OMAP: SmartReflex driver: integration to linux-omap
5Date: Fri, 6 Jun 2008 12:49:49 +0300
6Message-Id: <1212745789-13926-3-git-send-email-ext-kalle.jokiniemi@nokia.com>
7
8- Changed register accesses to use prm_{read,write}_mod_reg and
9 prm_{set,clear,rmw}_mod_reg_bits() functions instread of
10 "REG_X = REG_Y" type accesses.
11
12- Changed direct register clock enables/disables to clockframework calls.
13
14- replaced cpu-related #ifdefs with if (cpu_is_xxxx()) calls.
15
16- Added E-fuse support: Use silicon characteristics parameters from E-fuse
17
18- added smartreflex_disable/enable calls to pm34xx.c suspend function.
19
20- Added "SmartReflex support" entry into Kconfig under "System type->TI OMAP
21 Implementations". It depends on ARCH_OMAP34XX and TWL4030_CORE.
22
23- Added "SmartReflex testing support" Kconfig option for using hard coded
24 software parameters instead of E-fuse parameters.
25
26Signed-off-by: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
27---
28 arch/arm/mach-omap2/Makefile | 3 +
29 arch/arm/mach-omap2/pm34xx.c | 9 +
30 arch/arm/mach-omap2/smartreflex.c | 531 +++++++++++++++++++++++--------------
31 arch/arm/mach-omap2/smartreflex.h | 9 +-
32 arch/arm/plat-omap/Kconfig | 31 +++
33 5 files changed, 385 insertions(+), 198 deletions(-)
34
35diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
36index 50c6657..f645b6e 100644
37--- a/arch/arm/mach-omap2/Makefile
38+++ b/arch/arm/mach-omap2/Makefile
39@@ -25,6 +25,9 @@ obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
40 obj-$(CONFIG_PM_DEBUG) += pm-debug.o
41 endif
42
43+# SmartReflex driver
44+obj-$(CONFIG_OMAP_SMARTREFLEX) += smartreflex.o
45+
46 # Clock framework
47 obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o
48 obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o
49diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
50index 7e775cc..3da4f47 100644
51--- a/arch/arm/mach-omap2/pm34xx.c
52+++ b/arch/arm/mach-omap2/pm34xx.c
53@@ -36,6 +36,7 @@
54
55 #include "prm.h"
56 #include "pm.h"
57+#include "smartreflex.h"
58
59 struct power_state {
60 struct powerdomain *pwrdm;
61@@ -256,6 +257,10 @@ static int omap3_pm_suspend(void)
62 struct power_state *pwrst;
63 int state, ret = 0;
64
65+ /* XXX Disable smartreflex before entering suspend */
66+ disable_smartreflex(SR1);
67+ disable_smartreflex(SR2);
68+
69 /* Read current next_pwrsts */
70 list_for_each_entry(pwrst, &pwrst_list, node)
71 pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
72@@ -287,6 +292,10 @@ restore:
73 printk(KERN_INFO "Successfully put all powerdomains "
74 "to target state\n");
75
76+ /* XXX Enable smartreflex after suspend */
77+ enable_smartreflex(SR1);
78+ enable_smartreflex(SR2);
79+
80 return ret;
81 }
82
83diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
84index dae7460..0b10a5d 100644
85--- a/arch/arm/mach-omap2/smartreflex.c
86+++ b/arch/arm/mach-omap2/smartreflex.c
87@@ -3,6 +3,9 @@
88 *
89 * OMAP34XX SmartReflex Voltage Control
90 *
91+ * Copyright (C) 2008 Nokia Corporation
92+ * Kalle Jokiniemi
93+ *
94 * Copyright (C) 2007 Texas Instruments, Inc.
95 * Lesly A M <x0080970@ti.com>
96 *
97@@ -20,13 +23,16 @@
98 #include <linux/err.h>
99 #include <linux/clk.h>
100 #include <linux/sysfs.h>
101-
102-#include <asm/arch/prcm.h>
103-#include <asm/arch/power_companion.h>
104+#include <linux/kobject.h>
105+#include <linux/i2c/twl4030.h>
106 #include <linux/io.h>
107
108-#include "prcm-regs.h"
109+#include <asm/arch/omap34xx.h>
110+#include <asm/arch/control.h>
111+
112+#include "prm.h"
113 #include "smartreflex.h"
114+#include "prm-regbits-34xx.h"
115
116
117 /* #define DEBUG_SR 1 */
118@@ -37,11 +43,16 @@
119 # define DPRINTK(fmt, args...)
120 #endif
121
122+/* XXX: These should be relocated where-ever the OPP implementation will be */
123+u32 current_vdd1_opp;
124+u32 current_vdd2_opp;
125+
126 struct omap_sr{
127 int srid;
128 int is_sr_reset;
129 int is_autocomp_active;
130 struct clk *fck;
131+ u32 clk_length;
132 u32 req_opp_no;
133 u32 opp1_nvalue, opp2_nvalue, opp3_nvalue, opp4_nvalue, opp5_nvalue;
134 u32 senp_mod, senn_mod;
135@@ -53,6 +64,7 @@ static struct omap_sr sr1 = {
136 .srid = SR1,
137 .is_sr_reset = 1,
138 .is_autocomp_active = 0,
139+ .clk_length = 0,
140 .srbase_addr = OMAP34XX_SR1_BASE,
141 };
142
143@@ -60,6 +72,7 @@ static struct omap_sr sr2 = {
144 .srid = SR2,
145 .is_sr_reset = 1,
146 .is_autocomp_active = 0,
147+ .clk_length = 0,
148 .srbase_addr = OMAP34XX_SR2_BASE,
149 };
150
151@@ -85,8 +98,6 @@ static inline u32 sr_read_reg(struct omap_sr *sr, int offset)
152 return omap_readl(sr->srbase_addr + offset);
153 }
154
155-
156-#ifndef USE_EFUSE_VALUES
157 static void cal_reciprocal(u32 sensor, u32 *sengain, u32 *rnsen)
158 {
159 u32 gn, rn, mul;
160@@ -100,7 +111,21 @@ static void cal_reciprocal(u32 sensor, u32 *sengain, u32 *rnsen)
161 }
162 }
163 }
164-#endif
165+
166+static void sr_clk_get(struct omap_sr *sr)
167+{
168+ if (sr->srid == SR1) {
169+ sr->fck = clk_get(NULL, "sr1_fck");
170+ if (IS_ERR(sr->fck))
171+ printk(KERN_ERR "Could not get sr1_fck\n");
172+
173+ } else if (sr->srid == SR2) {
174+ sr->fck = clk_get(NULL, "sr2_fck");
175+ if (IS_ERR(sr->fck))
176+ printk(KERN_ERR "Could not get sr2_fck\n");
177+
178+ }
179+}
180
181 static int sr_clk_enable(struct omap_sr *sr)
182 {
183@@ -131,22 +156,86 @@ static int sr_clk_disable(struct omap_sr *sr)
184 return 0;
185 }
186
187-static void sr_set_nvalues(struct omap_sr *sr)
188+static void sr_set_clk_length(struct omap_sr *sr)
189+{
190+ struct clk *osc_sys_ck;
191+ u32 sys_clk = 0;
192+
193+ osc_sys_ck = clk_get(NULL, "osc_sys_ck");
194+ sys_clk = clk_get_rate(osc_sys_ck);
195+ clk_put(osc_sys_ck);
196+
197+ switch (sys_clk) {
198+ case 12000000:
199+ sr->clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
200+ break;
201+ case 13000000:
202+ sr->clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
203+ break;
204+ case 19200000:
205+ sr->clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
206+ break;
207+ case 26000000:
208+ sr->clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
209+ break;
210+ case 38400000:
211+ sr->clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
212+ break;
213+ default :
214+ printk(KERN_ERR "Invalid sysclk value: %d\n", sys_clk);
215+ break;
216+ }
217+}
218+
219+static void sr_set_efuse_nvalues(struct omap_sr *sr)
220+{
221+ if (sr->srid == SR1) {
222+ sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
223+ OMAP343X_SR1_SENNENABLE_MASK) >>
224+ OMAP343X_SR1_SENNENABLE_SHIFT;
225+
226+ sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
227+ OMAP343X_SR1_SENPENABLE_MASK) >>
228+ OMAP343X_SR1_SENPENABLE_SHIFT;
229+
230+ sr->opp5_nvalue = omap_ctrl_readl(
231+ OMAP343X_CONTROL_FUSE_OPP5_VDD1);
232+ sr->opp4_nvalue = omap_ctrl_readl(
233+ OMAP343X_CONTROL_FUSE_OPP4_VDD1);
234+ sr->opp3_nvalue = omap_ctrl_readl(
235+ OMAP343X_CONTROL_FUSE_OPP3_VDD1);
236+ sr->opp2_nvalue = omap_ctrl_readl(
237+ OMAP343X_CONTROL_FUSE_OPP2_VDD1);
238+ sr->opp1_nvalue = omap_ctrl_readl(
239+ OMAP343X_CONTROL_FUSE_OPP1_VDD1);
240+ } else if (sr->srid == SR2) {
241+ sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
242+ OMAP343X_SR2_SENNENABLE_MASK) >>
243+ OMAP343X_SR2_SENNENABLE_SHIFT;
244+
245+ sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
246+ OMAP343X_SR2_SENPENABLE_MASK) >>
247+ OMAP343X_SR2_SENPENABLE_SHIFT;
248+
249+ sr->opp3_nvalue = omap_ctrl_readl(
250+ OMAP343X_CONTROL_FUSE_OPP3_VDD2);
251+ sr->opp2_nvalue = omap_ctrl_readl(
252+ OMAP343X_CONTROL_FUSE_OPP2_VDD2);
253+ sr->opp1_nvalue = omap_ctrl_readl(
254+ OMAP343X_CONTROL_FUSE_OPP1_VDD2);
255+ }
256+}
257+
258+/* Hard coded nvalues for testing purposes, may cause device to hang! */
259+static void sr_set_testing_nvalues(struct omap_sr *sr)
260 {
261-#ifdef USE_EFUSE_VALUES
262- u32 n1, n2;
263-#else
264 u32 senpval, sennval;
265 u32 senpgain, senngain;
266 u32 rnsenp, rnsenn;
267-#endif
268
269 if (sr->srid == SR1) {
270-#ifdef USE_EFUSE_VALUES
271- /* Read values for VDD1 from EFUSE */
272-#else
273- /* since E-Fuse Values are not available, calculating the
274- * reciprocal of the SenN and SenP values for SR1
275+ /* Calculating the reciprocal of the SenN and SenP values
276+ * for SR1
277 */
278 sr->senp_mod = 0x03; /* SenN-M5 enabled */
279 sr->senn_mod = 0x03;
280@@ -216,15 +305,16 @@ static void sr_set_nvalues(struct omap_sr *sr)
281 (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
282 (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
283
284+ /* XXX The clocks are enabled in the startup and NVALUE is
285+ * set also there. Disabling this for now, but this could
286+ * be related to dynamic sleep during boot */
287+#if 0
288 sr_clk_enable(sr);
289 sr_write_reg(sr, NVALUERECIPROCAL, sr->opp3_nvalue);
290 sr_clk_disable(sr);
291-
292 #endif
293+
294 } else if (sr->srid == SR2) {
295-#ifdef USE_EFUSE_VALUES
296- /* Read values for VDD2 from EFUSE */
297-#else
298 /* since E-Fuse Values are not available, calculating the
299 * reciprocal of the SenN and SenP values for SR2
300 */
301@@ -269,134 +359,163 @@ static void sr_set_nvalues(struct omap_sr *sr)
302 (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
303 (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
304 (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
305-
306-#endif
307 }
308
309 }
310
311+static void sr_set_nvalues(struct omap_sr *sr)
312+{
313+ if (SR_TESTING_NVALUES)
314+ sr_set_testing_nvalues(sr);
315+ else
316+ sr_set_efuse_nvalues(sr);
317+}
318+
319 static void sr_configure_vp(int srid)
320 {
321 u32 vpconfig;
322
323 if (srid == SR1) {
324 vpconfig = PRM_VP1_CONFIG_ERROROFFSET | PRM_VP1_CONFIG_ERRORGAIN
325- | PRM_VP1_CONFIG_INITVOLTAGE | PRM_VP1_CONFIG_TIMEOUTEN;
326-
327- PRM_VP1_CONFIG = vpconfig;
328- PRM_VP1_VSTEPMIN = PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN |
329- PRM_VP1_VSTEPMIN_VSTEPMIN;
330-
331- PRM_VP1_VSTEPMAX = PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX |
332- PRM_VP1_VSTEPMAX_VSTEPMAX;
333-
334- PRM_VP1_VLIMITTO = PRM_VP1_VLIMITTO_VDDMAX |
335- PRM_VP1_VLIMITTO_VDDMIN | PRM_VP1_VLIMITTO_TIMEOUT;
336-
337- PRM_VP1_CONFIG |= PRM_VP1_CONFIG_INITVDD;
338- PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_INITVDD;
339+ | PRM_VP1_CONFIG_INITVOLTAGE
340+ | PRM_VP1_CONFIG_TIMEOUTEN;
341+
342+ prm_write_mod_reg(vpconfig, OMAP3430_GR_MOD,
343+ OMAP3_PRM_VP1_CONFIG_OFFSET);
344+ prm_write_mod_reg(PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN |
345+ PRM_VP1_VSTEPMIN_VSTEPMIN,
346+ OMAP3430_GR_MOD,
347+ OMAP3_PRM_VP1_VSTEPMIN_OFFSET);
348+
349+ prm_write_mod_reg(PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX |
350+ PRM_VP1_VSTEPMAX_VSTEPMAX,
351+ OMAP3430_GR_MOD,
352+ OMAP3_PRM_VP1_VSTEPMAX_OFFSET);
353+
354+ prm_write_mod_reg(PRM_VP1_VLIMITTO_VDDMAX |
355+ PRM_VP1_VLIMITTO_VDDMIN |
356+ PRM_VP1_VLIMITTO_TIMEOUT,
357+ OMAP3430_GR_MOD,
358+ OMAP3_PRM_VP1_VLIMITTO_OFFSET);
359+
360+ /* Trigger initVDD value copy to voltage processor */
361+ prm_set_mod_reg_bits(PRM_VP1_CONFIG_INITVDD, OMAP3430_GR_MOD,
362+ OMAP3_PRM_VP1_CONFIG_OFFSET);
363+ /* Clear initVDD copy trigger bit */
364+ prm_clear_mod_reg_bits(PRM_VP1_CONFIG_INITVDD, OMAP3430_GR_MOD,
365+ OMAP3_PRM_VP1_CONFIG_OFFSET);
366
367 } else if (srid == SR2) {
368 vpconfig = PRM_VP2_CONFIG_ERROROFFSET | PRM_VP2_CONFIG_ERRORGAIN
369- | PRM_VP2_CONFIG_INITVOLTAGE | PRM_VP2_CONFIG_TIMEOUTEN;
370-
371- PRM_VP2_CONFIG = vpconfig;
372- PRM_VP2_VSTEPMIN = PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN |
373- PRM_VP2_VSTEPMIN_VSTEPMIN;
374-
375- PRM_VP2_VSTEPMAX = PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX |
376- PRM_VP2_VSTEPMAX_VSTEPMAX;
377-
378- PRM_VP2_VLIMITTO = PRM_VP2_VLIMITTO_VDDMAX |
379- PRM_VP2_VLIMITTO_VDDMIN | PRM_VP2_VLIMITTO_TIMEOUT;
380-
381- PRM_VP2_CONFIG |= PRM_VP2_CONFIG_INITVDD;
382- PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_INITVDD;
383+ | PRM_VP2_CONFIG_INITVOLTAGE
384+ | PRM_VP2_CONFIG_TIMEOUTEN;
385+
386+ prm_write_mod_reg(vpconfig, OMAP3430_GR_MOD,
387+ OMAP3_PRM_VP2_CONFIG_OFFSET);
388+ prm_write_mod_reg(PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN |
389+ PRM_VP2_VSTEPMIN_VSTEPMIN,
390+ OMAP3430_GR_MOD,
391+ OMAP3_PRM_VP2_VSTEPMIN_OFFSET);
392+
393+ prm_write_mod_reg(PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX |
394+ PRM_VP2_VSTEPMAX_VSTEPMAX,
395+ OMAP3430_GR_MOD,
396+ OMAP3_PRM_VP2_VSTEPMAX_OFFSET);
397+
398+ prm_write_mod_reg(PRM_VP2_VLIMITTO_VDDMAX |
399+ PRM_VP2_VLIMITTO_VDDMIN |
400+ PRM_VP2_VLIMITTO_TIMEOUT,
401+ OMAP3430_GR_MOD,
402+ OMAP3_PRM_VP2_VLIMITTO_OFFSET);
403+
404+ /* Trigger initVDD value copy to voltage processor */
405+ prm_set_mod_reg_bits(PRM_VP2_CONFIG_INITVDD, OMAP3430_GR_MOD,
406+ OMAP3_PRM_VP2_CONFIG_OFFSET);
407+ /* Reset initVDD copy trigger bit */
408+ prm_clear_mod_reg_bits(PRM_VP2_CONFIG_INITVDD, OMAP3430_GR_MOD,
409+ OMAP3_PRM_VP2_CONFIG_OFFSET);
410
411 }
412 }
413
414 static void sr_configure_vc(void)
415 {
416- PRM_VC_SMPS_SA =
417- (R_SRI2C_SLAVE_ADDR << PRM_VC_SMPS_SA1_SHIFT) |
418- (R_SRI2C_SLAVE_ADDR << PRM_VC_SMPS_SA0_SHIFT);
419-
420- PRM_VC_SMPS_VOL_RA = (R_VDD2_SR_CONTROL << PRM_VC_SMPS_VOLRA1_SHIFT) |
421- (R_VDD1_SR_CONTROL << PRM_VC_SMPS_VOLRA0_SHIFT);
422-
423- PRM_VC_CMD_VAL_0 = (PRM_VC_CMD_VAL0_ON << PRM_VC_CMD_ON_SHIFT) |
424- (PRM_VC_CMD_VAL0_ONLP << PRM_VC_CMD_ONLP_SHIFT) |
425- (PRM_VC_CMD_VAL0_RET << PRM_VC_CMD_RET_SHIFT) |
426- (PRM_VC_CMD_VAL0_OFF << PRM_VC_CMD_OFF_SHIFT);
427-
428- PRM_VC_CMD_VAL_1 = (PRM_VC_CMD_VAL1_ON << PRM_VC_CMD_ON_SHIFT) |
429- (PRM_VC_CMD_VAL1_ONLP << PRM_VC_CMD_ONLP_SHIFT) |
430- (PRM_VC_CMD_VAL1_RET << PRM_VC_CMD_RET_SHIFT) |
431- (PRM_VC_CMD_VAL1_OFF << PRM_VC_CMD_OFF_SHIFT);
432-
433- PRM_VC_CH_CONF = PRM_VC_CH_CONF_CMD1 | PRM_VC_CH_CONF_RAV1;
434-
435- PRM_VC_I2C_CFG = PRM_VC_I2C_CFG_MCODE | PRM_VC_I2C_CFG_HSEN
436- | PRM_VC_I2C_CFG_SREN;
437+ prm_write_mod_reg((R_SRI2C_SLAVE_ADDR << OMAP3430_SMPS_SA1_SHIFT) |
438+ (R_SRI2C_SLAVE_ADDR << OMAP3430_SMPS_SA0_SHIFT),
439+ OMAP3430_GR_MOD, OMAP3_PRM_VC_SMPS_SA_OFFSET);
440+
441+ prm_write_mod_reg((R_VDD2_SR_CONTROL << OMAP3430_VOLRA1_SHIFT) |
442+ (R_VDD1_SR_CONTROL << OMAP3430_VOLRA0_SHIFT),
443+ OMAP3430_GR_MOD, OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET);
444+
445+ prm_write_mod_reg((OMAP3430_VC_CMD_VAL0_ON <<
446+ OMAP3430_VC_CMD_ON_SHIFT) |
447+ (OMAP3430_VC_CMD_VAL0_ONLP << OMAP3430_VC_CMD_ONLP_SHIFT) |
448+ (OMAP3430_VC_CMD_VAL0_RET << OMAP3430_VC_CMD_RET_SHIFT) |
449+ (OMAP3430_VC_CMD_VAL0_OFF << OMAP3430_VC_CMD_OFF_SHIFT),
450+ OMAP3430_GR_MOD, OMAP3_PRM_VC_CMD_VAL_0_OFFSET);
451+
452+ prm_write_mod_reg((OMAP3430_VC_CMD_VAL1_ON <<
453+ OMAP3430_VC_CMD_ON_SHIFT) |
454+ (OMAP3430_VC_CMD_VAL1_ONLP << OMAP3430_VC_CMD_ONLP_SHIFT) |
455+ (OMAP3430_VC_CMD_VAL1_RET << OMAP3430_VC_CMD_RET_SHIFT) |
456+ (OMAP3430_VC_CMD_VAL1_OFF << OMAP3430_VC_CMD_OFF_SHIFT),
457+ OMAP3430_GR_MOD, OMAP3_PRM_VC_CMD_VAL_1_OFFSET);
458+
459+ prm_write_mod_reg(OMAP3430_CMD1 | OMAP3430_RAV1,
460+ OMAP3430_GR_MOD,
461+ OMAP3_PRM_VC_CH_CONF_OFFSET);
462+
463+ prm_write_mod_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN | OMAP3430_SREN,
464+ OMAP3430_GR_MOD,
465+ OMAP3_PRM_VC_I2C_CFG_OFFSET);
466
467 /* Setup voltctrl and other setup times */
468+ /* XXX CONFIG_SYSOFFMODE has not been implemented yet */
469 #ifdef CONFIG_SYSOFFMODE
470- PRM_VOLTCTRL = PRM_VOLTCTRL_AUTO_OFF | PRM_VOLTCTRL_AUTO_RET;
471- PRM_CLKSETUP = PRM_CLKSETUP_DURATION;
472- PRM_VOLTSETUP1 = (PRM_VOLTSETUP_TIME2 << PRM_VOLTSETUP_TIME2_OFFSET) |
473- (PRM_VOLTSETUP_TIME1 << PRM_VOLTSETUP_TIME1_OFFSET);
474- PRM_VOLTOFFSET = PRM_VOLTOFFSET_DURATION;
475- PRM_VOLTSETUP2 = PRM_VOLTSETUP2_DURATION;
476+ prm_write_mod_reg(OMAP3430_AUTO_OFF | OMAP3430_AUTO_RET,
477+ OMAP3430_GR_MOD,
478+ OMAP3_PRM_VOLTCTRL_OFFSET);
479+
480+ prm_write_mod_reg(OMAP3430_CLKSETUP_DURATION, OMAP3430_GR_MOD,
481+ OMAP3_PRM_CLKSETUP_OFFSET);
482+ prm_write_mod_reg((OMAP3430_VOLTSETUP_TIME2 <<
483+ OMAP3430_VOLTSETUP_TIME2_OFFSET) |
484+ (OMAP3430_VOLTSETUP_TIME1 <<
485+ OMAP3430_VOLTSETUP_TIME1_OFFSET),
486+ OMAP3430_GR_MOD, OMAP3_PRM_VOLTSETUP1_OFFSET);
487+
488+ prm_write_mod_reg(OMAP3430_VOLTOFFSET_DURATION, OMAP3430_GR_MOD,
489+ OMAP3_PRM_VOLTOFFSET_OFFSET);
490+ prm_write_mod_reg(OMAP3430_VOLTSETUP2_DURATION, OMAP3430_GR_MOD,
491+ OMAP3_PRM_VOLTSETUP2_OFFSET);
492 #else
493- PRM_VOLTCTRL |= PRM_VOLTCTRL_AUTO_RET;
494+ prm_set_mod_reg_bits(OMAP3430_AUTO_RET, OMAP3430_GR_MOD,
495+ OMAP3_PRM_VOLTCTRL_OFFSET);
496 #endif
497
498 }
499
500-
501 static void sr_configure(struct omap_sr *sr)
502 {
503- u32 sys_clk, sr_clk_length = 0;
504 u32 sr_config;
505 u32 senp_en , senn_en;
506
507+ if (sr->clk_length == 0)
508+ sr_set_clk_length(sr);
509+
510 senp_en = sr->senp_mod;
511 senn_en = sr->senn_mod;
512-
513- sys_clk = prcm_get_system_clock_speed();
514-
515- switch (sys_clk) {
516- case 12000:
517- sr_clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
518- break;
519- case 13000:
520- sr_clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
521- break;
522- case 19200:
523- sr_clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
524- break;
525- case 26000:
526- sr_clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
527- break;
528- case 38400:
529- sr_clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
530- break;
531- default :
532- printk(KERN_ERR "Invalid sysclk value\n");
533- break;
534- }
535-
536- DPRINTK(KERN_DEBUG "SR : sys clk %lu\n", sys_clk);
537 if (sr->srid == SR1) {
538 sr_config = SR1_SRCONFIG_ACCUMDATA |
539- (sr_clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
540+ (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
541 SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
542 SRCONFIG_MINMAXAVG_EN |
543 (senn_en << SRCONFIG_SENNENABLE_SHIFT) |
544 (senp_en << SRCONFIG_SENPENABLE_SHIFT) |
545 SRCONFIG_DELAYCTRL;
546-
547+ DPRINTK(KERN_DEBUG "setting SRCONFIG1 to 0x%08lx\n",
548+ (unsigned long int) sr_config);
549 sr_write_reg(sr, SRCONFIG, sr_config);
550
551 sr_write_reg(sr, AVGWEIGHT, SR1_AVGWEIGHT_SENPAVGWEIGHT |
552@@ -408,18 +527,18 @@ static void sr_configure(struct omap_sr *sr)
553
554 } else if (sr->srid == SR2) {
555 sr_config = SR2_SRCONFIG_ACCUMDATA |
556- (sr_clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
557+ (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
558 SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
559 SRCONFIG_MINMAXAVG_EN |
560 (senn_en << SRCONFIG_SENNENABLE_SHIFT) |
561 (senp_en << SRCONFIG_SENPENABLE_SHIFT) |
562 SRCONFIG_DELAYCTRL;
563
564+ DPRINTK(KERN_DEBUG "setting SRCONFIG2 to 0x%08lx\n",
565+ (unsigned long int) sr_config);
566 sr_write_reg(sr, SRCONFIG, sr_config);
567-
568 sr_write_reg(sr, AVGWEIGHT, SR2_AVGWEIGHT_SENPAVGWEIGHT |
569 SR2_AVGWEIGHT_SENNAVGWEIGHT);
570-
571 sr_modify_reg(sr, ERRCONFIG, (SR_ERRWEIGHT_MASK |
572 SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
573 (SR2_ERRWEIGHT | SR2_ERRMAXLIMIT | SR2_ERRMINLIMIT));
574@@ -428,9 +547,9 @@ static void sr_configure(struct omap_sr *sr)
575 sr->is_sr_reset = 0;
576 }
577
578-static void sr_enable(struct omap_sr *sr, u32 target_opp_no)
579+static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
580 {
581- u32 nvalue_reciprocal, current_nvalue;
582+ u32 nvalue_reciprocal;
583
584 sr->req_opp_no = target_opp_no;
585
586@@ -472,11 +591,10 @@ static void sr_enable(struct omap_sr *sr, u32 target_opp_no)
587 }
588 }
589
590- current_nvalue = sr_read_reg(sr, NVALUERECIPROCAL);
591-
592- if (current_nvalue == nvalue_reciprocal) {
593- DPRINTK("System is already at the desired voltage level\n");
594- return;
595+ if (nvalue_reciprocal == 0) {
596+ printk(KERN_NOTICE "OPP%d doesn't support SmartReflex\n",
597+ target_opp_no);
598+ return SR_FALSE;
599 }
600
601 sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
602@@ -485,18 +603,19 @@ static void sr_enable(struct omap_sr *sr, u32 target_opp_no)
603 sr_modify_reg(sr, ERRCONFIG,
604 (ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST),
605 (ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
606-
607 if (sr->srid == SR1) {
608 /* Enable VP1 */
609- PRM_VP1_CONFIG |= PRM_VP1_CONFIG_VPENABLE;
610+ prm_set_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE, OMAP3430_GR_MOD,
611+ OMAP3_PRM_VP1_CONFIG_OFFSET);
612 } else if (sr->srid == SR2) {
613 /* Enable VP2 */
614- PRM_VP2_CONFIG |= PRM_VP2_CONFIG_VPENABLE;
615+ prm_set_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE, OMAP3430_GR_MOD,
616+ OMAP3_PRM_VP2_CONFIG_OFFSET);
617 }
618
619 /* SRCONFIG - enable SR */
620 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
621-
622+ return SR_TRUE;
623 }
624
625 static void sr_disable(struct omap_sr *sr)
626@@ -507,11 +626,13 @@ static void sr_disable(struct omap_sr *sr)
627 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, ~SRCONFIG_SRENABLE);
628
629 if (sr->srid == SR1) {
630- /* Enable VP1 */
631- PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_VPENABLE;
632+ /* Disable VP1 */
633+ prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE, OMAP3430_GR_MOD,
634+ OMAP3_PRM_VP1_CONFIG_OFFSET);
635 } else if (sr->srid == SR2) {
636- /* Enable VP2 */
637- PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_VPENABLE;
638+ /* Disable VP2 */
639+ prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE, OMAP3430_GR_MOD,
640+ OMAP3_PRM_VP2_CONFIG_OFFSET);
641 }
642 }
643
644@@ -535,7 +656,12 @@ void sr_start_vddautocomap(int srid, u32 target_opp_no)
645 srid);
646
647 sr->is_autocomp_active = 1;
648- sr_enable(sr, target_opp_no);
649+ if (!sr_enable(sr, target_opp_no)) {
650+ printk(KERN_WARNING "SR%d: VDD autocomp not activated\n", srid);
651+ sr->is_autocomp_active = 0;
652+ if (sr->is_sr_reset == 1)
653+ sr_clk_disable(sr);
654+ }
655 }
656 EXPORT_SYMBOL(sr_start_vddautocomap);
657
658@@ -574,20 +700,18 @@ void enable_smartreflex(int srid)
659
660 if (sr->is_autocomp_active == 1) {
661 if (sr->is_sr_reset == 1) {
662- if (srid == SR1) {
663- /* Enable SR clks */
664- CM_FCLKEN_WKUP |= SR1_CLK_ENABLE;
665- target_opp_no = get_opp_no(current_vdd1_opp);
666+ /* Enable SR clks */
667+ sr_clk_enable(sr);
668
669- } else if (srid == SR2) {
670- /* Enable SR clks */
671- CM_FCLKEN_WKUP |= SR2_CLK_ENABLE;
672+ if (srid == SR1)
673+ target_opp_no = get_opp_no(current_vdd1_opp);
674+ else if (srid == SR2)
675 target_opp_no = get_opp_no(current_vdd2_opp);
676- }
677
678 sr_configure(sr);
679
680- sr_enable(sr, target_opp_no);
681+ if (!sr_enable(sr, target_opp_no))
682+ sr_clk_disable(sr);
683 }
684 }
685 }
686@@ -602,15 +726,6 @@ void disable_smartreflex(int srid)
687 sr = &sr2;
688
689 if (sr->is_autocomp_active == 1) {
690- if (srid == SR1) {
691- /* Enable SR clk */
692- CM_FCLKEN_WKUP |= SR1_CLK_ENABLE;
693-
694- } else if (srid == SR2) {
695- /* Enable SR clk */
696- CM_FCLKEN_WKUP |= SR2_CLK_ENABLE;
697- }
698-
699 if (sr->is_sr_reset == 0) {
700
701 sr->is_sr_reset = 1;
702@@ -618,17 +733,18 @@ void disable_smartreflex(int srid)
703 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE,
704 ~SRCONFIG_SRENABLE);
705
706+ /* Disable SR clk */
707+ sr_clk_disable(sr);
708 if (sr->srid == SR1) {
709- /* Disable SR clk */
710- CM_FCLKEN_WKUP &= ~SR1_CLK_ENABLE;
711- /* Enable VP1 */
712- PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_VPENABLE;
713-
714+ /* Disable VP1 */
715+ prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE,
716+ OMAP3430_GR_MOD,
717+ OMAP3_PRM_VP1_CONFIG_OFFSET);
718 } else if (sr->srid == SR2) {
719- /* Disable SR clk */
720- CM_FCLKEN_WKUP &= ~SR2_CLK_ENABLE;
721- /* Enable VP2 */
722- PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_VPENABLE;
723+ /* Disable VP2 */
724+ prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE,
725+ OMAP3430_GR_MOD,
726+ OMAP3_PRM_VP2_CONFIG_OFFSET);
727 }
728 }
729 }
730@@ -638,7 +754,6 @@ void disable_smartreflex(int srid)
731 /* Voltage Scaling using SR VCBYPASS */
732 int sr_voltagescale_vcbypass(u32 target_opp, u8 vsel)
733 {
734- int ret;
735 int sr_status = 0;
736 u32 vdd, target_opp_no;
737 u32 vc_bypass_value;
738@@ -651,39 +766,53 @@ int sr_voltagescale_vcbypass(u32 target_opp, u8 vsel)
739 if (vdd == PRCM_VDD1) {
740 sr_status = sr_stop_vddautocomap(SR1);
741
742- PRM_VC_CMD_VAL_0 = (PRM_VC_CMD_VAL_0 & ~PRM_VC_CMD_ON_MASK) |
743- (vsel << PRM_VC_CMD_ON_SHIFT);
744+ prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK,
745+ (vsel << OMAP3430_VC_CMD_ON_SHIFT),
746+ OMAP3430_GR_MOD,
747+ OMAP3_PRM_VC_CMD_VAL_0_OFFSET);
748 reg_addr = R_VDD1_SR_CONTROL;
749
750 } else if (vdd == PRCM_VDD2) {
751 sr_status = sr_stop_vddautocomap(SR2);
752
753- PRM_VC_CMD_VAL_1 = (PRM_VC_CMD_VAL_1 & ~PRM_VC_CMD_ON_MASK) |
754- (vsel << PRM_VC_CMD_ON_SHIFT);
755+ prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK,
756+ (vsel << OMAP3430_VC_CMD_ON_SHIFT),
757+ OMAP3430_GR_MOD,
758+ OMAP3_PRM_VC_CMD_VAL_1_OFFSET);
759 reg_addr = R_VDD2_SR_CONTROL;
760 }
761
762- vc_bypass_value = (vsel << PRM_VC_BYPASS_DATA_SHIFT) |
763- (reg_addr << PRM_VC_BYPASS_REGADDR_SHIFT) |
764- (R_SRI2C_SLAVE_ADDR << PRM_VC_BYPASS_SLAVEADDR_SHIFT);
765+ vc_bypass_value = (vsel << OMAP3430_DATA_SHIFT) |
766+ (reg_addr << OMAP3430_REGADDR_SHIFT) |
767+ (R_SRI2C_SLAVE_ADDR << OMAP3430_SLAVEADDR_SHIFT);
768
769- PRM_VC_BYPASS_VAL = vc_bypass_value;
770+ prm_write_mod_reg(vc_bypass_value, OMAP3430_GR_MOD,
771+ OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
772
773- PRM_VC_BYPASS_VAL |= PRM_VC_BYPASS_VALID;
774+ vc_bypass_value = prm_set_mod_reg_bits(OMAP3430_VALID, OMAP3430_GR_MOD,
775+ OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
776
777- DPRINTK("%s : PRM_VC_BYPASS_VAL %X\n", __func__, PRM_VC_BYPASS_VAL);
778- DPRINTK("PRM_IRQST_MPU %X\n", PRM_IRQSTATUS_MPU);
779+ DPRINTK("%s : PRM_VC_BYPASS_VAL %X\n", __func__, vc_bypass_value);
780+ DPRINTK("PRM_IRQST_MPU %X\n", prm_read_mod_reg(OCP_MOD,
781+ OMAP3_PRM_IRQSTATUS_MPU_OFFSET));
782
783- while ((PRM_VC_BYPASS_VAL & PRM_VC_BYPASS_VALID) != 0x0) {
784- ret = loop_wait(&loop_cnt, &retries_cnt, 10);
785- if (ret != PRCM_PASS) {
786+ while ((vc_bypass_value & OMAP3430_VALID) != 0x0) {
787+ loop_cnt++;
788+ if (retries_cnt > 10) {
789 printk(KERN_INFO "Loop count exceeded in check SR I2C"
790 "write\n");
791- return ret;
792+ return SR_FAIL;
793+ }
794+ if (loop_cnt > 50) {
795+ retries_cnt++;
796+ loop_cnt = 0;
797+ udelay(10);
798 }
799+ vc_bypass_value = prm_read_mod_reg(OMAP3430_GR_MOD,
800+ OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
801 }
802
803- omap_udelay(T2_SMPS_UPDATE_DELAY);
804+ udelay(T2_SMPS_UPDATE_DELAY);
805
806 if (sr_status) {
807 if (vdd == PRCM_VDD1)
808@@ -696,13 +825,15 @@ int sr_voltagescale_vcbypass(u32 target_opp, u8 vsel)
809 }
810
811 /* Sysfs interface to select SR VDD1 auto compensation */
812-static ssize_t omap_sr_vdd1_autocomp_show(struct kset *subsys, char *buf)
813+static ssize_t omap_sr_vdd1_autocomp_show(struct kobject *kobj,
814+ struct kobj_attribute *attr, char *buf)
815 {
816 return sprintf(buf, "%d\n", sr1.is_autocomp_active);
817 }
818
819-static ssize_t omap_sr_vdd1_autocomp_store(struct kset *subsys,
820- const char *buf, size_t n)
821+static ssize_t omap_sr_vdd1_autocomp_store(struct kobject *kobj,
822+ struct kobj_attribute *attr,
823+ const char *buf, size_t n)
824 {
825 u32 current_vdd1opp_no;
826 unsigned short value;
827@@ -722,7 +853,7 @@ static ssize_t omap_sr_vdd1_autocomp_store(struct kset *subsys,
828 return n;
829 }
830
831-static struct subsys_attribute sr_vdd1_autocomp = {
832+static struct kobj_attribute sr_vdd1_autocomp = {
833 .attr = {
834 .name = __stringify(sr_vdd1_autocomp),
835 .mode = 0644,
836@@ -732,13 +863,15 @@ static struct subsys_attribute sr_vdd1_autocomp = {
837 };
838
839 /* Sysfs interface to select SR VDD2 auto compensation */
840-static ssize_t omap_sr_vdd2_autocomp_show(struct kset *subsys, char *buf)
841+static ssize_t omap_sr_vdd2_autocomp_show(struct kobject *kobj,
842+ struct kobj_attribute *attr, char *buf)
843 {
844 return sprintf(buf, "%d\n", sr2.is_autocomp_active);
845 }
846
847-static ssize_t omap_sr_vdd2_autocomp_store(struct kset *subsys,
848- const char *buf, size_t n)
849+static ssize_t omap_sr_vdd2_autocomp_store(struct kobject *kobj,
850+ struct kobj_attribute *attr,
851+ const char *buf, size_t n)
852 {
853 u32 current_vdd2opp_no;
854 unsigned short value;
855@@ -758,7 +891,7 @@ static ssize_t omap_sr_vdd2_autocomp_store(struct kset *subsys,
856 return n;
857 }
858
859-static struct subsys_attribute sr_vdd2_autocomp = {
860+static struct kobj_attribute sr_vdd2_autocomp = {
861 .attr = {
862 .name = __stringify(sr_vdd2_autocomp),
863 .mode = 0644,
864@@ -774,15 +907,19 @@ static int __init omap3_sr_init(void)
865 int ret = 0;
866 u8 RdReg;
867
868-#ifdef CONFIG_ARCH_OMAP34XX
869- sr1.fck = clk_get(NULL, "sr1_fck");
870- if (IS_ERR(sr1.fck))
871- printk(KERN_ERR "Could not get sr1_fck\n");
872-
873- sr2.fck = clk_get(NULL, "sr2_fck");
874- if (IS_ERR(sr2.fck))
875- printk(KERN_ERR "Could not get sr2_fck\n");
876-#endif /* #ifdef CONFIG_ARCH_OMAP34XX */
877+ if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) {
878+ current_vdd1_opp = PRCM_VDD1_OPP3;
879+ current_vdd2_opp = PRCM_VDD2_OPP3;
880+ } else {
881+ current_vdd1_opp = PRCM_VDD1_OPP1;
882+ current_vdd2_opp = PRCM_VDD1_OPP1;
883+ }
884+ if (cpu_is_omap34xx()) {
885+ sr_clk_get(&sr1);
886+ sr_clk_get(&sr2);
887+ }
888+ sr_set_clk_length(&sr1);
889+ sr_set_clk_length(&sr2);
890
891 /* Call the VPConfig, VCConfig, set N Values. */
892 sr_set_nvalues(&sr1);
893@@ -794,22 +931,24 @@ static int __init omap3_sr_init(void)
894 sr_configure_vc();
895
896 /* Enable SR on T2 */
897- ret = t2_in(PM_RECEIVER, &RdReg, R_DCDC_GLOBAL_CFG);
898- RdReg |= DCDC_GLOBAL_CFG_ENABLE_SRFLX;
899- ret |= t2_out(PM_RECEIVER, RdReg, R_DCDC_GLOBAL_CFG);
900+ ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &RdReg,
901+ R_DCDC_GLOBAL_CFG);
902
903+ RdReg |= DCDC_GLOBAL_CFG_ENABLE_SRFLX;
904+ ret |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, RdReg,
905+ R_DCDC_GLOBAL_CFG);
906
907 printk(KERN_INFO "SmartReflex driver initialized\n");
908
909- ret = subsys_create_file(&power_subsys, &sr_vdd1_autocomp);
910+ ret = sysfs_create_file(power_kobj, &sr_vdd1_autocomp.attr);
911 if (ret)
912- printk(KERN_ERR "subsys_create_file failed: %d\n", ret);
913+ printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
914
915- ret = subsys_create_file(&power_subsys, &sr_vdd2_autocomp);
916+ ret = sysfs_create_file(power_kobj, &sr_vdd2_autocomp.attr);
917 if (ret)
918- printk(KERN_ERR "subsys_create_file failed: %d\n", ret);
919+ printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
920
921 return 0;
922 }
923
924-arch_initcall(omap3_sr_init);
925+late_initcall(omap3_sr_init);
926diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
927index 2091a15..194429e 100644
928--- a/arch/arm/mach-omap2/smartreflex.h
929+++ b/arch/arm/mach-omap2/smartreflex.h
930@@ -233,12 +233,18 @@
931 extern u32 current_vdd1_opp;
932 extern u32 current_vdd2_opp;
933
934+#ifdef CONFIG_OMAP_SMARTREFLEX_TESTING
935+#define SR_TESTING_NVALUES 1
936+#else
937+#define SR_TESTING_NVALUES 0
938+#endif
939+
940 /*
941 * Smartreflex module enable/disable interface.
942 * NOTE: if smartreflex is not enabled from sysfs, these functions will not
943 * do anything.
944 */
945-#if defined(CONFIG_ARCH_OMAP34XX) && defined(CONFIG_TWL4030_CORE)
946+#ifdef CONFIG_OMAP_SMARTREFLEX
947 void enable_smartreflex(int srid);
948 void disable_smartreflex(int srid);
949 #else
950@@ -246,7 +252,6 @@ static inline void enable_smartreflex(int srid) {}
951 static inline void disable_smartreflex(int srid) {}
952 #endif
953
954-
955 #endif
956
957
958diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
959index b085b07..960c13f 100644
960--- a/arch/arm/plat-omap/Kconfig
961+++ b/arch/arm/plat-omap/Kconfig
962@@ -56,6 +56,37 @@ config OMAP_DEBUG_CLOCKDOMAIN
963 for every clockdomain register write. However, the
964 extra detail costs some memory.
965
966+config OMAP_SMARTREFLEX
967+ bool "SmartReflex support"
968+ depends on ARCH_OMAP34XX && TWL4030_CORE
969+ help
970+ Say Y if you want to enable SmartReflex.
971+
972+ SmartReflex can perform continuous dynamic voltage
973+ scaling around the nominal operating point voltage
974+ according to silicon characteristics and operating
975+ conditions. Enabling SmartReflex reduces power
976+ consumption.
977+
978+ Please note, that by default SmartReflex is only
979+ initialized. To enable the automatic voltage
980+ compensation for VDD1 and VDD2, user must write 1 to
981+ /sys/power/sr_vddX_autocomp, where X is 1 or 2.
982+
983+config OMAP_SMARTREFLEX_TESTING
984+ bool "Smartreflex testing support"
985+ depends on OMAP_SMARTREFLEX
986+ default n
987+ help
988+ Say Y if you want to enable SmartReflex testing with SW hardcoded
989+ NVALUES intead of E-fuse NVALUES set in factory silicon testing.
990+
991+ In some devices the E-fuse values have not been set, even though
992+ SmartReflex modules are included. Using these hardcoded values set
993+ in software, one can test the SmartReflex features without E-fuse.
994+
995+ WARNING: Enabling this option may cause your device to hang!
996+
997 config OMAP_RESET_CLOCKS
998 bool "Reset unused clocks during boot"
999 depends on ARCH_OMAP
1000--
10011.5.4.3