iscsi-target: Add package iscsi-target
[vuplus_openembedded] / packages / linux / linux-omap2-git / beagleboard / 0001-ARM-OMAP-SmartReflex-driver.patch
1 From: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
2 To: linux-omap@vger.kernel.org
3 Cc: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
4 Subject: [PATCH 1/3] ARM: OMAP: SmartReflex driver, reference source and header files
5 Date:   Mon,  2 Jun 2008 14:30:12 +0300
6
7 The following patch set integrates TI's SmartReflex driver. SmartReflex is a
8 module that adjusts OMAP3 VDD1 and VDD2 operating voltages around the nominal
9 values of current operating point depending on silicon characteristics and
10 operating conditions.
11
12 The driver creates two sysfs entries into /sys/power/ named "sr_vdd1_autocomp"
13 and "sr_vdd2_autocomp" which can be used to activate SmartReflex modules 1 and
14 2.
15
16 Use the following commands to enable SmartReflex:
17
18 echo -n 1 > /sys/power/sr_vdd1_autocomp
19 echo -n 1 > /sys/power/sr_vdd2_autocomp
20
21 To disable:
22
23 echo -n 0 > /sys/power/sr_vdd1_autocomp
24 echo -n 0 > /sys/power/sr_vdd2_autocomp
25
26 This particular patch adds the TI reference source and header files for
27 SmartReflex. Only modifications include minor styling to pass checkpatch.pl
28 test.
29
30 Signed-off-by: Kalle Jokiniemi <ext-kalle.jokiniemi@nokia.com>
31 ---
32  arch/arm/mach-omap2/smartreflex.c |  815 +++++++++++++++++++++++++++++++++++++
33  arch/arm/mach-omap2/smartreflex.h |  136 ++++++
34  2 files changed, 951 insertions(+), 0 deletions(-)
35  create mode 100644 arch/arm/mach-omap2/smartreflex.c
36  create mode 100644 arch/arm/mach-omap2/smartreflex.h
37
38 diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
39 new file mode 100644
40 index 0000000..dae7460
41 --- /dev/null
42 +++ b/arch/arm/mach-omap2/smartreflex.c
43 @@ -0,0 +1,815 @@
44 +/*
45 + * linux/arch/arm/mach-omap3/smartreflex.c
46 + *
47 + * OMAP34XX SmartReflex Voltage Control
48 + *
49 + * Copyright (C) 2007 Texas Instruments, Inc.
50 + * Lesly A M <x0080970@ti.com>
51 + *
52 + * This program is free software; you can redistribute it and/or modify
53 + * it under the terms of the GNU General Public License version 2 as
54 + * published by the Free Software Foundation.
55 + */
56 +
57 +
58 +#include <linux/kernel.h>
59 +#include <linux/init.h>
60 +#include <linux/interrupt.h>
61 +#include <linux/module.h>
62 +#include <linux/delay.h>
63 +#include <linux/err.h>
64 +#include <linux/clk.h>
65 +#include <linux/sysfs.h>
66 +
67 +#include <asm/arch/prcm.h>
68 +#include <asm/arch/power_companion.h>
69 +#include <linux/io.h>
70 +
71 +#include "prcm-regs.h"
72 +#include "smartreflex.h"
73 +
74 +
75 +/* #define DEBUG_SR 1 */
76 +#ifdef DEBUG_SR
77 +#  define DPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__ ,\
78 +                                                                       ## args)
79 +#else
80 +#  define DPRINTK(fmt, args...)
81 +#endif
82 +
83 +struct omap_sr{
84 +       int srid;
85 +       int is_sr_reset;
86 +       int is_autocomp_active;
87 +       struct clk *fck;
88 +       u32 req_opp_no;
89 +       u32 opp1_nvalue, opp2_nvalue, opp3_nvalue, opp4_nvalue, opp5_nvalue;
90 +       u32 senp_mod, senn_mod;
91 +       u32 srbase_addr;
92 +       u32 vpbase_addr;
93 +};
94 +
95 +static struct omap_sr sr1 = {
96 +       .srid = SR1,
97 +       .is_sr_reset = 1,
98 +       .is_autocomp_active = 0,
99 +       .srbase_addr = OMAP34XX_SR1_BASE,
100 +};
101 +
102 +static struct omap_sr sr2 = {
103 +       .srid = SR2,
104 +       .is_sr_reset = 1,
105 +       .is_autocomp_active = 0,
106 +       .srbase_addr = OMAP34XX_SR2_BASE,
107 +};
108 +
109 +static inline void sr_write_reg(struct omap_sr *sr, int offset, u32 value)
110 +{
111 +       omap_writel(value, sr->srbase_addr + offset);
112 +}
113 +
114 +static inline void sr_modify_reg(struct omap_sr *sr, int offset, u32 mask,
115 +                                                               u32 value)
116 +{
117 +       u32 reg_val;
118 +
119 +       reg_val = omap_readl(sr->srbase_addr + offset);
120 +       reg_val &= ~mask;
121 +       reg_val |= value;
122 +
123 +       omap_writel(reg_val, sr->srbase_addr + offset);
124 +}
125 +
126 +static inline u32 sr_read_reg(struct omap_sr *sr, int offset)
127 +{
128 +       return omap_readl(sr->srbase_addr + offset);
129 +}
130 +
131 +
132 +#ifndef USE_EFUSE_VALUES
133 +static void cal_reciprocal(u32 sensor, u32 *sengain, u32 *rnsen)
134 +{
135 +       u32 gn, rn, mul;
136 +
137 +       for (gn = 0; gn < GAIN_MAXLIMIT; gn++) {
138 +               mul = 1 << (gn + 8);
139 +               rn = mul / sensor;
140 +               if (rn < R_MAXLIMIT) {
141 +                       *sengain = gn;
142 +                       *rnsen = rn;
143 +               }
144 +       }
145 +}
146 +#endif
147 +
148 +static int sr_clk_enable(struct omap_sr *sr)
149 +{
150 +       if (clk_enable(sr->fck) != 0) {
151 +               printk(KERN_ERR "Could not enable sr%d_fck\n", sr->srid);
152 +               goto clk_enable_err;
153 +       }
154 +
155 +       /* set fclk- active , iclk- idle */
156 +       sr_modify_reg(sr, ERRCONFIG, SR_CLKACTIVITY_MASK,
157 +                                               SR_CLKACTIVITY_IOFF_FON);
158 +
159 +       return 0;
160 +
161 +clk_enable_err:
162 +       return -1;
163 +}
164 +
165 +static int sr_clk_disable(struct omap_sr *sr)
166 +{
167 +       /* set fclk, iclk- idle */
168 +       sr_modify_reg(sr, ERRCONFIG, SR_CLKACTIVITY_MASK,
169 +                                               SR_CLKACTIVITY_IOFF_FOFF);
170 +
171 +       clk_disable(sr->fck);
172 +       sr->is_sr_reset = 1;
173 +
174 +       return 0;
175 +}
176 +
177 +static void sr_set_nvalues(struct omap_sr *sr)
178 +{
179 +#ifdef USE_EFUSE_VALUES
180 +       u32 n1, n2;
181 +#else
182 +       u32 senpval, sennval;
183 +       u32 senpgain, senngain;
184 +       u32 rnsenp, rnsenn;
185 +#endif
186 +
187 +       if (sr->srid == SR1) {
188 +#ifdef USE_EFUSE_VALUES
189 +               /* Read values for VDD1 from EFUSE */
190 +#else
191 +               /* since E-Fuse Values are not available, calculating the
192 +                * reciprocal of the SenN and SenP values for SR1
193 +                */
194 +               sr->senp_mod = 0x03;        /* SenN-M5 enabled */
195 +               sr->senn_mod = 0x03;
196 +
197 +               /* for OPP5 */
198 +               senpval = 0x848 + 0x330;
199 +               sennval = 0xacd + 0x330;
200 +
201 +               cal_reciprocal(senpval, &senpgain, &rnsenp);
202 +               cal_reciprocal(sennval, &senngain, &rnsenn);
203 +
204 +               sr->opp5_nvalue =
205 +                               ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
206 +                               (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
207 +                               (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
208 +                               (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
209 +
210 +               /* for OPP4 */
211 +               senpval = 0x727 + 0x2a0;
212 +               sennval = 0x964 + 0x2a0;
213 +
214 +               cal_reciprocal(senpval, &senpgain, &rnsenp);
215 +               cal_reciprocal(sennval, &senngain, &rnsenn);
216 +
217 +               sr->opp4_nvalue =
218 +                               ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
219 +                               (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
220 +                               (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
221 +                               (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
222 +
223 +               /* for OPP3 */
224 +               senpval = 0x655 + 0x200;
225 +               sennval = 0x85b + 0x200;
226 +
227 +               cal_reciprocal(senpval, &senpgain, &rnsenp);
228 +               cal_reciprocal(sennval, &senngain, &rnsenn);
229 +
230 +               sr->opp3_nvalue =
231 +                               ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
232 +                               (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
233 +                               (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
234 +                               (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
235 +
236 +               /* for OPP2 */
237 +               senpval = 0x3be + 0x1a0;
238 +               sennval = 0x506 + 0x1a0;
239 +
240 +               cal_reciprocal(senpval, &senpgain, &rnsenp);
241 +               cal_reciprocal(sennval, &senngain, &rnsenn);
242 +
243 +               sr->opp2_nvalue =
244 +                               ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
245 +                               (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
246 +                               (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
247 +                               (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
248 +
249 +               /* for OPP1 */
250 +               senpval = 0x28c + 0x100;
251 +               sennval = 0x373 + 0x100;
252 +
253 +               cal_reciprocal(senpval, &senpgain, &rnsenp);
254 +               cal_reciprocal(sennval, &senngain, &rnsenn);
255 +
256 +               sr->opp1_nvalue =
257 +                               ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
258 +                               (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
259 +                               (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
260 +                               (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
261 +
262 +               sr_clk_enable(sr);
263 +               sr_write_reg(sr, NVALUERECIPROCAL, sr->opp3_nvalue);
264 +               sr_clk_disable(sr);
265 +
266 +#endif
267 +       } else if (sr->srid == SR2) {
268 +#ifdef USE_EFUSE_VALUES
269 +               /* Read values for VDD2 from EFUSE */
270 +#else
271 +               /* since E-Fuse Values are not available, calculating the
272 +                * reciprocal of the SenN and SenP values for SR2
273 +                */
274 +               sr->senp_mod = 0x03;
275 +               sr->senn_mod = 0x03;
276 +
277 +               /* for OPP3 */
278 +               senpval = 0x579 + 0x200;
279 +               sennval = 0x76f + 0x200;
280 +
281 +               cal_reciprocal(senpval, &senpgain, &rnsenp);
282 +               cal_reciprocal(sennval, &senngain, &rnsenn);
283 +
284 +               sr->opp3_nvalue =
285 +                               ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
286 +                               (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
287 +                               (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
288 +                               (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
289 +
290 +               /* for OPP2 */
291 +               senpval = 0x390 + 0x1c0;
292 +               sennval = 0x4f5 + 0x1c0;
293 +
294 +               cal_reciprocal(senpval, &senpgain, &rnsenp);
295 +               cal_reciprocal(sennval, &senngain, &rnsenn);
296 +
297 +               sr->opp2_nvalue =
298 +                               ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
299 +                               (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
300 +                               (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
301 +                               (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
302 +
303 +               /* for OPP1 */
304 +               senpval = 0x25d;
305 +               sennval = 0x359;
306 +
307 +               cal_reciprocal(senpval, &senpgain, &rnsenp);
308 +               cal_reciprocal(sennval, &senngain, &rnsenn);
309 +
310 +               sr->opp1_nvalue =
311 +                               ((senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) |
312 +                               (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) |
313 +                               (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) |
314 +                               (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT));
315 +
316 +#endif
317 +       }
318 +
319 +}
320 +
321 +static void sr_configure_vp(int srid)
322 +{
323 +       u32 vpconfig;
324 +
325 +       if (srid == SR1) {
326 +               vpconfig = PRM_VP1_CONFIG_ERROROFFSET | PRM_VP1_CONFIG_ERRORGAIN
327 +                       | PRM_VP1_CONFIG_INITVOLTAGE | PRM_VP1_CONFIG_TIMEOUTEN;
328 +
329 +               PRM_VP1_CONFIG = vpconfig;
330 +               PRM_VP1_VSTEPMIN = PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN |
331 +                                               PRM_VP1_VSTEPMIN_VSTEPMIN;
332 +
333 +               PRM_VP1_VSTEPMAX = PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX |
334 +                                               PRM_VP1_VSTEPMAX_VSTEPMAX;
335 +
336 +               PRM_VP1_VLIMITTO = PRM_VP1_VLIMITTO_VDDMAX |
337 +                       PRM_VP1_VLIMITTO_VDDMIN | PRM_VP1_VLIMITTO_TIMEOUT;
338 +
339 +               PRM_VP1_CONFIG |= PRM_VP1_CONFIG_INITVDD;
340 +               PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_INITVDD;
341 +
342 +       } else if (srid == SR2) {
343 +               vpconfig = PRM_VP2_CONFIG_ERROROFFSET | PRM_VP2_CONFIG_ERRORGAIN
344 +                       | PRM_VP2_CONFIG_INITVOLTAGE | PRM_VP2_CONFIG_TIMEOUTEN;
345 +
346 +               PRM_VP2_CONFIG = vpconfig;
347 +               PRM_VP2_VSTEPMIN = PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN |
348 +                                               PRM_VP2_VSTEPMIN_VSTEPMIN;
349 +
350 +               PRM_VP2_VSTEPMAX = PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX |
351 +                                               PRM_VP2_VSTEPMAX_VSTEPMAX;
352 +
353 +               PRM_VP2_VLIMITTO = PRM_VP2_VLIMITTO_VDDMAX |
354 +                       PRM_VP2_VLIMITTO_VDDMIN | PRM_VP2_VLIMITTO_TIMEOUT;
355 +
356 +               PRM_VP2_CONFIG |= PRM_VP2_CONFIG_INITVDD;
357 +               PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_INITVDD;
358 +
359 +       }
360 +}
361 +
362 +static void sr_configure_vc(void)
363 +{
364 +       PRM_VC_SMPS_SA =
365 +               (R_SRI2C_SLAVE_ADDR << PRM_VC_SMPS_SA1_SHIFT) |
366 +               (R_SRI2C_SLAVE_ADDR << PRM_VC_SMPS_SA0_SHIFT);
367 +
368 +       PRM_VC_SMPS_VOL_RA = (R_VDD2_SR_CONTROL << PRM_VC_SMPS_VOLRA1_SHIFT) |
369 +                               (R_VDD1_SR_CONTROL << PRM_VC_SMPS_VOLRA0_SHIFT);
370 +
371 +       PRM_VC_CMD_VAL_0 = (PRM_VC_CMD_VAL0_ON << PRM_VC_CMD_ON_SHIFT) |
372 +                       (PRM_VC_CMD_VAL0_ONLP << PRM_VC_CMD_ONLP_SHIFT) |
373 +                       (PRM_VC_CMD_VAL0_RET << PRM_VC_CMD_RET_SHIFT) |
374 +                       (PRM_VC_CMD_VAL0_OFF << PRM_VC_CMD_OFF_SHIFT);
375 +
376 +       PRM_VC_CMD_VAL_1 = (PRM_VC_CMD_VAL1_ON << PRM_VC_CMD_ON_SHIFT) |
377 +                       (PRM_VC_CMD_VAL1_ONLP << PRM_VC_CMD_ONLP_SHIFT) |
378 +                       (PRM_VC_CMD_VAL1_RET << PRM_VC_CMD_RET_SHIFT) |
379 +                       (PRM_VC_CMD_VAL1_OFF << PRM_VC_CMD_OFF_SHIFT);
380 +
381 +       PRM_VC_CH_CONF = PRM_VC_CH_CONF_CMD1 | PRM_VC_CH_CONF_RAV1;
382 +
383 +       PRM_VC_I2C_CFG = PRM_VC_I2C_CFG_MCODE | PRM_VC_I2C_CFG_HSEN
384 +                                                       | PRM_VC_I2C_CFG_SREN;
385 +
386 +       /* Setup voltctrl and other setup times */
387 +#ifdef CONFIG_SYSOFFMODE
388 +       PRM_VOLTCTRL = PRM_VOLTCTRL_AUTO_OFF | PRM_VOLTCTRL_AUTO_RET;
389 +       PRM_CLKSETUP = PRM_CLKSETUP_DURATION;
390 +       PRM_VOLTSETUP1 = (PRM_VOLTSETUP_TIME2 << PRM_VOLTSETUP_TIME2_OFFSET) |
391 +                       (PRM_VOLTSETUP_TIME1 << PRM_VOLTSETUP_TIME1_OFFSET);
392 +       PRM_VOLTOFFSET = PRM_VOLTOFFSET_DURATION;
393 +       PRM_VOLTSETUP2 = PRM_VOLTSETUP2_DURATION;
394 +#else
395 +       PRM_VOLTCTRL |= PRM_VOLTCTRL_AUTO_RET;
396 +#endif
397 +
398 +}
399 +
400 +
401 +static void sr_configure(struct omap_sr *sr)
402 +{
403 +       u32 sys_clk, sr_clk_length = 0;
404 +       u32 sr_config;
405 +       u32 senp_en , senn_en;
406 +
407 +       senp_en = sr->senp_mod;
408 +       senn_en = sr->senn_mod;
409 +
410 +       sys_clk = prcm_get_system_clock_speed();
411 +
412 +       switch (sys_clk) {
413 +       case 12000:
414 +               sr_clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
415 +               break;
416 +       case 13000:
417 +               sr_clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
418 +               break;
419 +       case 19200:
420 +               sr_clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
421 +               break;
422 +       case 26000:
423 +               sr_clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
424 +               break;
425 +       case 38400:
426 +               sr_clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
427 +               break;
428 +       default :
429 +               printk(KERN_ERR "Invalid sysclk value\n");
430 +               break;
431 +       }
432 +
433 +       DPRINTK(KERN_DEBUG "SR : sys clk %lu\n", sys_clk);
434 +       if (sr->srid == SR1) {
435 +               sr_config = SR1_SRCONFIG_ACCUMDATA |
436 +                       (sr_clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
437 +                       SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
438 +                       SRCONFIG_MINMAXAVG_EN |
439 +                       (senn_en << SRCONFIG_SENNENABLE_SHIFT) |
440 +                       (senp_en << SRCONFIG_SENPENABLE_SHIFT) |
441 +                       SRCONFIG_DELAYCTRL;
442 +
443 +               sr_write_reg(sr, SRCONFIG, sr_config);
444 +
445 +               sr_write_reg(sr, AVGWEIGHT, SR1_AVGWEIGHT_SENPAVGWEIGHT |
446 +                                       SR1_AVGWEIGHT_SENNAVGWEIGHT);
447 +
448 +               sr_modify_reg(sr, ERRCONFIG, (SR_ERRWEIGHT_MASK |
449 +                       SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
450 +                       (SR1_ERRWEIGHT | SR1_ERRMAXLIMIT | SR1_ERRMINLIMIT));
451 +
452 +       } else if (sr->srid == SR2) {
453 +               sr_config = SR2_SRCONFIG_ACCUMDATA |
454 +                       (sr_clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
455 +                       SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
456 +                       SRCONFIG_MINMAXAVG_EN |
457 +                       (senn_en << SRCONFIG_SENNENABLE_SHIFT) |
458 +                       (senp_en << SRCONFIG_SENPENABLE_SHIFT) |
459 +                       SRCONFIG_DELAYCTRL;
460 +
461 +               sr_write_reg(sr, SRCONFIG, sr_config);
462 +
463 +               sr_write_reg(sr, AVGWEIGHT, SR2_AVGWEIGHT_SENPAVGWEIGHT |
464 +                                       SR2_AVGWEIGHT_SENNAVGWEIGHT);
465 +
466 +               sr_modify_reg(sr, ERRCONFIG, (SR_ERRWEIGHT_MASK |
467 +                       SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
468 +                       (SR2_ERRWEIGHT | SR2_ERRMAXLIMIT | SR2_ERRMINLIMIT));
469 +
470 +       }
471 +       sr->is_sr_reset = 0;
472 +}
473 +
474 +static void sr_enable(struct omap_sr *sr, u32 target_opp_no)
475 +{
476 +       u32 nvalue_reciprocal, current_nvalue;
477 +
478 +       sr->req_opp_no = target_opp_no;
479 +
480 +       if (sr->srid == SR1) {
481 +               switch (target_opp_no) {
482 +               case 5:
483 +                       nvalue_reciprocal = sr->opp5_nvalue;
484 +                       break;
485 +               case 4:
486 +                       nvalue_reciprocal = sr->opp4_nvalue;
487 +                       break;
488 +               case 3:
489 +                       nvalue_reciprocal = sr->opp3_nvalue;
490 +                       break;
491 +               case 2:
492 +                       nvalue_reciprocal = sr->opp2_nvalue;
493 +                       break;
494 +               case 1:
495 +                       nvalue_reciprocal = sr->opp1_nvalue;
496 +                       break;
497 +               default:
498 +                       nvalue_reciprocal = sr->opp3_nvalue;
499 +                       break;
500 +               }
501 +       } else {
502 +               switch (target_opp_no) {
503 +               case 3:
504 +                       nvalue_reciprocal = sr->opp3_nvalue;
505 +                       break;
506 +               case 2:
507 +                       nvalue_reciprocal = sr->opp2_nvalue;
508 +                       break;
509 +               case 1:
510 +                       nvalue_reciprocal = sr->opp1_nvalue;
511 +                       break;
512 +               default:
513 +                       nvalue_reciprocal = sr->opp3_nvalue;
514 +                       break;
515 +               }
516 +       }
517 +
518 +       current_nvalue = sr_read_reg(sr, NVALUERECIPROCAL);
519 +
520 +       if (current_nvalue == nvalue_reciprocal) {
521 +               DPRINTK("System is already at the desired voltage level\n");
522 +               return;
523 +       }
524 +
525 +       sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
526 +
527 +       /* Enable the interrupt */
528 +       sr_modify_reg(sr, ERRCONFIG,
529 +                       (ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST),
530 +                       (ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
531 +
532 +       if (sr->srid == SR1) {
533 +               /* Enable VP1 */
534 +               PRM_VP1_CONFIG |= PRM_VP1_CONFIG_VPENABLE;
535 +       } else if (sr->srid == SR2) {
536 +               /* Enable VP2 */
537 +               PRM_VP2_CONFIG |= PRM_VP2_CONFIG_VPENABLE;
538 +       }
539 +
540 +       /* SRCONFIG - enable SR */
541 +       sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
542 +
543 +}
544 +
545 +static void sr_disable(struct omap_sr *sr)
546 +{
547 +       sr->is_sr_reset = 1;
548 +
549 +       /* SRCONFIG - disable SR */
550 +       sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, ~SRCONFIG_SRENABLE);
551 +
552 +       if (sr->srid == SR1) {
553 +               /* Enable VP1 */
554 +               PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_VPENABLE;
555 +       } else if (sr->srid == SR2) {
556 +               /* Enable VP2 */
557 +               PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_VPENABLE;
558 +       }
559 +}
560 +
561 +
562 +void sr_start_vddautocomap(int srid, u32 target_opp_no)
563 +{
564 +       struct omap_sr *sr = NULL;
565 +
566 +       if (srid == SR1)
567 +               sr = &sr1;
568 +       else if (srid == SR2)
569 +               sr = &sr2;
570 +
571 +       if (sr->is_sr_reset == 1) {
572 +               sr_clk_enable(sr);
573 +               sr_configure(sr);
574 +       }
575 +
576 +       if (sr->is_autocomp_active == 1)
577 +               DPRINTK(KERN_WARNING "SR%d: VDD autocomp is already active\n",
578 +                                                                       srid);
579 +
580 +       sr->is_autocomp_active = 1;
581 +       sr_enable(sr, target_opp_no);
582 +}
583 +EXPORT_SYMBOL(sr_start_vddautocomap);
584 +
585 +int sr_stop_vddautocomap(int srid)
586 +{
587 +       struct omap_sr *sr = NULL;
588 +
589 +       if (srid == SR1)
590 +               sr = &sr1;
591 +       else if (srid == SR2)
592 +               sr = &sr2;
593 +
594 +       if (sr->is_autocomp_active == 1) {
595 +               sr_disable(sr);
596 +               sr_clk_disable(sr);
597 +               sr->is_autocomp_active = 0;
598 +               return SR_TRUE;
599 +       } else {
600 +               DPRINTK(KERN_WARNING "SR%d: VDD autocomp is not active\n",
601 +                                                               srid);
602 +               return SR_FALSE;
603 +       }
604 +
605 +}
606 +EXPORT_SYMBOL(sr_stop_vddautocomap);
607 +
608 +void enable_smartreflex(int srid)
609 +{
610 +       u32 target_opp_no = 0;
611 +       struct omap_sr *sr = NULL;
612 +
613 +       if (srid == SR1)
614 +               sr = &sr1;
615 +       else if (srid == SR2)
616 +               sr = &sr2;
617 +
618 +       if (sr->is_autocomp_active == 1) {
619 +               if (sr->is_sr_reset == 1) {
620 +                       if (srid == SR1) {
621 +                               /* Enable SR clks */
622 +                               CM_FCLKEN_WKUP |= SR1_CLK_ENABLE;
623 +                               target_opp_no = get_opp_no(current_vdd1_opp);
624 +
625 +                       } else if (srid == SR2) {
626 +                               /* Enable SR clks */
627 +                               CM_FCLKEN_WKUP |= SR2_CLK_ENABLE;
628 +                               target_opp_no = get_opp_no(current_vdd2_opp);
629 +                       }
630 +
631 +                       sr_configure(sr);
632 +
633 +                       sr_enable(sr, target_opp_no);
634 +               }
635 +       }
636 +}
637 +
638 +void disable_smartreflex(int srid)
639 +{
640 +       struct omap_sr *sr = NULL;
641 +
642 +       if (srid == SR1)
643 +               sr = &sr1;
644 +       else if (srid == SR2)
645 +               sr = &sr2;
646 +
647 +       if (sr->is_autocomp_active == 1) {
648 +               if (srid == SR1) {
649 +                       /* Enable SR clk */
650 +                       CM_FCLKEN_WKUP |= SR1_CLK_ENABLE;
651 +
652 +               } else if (srid == SR2) {
653 +                       /* Enable SR clk */
654 +                       CM_FCLKEN_WKUP |= SR2_CLK_ENABLE;
655 +               }
656 +
657 +               if (sr->is_sr_reset == 0) {
658 +
659 +                       sr->is_sr_reset = 1;
660 +                       /* SRCONFIG - disable SR */
661 +                       sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE,
662 +                                                       ~SRCONFIG_SRENABLE);
663 +
664 +                       if (sr->srid == SR1) {
665 +                               /* Disable SR clk */
666 +                               CM_FCLKEN_WKUP &= ~SR1_CLK_ENABLE;
667 +                               /* Enable VP1 */
668 +                               PRM_VP1_CONFIG &= ~PRM_VP1_CONFIG_VPENABLE;
669 +
670 +                       } else if (sr->srid == SR2) {
671 +                               /* Disable SR clk */
672 +                               CM_FCLKEN_WKUP &= ~SR2_CLK_ENABLE;
673 +                               /* Enable VP2 */
674 +                               PRM_VP2_CONFIG &= ~PRM_VP2_CONFIG_VPENABLE;
675 +                       }
676 +               }
677 +       }
678 +}
679 +
680 +
681 +/* Voltage Scaling using SR VCBYPASS */
682 +int sr_voltagescale_vcbypass(u32 target_opp, u8 vsel)
683 +{
684 +       int ret;
685 +       int sr_status = 0;
686 +       u32 vdd, target_opp_no;
687 +       u32 vc_bypass_value;
688 +       u32 reg_addr = 0;
689 +       u32 loop_cnt = 0, retries_cnt = 0;
690 +
691 +       vdd = get_vdd(target_opp);
692 +       target_opp_no = get_opp_no(target_opp);
693 +
694 +       if (vdd == PRCM_VDD1) {
695 +               sr_status = sr_stop_vddautocomap(SR1);
696 +
697 +               PRM_VC_CMD_VAL_0 = (PRM_VC_CMD_VAL_0 & ~PRM_VC_CMD_ON_MASK) |
698 +                                               (vsel << PRM_VC_CMD_ON_SHIFT);
699 +               reg_addr = R_VDD1_SR_CONTROL;
700 +
701 +       } else if (vdd == PRCM_VDD2) {
702 +               sr_status = sr_stop_vddautocomap(SR2);
703 +
704 +               PRM_VC_CMD_VAL_1 = (PRM_VC_CMD_VAL_1 & ~PRM_VC_CMD_ON_MASK) |
705 +                                               (vsel << PRM_VC_CMD_ON_SHIFT);
706 +               reg_addr = R_VDD2_SR_CONTROL;
707 +       }
708 +
709 +       vc_bypass_value = (vsel << PRM_VC_BYPASS_DATA_SHIFT) |
710 +                       (reg_addr << PRM_VC_BYPASS_REGADDR_SHIFT) |
711 +                       (R_SRI2C_SLAVE_ADDR << PRM_VC_BYPASS_SLAVEADDR_SHIFT);
712 +
713 +       PRM_VC_BYPASS_VAL = vc_bypass_value;
714 +
715 +       PRM_VC_BYPASS_VAL |= PRM_VC_BYPASS_VALID;
716 +
717 +       DPRINTK("%s : PRM_VC_BYPASS_VAL %X\n", __func__, PRM_VC_BYPASS_VAL);
718 +       DPRINTK("PRM_IRQST_MPU %X\n", PRM_IRQSTATUS_MPU);
719 +
720 +       while ((PRM_VC_BYPASS_VAL & PRM_VC_BYPASS_VALID) != 0x0) {
721 +               ret = loop_wait(&loop_cnt, &retries_cnt, 10);
722 +               if (ret != PRCM_PASS) {
723 +                       printk(KERN_INFO "Loop count exceeded in check SR I2C"
724 +                                                               "write\n");
725 +                       return ret;
726 +               }
727 +       }
728 +
729 +       omap_udelay(T2_SMPS_UPDATE_DELAY);
730 +
731 +       if (sr_status) {
732 +               if (vdd == PRCM_VDD1)
733 +                       sr_start_vddautocomap(SR1, target_opp_no);
734 +               else if (vdd == PRCM_VDD2)
735 +                       sr_start_vddautocomap(SR2, target_opp_no);
736 +       }
737 +
738 +       return SR_PASS;
739 +}
740 +
741 +/* Sysfs interface to select SR VDD1 auto compensation */
742 +static ssize_t omap_sr_vdd1_autocomp_show(struct kset *subsys, char *buf)
743 +{
744 +       return sprintf(buf, "%d\n", sr1.is_autocomp_active);
745 +}
746 +
747 +static ssize_t omap_sr_vdd1_autocomp_store(struct kset *subsys,
748 +                               const char *buf, size_t n)
749 +{
750 +       u32 current_vdd1opp_no;
751 +       unsigned short value;
752 +
753 +       if (sscanf(buf, "%hu", &value) != 1 || (value > 1)) {
754 +               printk(KERN_ERR "sr_vdd1_autocomp: Invalid value\n");
755 +               return -EINVAL;
756 +       }
757 +
758 +       current_vdd1opp_no = get_opp_no(current_vdd1_opp);
759 +
760 +       if (value == 0)
761 +               sr_stop_vddautocomap(SR1);
762 +       else
763 +               sr_start_vddautocomap(SR1, current_vdd1opp_no);
764 +
765 +       return n;
766 +}
767 +
768 +static struct subsys_attribute sr_vdd1_autocomp = {
769 +       .attr = {
770 +       .name = __stringify(sr_vdd1_autocomp),
771 +       .mode = 0644,
772 +       },
773 +       .show = omap_sr_vdd1_autocomp_show,
774 +       .store = omap_sr_vdd1_autocomp_store,
775 +};
776 +
777 +/* Sysfs interface to select SR VDD2 auto compensation */
778 +static ssize_t omap_sr_vdd2_autocomp_show(struct kset *subsys, char *buf)
779 +{
780 +       return sprintf(buf, "%d\n", sr2.is_autocomp_active);
781 +}
782 +
783 +static ssize_t omap_sr_vdd2_autocomp_store(struct kset *subsys,
784 +                               const char *buf, size_t n)
785 +{
786 +       u32 current_vdd2opp_no;
787 +       unsigned short value;
788 +
789 +       if (sscanf(buf, "%hu", &value) != 1 || (value > 1)) {
790 +               printk(KERN_ERR "sr_vdd2_autocomp: Invalid value\n");
791 +               return -EINVAL;
792 +       }
793 +
794 +       current_vdd2opp_no = get_opp_no(current_vdd2_opp);
795 +
796 +       if (value == 0)
797 +               sr_stop_vddautocomap(SR2);
798 +       else
799 +               sr_start_vddautocomap(SR2, current_vdd2opp_no);
800 +
801 +       return n;
802 +}
803 +
804 +static struct subsys_attribute sr_vdd2_autocomp = {
805 +       .attr = {
806 +       .name = __stringify(sr_vdd2_autocomp),
807 +       .mode = 0644,
808 +       },
809 +       .show = omap_sr_vdd2_autocomp_show,
810 +       .store = omap_sr_vdd2_autocomp_store,
811 +};
812 +
813 +
814 +
815 +static int __init omap3_sr_init(void)
816 +{
817 +       int ret = 0;
818 +       u8 RdReg;
819 +
820 +#ifdef CONFIG_ARCH_OMAP34XX
821 +       sr1.fck = clk_get(NULL, "sr1_fck");
822 +       if (IS_ERR(sr1.fck))
823 +               printk(KERN_ERR "Could not get sr1_fck\n");
824 +
825 +       sr2.fck = clk_get(NULL, "sr2_fck");
826 +       if (IS_ERR(sr2.fck))
827 +               printk(KERN_ERR "Could not get sr2_fck\n");
828 +#endif /* #ifdef CONFIG_ARCH_OMAP34XX */
829 +
830 +       /* Call the VPConfig, VCConfig, set N Values. */
831 +       sr_set_nvalues(&sr1);
832 +       sr_configure_vp(SR1);
833 +
834 +       sr_set_nvalues(&sr2);
835 +       sr_configure_vp(SR2);
836 +
837 +       sr_configure_vc();
838 +
839 +       /* Enable SR on T2 */
840 +       ret = t2_in(PM_RECEIVER, &RdReg, R_DCDC_GLOBAL_CFG);
841 +       RdReg |= DCDC_GLOBAL_CFG_ENABLE_SRFLX;
842 +       ret |= t2_out(PM_RECEIVER, RdReg, R_DCDC_GLOBAL_CFG);
843 +
844 +
845 +       printk(KERN_INFO "SmartReflex driver initialized\n");
846 +
847 +       ret = subsys_create_file(&power_subsys, &sr_vdd1_autocomp);
848 +       if (ret)
849 +               printk(KERN_ERR "subsys_create_file failed: %d\n", ret);
850 +
851 +       ret = subsys_create_file(&power_subsys, &sr_vdd2_autocomp);
852 +       if (ret)
853 +               printk(KERN_ERR "subsys_create_file failed: %d\n", ret);
854 +
855 +       return 0;
856 +}
857 +
858 +arch_initcall(omap3_sr_init);
859 diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
860 new file mode 100644
861 index 0000000..62907ef
862 --- /dev/null
863 +++ b/arch/arm/mach-omap2/smartreflex.h
864 @@ -0,0 +1,136 @@
865 +/*
866 + * linux/arch/arm/mach-omap3/smartreflex.h
867 + *
868 + * Copyright (C) 2007 Texas Instruments, Inc.
869 + * Lesly A M <x0080970@ti.com>
870 + *
871 + * This program is free software; you can redistribute it and/or modify
872 + * it under the terms of the GNU General Public License version 2 as
873 + * published by the Free Software Foundation.
874 + */
875 +
876 +
877 +/* SR Modules */
878 +#define SR1            1
879 +#define SR2            2
880 +
881 +#define SR_FAIL                1
882 +#define SR_PASS                0
883 +
884 +#define SR_TRUE                1
885 +#define SR_FALSE       0
886 +
887 +#define GAIN_MAXLIMIT  16
888 +#define R_MAXLIMIT     256
889 +
890 +#define SR1_CLK_ENABLE (0x1 << 6)
891 +#define SR2_CLK_ENABLE (0x1 << 7)
892 +
893 +/* PRM_VP1_CONFIG */
894 +#define PRM_VP1_CONFIG_ERROROFFSET     (0x00 << 24)
895 +#define PRM_VP1_CONFIG_ERRORGAIN       (0x20 << 16)
896 +
897 +#define PRM_VP1_CONFIG_INITVOLTAGE     (0x30 << 8) /* 1.2 volt */
898 +#define PRM_VP1_CONFIG_TIMEOUTEN       (0x1 << 3)
899 +#define PRM_VP1_CONFIG_INITVDD         (0x1 << 2)
900 +#define PRM_VP1_CONFIG_FORCEUPDATE     (0x1 << 1)
901 +#define PRM_VP1_CONFIG_VPENABLE                (0x1 << 0)
902 +
903 +/* PRM_VP1_VSTEPMIN */
904 +#define PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN       (0x01F4 << 8)
905 +#define PRM_VP1_VSTEPMIN_VSTEPMIN              (0x01 << 0)
906 +
907 +/* PRM_VP1_VSTEPMAX */
908 +#define PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX       (0x01F4 << 8)
909 +#define PRM_VP1_VSTEPMAX_VSTEPMAX              (0x04 << 0)
910 +
911 +/* PRM_VP1_VLIMITTO */
912 +#define PRM_VP1_VLIMITTO_VDDMAX                (0x3C << 24)
913 +#define PRM_VP1_VLIMITTO_VDDMIN                (0x0 << 16)
914 +#define PRM_VP1_VLIMITTO_TIMEOUT       (0xFFFF << 0)
915 +
916 +/* PRM_VP2_CONFIG */
917 +#define PRM_VP2_CONFIG_ERROROFFSET     (0x00 << 24)
918 +#define PRM_VP2_CONFIG_ERRORGAIN       (0x20 << 16)
919 +
920 +#define PRM_VP2_CONFIG_INITVOLTAGE     (0x30 << 8) /* 1.2 volt */
921 +#define PRM_VP2_CONFIG_TIMEOUTEN       (0x1 << 3)
922 +#define PRM_VP2_CONFIG_INITVDD         (0x1 << 2)
923 +#define PRM_VP2_CONFIG_FORCEUPDATE     (0x1 << 1)
924 +#define PRM_VP2_CONFIG_VPENABLE                (0x1 << 0)
925 +
926 +/* PRM_VP2_VSTEPMIN */
927 +#define PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN       (0x01F4 << 8)
928 +#define PRM_VP2_VSTEPMIN_VSTEPMIN              (0x01 << 0)
929 +
930 +/* PRM_VP2_VSTEPMAX */
931 +#define PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX       (0x01F4 << 8)
932 +#define PRM_VP2_VSTEPMAX_VSTEPMAX              (0x04 << 0)
933 +
934 +/* PRM_VP2_VLIMITTO */
935 +#define PRM_VP2_VLIMITTO_VDDMAX                (0x2C << 24)
936 +#define PRM_VP2_VLIMITTO_VDDMIN                (0x0 << 16)
937 +#define PRM_VP2_VLIMITTO_TIMEOUT       (0xFFFF << 0)
938 +
939 +/* SRCONFIG */
940 +#define SR1_SRCONFIG_ACCUMDATA         (0x1F4 << 22)
941 +#define SR2_SRCONFIG_ACCUMDATA         (0x1F4 << 22)
942 +
943 +#define SRCLKLENGTH_12MHZ_SYSCLK       0x3C
944 +#define SRCLKLENGTH_13MHZ_SYSCLK       0x41
945 +#define SRCLKLENGTH_19MHZ_SYSCLK       0x60
946 +#define SRCLKLENGTH_26MHZ_SYSCLK       0x82
947 +#define SRCLKLENGTH_38MHZ_SYSCLK       0xC0
948 +
949 +#define SRCONFIG_SRCLKLENGTH_SHIFT     12
950 +#define SRCONFIG_SENNENABLE_SHIFT      5
951 +#define SRCONFIG_SENPENABLE_SHIFT      3
952 +
953 +#define SRCONFIG_SRENABLE              (0x01 << 11)
954 +#define SRCONFIG_SENENABLE             (0x01 << 10)
955 +#define SRCONFIG_ERRGEN_EN             (0x01 << 9)
956 +#define SRCONFIG_MINMAXAVG_EN          (0x01 << 8)
957 +
958 +#define SRCONFIG_DELAYCTRL             (0x01 << 2)
959 +#define SRCONFIG_CLKCTRL               (0x00 << 0)
960 +
961 +/* AVGWEIGHT */
962 +#define SR1_AVGWEIGHT_SENPAVGWEIGHT    (0x03 << 2)
963 +#define SR1_AVGWEIGHT_SENNAVGWEIGHT    (0x03 << 0)
964 +
965 +#define SR2_AVGWEIGHT_SENPAVGWEIGHT    (0x01 << 2)
966 +#define SR2_AVGWEIGHT_SENNAVGWEIGHT    (0x01 << 0)
967 +
968 +/* NVALUERECIPROCAL */
969 +#define NVALUERECIPROCAL_SENPGAIN_SHIFT        20
970 +#define NVALUERECIPROCAL_SENNGAIN_SHIFT        16
971 +#define NVALUERECIPROCAL_RNSENP_SHIFT  8
972 +#define NVALUERECIPROCAL_RNSENN_SHIFT  0
973 +
974 +/* ERRCONFIG */
975 +#define SR_CLKACTIVITY_MASK            (0x03 << 20)
976 +#define SR_ERRWEIGHT_MASK              (0x07 << 16)
977 +#define SR_ERRMAXLIMIT_MASK            (0xFF << 8)
978 +#define SR_ERRMINLIMIT_MASK            (0xFF << 0)
979 +
980 +#define SR_CLKACTIVITY_IOFF_FOFF       (0x00 << 20)
981 +#define SR_CLKACTIVITY_IOFF_FON                (0x02 << 20)
982 +
983 +#define ERRCONFIG_VPBOUNDINTEN         (0x1 << 31)
984 +#define ERRCONFIG_VPBOUNDINTST         (0x1 << 30)
985 +
986 +#define SR1_ERRWEIGHT                  (0x07 << 16)
987 +#define SR1_ERRMAXLIMIT                        (0x02 << 8)
988 +#define SR1_ERRMINLIMIT                        (0xFA << 0)
989 +
990 +#define SR2_ERRWEIGHT                  (0x07 << 16)
991 +#define SR2_ERRMAXLIMIT                        (0x02 << 8)
992 +#define SR2_ERRMINLIMIT                        (0xF9 << 0)
993 +
994 +extern u32 current_vdd1_opp;
995 +extern u32 current_vdd2_opp;
996 +extern struct kset power_subsys;
997 +
998 +extern inline int loop_wait(u32 *lcnt, u32 *rcnt, u32 delay);
999 +extern void omap_udelay(u32 udelay);
1000 +
1001 -- 
1002 1.5.4.3