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"
41 #define SWCALC_OPP6_DELTA_NNT 379
42 #define SWCALC_OPP6_DELTA_PNT 227
47 int is_autocomp_active
;
49 struct clk
*vdd_opp_clk
;
52 u32 opp1_nvalue
, opp2_nvalue
, opp3_nvalue
, opp4_nvalue
;
53 u32 opp5_nvalue
, opp6_nvalue
;
54 u32 senp_mod
, senn_mod
;
55 void __iomem
*srbase_addr
;
56 void __iomem
*vpbase_addr
;
59 #define SR_REGADDR(offs) (sr->srbase_addr + offset)
61 static inline void sr_write_reg(struct omap_sr
*sr
, unsigned offset
, u32 value
)
63 __raw_writel(value
, SR_REGADDR(offset
));
66 static inline void sr_modify_reg(struct omap_sr
*sr
, unsigned offset
, u32 mask
,
71 reg_val
= __raw_readl(SR_REGADDR(offset
));
75 __raw_writel(reg_val
, SR_REGADDR(offset
));
78 static inline u32
sr_read_reg(struct omap_sr
*sr
, unsigned offset
)
80 return __raw_readl(SR_REGADDR(offset
));
83 static int sr_clk_enable(struct omap_sr
*sr
)
85 if (clk_enable(sr
->clk
) != 0) {
86 pr_err("Could not enable %s\n", sr
->clk
->name
);
90 /* set fclk- active , iclk- idle */
91 sr_modify_reg(sr
, ERRCONFIG
, SR_CLKACTIVITY_MASK
,
92 SR_CLKACTIVITY_IOFF_FON
);
97 static void sr_clk_disable(struct omap_sr
*sr
)
99 /* set fclk, iclk- idle */
100 sr_modify_reg(sr
, ERRCONFIG
, SR_CLKACTIVITY_MASK
,
101 SR_CLKACTIVITY_IOFF_FOFF
);
103 clk_disable(sr
->clk
);
107 static struct omap_sr sr1
= {
110 .is_autocomp_active
= 0,
112 .srbase_addr
= OMAP2_L4_IO_ADDRESS(OMAP34XX_SR1_BASE
),
115 static struct omap_sr sr2
= {
118 .is_autocomp_active
= 0,
120 .srbase_addr
= OMAP2_L4_IO_ADDRESS(OMAP34XX_SR2_BASE
),
123 static void cal_reciprocal(u32 sensor
, u32
*sengain
, u32
*rnsen
)
127 for (gn
= 0; gn
< GAIN_MAXLIMIT
; gn
++) {
130 if (rn
< R_MAXLIMIT
) {
137 static u32
cal_test_nvalue(u32 sennval
, u32 senpval
)
139 u32 senpgain
, senngain
;
142 /* Calculating the gain and reciprocal of the SenN and SenP values */
143 cal_reciprocal(senpval
, &senpgain
, &rnsenp
);
144 cal_reciprocal(sennval
, &senngain
, &rnsenn
);
146 return (senpgain
<< NVALUERECIPROCAL_SENPGAIN_SHIFT
) |
147 (senngain
<< NVALUERECIPROCAL_SENNGAIN_SHIFT
) |
148 (rnsenp
<< NVALUERECIPROCAL_RNSENP_SHIFT
) |
149 (rnsenn
<< NVALUERECIPROCAL_RNSENN_SHIFT
);
152 /* determine the current OPP from the frequency
153 * we need to give this function last element of OPP rate table
156 static u16
get_opp(struct omap_opp
*opp_freq_table
,
159 struct omap_opp
*prcm_config
;
161 prcm_config
= opp_freq_table
;
163 if (prcm_config
->rate
<= freq
)
164 return prcm_config
->opp_id
; /* Return the Highest OPP */
165 for (; prcm_config
->rate
; prcm_config
--)
166 if (prcm_config
->rate
< freq
)
167 return (prcm_config
+1)->opp_id
;
168 else if (prcm_config
->rate
== freq
)
169 return prcm_config
->opp_id
;
170 /* Return the least OPP */
171 return (prcm_config
+1)->opp_id
;
174 static u16
get_vdd1_opp(void)
178 if (sr1
.vdd_opp_clk
== NULL
|| IS_ERR(sr1
.vdd_opp_clk
) ||
182 opp
= get_opp(mpu_opps
+ MAX_VDD1_OPP
, sr1
.vdd_opp_clk
->rate
);
186 static u16
get_vdd2_opp(void)
190 if (sr2
.vdd_opp_clk
== NULL
|| IS_ERR(sr2
.vdd_opp_clk
) ||
194 opp
= get_opp(l3_opps
+ MAX_VDD2_OPP
, sr2
.vdd_opp_clk
->rate
);
199 static void sr_set_clk_length(struct omap_sr
*sr
)
204 sys_ck
= clk_get(NULL
, "sys_ck");
205 sys_clk_speed
= clk_get_rate(sys_ck
);
208 switch (sys_clk_speed
) {
210 sr
->clk_length
= SRCLKLENGTH_12MHZ_SYSCLK
;
213 sr
->clk_length
= SRCLKLENGTH_13MHZ_SYSCLK
;
216 sr
->clk_length
= SRCLKLENGTH_19MHZ_SYSCLK
;
219 sr
->clk_length
= SRCLKLENGTH_26MHZ_SYSCLK
;
222 sr
->clk_length
= SRCLKLENGTH_38MHZ_SYSCLK
;
225 pr_err("Invalid sysclk value: %d\n", sys_clk_speed
);
230 static void swcalc_opp6_RG(u32 rFuse
, u32 gainFuse
, u32 deltaNT
,
231 u32
* rAdj
, u32
* gainAdj
)
236 nAdj
= ((1 << (gainFuse
+ 8))/rFuse
) + deltaNT
;
238 for (g
= 0; g
< GAIN_MAXLIMIT
; g
++) {
239 r
= (1 << (g
+ 8)) / nAdj
;
247 static u32
swcalc_opp6_nvalue(void)
249 u32 opp5_nvalue
, opp6_nvalue
;
250 u32 opp5_senPgain
, opp5_senNgain
, opp5_senPRN
, opp5_senNRN
;
251 u32 opp6_senPgain
, opp6_senNgain
, opp6_senPRN
, opp6_senNRN
;
253 opp5_nvalue
= omap_ctrl_readl(OMAP343X_CONTROL_FUSE_OPP5_VDD1
);
255 opp5_senPgain
= (opp5_nvalue
& 0x00f00000) >> 0x14;
256 opp5_senNgain
= (opp5_nvalue
& 0x000f0000) >> 0x10;
258 opp5_senPRN
= (opp5_nvalue
& 0x0000ff00) >> 0x8;
259 opp5_senNRN
= (opp5_nvalue
& 0x000000ff);
261 swcalc_opp6_RG(opp5_senNRN
, opp5_senNgain
, SWCALC_OPP6_DELTA_NNT
,
262 &opp6_senNRN
, &opp6_senNgain
);
264 swcalc_opp6_RG(opp5_senPRN
, opp5_senPgain
, SWCALC_OPP6_DELTA_PNT
,
265 &opp6_senPRN
, &opp6_senPgain
);
267 opp6_nvalue
= (opp6_senPgain
<< 0x14) | (opp6_senNgain
< 0x10) |
268 (opp6_senPRN
<< 0x8) | opp6_senNRN
;
273 static void sr_set_efuse_nvalues(struct omap_sr
*sr
)
275 if (sr
->srid
== SR1
) {
276 sr
->senn_mod
= (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR
) &
277 OMAP343X_SR1_SENNENABLE_MASK
) >>
278 OMAP343X_SR1_SENNENABLE_SHIFT
;
279 sr
->senp_mod
= (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR
) &
280 OMAP343X_SR1_SENPENABLE_MASK
) >>
281 OMAP343X_SR1_SENPENABLE_SHIFT
;
283 sr
->opp6_nvalue
= swcalc_opp6_nvalue();
284 sr
->opp5_nvalue
= omap_ctrl_readl(
285 OMAP343X_CONTROL_FUSE_OPP5_VDD1
);
286 sr
->opp4_nvalue
= omap_ctrl_readl(
287 OMAP343X_CONTROL_FUSE_OPP4_VDD1
);
288 sr
->opp3_nvalue
= omap_ctrl_readl(
289 OMAP343X_CONTROL_FUSE_OPP3_VDD1
);
290 sr
->opp2_nvalue
= omap_ctrl_readl(
291 OMAP343X_CONTROL_FUSE_OPP2_VDD1
);
292 sr
->opp1_nvalue
= omap_ctrl_readl(
293 OMAP343X_CONTROL_FUSE_OPP1_VDD1
);
294 } else if (sr
->srid
== SR2
) {
295 sr
->senn_mod
= (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR
) &
296 OMAP343X_SR2_SENNENABLE_MASK
) >>
297 OMAP343X_SR2_SENNENABLE_SHIFT
;
299 sr
->senp_mod
= (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR
) &
300 OMAP343X_SR2_SENPENABLE_MASK
) >>
301 OMAP343X_SR2_SENPENABLE_SHIFT
;
303 sr
->opp3_nvalue
= omap_ctrl_readl(
304 OMAP343X_CONTROL_FUSE_OPP3_VDD2
);
305 sr
->opp2_nvalue
= omap_ctrl_readl(
306 OMAP343X_CONTROL_FUSE_OPP2_VDD2
);
307 sr
->opp1_nvalue
= omap_ctrl_readl(
308 OMAP343X_CONTROL_FUSE_OPP1_VDD2
);
312 /* Hard coded nvalues for testing purposes, may cause device to hang! */
313 static void sr_set_testing_nvalues(struct omap_sr
*sr
)
315 if (sr
->srid
== SR1
) {
316 sr
->senp_mod
= 0x03; /* SenN-M5 enabled */
319 /* calculate nvalues for each opp */
320 sr
->opp5_nvalue
= cal_test_nvalue(0xacd + 0x330, 0x848 + 0x330);
321 sr
->opp4_nvalue
= cal_test_nvalue(0x964 + 0x2a0, 0x727 + 0x2a0);
322 sr
->opp3_nvalue
= cal_test_nvalue(0x85b + 0x200, 0x655 + 0x200);
323 sr
->opp2_nvalue
= cal_test_nvalue(0x506 + 0x1a0, 0x3be + 0x1a0);
324 sr
->opp1_nvalue
= cal_test_nvalue(0x373 + 0x100, 0x28c + 0x100);
325 } else if (sr
->srid
== SR2
) {
329 sr
->opp3_nvalue
= cal_test_nvalue(0x76f + 0x200, 0x579 + 0x200);
330 sr
->opp2_nvalue
= cal_test_nvalue(0x4f5 + 0x1c0, 0x390 + 0x1c0);
331 sr
->opp1_nvalue
= cal_test_nvalue(0x359, 0x25d);
336 static void sr_set_nvalues(struct omap_sr
*sr
)
338 if (SR_TESTING_NVALUES
)
339 sr_set_testing_nvalues(sr
);
341 sr_set_efuse_nvalues(sr
);
344 static void sr_configure_vp(int srid
)
351 target_opp_no
= get_vdd1_opp();
353 /* Assume Nominal OPP as current OPP unknown */
354 vsel
= mpu_opps
[VDD1_OPP3
].vsel
;
356 vsel
= mpu_opps
[target_opp_no
].vsel
;
358 vpconfig
= PRM_VP1_CONFIG_ERROROFFSET
|
359 PRM_VP1_CONFIG_ERRORGAIN
|
360 PRM_VP1_CONFIG_TIMEOUTEN
|
361 vsel
<< OMAP3430_INITVOLTAGE_SHIFT
;
364 * Update the 'ON' voltage levels based on the VSEL.
365 * (See spruf8c.pdf sec 1.5.3.1)
367 prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK
,
368 (vsel
<< OMAP3430_VC_CMD_ON_SHIFT
),
370 OMAP3_PRM_VC_CMD_VAL_0_OFFSET
);
372 prm_write_mod_reg(vpconfig
, OMAP3430_GR_MOD
,
373 OMAP3_PRM_VP1_CONFIG_OFFSET
);
374 prm_write_mod_reg(PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN
|
375 PRM_VP1_VSTEPMIN_VSTEPMIN
,
377 OMAP3_PRM_VP1_VSTEPMIN_OFFSET
);
379 prm_write_mod_reg(PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX
|
380 PRM_VP1_VSTEPMAX_VSTEPMAX
,
382 OMAP3_PRM_VP1_VSTEPMAX_OFFSET
);
384 prm_write_mod_reg(PRM_VP1_VLIMITTO_VDDMAX
|
385 PRM_VP1_VLIMITTO_VDDMIN
|
386 PRM_VP1_VLIMITTO_TIMEOUT
,
388 OMAP3_PRM_VP1_VLIMITTO_OFFSET
);
390 /* Trigger initVDD value copy to voltage processor */
391 prm_set_mod_reg_bits(PRM_VP1_CONFIG_INITVDD
, OMAP3430_GR_MOD
,
392 OMAP3_PRM_VP1_CONFIG_OFFSET
);
394 /* Clear initVDD copy trigger bit */
395 prm_clear_mod_reg_bits(PRM_VP1_CONFIG_INITVDD
, OMAP3430_GR_MOD
,
396 OMAP3_PRM_VP1_CONFIG_OFFSET
);
398 /* Force update of voltage */
399 prm_set_mod_reg_bits(OMAP3430_FORCEUPDATE
, OMAP3430_GR_MOD
,
400 OMAP3_PRM_VP1_CONFIG_OFFSET
);
401 /* Clear force bit */
402 prm_clear_mod_reg_bits(OMAP3430_FORCEUPDATE
, OMAP3430_GR_MOD
,
403 OMAP3_PRM_VP1_CONFIG_OFFSET
);
405 } else if (srid
== SR2
) {
406 target_opp_no
= get_vdd2_opp();
408 /* Assume Nominal OPP */
409 vsel
= l3_opps
[VDD2_OPP3
].vsel
;
411 vsel
= l3_opps
[target_opp_no
].vsel
;
414 * Update the 'ON' voltage levels based on the VSEL.
415 * (See spruf8c.pdf sec 1.5.3.1)
417 prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK
,
418 (vsel
<< OMAP3430_VC_CMD_ON_SHIFT
),
420 OMAP3_PRM_VC_CMD_VAL_1_OFFSET
);
422 vpconfig
= PRM_VP2_CONFIG_ERROROFFSET
|
423 PRM_VP2_CONFIG_ERRORGAIN
|
424 PRM_VP2_CONFIG_TIMEOUTEN
|
425 vsel
<< OMAP3430_INITVOLTAGE_SHIFT
;
427 prm_write_mod_reg(vpconfig
, OMAP3430_GR_MOD
,
428 OMAP3_PRM_VP2_CONFIG_OFFSET
);
429 prm_write_mod_reg(PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN
|
430 PRM_VP2_VSTEPMIN_VSTEPMIN
,
432 OMAP3_PRM_VP2_VSTEPMIN_OFFSET
);
434 prm_write_mod_reg(PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX
|
435 PRM_VP2_VSTEPMAX_VSTEPMAX
,
437 OMAP3_PRM_VP2_VSTEPMAX_OFFSET
);
439 prm_write_mod_reg(PRM_VP2_VLIMITTO_VDDMAX
|
440 PRM_VP2_VLIMITTO_VDDMIN
|
441 PRM_VP2_VLIMITTO_TIMEOUT
,
443 OMAP3_PRM_VP2_VLIMITTO_OFFSET
);
445 /* Trigger initVDD value copy to voltage processor */
446 prm_set_mod_reg_bits(PRM_VP1_CONFIG_INITVDD
, OMAP3430_GR_MOD
,
447 OMAP3_PRM_VP2_CONFIG_OFFSET
);
449 /* Clear initVDD copy trigger bit */
450 prm_clear_mod_reg_bits(PRM_VP1_CONFIG_INITVDD
, OMAP3430_GR_MOD
,
451 OMAP3_PRM_VP2_CONFIG_OFFSET
);
453 /* Force update of voltage */
454 prm_set_mod_reg_bits(OMAP3430_FORCEUPDATE
, OMAP3430_GR_MOD
,
455 OMAP3_PRM_VP2_CONFIG_OFFSET
);
456 /* Clear force bit */
457 prm_clear_mod_reg_bits(OMAP3430_FORCEUPDATE
, OMAP3430_GR_MOD
,
458 OMAP3_PRM_VP2_CONFIG_OFFSET
);
462 static void sr_configure(struct omap_sr
*sr
)
465 u32 senp_en
, senn_en
;
467 if (sr
->clk_length
== 0)
468 sr_set_clk_length(sr
);
470 senp_en
= sr
->senp_mod
;
471 senn_en
= sr
->senn_mod
;
472 if (sr
->srid
== SR1
) {
473 sr_config
= SR1_SRCONFIG_ACCUMDATA
|
474 (sr
->clk_length
<< SRCONFIG_SRCLKLENGTH_SHIFT
) |
475 SRCONFIG_SENENABLE
| SRCONFIG_ERRGEN_EN
|
476 SRCONFIG_MINMAXAVG_EN
|
477 (senn_en
<< SRCONFIG_SENNENABLE_SHIFT
) |
478 (senp_en
<< SRCONFIG_SENPENABLE_SHIFT
) |
481 sr_write_reg(sr
, SRCONFIG
, sr_config
);
482 sr_write_reg(sr
, AVGWEIGHT
, SR1_AVGWEIGHT_SENPAVGWEIGHT
|
483 SR1_AVGWEIGHT_SENNAVGWEIGHT
);
485 sr_modify_reg(sr
, ERRCONFIG
, (SR_ERRWEIGHT_MASK
|
486 SR_ERRMAXLIMIT_MASK
| SR_ERRMINLIMIT_MASK
),
487 (SR1_ERRWEIGHT
| SR1_ERRMAXLIMIT
| SR1_ERRMINLIMIT
));
489 } else if (sr
->srid
== SR2
) {
490 sr_config
= SR2_SRCONFIG_ACCUMDATA
|
491 (sr
->clk_length
<< SRCONFIG_SRCLKLENGTH_SHIFT
) |
492 SRCONFIG_SENENABLE
| SRCONFIG_ERRGEN_EN
|
493 SRCONFIG_MINMAXAVG_EN
|
494 (senn_en
<< SRCONFIG_SENNENABLE_SHIFT
) |
495 (senp_en
<< SRCONFIG_SENPENABLE_SHIFT
) |
498 sr_write_reg(sr
, SRCONFIG
, sr_config
);
499 sr_write_reg(sr
, AVGWEIGHT
, SR2_AVGWEIGHT_SENPAVGWEIGHT
|
500 SR2_AVGWEIGHT_SENNAVGWEIGHT
);
501 sr_modify_reg(sr
, ERRCONFIG
, (SR_ERRWEIGHT_MASK
|
502 SR_ERRMAXLIMIT_MASK
| SR_ERRMINLIMIT_MASK
),
503 (SR2_ERRWEIGHT
| SR2_ERRMAXLIMIT
| SR2_ERRMINLIMIT
));
509 static int sr_reset_voltage(int srid
)
511 u32 target_opp_no
, vsel
= 0;
513 u32 loop_cnt
= 0, retries_cnt
= 0;
515 u32 t2_smps_steps
= 0;
516 u32 t2_smps_delay
= 0;
517 u32 prm_vp1_voltage
, prm_vp2_voltage
;
520 target_opp_no
= get_vdd1_opp();
522 if (!target_opp_no
) {
523 pr_info("Current OPP unknown: Cannot reset voltage\n");
526 vsel
= mpu_opps
[target_opp_no
].vsel
;
527 reg_addr
= R_VDD1_SR_CONTROL
;
528 prm_vp1_voltage
= prm_read_mod_reg(OMAP3430_GR_MOD
,
529 OMAP3_PRM_VP1_VOLTAGE_OFFSET
);
530 t2_smps_steps
= abs(vsel
- prm_vp1_voltage
);
531 } else if (srid
== SR2
) {
532 target_opp_no
= get_vdd2_opp();
533 if (!target_opp_no
) {
534 pr_info("Current OPP unknown: Cannot reset voltage\n");
537 vsel
= l3_opps
[target_opp_no
].vsel
;
538 reg_addr
= R_VDD2_SR_CONTROL
;
539 prm_vp2_voltage
= prm_read_mod_reg(OMAP3430_GR_MOD
,
540 OMAP3_PRM_VP2_VOLTAGE_OFFSET
);
541 t2_smps_steps
= abs(vsel
- prm_vp2_voltage
);
544 vc_bypass_value
= (vsel
<< OMAP3430_DATA_SHIFT
) |
545 (reg_addr
<< OMAP3430_REGADDR_SHIFT
) |
546 (R_SRI2C_SLAVE_ADDR
<< OMAP3430_SLAVEADDR_SHIFT
);
548 prm_write_mod_reg(vc_bypass_value
, OMAP3430_GR_MOD
,
549 OMAP3_PRM_VC_BYPASS_VAL_OFFSET
);
551 vc_bypass_value
= prm_set_mod_reg_bits(OMAP3430_VALID
, OMAP3430_GR_MOD
,
552 OMAP3_PRM_VC_BYPASS_VAL_OFFSET
);
554 while ((vc_bypass_value
& OMAP3430_VALID
) != 0x0) {
556 if (retries_cnt
> 10) {
557 pr_info("Loop count exceeded in check SR I2C"
566 vc_bypass_value
= prm_read_mod_reg(OMAP3430_GR_MOD
,
567 OMAP3_PRM_VC_BYPASS_VAL_OFFSET
);
571 * T2 SMPS slew rate (min) 4mV/uS, step size 12.5mV,
572 * 2us added as buffer.
574 t2_smps_delay
= ((t2_smps_steps
* 125) / 40) + 2;
575 udelay(t2_smps_delay
);
580 static int sr_enable(struct omap_sr
*sr
, u32 target_opp_no
)
582 u32 nvalue_reciprocal
, v
;
584 if (!(mpu_opps
&& l3_opps
)) {
585 pr_notice("VSEL values not found\n");
589 sr
->req_opp_no
= target_opp_no
;
591 if (sr
->srid
== SR1
) {
592 switch (target_opp_no
) {
594 nvalue_reciprocal
= sr
->opp6_nvalue
;
597 nvalue_reciprocal
= sr
->opp5_nvalue
;
600 nvalue_reciprocal
= sr
->opp4_nvalue
;
603 nvalue_reciprocal
= sr
->opp3_nvalue
;
606 nvalue_reciprocal
= sr
->opp2_nvalue
;
609 nvalue_reciprocal
= sr
->opp1_nvalue
;
612 nvalue_reciprocal
= sr
->opp3_nvalue
;
616 switch (target_opp_no
) {
618 nvalue_reciprocal
= sr
->opp3_nvalue
;
621 nvalue_reciprocal
= sr
->opp2_nvalue
;
624 nvalue_reciprocal
= sr
->opp1_nvalue
;
627 nvalue_reciprocal
= sr
->opp3_nvalue
;
632 if (nvalue_reciprocal
== 0) {
633 pr_notice("OPP%d doesn't support SmartReflex\n",
638 sr_write_reg(sr
, NVALUERECIPROCAL
, nvalue_reciprocal
);
640 /* Enable the interrupt */
641 sr_modify_reg(sr
, ERRCONFIG
,
642 (ERRCONFIG_VPBOUNDINTEN
| ERRCONFIG_VPBOUNDINTST
),
643 (ERRCONFIG_VPBOUNDINTEN
| ERRCONFIG_VPBOUNDINTST
));
645 if (sr
->srid
== SR1
) {
646 /* set/latch init voltage */
647 v
= prm_read_mod_reg(OMAP3430_GR_MOD
,
648 OMAP3_PRM_VP1_CONFIG_OFFSET
);
649 v
&= ~(OMAP3430_INITVOLTAGE_MASK
| OMAP3430_INITVDD
);
650 v
|= mpu_opps
[target_opp_no
].vsel
<<
651 OMAP3430_INITVOLTAGE_SHIFT
;
652 prm_write_mod_reg(v
, OMAP3430_GR_MOD
,
653 OMAP3_PRM_VP1_CONFIG_OFFSET
);
654 /* write1 to latch */
655 prm_set_mod_reg_bits(OMAP3430_INITVDD
, OMAP3430_GR_MOD
,
656 OMAP3_PRM_VP1_CONFIG_OFFSET
);
658 prm_clear_mod_reg_bits(OMAP3430_INITVDD
, OMAP3430_GR_MOD
,
659 OMAP3_PRM_VP1_CONFIG_OFFSET
);
661 prm_set_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE
, OMAP3430_GR_MOD
,
662 OMAP3_PRM_VP1_CONFIG_OFFSET
);
663 } else if (sr
->srid
== SR2
) {
664 /* set/latch init voltage */
665 v
= prm_read_mod_reg(OMAP3430_GR_MOD
,
666 OMAP3_PRM_VP2_CONFIG_OFFSET
);
667 v
&= ~(OMAP3430_INITVOLTAGE_MASK
| OMAP3430_INITVDD
);
668 v
|= l3_opps
[target_opp_no
].vsel
<<
669 OMAP3430_INITVOLTAGE_SHIFT
;
670 prm_write_mod_reg(v
, OMAP3430_GR_MOD
,
671 OMAP3_PRM_VP2_CONFIG_OFFSET
);
672 /* write1 to latch */
673 prm_set_mod_reg_bits(OMAP3430_INITVDD
, OMAP3430_GR_MOD
,
674 OMAP3_PRM_VP2_CONFIG_OFFSET
);
676 prm_clear_mod_reg_bits(OMAP3430_INITVDD
, OMAP3430_GR_MOD
,
677 OMAP3_PRM_VP2_CONFIG_OFFSET
);
679 prm_set_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE
, OMAP3430_GR_MOD
,
680 OMAP3_PRM_VP2_CONFIG_OFFSET
);
683 /* SRCONFIG - enable SR */
684 sr_modify_reg(sr
, SRCONFIG
, SRCONFIG_SRENABLE
, SRCONFIG_SRENABLE
);
688 static void sr_disable(struct omap_sr
*sr
)
694 /* SRCONFIG - disable SR */
695 sr_modify_reg(sr
, SRCONFIG
, SRCONFIG_SRENABLE
, ~SRCONFIG_SRENABLE
);
697 if (sr
->srid
== SR1
) {
698 /* Wait for VP idle before disabling VP */
699 while ((!prm_read_mod_reg(OMAP3430_GR_MOD
,
700 OMAP3_PRM_VP1_STATUS_OFFSET
))
705 pr_warning("VP1 not idle, still going ahead with \
709 prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE
, OMAP3430_GR_MOD
,
710 OMAP3_PRM_VP1_CONFIG_OFFSET
);
712 } else if (sr
->srid
== SR2
) {
713 /* Wait for VP idle before disabling VP */
714 while ((!prm_read_mod_reg(OMAP3430_GR_MOD
,
715 OMAP3_PRM_VP2_STATUS_OFFSET
))
720 pr_warning("VP2 not idle, still going ahead with \
724 prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE
, OMAP3430_GR_MOD
,
725 OMAP3_PRM_VP2_CONFIG_OFFSET
);
730 void sr_start_vddautocomap(int srid
, u32 target_opp_no
)
732 struct omap_sr
*sr
= NULL
;
736 else if (srid
== SR2
)
741 if (sr
->is_sr_reset
== 1) {
746 if (sr
->is_autocomp_active
== 1)
747 pr_warning("SR%d: VDD autocomp is already active\n",
750 sr
->is_autocomp_active
= 1;
751 if (!sr_enable(sr
, target_opp_no
)) {
752 pr_warning("SR%d: VDD autocomp not activated\n", srid
);
753 sr
->is_autocomp_active
= 0;
754 if (sr
->is_sr_reset
== 1)
758 EXPORT_SYMBOL(sr_start_vddautocomap
);
760 int sr_stop_vddautocomap(int srid
)
762 struct omap_sr
*sr
= NULL
;
766 else if (srid
== SR2
)
771 if (sr
->is_autocomp_active
== 1) {
774 sr
->is_autocomp_active
= 0;
775 /* Reset the volatage for current OPP */
776 sr_reset_voltage(srid
);
779 pr_warning("SR%d: VDD autocomp is not active\n",
785 EXPORT_SYMBOL(sr_stop_vddautocomap
);
787 void enable_smartreflex(int srid
)
789 u32 target_opp_no
= 0;
790 struct omap_sr
*sr
= NULL
;
794 else if (srid
== SR2
)
799 if (sr
->is_autocomp_active
== 1) {
800 if (sr
->is_sr_reset
== 1) {
805 target_opp_no
= get_vdd1_opp();
806 else if (srid
== SR2
)
807 target_opp_no
= get_vdd2_opp();
809 if (!target_opp_no
) {
810 pr_info("Current OPP unknown \
811 Cannot configure SR\n");
816 if (!sr_enable(sr
, target_opp_no
))
822 void disable_smartreflex(int srid
)
826 struct omap_sr
*sr
= NULL
;
830 else if (srid
== SR2
)
835 if (sr
->is_autocomp_active
== 1) {
836 if (sr
->is_sr_reset
== 0) {
839 /* SRCONFIG - disable SR */
840 sr_modify_reg(sr
, SRCONFIG
, SRCONFIG_SRENABLE
,
845 if (sr
->srid
== SR1
) {
846 /* Wait for VP idle before disabling VP */
847 while ((!prm_read_mod_reg(OMAP3430_GR_MOD
,
848 OMAP3_PRM_VP1_STATUS_OFFSET
))
853 pr_warning("VP1 not idle, still going \
854 ahead with VP1 disable\n");
857 prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE
,
859 OMAP3_PRM_VP1_CONFIG_OFFSET
);
860 } else if (sr
->srid
== SR2
) {
861 /* Wait for VP idle before disabling VP */
862 while ((!prm_read_mod_reg(OMAP3430_GR_MOD
,
863 OMAP3_PRM_VP2_STATUS_OFFSET
))
868 pr_warning("VP2 not idle, still going \
869 ahead with VP2 disable\n");
872 prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE
,
874 OMAP3_PRM_VP2_CONFIG_OFFSET
);
876 /* Reset the volatage for current OPP */
877 sr_reset_voltage(srid
);
882 /* Voltage Scaling using SR VCBYPASS */
883 int sr_voltagescale_vcbypass(u32 target_opp
, u32 current_opp
,
884 u8 target_vsel
, u8 current_vsel
)
887 u32 vdd
, target_opp_no
, current_opp_no
;
890 u32 loop_cnt
= 0, retries_cnt
= 0;
891 u32 t2_smps_steps
= 0;
892 u32 t2_smps_delay
= 0;
894 vdd
= get_vdd(target_opp
);
895 target_opp_no
= get_opp_no(target_opp
);
896 current_opp_no
= get_opp_no(current_opp
);
898 if (vdd
== VDD1_OPP
) {
899 sr_status
= sr_stop_vddautocomap(SR1
);
900 t2_smps_steps
= abs(target_vsel
- current_vsel
);
902 prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK
,
903 (target_vsel
<< OMAP3430_VC_CMD_ON_SHIFT
),
905 OMAP3_PRM_VC_CMD_VAL_0_OFFSET
);
906 reg_addr
= R_VDD1_SR_CONTROL
;
908 } else if (vdd
== VDD2_OPP
) {
909 sr_status
= sr_stop_vddautocomap(SR2
);
910 t2_smps_steps
= abs(target_vsel
- current_vsel
);
912 prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK
,
913 (target_vsel
<< OMAP3430_VC_CMD_ON_SHIFT
),
915 OMAP3_PRM_VC_CMD_VAL_1_OFFSET
);
916 reg_addr
= R_VDD2_SR_CONTROL
;
919 vc_bypass_value
= (target_vsel
<< OMAP3430_DATA_SHIFT
) |
920 (reg_addr
<< OMAP3430_REGADDR_SHIFT
) |
921 (R_SRI2C_SLAVE_ADDR
<< OMAP3430_SLAVEADDR_SHIFT
);
923 prm_write_mod_reg(vc_bypass_value
, OMAP3430_GR_MOD
,
924 OMAP3_PRM_VC_BYPASS_VAL_OFFSET
);
926 vc_bypass_value
= prm_set_mod_reg_bits(OMAP3430_VALID
, OMAP3430_GR_MOD
,
927 OMAP3_PRM_VC_BYPASS_VAL_OFFSET
);
929 while ((vc_bypass_value
& OMAP3430_VALID
) != 0x0) {
931 if (retries_cnt
> 10) {
932 pr_info("Loop count exceeded in check SR I2C"
941 vc_bypass_value
= prm_read_mod_reg(OMAP3430_GR_MOD
,
942 OMAP3_PRM_VC_BYPASS_VAL_OFFSET
);
946 * T2 SMPS slew rate (min) 4mV/uS, step size 12.5mV,
947 * 2us added as buffer.
949 t2_smps_delay
= ((t2_smps_steps
* 125) / 40) + 2;
950 udelay(t2_smps_delay
);
954 sr_start_vddautocomap(SR1
, target_opp_no
);
955 else if (vdd
== VDD2_OPP
)
956 sr_start_vddautocomap(SR2
, target_opp_no
);
962 /* Sysfs interface to select SR VDD1 auto compensation */
963 static ssize_t
omap_sr_vdd1_autocomp_show(struct kobject
*kobj
,
964 struct kobj_attribute
*attr
, char *buf
)
966 return sprintf(buf
, "%d\n", sr1
.is_autocomp_active
);
969 static ssize_t
omap_sr_vdd1_autocomp_store(struct kobject
*kobj
,
970 struct kobj_attribute
*attr
,
971 const char *buf
, size_t n
)
973 unsigned short value
;
975 if (sscanf(buf
, "%hu", &value
) != 1 || (value
> 1)) {
976 pr_err("sr_vdd1_autocomp: Invalid value\n");
981 sr_stop_vddautocomap(SR1
);
983 u32 current_vdd1opp_no
= get_vdd1_opp();
984 if (!current_vdd1opp_no
) {
985 pr_err("sr_vdd1_autocomp: Current VDD1 opp unknown\n");
988 sr_start_vddautocomap(SR1
, current_vdd1opp_no
);
993 static struct kobj_attribute sr_vdd1_autocomp
= {
995 .name
= __stringify(sr_vdd1_autocomp
),
998 .show
= omap_sr_vdd1_autocomp_show
,
999 .store
= omap_sr_vdd1_autocomp_store
,
1002 /* Sysfs interface to select SR VDD2 auto compensation */
1003 static ssize_t
omap_sr_vdd2_autocomp_show(struct kobject
*kobj
,
1004 struct kobj_attribute
*attr
, char *buf
)
1006 return sprintf(buf
, "%d\n", sr2
.is_autocomp_active
);
1009 static ssize_t
omap_sr_vdd2_autocomp_store(struct kobject
*kobj
,
1010 struct kobj_attribute
*attr
,
1011 const char *buf
, size_t n
)
1013 unsigned short value
;
1015 if (sscanf(buf
, "%hu", &value
) != 1 || (value
> 1)) {
1016 pr_err("sr_vdd2_autocomp: Invalid value\n");
1021 sr_stop_vddautocomap(SR2
);
1023 u32 current_vdd2opp_no
= get_vdd2_opp();
1024 if (!current_vdd2opp_no
) {
1025 pr_err("sr_vdd2_autocomp: Current VDD2 opp unknown\n");
1028 sr_start_vddautocomap(SR2
, current_vdd2opp_no
);
1033 static struct kobj_attribute sr_vdd2_autocomp
= {
1035 .name
= __stringify(sr_vdd2_autocomp
),
1038 .show
= omap_sr_vdd2_autocomp_show
,
1039 .store
= omap_sr_vdd2_autocomp_store
,
1044 static int __init
omap3_sr_init(void)
1049 /* Exit if OPP tables are not defined */
1050 if (!(mpu_opps
&& l3_opps
)) {
1051 pr_err("SR: OPP rate tables not defined for platform, not enabling SmartReflex\n");
1055 /* Enable SR on T2 */
1056 ret
= twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER
, &RdReg
,
1059 RdReg
|= DCDC_GLOBAL_CFG_ENABLE_SRFLX
;
1060 ret
|= twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER
, RdReg
,
1063 if (cpu_is_omap34xx()) {
1064 sr1
.clk
= clk_get(NULL
, "sr1_fck");
1065 sr2
.clk
= clk_get(NULL
, "sr2_fck");
1067 sr1
.vdd_opp_clk
= clk_get(NULL
, "dpll1_ck");
1068 sr2
.vdd_opp_clk
= clk_get(NULL
, "l3_ick");
1069 sr_set_clk_length(&sr1
);
1070 sr_set_clk_length(&sr2
);
1072 /* Call the VPConfig, VCConfig, set N Values. */
1073 sr_set_nvalues(&sr1
);
1074 sr_configure_vp(SR1
);
1076 sr_set_nvalues(&sr2
);
1077 sr_configure_vp(SR2
);
1079 pr_info("SmartReflex driver initialized\n");
1081 ret
= sysfs_create_file(power_kobj
, &sr_vdd1_autocomp
.attr
);
1083 pr_err("sysfs_create_file failed: %d\n", ret
);
1085 ret
= sysfs_create_file(power_kobj
, &sr_vdd2_autocomp
.attr
);
1087 pr_err("sysfs_create_file failed: %d\n", ret
);
1092 late_initcall(omap3_sr_init
);