OMAP3: PM: Do not Enable SmartReflex if OPP tables not defined
[linux-ginger.git] / arch / arm / mach-omap2 / smartreflex.c
blobd8d10fdccb4e58b14e4824c8404353f2643a072c
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 /* determine the current OPP from the frequency
147 * we need to give this function last element of OPP rate table
148 * and the frequency
150 static u16 get_opp(struct omap_opp *opp_freq_table,
151 unsigned long freq)
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)
170 u16 opp;
171 struct clk *clk;
173 clk = clk_get(NULL, "dpll1_ck");
175 if (clk == NULL || IS_ERR(clk) || mpu_opps == NULL)
176 return 0;
178 opp = get_opp(mpu_opps + MAX_VDD1_OPP, clk->rate);
179 return opp;
182 static u16 get_vdd2_opp(void)
184 u16 opp;
185 struct clk *clk;
187 clk = clk_get(NULL, "dpll3_m2_ck");
189 if (clk == NULL || IS_ERR(clk) || l3_opps == NULL)
190 return 0;
192 opp = get_opp(l3_opps + MAX_VDD2_OPP, clk->rate);
193 return opp;
197 static void sr_set_clk_length(struct omap_sr *sr)
199 struct clk *sys_ck;
200 u32 sys_clk_speed;
202 sys_ck = clk_get(NULL, "sys_ck");
203 sys_clk_speed = clk_get_rate(sys_ck);
204 clk_put(sys_ck);
206 switch (sys_clk_speed) {
207 case 12000000:
208 sr->clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
209 break;
210 case 13000000:
211 sr->clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
212 break;
213 case 19200000:
214 sr->clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
215 break;
216 case 26000000:
217 sr->clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
218 break;
219 case 38400000:
220 sr->clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
221 break;
222 default:
223 pr_err("Invalid sysclk value: %d\n", sys_clk_speed);
224 break;
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 */
271 sr->senn_mod = 0x03;
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) {
280 sr->senp_mod = 0x03;
281 sr->senn_mod = 0x03;
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);
294 else
295 sr_set_efuse_nvalues(sr);
298 static void sr_configure_vp(int srid)
300 u32 vpconfig;
301 u32 vsel;
302 u32 target_opp_no;
304 if (srid == SR1) {
305 target_opp_no = get_vdd1_opp();
306 if (!target_opp_no)
307 /* Assume Nominal OPP as current OPP unknown */
308 vsel = mpu_opps[VDD1_OPP3].vsel;
309 else
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,
321 OMAP3430_GR_MOD,
322 OMAP3_PRM_VP1_VSTEPMIN_OFFSET);
324 prm_write_mod_reg(PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX |
325 PRM_VP1_VSTEPMAX_VSTEPMAX,
326 OMAP3430_GR_MOD,
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,
332 OMAP3430_GR_MOD,
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();
352 if (!target_opp_no)
353 /* Assume Nominal OPP */
354 vsel = l3_opps[VDD2_OPP3].vsel;
355 else
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,
367 OMAP3430_GR_MOD,
368 OMAP3_PRM_VP2_VSTEPMIN_OFFSET);
370 prm_write_mod_reg(PRM_VP2_VSTEPMAX_SMPSWAITTIMEMAX |
371 PRM_VP2_VSTEPMAX_VSTEPMAX,
372 OMAP3430_GR_MOD,
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,
378 OMAP3430_GR_MOD,
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)
401 u32 sr_config;
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) |
416 SRCONFIG_DELAYCTRL;
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) |
433 SRCONFIG_DELAYCTRL;
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));
443 sr->is_sr_reset = 0;
446 static int sr_reset_voltage(int srid)
448 u32 target_opp_no, vsel = 0;
449 u32 reg_addr = 0;
450 u32 loop_cnt = 0, retries_cnt = 0;
451 u32 vc_bypass_value;
453 if (srid == SR1) {
454 target_opp_no = get_vdd1_opp();
455 if (!target_opp_no) {
456 pr_info("Current OPP unknown: Cannot reset voltage\n");
457 return 1;
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");
465 return 1;
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) {
482 loop_cnt++;
483 if (retries_cnt > 10) {
484 pr_info("Loop count exceeded in check SR I2C"
485 "write\n");
486 return 1;
488 if (loop_cnt > 50) {
489 retries_cnt++;
490 loop_cnt = 0;
491 udelay(10);
493 vc_bypass_value = prm_read_mod_reg(OMAP3430_GR_MOD,
494 OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
496 return 0;
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");
505 return false;
508 sr->req_opp_no = target_opp_no;
510 if (sr->srid == SR1) {
511 switch (target_opp_no) {
512 case 5:
513 nvalue_reciprocal = sr->opp5_nvalue;
514 break;
515 case 4:
516 nvalue_reciprocal = sr->opp4_nvalue;
517 break;
518 case 3:
519 nvalue_reciprocal = sr->opp3_nvalue;
520 break;
521 case 2:
522 nvalue_reciprocal = sr->opp2_nvalue;
523 break;
524 case 1:
525 nvalue_reciprocal = sr->opp1_nvalue;
526 break;
527 default:
528 nvalue_reciprocal = sr->opp3_nvalue;
529 break;
531 } else {
532 switch (target_opp_no) {
533 case 3:
534 nvalue_reciprocal = sr->opp3_nvalue;
535 break;
536 case 2:
537 nvalue_reciprocal = sr->opp2_nvalue;
538 break;
539 case 1:
540 nvalue_reciprocal = sr->opp1_nvalue;
541 break;
542 default:
543 nvalue_reciprocal = sr->opp3_nvalue;
544 break;
548 if (nvalue_reciprocal == 0) {
549 pr_notice("OPP%d doesn't support SmartReflex\n",
550 target_opp_no);
551 return false;
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);
573 /* write2 clear */
574 prm_clear_mod_reg_bits(OMAP3430_INITVDD, OMAP3430_GR_MOD,
575 OMAP3_PRM_VP1_CONFIG_OFFSET);
576 /* Enable VP1 */
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);
591 /* write2 clear */
592 prm_clear_mod_reg_bits(OMAP3430_INITVDD, OMAP3430_GR_MOD,
593 OMAP3_PRM_VP2_CONFIG_OFFSET);
594 /* Enable VP2 */
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);
601 return true;
604 static void sr_disable(struct omap_sr *sr)
606 sr->is_sr_reset = 1;
608 /* SRCONFIG - disable SR */
609 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, ~SRCONFIG_SRENABLE);
611 if (sr->srid == SR1) {
612 /* Disable VP1 */
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) {
616 /* Disable VP2 */
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;
627 if (srid == SR1)
628 sr = &sr1;
629 else if (srid == SR2)
630 sr = &sr2;
631 else
632 return;
634 if (sr->is_sr_reset == 1) {
635 sr_clk_enable(sr);
636 sr_configure(sr);
639 if (sr->is_autocomp_active == 1)
640 pr_warning("SR%d: VDD autocomp is already active\n",
641 srid);
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)
648 sr_clk_disable(sr);
651 EXPORT_SYMBOL(sr_start_vddautocomap);
653 int sr_stop_vddautocomap(int srid)
655 struct omap_sr *sr = NULL;
657 if (srid == SR1)
658 sr = &sr1;
659 else if (srid == SR2)
660 sr = &sr2;
661 else
662 return -EINVAL;
664 if (sr->is_autocomp_active == 1) {
665 sr_disable(sr);
666 sr_clk_disable(sr);
667 sr->is_autocomp_active = 0;
668 /* Reset the volatage for current OPP */
669 sr_reset_voltage(srid);
670 return true;
671 } else {
672 pr_warning("SR%d: VDD autocomp is not active\n",
673 srid);
674 return false;
678 EXPORT_SYMBOL(sr_stop_vddautocomap);
680 void enable_smartreflex(int srid)
682 u32 target_opp_no = 0;
683 struct omap_sr *sr = NULL;
685 if (srid == SR1)
686 sr = &sr1;
687 else if (srid == SR2)
688 sr = &sr2;
689 else
690 return;
692 if (sr->is_autocomp_active == 1) {
693 if (sr->is_sr_reset == 1) {
694 /* Enable SR clks */
695 sr_clk_enable(sr);
697 if (srid == SR1)
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");
707 sr_configure(sr);
709 if (!sr_enable(sr, target_opp_no))
710 sr_clk_disable(sr);
715 void disable_smartreflex(int srid)
717 struct omap_sr *sr = NULL;
719 if (srid == SR1)
720 sr = &sr1;
721 else if (srid == SR2)
722 sr = &sr2;
723 else
724 return;
726 if (sr->is_autocomp_active == 1) {
727 if (sr->is_sr_reset == 0) {
729 sr->is_sr_reset = 1;
730 /* SRCONFIG - disable SR */
731 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE,
732 ~SRCONFIG_SRENABLE);
734 /* Disable SR clk */
735 sr_clk_disable(sr);
736 if (sr->srid == SR1) {
737 /* Disable VP1 */
738 prm_clear_mod_reg_bits(PRM_VP1_CONFIG_VPENABLE,
739 OMAP3430_GR_MOD,
740 OMAP3_PRM_VP1_CONFIG_OFFSET);
741 } else if (sr->srid == SR2) {
742 /* Disable VP2 */
743 prm_clear_mod_reg_bits(PRM_VP2_CONFIG_VPENABLE,
744 OMAP3430_GR_MOD,
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)
756 int sr_status = 0;
757 u32 vdd, target_opp_no;
758 u32 vc_bypass_value;
759 u32 reg_addr = 0;
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),
770 OMAP3430_GR_MOD,
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),
779 OMAP3430_GR_MOD,
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) {
795 loop_cnt++;
796 if (retries_cnt > 10) {
797 pr_info("Loop count exceeded in check SR I2C"
798 "write\n");
799 return 1;
801 if (loop_cnt > 50) {
802 retries_cnt++;
803 loop_cnt = 0;
804 udelay(10);
806 vc_bypass_value = prm_read_mod_reg(OMAP3430_GR_MOD,
807 OMAP3_PRM_VC_BYPASS_VAL_OFFSET);
810 udelay(T2_SMPS_UPDATE_DELAY);
812 if (sr_status) {
813 if (vdd == VDD1_OPP)
814 sr_start_vddautocomap(SR1, target_opp_no);
815 else if (vdd == VDD2_OPP)
816 sr_start_vddautocomap(SR2, target_opp_no);
819 return 0;
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");
837 return -EINVAL;
840 if (value == 0) {
841 sr_stop_vddautocomap(SR1);
842 } else {
843 u32 current_vdd1opp_no = get_vdd1_opp();
844 if (!current_vdd1opp_no) {
845 pr_err("sr_vdd1_autocomp: Current VDD1 opp unknown\n");
846 return -EINVAL;
848 sr_start_vddautocomap(SR1, current_vdd1opp_no);
850 return n;
853 static struct kobj_attribute sr_vdd1_autocomp = {
854 .attr = {
855 .name = __stringify(sr_vdd1_autocomp),
856 .mode = 0644,
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");
877 return -EINVAL;
880 if (value == 0) {
881 sr_stop_vddautocomap(SR2);
882 } else {
883 u32 current_vdd2opp_no = get_vdd2_opp();
884 if (!current_vdd2opp_no) {
885 pr_err("sr_vdd2_autocomp: Current VDD2 opp unknown\n");
886 return -EINVAL;
888 sr_start_vddautocomap(SR2, current_vdd2opp_no);
890 return n;
893 static struct kobj_attribute sr_vdd2_autocomp = {
894 .attr = {
895 .name = __stringify(sr_vdd2_autocomp),
896 .mode = 0644,
898 .show = omap_sr_vdd2_autocomp_show,
899 .store = omap_sr_vdd2_autocomp_store,
904 static int __init omap3_sr_init(void)
906 int ret = 0;
907 u8 RdReg;
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");
912 return -ENODEV;
915 /* Enable SR on T2 */
916 ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &RdReg,
917 R_DCDC_GLOBAL_CFG);
919 RdReg |= DCDC_GLOBAL_CFG_ENABLE_SRFLX;
920 ret |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, RdReg,
921 R_DCDC_GLOBAL_CFG);
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);
940 if (ret)
941 pr_err("sysfs_create_file failed: %d\n", ret);
943 ret = sysfs_create_file(power_kobj, &sr_vdd2_autocomp.attr);
944 if (ret)
945 pr_err("sysfs_create_file failed: %d\n", ret);
947 return 0;
950 late_initcall(omap3_sr_init);