2 * linux/arch/arm/mach-omap3/smartreflex.c
4 * OMAP34XX SmartReflex Voltage Control
6 * Copyright (C) 2008 Nokia Corporation
9 * Copyright (C) 2007 Texas Instruments, Inc.
10 * Lesly A M <x0080970@ti.com>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
18 #include <linux/kernel.h>
19 #include <linux/init.h>
20 #include <linux/interrupt.h>
21 #include <linux/module.h>
22 #include <linux/delay.h>
23 #include <linux/err.h>
24 #include <linux/clk.h>
25 #include <linux/sysfs.h>
26 #include <linux/kobject.h>
27 #include <linux/i2c/twl4030.h>
30 #include <plat/omap34xx.h>
31 #include <plat/control.h>
32 #include <plat/clock.h>
33 #include <plat/omap-pm.h>
36 #include "smartreflex.h"
37 #include "prm-regbits-34xx.h"
42 int is_autocomp_active
;
46 u32 opp1_nvalue
, opp2_nvalue
, opp3_nvalue
, opp4_nvalue
;
48 u32 senp_mod
, senn_mod
;
49 void __iomem
*srbase_addr
;
50 void __iomem
*vpbase_addr
;
53 #define SR_REGADDR(offs) (sr->srbase_addr + offset)
55 static inline void sr_write_reg(struct omap_sr
*sr
, unsigned offset
, u32 value
)
57 __raw_writel(value
, SR_REGADDR(offset
));
60 static inline void sr_modify_reg(struct omap_sr
*sr
, unsigned offset
, u32 mask
,
65 reg_val
= __raw_readl(SR_REGADDR(offset
));
69 __raw_writel(reg_val
, SR_REGADDR(offset
));
72 static inline u32
sr_read_reg(struct omap_sr
*sr
, unsigned offset
)
74 return __raw_readl(SR_REGADDR(offset
));
77 static int sr_clk_enable(struct omap_sr
*sr
)
79 if (clk_enable(sr
->clk
) != 0) {
80 pr_err("Could not enable %s\n", sr
->clk
->name
);
84 /* set fclk- active , iclk- idle */
85 sr_modify_reg(sr
, ERRCONFIG
, SR_CLKACTIVITY_MASK
,
86 SR_CLKACTIVITY_IOFF_FON
);
91 static void sr_clk_disable(struct omap_sr
*sr
)
93 /* set fclk, iclk- idle */
94 sr_modify_reg(sr
, ERRCONFIG
, SR_CLKACTIVITY_MASK
,
95 SR_CLKACTIVITY_IOFF_FOFF
);
101 static struct omap_sr sr1
= {
104 .is_autocomp_active
= 0,
106 .srbase_addr
= OMAP2_IO_ADDRESS(OMAP34XX_SR1_BASE
),
109 static struct omap_sr sr2
= {
112 .is_autocomp_active
= 0,
114 .srbase_addr
= OMAP2_IO_ADDRESS(OMAP34XX_SR2_BASE
),
117 static void cal_reciprocal(u32 sensor
, u32
*sengain
, u32
*rnsen
)
121 for (gn
= 0; gn
< GAIN_MAXLIMIT
; gn
++) {
124 if (rn
< R_MAXLIMIT
) {
131 static u32
cal_test_nvalue(u32 sennval
, u32 senpval
)
133 u32 senpgain
, senngain
;
136 /* Calculating the gain and reciprocal of the SenN and SenP values */
137 cal_reciprocal(senpval
, &senpgain
, &rnsenp
);
138 cal_reciprocal(sennval
, &senngain
, &rnsenn
);
140 return (senpgain
<< NVALUERECIPROCAL_SENPGAIN_SHIFT
) |
141 (senngain
<< NVALUERECIPROCAL_SENNGAIN_SHIFT
) |
142 (rnsenp
<< NVALUERECIPROCAL_RNSENP_SHIFT
) |
143 (rnsenn
<< NVALUERECIPROCAL_RNSENN_SHIFT
);
146 /* determine the current OPP from the frequency
147 * we need to give this function last element of OPP rate table
150 static u16
get_opp(struct omap_opp
*opp_freq_table
,
153 struct omap_opp
*prcm_config
;
155 prcm_config
= opp_freq_table
;
157 if (prcm_config
->rate
<= freq
)
158 return prcm_config
->opp_id
; /* Return the Highest OPP */
159 for (; prcm_config
->rate
; prcm_config
--)
160 if (prcm_config
->rate
< freq
)
161 return (prcm_config
+1)->opp_id
;
162 else if (prcm_config
->rate
== freq
)
163 return prcm_config
->opp_id
;
164 /* Return the least OPP */
165 return (prcm_config
+1)->opp_id
;
168 static u16
get_vdd1_opp(void)
173 clk
= clk_get(NULL
, "dpll1_ck");
175 if (clk
== NULL
|| IS_ERR(clk
) || mpu_opps
== NULL
)
178 opp
= get_opp(mpu_opps
+ MAX_VDD1_OPP
, clk
->rate
);
182 static u16
get_vdd2_opp(void)
187 clk
= clk_get(NULL
, "dpll3_m2_ck");
189 if (clk
== NULL
|| IS_ERR(clk
) || l3_opps
== NULL
)
192 opp
= get_opp(l3_opps
+ MAX_VDD2_OPP
, clk
->rate
);
197 static void sr_set_clk_length(struct omap_sr
*sr
)
202 sys_ck
= clk_get(NULL
, "sys_ck");
203 sys_clk_speed
= clk_get_rate(sys_ck
);
206 switch (sys_clk_speed
) {
208 sr
->clk_length
= SRCLKLENGTH_12MHZ_SYSCLK
;
211 sr
->clk_length
= SRCLKLENGTH_13MHZ_SYSCLK
;
214 sr
->clk_length
= SRCLKLENGTH_19MHZ_SYSCLK
;
217 sr
->clk_length
= SRCLKLENGTH_26MHZ_SYSCLK
;
220 sr
->clk_length
= SRCLKLENGTH_38MHZ_SYSCLK
;
223 pr_err("Invalid sysclk value: %d\n", sys_clk_speed
);
228 static void sr_set_efuse_nvalues(struct omap_sr
*sr
)
230 if (sr
->srid
== SR1
) {
231 sr
->senn_mod
= (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR
) &
232 OMAP343X_SR1_SENNENABLE_MASK
) >>
233 OMAP343X_SR1_SENNENABLE_SHIFT
;
234 sr
->senp_mod
= (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR
) &
235 OMAP343X_SR1_SENPENABLE_MASK
) >>
236 OMAP343X_SR1_SENPENABLE_SHIFT
;
238 sr
->opp5_nvalue
= omap_ctrl_readl(
239 OMAP343X_CONTROL_FUSE_OPP5_VDD1
);
240 sr
->opp4_nvalue
= omap_ctrl_readl(
241 OMAP343X_CONTROL_FUSE_OPP4_VDD1
);
242 sr
->opp3_nvalue
= omap_ctrl_readl(
243 OMAP343X_CONTROL_FUSE_OPP3_VDD1
);
244 sr
->opp2_nvalue
= omap_ctrl_readl(
245 OMAP343X_CONTROL_FUSE_OPP2_VDD1
);
246 sr
->opp1_nvalue
= omap_ctrl_readl(
247 OMAP343X_CONTROL_FUSE_OPP1_VDD1
);
248 } else if (sr
->srid
== SR2
) {
249 sr
->senn_mod
= (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR
) &
250 OMAP343X_SR2_SENNENABLE_MASK
) >>
251 OMAP343X_SR2_SENNENABLE_SHIFT
;
253 sr
->senp_mod
= (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR
) &
254 OMAP343X_SR2_SENPENABLE_MASK
) >>
255 OMAP343X_SR2_SENPENABLE_SHIFT
;
257 sr
->opp3_nvalue
= omap_ctrl_readl(
258 OMAP343X_CONTROL_FUSE_OPP3_VDD2
);
259 sr
->opp2_nvalue
= omap_ctrl_readl(
260 OMAP343X_CONTROL_FUSE_OPP2_VDD2
);
261 sr
->opp1_nvalue
= omap_ctrl_readl(
262 OMAP343X_CONTROL_FUSE_OPP1_VDD2
);
266 /* Hard coded nvalues for testing purposes, may cause device to hang! */
267 static void sr_set_testing_nvalues(struct omap_sr
*sr
)
269 if (sr
->srid
== SR1
) {
270 sr
->senp_mod
= 0x03; /* SenN-M5 enabled */
273 /* calculate nvalues for each opp */
274 sr
->opp5_nvalue
= cal_test_nvalue(0xacd + 0x330, 0x848 + 0x330);
275 sr
->opp4_nvalue
= cal_test_nvalue(0x964 + 0x2a0, 0x727 + 0x2a0);
276 sr
->opp3_nvalue
= cal_test_nvalue(0x85b + 0x200, 0x655 + 0x200);
277 sr
->opp2_nvalue
= cal_test_nvalue(0x506 + 0x1a0, 0x3be + 0x1a0);
278 sr
->opp1_nvalue
= cal_test_nvalue(0x373 + 0x100, 0x28c + 0x100);
279 } else if (sr
->srid
== SR2
) {
283 sr
->opp3_nvalue
= cal_test_nvalue(0x76f + 0x200, 0x579 + 0x200);
284 sr
->opp2_nvalue
= cal_test_nvalue(0x4f5 + 0x1c0, 0x390 + 0x1c0);
285 sr
->opp1_nvalue
= cal_test_nvalue(0x359, 0x25d);
290 static void sr_set_nvalues(struct omap_sr
*sr
)
292 if (SR_TESTING_NVALUES
)
293 sr_set_testing_nvalues(sr
);
295 sr_set_efuse_nvalues(sr
);
298 static void sr_configure_vp(int srid
)
305 target_opp_no
= get_vdd1_opp();
307 /* Assume Nominal OPP as current OPP unknown */
308 vsel
= mpu_opps
[VDD1_OPP3
].vsel
;
310 vsel
= mpu_opps
[target_opp_no
].vsel
;
312 vpconfig
= PRM_VP1_CONFIG_ERROROFFSET
|
313 PRM_VP1_CONFIG_ERRORGAIN
|
314 PRM_VP1_CONFIG_TIMEOUTEN
|
315 vsel
<< OMAP3430_INITVOLTAGE_SHIFT
;
317 prm_write_mod_reg(vpconfig
, OMAP3430_GR_MOD
,
318 OMAP3_PRM_VP1_CONFIG_OFFSET
);
319 prm_write_mod_reg(PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN
|
320 PRM_VP1_VSTEPMIN_VSTEPMIN
,
322 OMAP3_PRM_VP1_VSTEPMIN_OFFSET
);
324 prm_write_mod_reg(PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX
|
325 PRM_VP1_VSTEPMAX_VSTEPMAX
,
327 OMAP3_PRM_VP1_VSTEPMAX_OFFSET
);
329 prm_write_mod_reg(PRM_VP1_VLIMITTO_VDDMAX
|
330 PRM_VP1_VLIMITTO_VDDMIN
|
331 PRM_VP1_VLIMITTO_TIMEOUT
,
333 OMAP3_PRM_VP1_VLIMITTO_OFFSET
);
335 /* Trigger initVDD value copy to voltage processor */
336 prm_set_mod_reg_bits(PRM_VP1_CONFIG_INITVDD
, OMAP3430_GR_MOD
,
337 OMAP3_PRM_VP1_CONFIG_OFFSET
);
339 /* Clear initVDD copy trigger bit */
340 prm_clear_mod_reg_bits(PRM_VP1_CONFIG_INITVDD
, OMAP3430_GR_MOD
,
341 OMAP3_PRM_VP1_CONFIG_OFFSET
);
343 /* Force update of voltage */
344 prm_set_mod_reg_bits(OMAP3430_FORCEUPDATE
, OMAP3430_GR_MOD
,
345 OMAP3_PRM_VP1_CONFIG_OFFSET
);
346 /* Clear force bit */
347 prm_clear_mod_reg_bits(OMAP3430_FORCEUPDATE
, OMAP3430_GR_MOD
,
348 OMAP3_PRM_VP1_CONFIG_OFFSET
);
350 } else if (srid
== SR2
) {
351 target_opp_no
= get_vdd2_opp();
353 /* Assume Nominal OPP */
354 vsel
= l3_opps
[VDD2_OPP3
].vsel
;
356 vsel
= l3_opps
[target_opp_no
].vsel
;
358 vpconfig
= PRM_VP2_CONFIG_ERROROFFSET
|
359 PRM_VP2_CONFIG_ERRORGAIN
|
360 PRM_VP2_CONFIG_TIMEOUTEN
|
361 vsel
<< OMAP3430_INITVOLTAGE_SHIFT
;
363 prm_write_mod_reg(vpconfig
, OMAP3430_GR_MOD
,
364 OMAP3_PRM_VP2_CONFIG_OFFSET
);
365 prm_write_mod_reg(PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN
|
366 PRM_VP2_VSTEPMIN_VSTEPMIN
,
368 OMAP3_PRM_VP2_VSTEPMIN_OFFSET
);
370 prm_write_mod_reg(PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX
|
371 PRM_VP2_VSTEPMAX_VSTEPMAX
,
373 OMAP3_PRM_VP2_VSTEPMAX_OFFSET
);
375 prm_write_mod_reg(PRM_VP2_VLIMITTO_VDDMAX
|
376 PRM_VP2_VLIMITTO_VDDMIN
|
377 PRM_VP2_VLIMITTO_TIMEOUT
,
379 OMAP3_PRM_VP2_VLIMITTO_OFFSET
);
381 /* Trigger initVDD value copy to voltage processor */
382 prm_set_mod_reg_bits(PRM_VP1_CONFIG_INITVDD
, OMAP3430_GR_MOD
,
383 OMAP3_PRM_VP2_CONFIG_OFFSET
);
385 /* Clear initVDD copy trigger bit */
386 prm_clear_mod_reg_bits(PRM_VP1_CONFIG_INITVDD
, OMAP3430_GR_MOD
,
387 OMAP3_PRM_VP2_CONFIG_OFFSET
);
389 /* Force update of voltage */
390 prm_set_mod_reg_bits(OMAP3430_FORCEUPDATE
, OMAP3430_GR_MOD
,
391 OMAP3_PRM_VP2_CONFIG_OFFSET
);
392 /* Clear force bit */
393 prm_clear_mod_reg_bits(OMAP3430_FORCEUPDATE
, OMAP3430_GR_MOD
,
394 OMAP3_PRM_VP2_CONFIG_OFFSET
);
399 static void sr_configure(struct omap_sr
*sr
)
402 u32 senp_en
, senn_en
;
404 if (sr
->clk_length
== 0)
405 sr_set_clk_length(sr
);
407 senp_en
= sr
->senp_mod
;
408 senn_en
= sr
->senn_mod
;
409 if (sr
->srid
== SR1
) {
410 sr_config
= SR1_SRCONFIG_ACCUMDATA
|
411 (sr
->clk_length
<< SRCONFIG_SRCLKLENGTH_SHIFT
) |
412 SRCONFIG_SENENABLE
| SRCONFIG_ERRGEN_EN
|
413 SRCONFIG_MINMAXAVG_EN
|
414 (senn_en
<< SRCONFIG_SENNENABLE_SHIFT
) |
415 (senp_en
<< SRCONFIG_SENPENABLE_SHIFT
) |
418 sr_write_reg(sr
, SRCONFIG
, sr_config
);
419 sr_write_reg(sr
, AVGWEIGHT
, SR1_AVGWEIGHT_SENPAVGWEIGHT
|
420 SR1_AVGWEIGHT_SENNAVGWEIGHT
);
422 sr_modify_reg(sr
, ERRCONFIG
, (SR_ERRWEIGHT_MASK
|
423 SR_ERRMAXLIMIT_MASK
| SR_ERRMINLIMIT_MASK
),
424 (SR1_ERRWEIGHT
| SR1_ERRMAXLIMIT
| SR1_ERRMINLIMIT
));
426 } else if (sr
->srid
== SR2
) {
427 sr_config
= SR2_SRCONFIG_ACCUMDATA
|
428 (sr
->clk_length
<< SRCONFIG_SRCLKLENGTH_SHIFT
) |
429 SRCONFIG_SENENABLE
| SRCONFIG_ERRGEN_EN
|
430 SRCONFIG_MINMAXAVG_EN
|
431 (senn_en
<< SRCONFIG_SENNENABLE_SHIFT
) |
432 (senp_en
<< SRCONFIG_SENPENABLE_SHIFT
) |
435 sr_write_reg(sr
, SRCONFIG
, sr_config
);
436 sr_write_reg(sr
, AVGWEIGHT
, SR2_AVGWEIGHT_SENPAVGWEIGHT
|
437 SR2_AVGWEIGHT_SENNAVGWEIGHT
);
438 sr_modify_reg(sr
, ERRCONFIG
, (SR_ERRWEIGHT_MASK
|
439 SR_ERRMAXLIMIT_MASK
| SR_ERRMINLIMIT_MASK
),
440 (SR2_ERRWEIGHT
| SR2_ERRMAXLIMIT
| SR2_ERRMINLIMIT
));
446 static int sr_reset_voltage(int srid
)
448 u32 target_opp_no
, vsel
= 0;
450 u32 loop_cnt
= 0, retries_cnt
= 0;
454 target_opp_no
= get_vdd1_opp();
455 if (!target_opp_no
) {
456 pr_info("Current OPP unknown: Cannot reset voltage\n");
459 vsel
= mpu_opps
[target_opp_no
].vsel
;
460 reg_addr
= R_VDD1_SR_CONTROL
;
461 } else if (srid
== SR2
) {
462 target_opp_no
= get_vdd2_opp();
463 if (!target_opp_no
) {
464 pr_info("Current OPP unknown: Cannot reset voltage\n");
467 vsel
= l3_opps
[target_opp_no
].vsel
;
468 reg_addr
= R_VDD2_SR_CONTROL
;
471 vc_bypass_value
= (vsel
<< OMAP3430_DATA_SHIFT
) |
472 (reg_addr
<< OMAP3430_REGADDR_SHIFT
) |
473 (R_SRI2C_SLAVE_ADDR
<< OMAP3430_SLAVEADDR_SHIFT
);
475 prm_write_mod_reg(vc_bypass_value
, OMAP3430_GR_MOD
,
476 OMAP3_PRM_VC_BYPASS_VAL_OFFSET
);
478 vc_bypass_value
= prm_set_mod_reg_bits(OMAP3430_VALID
, OMAP3430_GR_MOD
,
479 OMAP3_PRM_VC_BYPASS_VAL_OFFSET
);
481 while ((vc_bypass_value
& OMAP3430_VALID
) != 0x0) {
483 if (retries_cnt
> 10) {
484 pr_info("Loop count exceeded in check SR I2C"
493 vc_bypass_value
= prm_read_mod_reg(OMAP3430_GR_MOD
,
494 OMAP3_PRM_VC_BYPASS_VAL_OFFSET
);
499 static int sr_enable(struct omap_sr
*sr
, u32 target_opp_no
)
501 u32 nvalue_reciprocal
, v
;
503 if (!(mpu_opps
&& l3_opps
)) {
504 pr_notice("VSEL values not found\n");
508 sr
->req_opp_no
= target_opp_no
;
510 if (sr
->srid
== SR1
) {
511 switch (target_opp_no
) {
513 nvalue_reciprocal
= sr
->opp5_nvalue
;
516 nvalue_reciprocal
= sr
->opp4_nvalue
;
519 nvalue_reciprocal
= sr
->opp3_nvalue
;
522 nvalue_reciprocal
= sr
->opp2_nvalue
;
525 nvalue_reciprocal
= sr
->opp1_nvalue
;
528 nvalue_reciprocal
= sr
->opp3_nvalue
;
532 switch (target_opp_no
) {
534 nvalue_reciprocal
= sr
->opp3_nvalue
;
537 nvalue_reciprocal
= sr
->opp2_nvalue
;
540 nvalue_reciprocal
= sr
->opp1_nvalue
;
543 nvalue_reciprocal
= sr
->opp3_nvalue
;
548 if (nvalue_reciprocal
== 0) {
549 pr_notice("OPP%d doesn't support SmartReflex\n",
554 sr_write_reg(sr
, NVALUERECIPROCAL
, nvalue_reciprocal
);
556 /* Enable the interrupt */
557 sr_modify_reg(sr
, ERRCONFIG
,
558 (ERRCONFIG_VPBOUNDINTEN
| ERRCONFIG_VPBOUNDINTST
),
559 (ERRCONFIG_VPBOUNDINTEN
| ERRCONFIG_VPBOUNDINTST
));
561 if (sr
->srid
== SR1
) {
562 /* set/latch init voltage */
563 v
= prm_read_mod_reg(OMAP3430_GR_MOD
,
564 OMAP3_PRM_VP1_CONFIG_OFFSET
);
565 v
&= ~(OMAP3430_INITVOLTAGE_MASK
| OMAP3430_INITVDD
);
566 v
|= mpu_opps
[target_opp_no
].vsel
<<
567 OMAP3430_INITVOLTAGE_SHIFT
;
568 prm_write_mod_reg(v
, OMAP3430_GR_MOD
,
569 OMAP3_PRM_VP1_CONFIG_OFFSET
);
570 /* write1 to latch */
571 prm_set_mod_reg_bits(OMAP3430_INITVDD
, OMAP3430_GR_MOD
,
572 OMAP3_PRM_VP1_CONFIG_OFFSET
);
574 prm_clear_mod_reg_bits(OMAP3430_INITVDD
, OMAP3430_GR_MOD
,
575 OMAP3_PRM_VP1_CONFIG_OFFSET
);
577 prm_set_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE
, OMAP3430_GR_MOD
,
578 OMAP3_PRM_VP1_CONFIG_OFFSET
);
579 } else if (sr
->srid
== SR2
) {
580 /* set/latch init voltage */
581 v
= prm_read_mod_reg(OMAP3430_GR_MOD
,
582 OMAP3_PRM_VP2_CONFIG_OFFSET
);
583 v
&= ~(OMAP3430_INITVOLTAGE_MASK
| OMAP3430_INITVDD
);
584 v
|= l3_opps
[target_opp_no
].vsel
<<
585 OMAP3430_INITVOLTAGE_SHIFT
;
586 prm_write_mod_reg(v
, OMAP3430_GR_MOD
,
587 OMAP3_PRM_VP2_CONFIG_OFFSET
);
588 /* write1 to latch */
589 prm_set_mod_reg_bits(OMAP3430_INITVDD
, OMAP3430_GR_MOD
,
590 OMAP3_PRM_VP2_CONFIG_OFFSET
);
592 prm_clear_mod_reg_bits(OMAP3430_INITVDD
, OMAP3430_GR_MOD
,
593 OMAP3_PRM_VP2_CONFIG_OFFSET
);
595 prm_set_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE
, OMAP3430_GR_MOD
,
596 OMAP3_PRM_VP2_CONFIG_OFFSET
);
599 /* SRCONFIG - enable SR */
600 sr_modify_reg(sr
, SRCONFIG
, SRCONFIG_SRENABLE
, SRCONFIG_SRENABLE
);
604 static void sr_disable(struct omap_sr
*sr
)
608 /* SRCONFIG - disable SR */
609 sr_modify_reg(sr
, SRCONFIG
, SRCONFIG_SRENABLE
, ~SRCONFIG_SRENABLE
);
611 if (sr
->srid
== SR1
) {
613 prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE
, OMAP3430_GR_MOD
,
614 OMAP3_PRM_VP1_CONFIG_OFFSET
);
615 } else if (sr
->srid
== SR2
) {
617 prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE
, OMAP3430_GR_MOD
,
618 OMAP3_PRM_VP2_CONFIG_OFFSET
);
623 void sr_start_vddautocomap(int srid
, u32 target_opp_no
)
625 struct omap_sr
*sr
= NULL
;
629 else if (srid
== SR2
)
634 if (sr
->is_sr_reset
== 1) {
639 if (sr
->is_autocomp_active
== 1)
640 pr_warning("SR%d: VDD autocomp is already active\n",
643 sr
->is_autocomp_active
= 1;
644 if (!sr_enable(sr
, target_opp_no
)) {
645 pr_warning("SR%d: VDD autocomp not activated\n", srid
);
646 sr
->is_autocomp_active
= 0;
647 if (sr
->is_sr_reset
== 1)
651 EXPORT_SYMBOL(sr_start_vddautocomap
);
653 int sr_stop_vddautocomap(int srid
)
655 struct omap_sr
*sr
= NULL
;
659 else if (srid
== SR2
)
664 if (sr
->is_autocomp_active
== 1) {
667 sr
->is_autocomp_active
= 0;
668 /* Reset the volatage for current OPP */
669 sr_reset_voltage(srid
);
672 pr_warning("SR%d: VDD autocomp is not active\n",
678 EXPORT_SYMBOL(sr_stop_vddautocomap
);
680 void enable_smartreflex(int srid
)
682 u32 target_opp_no
= 0;
683 struct omap_sr
*sr
= NULL
;
687 else if (srid
== SR2
)
692 if (sr
->is_autocomp_active
== 1) {
693 if (sr
->is_sr_reset
== 1) {
698 target_opp_no
= get_vdd1_opp();
699 else if (srid
== SR2
)
700 target_opp_no
= get_vdd2_opp();
702 if (!target_opp_no
) {
703 pr_info("Current OPP unknown \
704 Cannot configure SR\n");
709 if (!sr_enable(sr
, target_opp_no
))
715 void disable_smartreflex(int srid
)
717 struct omap_sr
*sr
= NULL
;
721 else if (srid
== SR2
)
726 if (sr
->is_autocomp_active
== 1) {
727 if (sr
->is_sr_reset
== 0) {
730 /* SRCONFIG - disable SR */
731 sr_modify_reg(sr
, SRCONFIG
, SRCONFIG_SRENABLE
,
736 if (sr
->srid
== SR1
) {
738 prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE
,
740 OMAP3_PRM_VP1_CONFIG_OFFSET
);
741 } else if (sr
->srid
== SR2
) {
743 prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE
,
745 OMAP3_PRM_VP2_CONFIG_OFFSET
);
747 /* Reset the volatage for current OPP */
748 sr_reset_voltage(srid
);
753 /* Voltage Scaling using SR VCBYPASS */
754 int sr_voltagescale_vcbypass(u32 target_opp
, u8 vsel
)
757 u32 vdd
, target_opp_no
;
760 u32 loop_cnt
= 0, retries_cnt
= 0;
762 vdd
= get_vdd(target_opp
);
763 target_opp_no
= get_opp_no(target_opp
);
765 if (vdd
== VDD1_OPP
) {
766 sr_status
= sr_stop_vddautocomap(SR1
);
768 prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK
,
769 (vsel
<< OMAP3430_VC_CMD_ON_SHIFT
),
771 OMAP3_PRM_VC_CMD_VAL_0_OFFSET
);
772 reg_addr
= R_VDD1_SR_CONTROL
;
774 } else if (vdd
== VDD2_OPP
) {
775 sr_status
= sr_stop_vddautocomap(SR2
);
777 prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK
,
778 (vsel
<< OMAP3430_VC_CMD_ON_SHIFT
),
780 OMAP3_PRM_VC_CMD_VAL_1_OFFSET
);
781 reg_addr
= R_VDD2_SR_CONTROL
;
784 vc_bypass_value
= (vsel
<< OMAP3430_DATA_SHIFT
) |
785 (reg_addr
<< OMAP3430_REGADDR_SHIFT
) |
786 (R_SRI2C_SLAVE_ADDR
<< OMAP3430_SLAVEADDR_SHIFT
);
788 prm_write_mod_reg(vc_bypass_value
, OMAP3430_GR_MOD
,
789 OMAP3_PRM_VC_BYPASS_VAL_OFFSET
);
791 vc_bypass_value
= prm_set_mod_reg_bits(OMAP3430_VALID
, OMAP3430_GR_MOD
,
792 OMAP3_PRM_VC_BYPASS_VAL_OFFSET
);
794 while ((vc_bypass_value
& OMAP3430_VALID
) != 0x0) {
796 if (retries_cnt
> 10) {
797 pr_info("Loop count exceeded in check SR I2C"
806 vc_bypass_value
= prm_read_mod_reg(OMAP3430_GR_MOD
,
807 OMAP3_PRM_VC_BYPASS_VAL_OFFSET
);
810 udelay(T2_SMPS_UPDATE_DELAY
);
814 sr_start_vddautocomap(SR1
, target_opp_no
);
815 else if (vdd
== VDD2_OPP
)
816 sr_start_vddautocomap(SR2
, target_opp_no
);
822 /* Sysfs interface to select SR VDD1 auto compensation */
823 static ssize_t
omap_sr_vdd1_autocomp_show(struct kobject
*kobj
,
824 struct kobj_attribute
*attr
, char *buf
)
826 return sprintf(buf
, "%d\n", sr1
.is_autocomp_active
);
829 static ssize_t
omap_sr_vdd1_autocomp_store(struct kobject
*kobj
,
830 struct kobj_attribute
*attr
,
831 const char *buf
, size_t n
)
833 unsigned short value
;
835 if (sscanf(buf
, "%hu", &value
) != 1 || (value
> 1)) {
836 pr_err("sr_vdd1_autocomp: Invalid value\n");
841 sr_stop_vddautocomap(SR1
);
843 u32 current_vdd1opp_no
= get_vdd1_opp();
844 if (!current_vdd1opp_no
) {
845 pr_err("sr_vdd1_autocomp: Current VDD1 opp unknown\n");
848 sr_start_vddautocomap(SR1
, current_vdd1opp_no
);
853 static struct kobj_attribute sr_vdd1_autocomp
= {
855 .name
= __stringify(sr_vdd1_autocomp
),
858 .show
= omap_sr_vdd1_autocomp_show
,
859 .store
= omap_sr_vdd1_autocomp_store
,
862 /* Sysfs interface to select SR VDD2 auto compensation */
863 static ssize_t
omap_sr_vdd2_autocomp_show(struct kobject
*kobj
,
864 struct kobj_attribute
*attr
, char *buf
)
866 return sprintf(buf
, "%d\n", sr2
.is_autocomp_active
);
869 static ssize_t
omap_sr_vdd2_autocomp_store(struct kobject
*kobj
,
870 struct kobj_attribute
*attr
,
871 const char *buf
, size_t n
)
873 unsigned short value
;
875 if (sscanf(buf
, "%hu", &value
) != 1 || (value
> 1)) {
876 pr_err("sr_vdd2_autocomp: Invalid value\n");
881 sr_stop_vddautocomap(SR2
);
883 u32 current_vdd2opp_no
= get_vdd2_opp();
884 if (!current_vdd2opp_no
) {
885 pr_err("sr_vdd2_autocomp: Current VDD2 opp unknown\n");
888 sr_start_vddautocomap(SR2
, current_vdd2opp_no
);
893 static struct kobj_attribute sr_vdd2_autocomp
= {
895 .name
= __stringify(sr_vdd2_autocomp
),
898 .show
= omap_sr_vdd2_autocomp_show
,
899 .store
= omap_sr_vdd2_autocomp_store
,
904 static int __init
omap3_sr_init(void)
909 /* Exit if OPP tables are not defined */
910 if (!(mpu_opps
&& l3_opps
)) {
911 pr_err("SR: OPP rate tables not defined for platform, not enabling SmartReflex\n");
915 /* Enable SR on T2 */
916 ret
= twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER
, &RdReg
,
919 RdReg
|= DCDC_GLOBAL_CFG_ENABLE_SRFLX
;
920 ret
|= twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER
, RdReg
,
923 if (cpu_is_omap34xx()) {
924 sr1
.clk
= clk_get(NULL
, "sr1_fck");
925 sr2
.clk
= clk_get(NULL
, "sr2_fck");
927 sr_set_clk_length(&sr1
);
928 sr_set_clk_length(&sr2
);
930 /* Call the VPConfig, VCConfig, set N Values. */
931 sr_set_nvalues(&sr1
);
932 sr_configure_vp(SR1
);
934 sr_set_nvalues(&sr2
);
935 sr_configure_vp(SR2
);
937 pr_info("SmartReflex driver initialized\n");
939 ret
= sysfs_create_file(power_kobj
, &sr_vdd1_autocomp
.attr
);
941 pr_err("sysfs_create_file failed: %d\n", ret
);
943 ret
= sysfs_create_file(power_kobj
, &sr_vdd2_autocomp
.attr
);
945 pr_err("sysfs_create_file failed: %d\n", ret
);
950 late_initcall(omap3_sr_init
);