OMAP3: SR: Remove redundant defines
[linux-ginger.git] / arch / arm / mach-omap2 / smartreflex.c
blob1cae940fdbb1bd37ccd4a3ecbefea8ddb65ceede
1 /*
2 * linux/arch/arm/mach-omap3/smartreflex.c
4 * OMAP34XX SmartReflex Voltage Control
6 * Copyright (C) 2008 Nokia Corporation
7 * Kalle Jokiniemi
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>
28 #include <linux/io.h>
30 #include <plat/omap34xx.h>
31 #include <plat/control.h>
32 #include <plat/clock.h>
33 #include <plat/omap-pm.h>
35 #include "prm.h"
36 #include "smartreflex.h"
37 #include "prm-regbits-34xx.h"
39 struct omap_sr {
40 int srid;
41 int is_sr_reset;
42 int is_autocomp_active;
43 struct clk *clk;
44 u32 clk_length;
45 u32 req_opp_no;
46 u32 opp1_nvalue, opp2_nvalue, opp3_nvalue, opp4_nvalue;
47 u32 opp5_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,
61 u32 value)
63 u32 reg_val;
65 reg_val = __raw_readl(SR_REGADDR(offset));
66 reg_val &= ~mask;
67 reg_val |= value;
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);
81 return -1;
84 /* set fclk- active , iclk- idle */
85 sr_modify_reg(sr, ERRCONFIG, SR_CLKACTIVITY_MASK,
86 SR_CLKACTIVITY_IOFF_FON);
88 return 0;
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);
97 clk_disable(sr->clk);
98 sr->is_sr_reset = 1;
101 static struct omap_sr sr1 = {
102 .srid = SR1,
103 .is_sr_reset = 1,
104 .is_autocomp_active = 0,
105 .clk_length = 0,
106 .srbase_addr = OMAP2_IO_ADDRESS(OMAP34XX_SR1_BASE),
109 static struct omap_sr sr2 = {
110 .srid = SR2,
111 .is_sr_reset = 1,
112 .is_autocomp_active = 0,
113 .clk_length = 0,
114 .srbase_addr = OMAP2_IO_ADDRESS(OMAP34XX_SR2_BASE),
117 static void cal_reciprocal(u32 sensor, u32 *sengain, u32 *rnsen)
119 u32 gn, rn, mul;
121 for (gn = 0; gn < GAIN_MAXLIMIT; gn++) {
122 mul = 1 << (gn + 8);
123 rn = mul / sensor;
124 if (rn < R_MAXLIMIT) {
125 *sengain = gn;
126 *rnsen = rn;
131 static u32 cal_test_nvalue(u32 sennval, u32 senpval)
133 u32 senpgain, senngain;
134 u32 rnsenp, rnsenn;
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 static void sr_set_clk_length(struct omap_sr *sr)
148 struct clk *sys_ck;
149 u32 sys_clk_speed;
151 sys_ck = clk_get(NULL, "sys_ck");
152 sys_clk_speed = clk_get_rate(sys_ck);
153 clk_put(sys_ck);
155 switch (sys_clk_speed) {
156 case 12000000:
157 sr->clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
158 break;
159 case 13000000:
160 sr->clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
161 break;
162 case 19200000:
163 sr->clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
164 break;
165 case 26000000:
166 sr->clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
167 break;
168 case 38400000:
169 sr->clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
170 break;
171 default:
172 pr_err("Invalid sysclk value: %d\n", sys_clk_speed);
173 break;
177 static void sr_set_efuse_nvalues(struct omap_sr *sr)
179 if (sr->srid == SR1) {
180 sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
181 OMAP343X_SR1_SENNENABLE_MASK) >>
182 OMAP343X_SR1_SENNENABLE_SHIFT;
183 sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
184 OMAP343X_SR1_SENPENABLE_MASK) >>
185 OMAP343X_SR1_SENPENABLE_SHIFT;
187 sr->opp5_nvalue = omap_ctrl_readl(
188 OMAP343X_CONTROL_FUSE_OPP5_VDD1);
189 sr->opp4_nvalue = omap_ctrl_readl(
190 OMAP343X_CONTROL_FUSE_OPP4_VDD1);
191 sr->opp3_nvalue = omap_ctrl_readl(
192 OMAP343X_CONTROL_FUSE_OPP3_VDD1);
193 sr->opp2_nvalue = omap_ctrl_readl(
194 OMAP343X_CONTROL_FUSE_OPP2_VDD1);
195 sr->opp1_nvalue = omap_ctrl_readl(
196 OMAP343X_CONTROL_FUSE_OPP1_VDD1);
197 } else if (sr->srid == SR2) {
198 sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
199 OMAP343X_SR2_SENNENABLE_MASK) >>
200 OMAP343X_SR2_SENNENABLE_SHIFT;
202 sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
203 OMAP343X_SR2_SENPENABLE_MASK) >>
204 OMAP343X_SR2_SENPENABLE_SHIFT;
206 sr->opp3_nvalue = omap_ctrl_readl(
207 OMAP343X_CONTROL_FUSE_OPP3_VDD2);
208 sr->opp2_nvalue = omap_ctrl_readl(
209 OMAP343X_CONTROL_FUSE_OPP2_VDD2);
210 sr->opp1_nvalue = omap_ctrl_readl(
211 OMAP343X_CONTROL_FUSE_OPP1_VDD2);
215 /* Hard coded nvalues for testing purposes, may cause device to hang! */
216 static void sr_set_testing_nvalues(struct omap_sr *sr)
218 if (sr->srid == SR1) {
219 sr->senp_mod = 0x03; /* SenN-M5 enabled */
220 sr->senn_mod = 0x03;
222 /* calculate nvalues for each opp */
223 sr->opp5_nvalue = cal_test_nvalue(0xacd + 0x330, 0x848 + 0x330);
224 sr->opp4_nvalue = cal_test_nvalue(0x964 + 0x2a0, 0x727 + 0x2a0);
225 sr->opp3_nvalue = cal_test_nvalue(0x85b + 0x200, 0x655 + 0x200);
226 sr->opp2_nvalue = cal_test_nvalue(0x506 + 0x1a0, 0x3be + 0x1a0);
227 sr->opp1_nvalue = cal_test_nvalue(0x373 + 0x100, 0x28c + 0x100);
228 } else if (sr->srid == SR2) {
229 sr->senp_mod = 0x03;
230 sr->senn_mod = 0x03;
232 sr->opp3_nvalue = cal_test_nvalue(0x76f + 0x200, 0x579 + 0x200);
233 sr->opp2_nvalue = cal_test_nvalue(0x4f5 + 0x1c0, 0x390 + 0x1c0);
234 sr->opp1_nvalue = cal_test_nvalue(0x359, 0x25d);
239 static void sr_set_nvalues(struct omap_sr *sr)
241 if (SR_TESTING_NVALUES)
242 sr_set_testing_nvalues(sr);
243 else
244 sr_set_efuse_nvalues(sr);
247 static void sr_configure_vp(int srid)
249 u32 vpconfig;
251 if (srid == SR1) {
252 vpconfig = PRM_VP1_CONFIG_ERROROFFSET |
253 PRM_VP1_CONFIG_ERRORGAIN |
254 PRM_VP1_CONFIG_TIMEOUTEN |
255 mpu_opps[omap_pm_vdd1_get_opp()].vsel <<
256 OMAP3430_INITVOLTAGE_SHIFT;
258 prm_write_mod_reg(vpconfig, OMAP3430_GR_MOD,
259 OMAP3_PRM_VP1_CONFIG_OFFSET);
260 prm_write_mod_reg(PRM_VP1_VSTEPMIN_SMPSWAITTIMEMIN |
261 PRM_VP1_VSTEPMIN_VSTEPMIN,
262 OMAP3430_GR_MOD,
263 OMAP3_PRM_VP1_VSTEPMIN_OFFSET);
265 prm_write_mod_reg(PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX |
266 PRM_VP1_VSTEPMAX_VSTEPMAX,
267 OMAP3430_GR_MOD,
268 OMAP3_PRM_VP1_VSTEPMAX_OFFSET);
270 prm_write_mod_reg(PRM_VP1_VLIMITTO_VDDMAX |
271 PRM_VP1_VLIMITTO_VDDMIN |
272 PRM_VP1_VLIMITTO_TIMEOUT,
273 OMAP3430_GR_MOD,
274 OMAP3_PRM_VP1_VLIMITTO_OFFSET);
276 /* Trigger initVDD value copy to voltage processor */
277 prm_set_mod_reg_bits(PRM_VP1_CONFIG_INITVDD, OMAP3430_GR_MOD,
278 OMAP3_PRM_VP1_CONFIG_OFFSET);
280 /* Clear initVDD copy trigger bit */
281 prm_clear_mod_reg_bits(PRM_VP1_CONFIG_INITVDD, OMAP3430_GR_MOD,
282 OMAP3_PRM_VP1_CONFIG_OFFSET);
284 /* Force update of voltage */
285 prm_set_mod_reg_bits(OMAP3430_FORCEUPDATE, OMAP3430_GR_MOD,
286 OMAP3_PRM_VP1_CONFIG_OFFSET);
287 /* Clear force bit */
288 prm_clear_mod_reg_bits(OMAP3430_FORCEUPDATE, OMAP3430_GR_MOD,
289 OMAP3_PRM_VP1_CONFIG_OFFSET);
291 } else if (srid == SR2) {
292 vpconfig = PRM_VP2_CONFIG_ERROROFFSET |
293 PRM_VP2_CONFIG_ERRORGAIN |
294 PRM_VP2_CONFIG_TIMEOUTEN |
295 l3_opps[omap_pm_vdd2_get_opp()].vsel <<
296 OMAP3430_INITVOLTAGE_SHIFT;
298 prm_write_mod_reg(vpconfig, OMAP3430_GR_MOD,
299 OMAP3_PRM_VP2_CONFIG_OFFSET);
300 prm_write_mod_reg(PRM_VP2_VSTEPMIN_SMPSWAITTIMEMIN |
301 PRM_VP2_VSTEPMIN_VSTEPMIN,
302 OMAP3430_GR_MOD,
303 OMAP3_PRM_VP2_VSTEPMIN_OFFSET);
305 prm_write_mod_reg(PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX |
306 PRM_VP2_VSTEPMAX_VSTEPMAX,
307 OMAP3430_GR_MOD,
308 OMAP3_PRM_VP2_VSTEPMAX_OFFSET);
310 prm_write_mod_reg(PRM_VP2_VLIMITTO_VDDMAX |
311 PRM_VP2_VLIMITTO_VDDMIN |
312 PRM_VP2_VLIMITTO_TIMEOUT,
313 OMAP3430_GR_MOD,
314 OMAP3_PRM_VP2_VLIMITTO_OFFSET);
316 /* Trigger initVDD value copy to voltage processor */
317 prm_set_mod_reg_bits(PRM_VP1_CONFIG_INITVDD, OMAP3430_GR_MOD,
318 OMAP3_PRM_VP2_CONFIG_OFFSET);
320 /* Clear initVDD copy trigger bit */
321 prm_clear_mod_reg_bits(PRM_VP1_CONFIG_INITVDD, OMAP3430_GR_MOD,
322 OMAP3_PRM_VP2_CONFIG_OFFSET);
324 /* Force update of voltage */
325 prm_set_mod_reg_bits(OMAP3430_FORCEUPDATE, OMAP3430_GR_MOD,
326 OMAP3_PRM_VP2_CONFIG_OFFSET);
327 /* Clear force bit */
328 prm_clear_mod_reg_bits(OMAP3430_FORCEUPDATE, OMAP3430_GR_MOD,
329 OMAP3_PRM_VP2_CONFIG_OFFSET);
334 static void sr_configure(struct omap_sr *sr)
336 u32 sr_config;
337 u32 senp_en , senn_en;
339 if (sr->clk_length == 0)
340 sr_set_clk_length(sr);
342 senp_en = sr->senp_mod;
343 senn_en = sr->senn_mod;
344 if (sr->srid == SR1) {
345 sr_config = SR1_SRCONFIG_ACCUMDATA |
346 (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
347 SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
348 SRCONFIG_MINMAXAVG_EN |
349 (senn_en << SRCONFIG_SENNENABLE_SHIFT) |
350 (senp_en << SRCONFIG_SENPENABLE_SHIFT) |
351 SRCONFIG_DELAYCTRL;
353 sr_write_reg(sr, SRCONFIG, sr_config);
354 sr_write_reg(sr, AVGWEIGHT, SR1_AVGWEIGHT_SENPAVGWEIGHT |
355 SR1_AVGWEIGHT_SENNAVGWEIGHT);
357 sr_modify_reg(sr, ERRCONFIG, (SR_ERRWEIGHT_MASK |
358 SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
359 (SR1_ERRWEIGHT | SR1_ERRMAXLIMIT | SR1_ERRMINLIMIT));
361 } else if (sr->srid == SR2) {
362 sr_config = SR2_SRCONFIG_ACCUMDATA |
363 (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
364 SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
365 SRCONFIG_MINMAXAVG_EN |
366 (senn_en << SRCONFIG_SENNENABLE_SHIFT) |
367 (senp_en << SRCONFIG_SENPENABLE_SHIFT) |
368 SRCONFIG_DELAYCTRL;
370 sr_write_reg(sr, SRCONFIG, sr_config);
371 sr_write_reg(sr, AVGWEIGHT, SR2_AVGWEIGHT_SENPAVGWEIGHT |
372 SR2_AVGWEIGHT_SENNAVGWEIGHT);
373 sr_modify_reg(sr, ERRCONFIG, (SR_ERRWEIGHT_MASK |
374 SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
375 (SR2_ERRWEIGHT | SR2_ERRMAXLIMIT | SR2_ERRMINLIMIT));
378 sr->is_sr_reset = 0;
381 static int sr_reset_voltage(int srid)
383 u32 target_opp_no, vsel = 0;
384 u32 reg_addr = 0;
385 u32 loop_cnt = 0, retries_cnt = 0;
386 u32 vc_bypass_value;
388 if (srid == SR1) {
389 target_opp_no = omap_pm_vdd1_get_opp();
390 vsel = mpu_opps[target_opp_no].vsel;
391 reg_addr = R_VDD1_SR_CONTROL;
392 } else if (srid == SR2) {
393 target_opp_no = omap_pm_vdd2_get_opp();
394 vsel = l3_opps[target_opp_no].vsel;
395 reg_addr = R_VDD2_SR_CONTROL;
398 vc_bypass_value = (vsel << OMAP3430_DATA_SHIFT) |
399 (reg_addr << OMAP3430_REGADDR_SHIFT) |
400 (R_SRI2C_SLAVE_ADDR << OMAP3430_SLAVEADDR_SHIFT);
402 prm_write_mod_reg(vc_bypass_value, OMAP3430_GR_MOD,
403 OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
405 vc_bypass_value = prm_set_mod_reg_bits(OMAP3430_VALID, OMAP3430_GR_MOD,
406 OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
408 while ((vc_bypass_value & OMAP3430_VALID) != 0x0) {
409 loop_cnt++;
410 if (retries_cnt > 10) {
411 pr_info("Loop count exceeded in check SR I2C"
412 "write\n");
413 return SR_FAIL;
415 if (loop_cnt > 50) {
416 retries_cnt++;
417 loop_cnt = 0;
418 udelay(10);
420 vc_bypass_value = prm_read_mod_reg(OMAP3430_GR_MOD,
421 OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
423 return SR_PASS;
426 static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
428 u32 nvalue_reciprocal, v;
430 if (!(mpu_opps && l3_opps)) {
431 pr_notice("VSEL values not found\n");
432 return false;
435 sr->req_opp_no = target_opp_no;
437 if (sr->srid == SR1) {
438 switch (target_opp_no) {
439 case 5:
440 nvalue_reciprocal = sr->opp5_nvalue;
441 break;
442 case 4:
443 nvalue_reciprocal = sr->opp4_nvalue;
444 break;
445 case 3:
446 nvalue_reciprocal = sr->opp3_nvalue;
447 break;
448 case 2:
449 nvalue_reciprocal = sr->opp2_nvalue;
450 break;
451 case 1:
452 nvalue_reciprocal = sr->opp1_nvalue;
453 break;
454 default:
455 nvalue_reciprocal = sr->opp3_nvalue;
456 break;
458 } else {
459 switch (target_opp_no) {
460 case 3:
461 nvalue_reciprocal = sr->opp3_nvalue;
462 break;
463 case 2:
464 nvalue_reciprocal = sr->opp2_nvalue;
465 break;
466 case 1:
467 nvalue_reciprocal = sr->opp1_nvalue;
468 break;
469 default:
470 nvalue_reciprocal = sr->opp3_nvalue;
471 break;
475 if (nvalue_reciprocal == 0) {
476 pr_notice("OPP%d doesn't support SmartReflex\n",
477 target_opp_no);
478 return SR_FALSE;
481 sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
483 /* Enable the interrupt */
484 sr_modify_reg(sr, ERRCONFIG,
485 (ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST),
486 (ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
488 if (sr->srid == SR1) {
489 /* set/latch init voltage */
490 v = prm_read_mod_reg(OMAP3430_GR_MOD,
491 OMAP3_PRM_VP1_CONFIG_OFFSET);
492 v &= ~(OMAP3430_INITVOLTAGE_MASK | OMAP3430_INITVDD);
493 v |= mpu_opps[target_opp_no].vsel <<
494 OMAP3430_INITVOLTAGE_SHIFT;
495 prm_write_mod_reg(v, OMAP3430_GR_MOD,
496 OMAP3_PRM_VP1_CONFIG_OFFSET);
497 /* write1 to latch */
498 prm_set_mod_reg_bits(OMAP3430_INITVDD, OMAP3430_GR_MOD,
499 OMAP3_PRM_VP1_CONFIG_OFFSET);
500 /* write2 clear */
501 prm_clear_mod_reg_bits(OMAP3430_INITVDD, OMAP3430_GR_MOD,
502 OMAP3_PRM_VP1_CONFIG_OFFSET);
503 /* Enable VP1 */
504 prm_set_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE, OMAP3430_GR_MOD,
505 OMAP3_PRM_VP1_CONFIG_OFFSET);
506 } else if (sr->srid == SR2) {
507 /* set/latch init voltage */
508 v = prm_read_mod_reg(OMAP3430_GR_MOD,
509 OMAP3_PRM_VP2_CONFIG_OFFSET);
510 v &= ~(OMAP3430_INITVOLTAGE_MASK | OMAP3430_INITVDD);
511 v |= l3_opps[target_opp_no].vsel <<
512 OMAP3430_INITVOLTAGE_SHIFT;
513 prm_write_mod_reg(v, OMAP3430_GR_MOD,
514 OMAP3_PRM_VP2_CONFIG_OFFSET);
515 /* write1 to latch */
516 prm_set_mod_reg_bits(OMAP3430_INITVDD, OMAP3430_GR_MOD,
517 OMAP3_PRM_VP2_CONFIG_OFFSET);
518 /* write2 clear */
519 prm_clear_mod_reg_bits(OMAP3430_INITVDD, OMAP3430_GR_MOD,
520 OMAP3_PRM_VP2_CONFIG_OFFSET);
521 /* Enable VP2 */
522 prm_set_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE, OMAP3430_GR_MOD,
523 OMAP3_PRM_VP2_CONFIG_OFFSET);
526 /* SRCONFIG - enable SR */
527 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
528 return SR_TRUE;
531 static void sr_disable(struct omap_sr *sr)
533 sr->is_sr_reset = 1;
535 /* SRCONFIG - disable SR */
536 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, ~SRCONFIG_SRENABLE);
538 if (sr->srid == SR1) {
539 /* Disable VP1 */
540 prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE, OMAP3430_GR_MOD,
541 OMAP3_PRM_VP1_CONFIG_OFFSET);
542 } else if (sr->srid == SR2) {
543 /* Disable VP2 */
544 prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE, OMAP3430_GR_MOD,
545 OMAP3_PRM_VP2_CONFIG_OFFSET);
550 void sr_start_vddautocomap(int srid, u32 target_opp_no)
552 struct omap_sr *sr = NULL;
554 if (srid == SR1)
555 sr = &sr1;
556 else if (srid == SR2)
557 sr = &sr2;
559 if (sr->is_sr_reset == 1) {
560 sr_clk_enable(sr);
561 sr_configure(sr);
564 if (sr->is_autocomp_active == 1)
565 pr_warning("SR%d: VDD autocomp is already active\n",
566 srid);
568 sr->is_autocomp_active = 1;
569 if (!sr_enable(sr, target_opp_no)) {
570 pr_warning("SR%d: VDD autocomp not activated\n", srid);
571 sr->is_autocomp_active = 0;
572 if (sr->is_sr_reset == 1)
573 sr_clk_disable(sr);
576 EXPORT_SYMBOL(sr_start_vddautocomap);
578 int sr_stop_vddautocomap(int srid)
580 struct omap_sr *sr = NULL;
582 if (srid == SR1)
583 sr = &sr1;
584 else if (srid == SR2)
585 sr = &sr2;
587 if (sr->is_autocomp_active == 1) {
588 sr_disable(sr);
589 sr_clk_disable(sr);
590 sr->is_autocomp_active = 0;
591 /* Reset the volatage for current OPP */
592 sr_reset_voltage(srid);
593 return SR_TRUE;
594 } else {
595 pr_warning("SR%d: VDD autocomp is not active\n",
596 srid);
597 return SR_FALSE;
601 EXPORT_SYMBOL(sr_stop_vddautocomap);
603 void enable_smartreflex(int srid)
605 u32 target_opp_no = 0;
606 struct omap_sr *sr = NULL;
608 if (srid == SR1)
609 sr = &sr1;
610 else if (srid == SR2)
611 sr = &sr2;
613 if (sr->is_autocomp_active == 1) {
614 if (sr->is_sr_reset == 1) {
615 /* Enable SR clks */
616 sr_clk_enable(sr);
618 if (srid == SR1)
619 target_opp_no = omap_pm_vdd1_get_opp();
620 else if (srid == SR2)
621 target_opp_no = omap_pm_vdd2_get_opp();
623 sr_configure(sr);
625 if (!sr_enable(sr, target_opp_no))
626 sr_clk_disable(sr);
631 void disable_smartreflex(int srid)
633 struct omap_sr *sr = NULL;
635 if (srid == SR1)
636 sr = &sr1;
637 else if (srid == SR2)
638 sr = &sr2;
640 if (sr->is_autocomp_active == 1) {
641 if (sr->is_sr_reset == 0) {
643 sr->is_sr_reset = 1;
644 /* SRCONFIG - disable SR */
645 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE,
646 ~SRCONFIG_SRENABLE);
648 /* Disable SR clk */
649 sr_clk_disable(sr);
650 if (sr->srid == SR1) {
651 /* Disable VP1 */
652 prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE,
653 OMAP3430_GR_MOD,
654 OMAP3_PRM_VP1_CONFIG_OFFSET);
655 } else if (sr->srid == SR2) {
656 /* Disable VP2 */
657 prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE,
658 OMAP3430_GR_MOD,
659 OMAP3_PRM_VP2_CONFIG_OFFSET);
661 /* Reset the volatage for current OPP */
662 sr_reset_voltage(srid);
667 /* Voltage Scaling using SR VCBYPASS */
668 int sr_voltagescale_vcbypass(u32 target_opp, u8 vsel)
670 int sr_status = 0;
671 u32 vdd, target_opp_no;
672 u32 vc_bypass_value;
673 u32 reg_addr = 0;
674 u32 loop_cnt = 0, retries_cnt = 0;
676 vdd = get_vdd(target_opp);
677 target_opp_no = get_opp_no(target_opp);
679 if (vdd == VDD1_OPP) {
680 sr_status = sr_stop_vddautocomap(SR1);
682 prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK,
683 (vsel << OMAP3430_VC_CMD_ON_SHIFT),
684 OMAP3430_GR_MOD,
685 OMAP3_PRM_VC_CMD_VAL_0_OFFSET);
686 reg_addr = R_VDD1_SR_CONTROL;
688 } else if (vdd == VDD2_OPP) {
689 sr_status = sr_stop_vddautocomap(SR2);
691 prm_rmw_mod_reg_bits(OMAP3430_VC_CMD_ON_MASK,
692 (vsel << OMAP3430_VC_CMD_ON_SHIFT),
693 OMAP3430_GR_MOD,
694 OMAP3_PRM_VC_CMD_VAL_1_OFFSET);
695 reg_addr = R_VDD2_SR_CONTROL;
698 vc_bypass_value = (vsel << OMAP3430_DATA_SHIFT) |
699 (reg_addr << OMAP3430_REGADDR_SHIFT) |
700 (R_SRI2C_SLAVE_ADDR << OMAP3430_SLAVEADDR_SHIFT);
702 prm_write_mod_reg(vc_bypass_value, OMAP3430_GR_MOD,
703 OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
705 vc_bypass_value = prm_set_mod_reg_bits(OMAP3430_VALID, OMAP3430_GR_MOD,
706 OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
708 while ((vc_bypass_value & OMAP3430_VALID) != 0x0) {
709 loop_cnt++;
710 if (retries_cnt > 10) {
711 pr_info("Loop count exceeded in check SR I2C"
712 "write\n");
713 return SR_FAIL;
715 if (loop_cnt > 50) {
716 retries_cnt++;
717 loop_cnt = 0;
718 udelay(10);
720 vc_bypass_value = prm_read_mod_reg(OMAP3430_GR_MOD,
721 OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
724 udelay(T2_SMPS_UPDATE_DELAY);
726 if (sr_status) {
727 if (vdd == VDD1_OPP)
728 sr_start_vddautocomap(SR1, target_opp_no);
729 else if (vdd == VDD2_OPP)
730 sr_start_vddautocomap(SR2, target_opp_no);
733 return SR_PASS;
736 /* Sysfs interface to select SR VDD1 auto compensation */
737 static ssize_t omap_sr_vdd1_autocomp_show(struct kobject *kobj,
738 struct kobj_attribute *attr, char *buf)
740 return sprintf(buf, "%d\n", sr1.is_autocomp_active);
743 static ssize_t omap_sr_vdd1_autocomp_store(struct kobject *kobj,
744 struct kobj_attribute *attr,
745 const char *buf, size_t n)
747 u32 current_vdd1opp_no;
748 unsigned short value;
750 if (sscanf(buf, "%hu", &value) != 1 || (value > 1)) {
751 pr_err("sr_vdd1_autocomp: Invalid value\n");
752 return -EINVAL;
755 current_vdd1opp_no = omap_pm_vdd1_get_opp();
757 if (value == 0)
758 sr_stop_vddautocomap(SR1);
759 else
760 sr_start_vddautocomap(SR1, current_vdd1opp_no);
762 return n;
765 static struct kobj_attribute sr_vdd1_autocomp = {
766 .attr = {
767 .name = __stringify(sr_vdd1_autocomp),
768 .mode = 0644,
770 .show = omap_sr_vdd1_autocomp_show,
771 .store = omap_sr_vdd1_autocomp_store,
774 /* Sysfs interface to select SR VDD2 auto compensation */
775 static ssize_t omap_sr_vdd2_autocomp_show(struct kobject *kobj,
776 struct kobj_attribute *attr, char *buf)
778 return sprintf(buf, "%d\n", sr2.is_autocomp_active);
781 static ssize_t omap_sr_vdd2_autocomp_store(struct kobject *kobj,
782 struct kobj_attribute *attr,
783 const char *buf, size_t n)
785 u32 current_vdd2opp_no;
786 unsigned short value;
788 if (sscanf(buf, "%hu", &value) != 1 || (value > 1)) {
789 pr_err("sr_vdd2_autocomp: Invalid value\n");
790 return -EINVAL;
793 current_vdd2opp_no = omap_pm_vdd2_get_opp();
795 if (value == 0)
796 sr_stop_vddautocomap(SR2);
797 else
798 sr_start_vddautocomap(SR2, current_vdd2opp_no);
800 return n;
803 static struct kobj_attribute sr_vdd2_autocomp = {
804 .attr = {
805 .name = __stringify(sr_vdd2_autocomp),
806 .mode = 0644,
808 .show = omap_sr_vdd2_autocomp_show,
809 .store = omap_sr_vdd2_autocomp_store,
814 static int __init omap3_sr_init(void)
816 int ret = 0;
817 u8 RdReg;
819 /* Enable SR on T2 */
820 ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &RdReg,
821 R_DCDC_GLOBAL_CFG);
823 RdReg |= DCDC_GLOBAL_CFG_ENABLE_SRFLX;
824 ret |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, RdReg,
825 R_DCDC_GLOBAL_CFG);
827 if (cpu_is_omap34xx()) {
828 sr1.clk = clk_get(NULL, "sr1_fck");
829 sr2.clk = clk_get(NULL, "sr2_fck");
831 sr_set_clk_length(&sr1);
832 sr_set_clk_length(&sr2);
834 /* Call the VPConfig, VCConfig, set N Values. */
835 sr_set_nvalues(&sr1);
836 sr_configure_vp(SR1);
838 sr_set_nvalues(&sr2);
839 sr_configure_vp(SR2);
841 pr_info("SmartReflex driver initialized\n");
843 ret = sysfs_create_file(power_kobj, &sr_vdd1_autocomp.attr);
844 if (ret)
845 pr_err("sysfs_create_file failed: %d\n", ret);
847 ret = sysfs_create_file(power_kobj, &sr_vdd2_autocomp.attr);
848 if (ret)
849 pr_err("sysfs_create_file failed: %d\n", ret);
851 return 0;
854 late_initcall(omap3_sr_init);