ad7f347b67eeda5549ab553dac126171d4f5c1a3
[kernel-power] / kernel-power-2.6.28 / debian / patches / overclock_smartreflex_900.diff
1 diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/omap3-opp.h kernel-power-2.6.28.new/arch/arm/mach-omap2/omap3-opp.h
2 --- kernel-power-2.6.28/arch/arm/mach-omap2/omap3-opp.h 2012-01-07 13:49:16.551071653 +0000
3 +++ kernel-power-2.6.28.new/arch/arm/mach-omap2/omap3-opp.h     2011-12-31 12:54:23.719318887 +0000
4 @@ -11,8 +11,7 @@
5  #define S900M   900000000
6  #define S850M   850000000
7  #define S805M   805000000
8 -#define S750M   750000000
9 -#define S700M   700000000
10 +#define S720M   720000000
11  #define S600M   600000000
12  #define S550M   550000000
13  #define S500M   500000000
14 diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/pm34xx.c kernel-power-2.6.28.new/arch/arm/mach-omap2/pm34xx.c
15 --- kernel-power-2.6.28/arch/arm/mach-omap2/pm34xx.c    2012-01-07 13:49:16.515051220 +0000
16 +++ kernel-power-2.6.28.new/arch/arm/mach-omap2/pm34xx.c        2011-12-31 12:54:23.735963309 +0000
17 @@ -629,9 +629,9 @@
18          * Only needed if we are going to enter retention.
19          */
20         if (mpu_next_state < PWRDM_POWER_ON)
21 -               disable_smartreflex(SR1);
22 +               disable_smartreflex(SR1,0);
23         if (core_next_state < PWRDM_POWER_ON)
24 -               disable_smartreflex(SR2);
25 +               disable_smartreflex(SR2,0);
26  
27         /* CORE */
28         if (core_next_state < PWRDM_POWER_ON) {
29 diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/pm.c kernel-power-2.6.28.new/arch/arm/mach-omap2/pm.c
30 --- kernel-power-2.6.28/arch/arm/mach-omap2/pm.c        2012-01-07 13:49:16.567287927 +0000
31 +++ kernel-power-2.6.28.new/arch/arm/mach-omap2/pm.c    2011-12-31 12:54:23.772101815 +0000
32 @@ -44,25 +44,23 @@
33  
34  struct omap_opp omap3_mpu_rate_table[] = {
35         {0, 0, 0},
36 -       {0, 1, 0x1E},
37 -       /*underclocking*/
38 -       {S125M, 2, 0x1E},
39         /*default*/
40 -       {S250M, 3, 0x26},
41 -       {S500M, 4, 0x30},
42 -       {S550M, 5, 0x36},
43 -       {S600M, 6, 0x3C},
44 +       {S125M, VDD1_OPP1,  0x1E},
45 +       {S250M, VDD1_OPP2,  0x26},
46 +       {S500M, VDD1_OPP3,  0x30},
47 +       {S550M, VDD1_OPP4,  0x36},
48 +       {S600M, VDD1_OPP5,  0x3C},
49         /*overclocking*/
50 -       {S700M, 7, 0x3C},
51 -       {S750M, 8, 0x3C},
52 -       {S805M, 9, 0x3C},
53 -       {S850M, 10, 0x3C},
54 -       {S900M, 11, 0x3C},
55 -       {S950M, 12, 0x3C},
56 -       {S1000M, 13, 0x3C},
57 -       {S1100M, 14, 0x48},
58 -       {S1150M, 15, 0x48},
59 +       {S720M, VDD1_OPP6,  0x3C},
60 +       {S805M, VDD1_OPP7,  0x3C},
61 +       {S850M, VDD1_OPP8,  0x3C},
62 +       {S900M, VDD1_OPP9,  0x3C},
63 +       {S950M, VDD1_OPP10, 0x3C},
64 +       {S1000M,VDD1_OPP11, 0x3C},
65 +       {S1100M,VDD1_OPP12, 0x48},
66 +       {S1150M,VDD1_OPP13, 0x48},
67  };
68 +EXPORT_SYMBOL(omap3_mpu_rate_table);
69  
70  struct omap_opp omap3_l3_rate_table[] = {
71         {0, 0, 0},
72 @@ -76,25 +74,23 @@
73  
74  struct omap_opp omap3_dsp_rate_table[] = {
75         {0, 0, 0},
76 -       /*underclocking*/
77 -       {S90M,  1, 0x1E},
78         /*default*/
79 -       {S90M,  2, 0x1E},
80 -       {S180M, 3, 0x26},
81 -       {S360M, 4, 0x30},
82 -       {S400M, 5, 0x36},
83 -       {S430M, 6, 0x3C},
84 +       {S90M,  VDD1_OPP1,  0x1E},
85 +       {S180M, VDD1_OPP2,  0x26},
86 +       {S360M, VDD1_OPP3,  0x30},
87 +       {S400M, VDD1_OPP4,  0x36},
88 +       {S430M, VDD1_OPP5,  0x3C},
89         /*overclocking*/
90 -       {S430M, 7, 0x3C},
91 -       {S430M, 8, 0x3C},
92 -       {S430M, 9, 0x3C},/*800MHz*/
93 -       {S500M, 10, 0x3C},
94 -       {S500M, 11, 0x3C},
95 -       {S500M, 12, 0x3C},
96 -       {S500M, 13, 0x3C},
97 -       {S520M, 14, 0x48},
98 -       {S520M, 15, 0x48},
99 +       {S520M, VDD1_OPP6,  0x3C},
100 +       {S520M, VDD1_OPP7,  0x3C},
101 +       {S520M, VDD1_OPP8,  0x3C},
102 +       {S520M, VDD1_OPP9,  0x3C},
103 +       {S520M, VDD1_OPP10, 0x3C},
104 +       {S520M, VDD1_OPP11, 0x3C},
105 +       {S520M, VDD1_OPP12, 0x48},
106 +       {S520M, VDD1_OPP13, 0x48},
107  };
108 +EXPORT_SYMBOL(omap3_dsp_rate_table);
109  
110  unsigned short enable_dyn_sleep;
111  unsigned short clocks_off_while_idle;
112 @@ -342,13 +338,13 @@
113         }
114  
115         if (attr == &vdd1_opp_attr) {
116 -               if (value < 1 || value > 5) {
117 +               if (value < MIN_VDD1_OPP || value > MAX_VDD1_OPP) {
118                         printk(KERN_ERR "vdd_opp_store: Invalid value\n");
119                         return -EINVAL;
120                 }
121                 resource_set_opp_level(PRCM_VDD1, value, flags);
122         } else if (attr == &vdd2_opp_attr) {
123 -               if (value < 1 || value > 3) {
124 +               if (value < MIN_VDD2_OPP || value > MAX_VDD2_OPP) {
125                         printk(KERN_ERR "vdd_opp_store: Invalid value\n");
126                         return -EINVAL;
127                 }
128 diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/resource34xx.c kernel-power-2.6.28.new/arch/arm/mach-omap2/resource34xx.c
129 --- kernel-power-2.6.28/arch/arm/mach-omap2/resource34xx.c      2012-01-07 13:49:16.527031015 +0000
130 +++ kernel-power-2.6.28.new/arch/arm/mach-omap2/resource34xx.c  2011-12-31 12:54:23.772101815 +0000
131 @@ -279,7 +279,7 @@
132  
133  #ifdef CONFIG_OMAP_SMARTREFLEX
134         sr_status = sr_stop_vddautocomap((get_vdd(t_opp) == PRCM_VDD1) ?
135 -                       SR1 : SR2);
136 +                       SR1 : SR2,opp[current_level].opp_id);
137  #endif
138         for (i = 0; i < 2; i++) {
139                 if (i == raise)
140 diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c kernel-power-2.6.28.new/arch/arm/mach-omap2/smartreflex.c
141 --- kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.c       2012-01-07 13:49:16.583042210 +0000
142 +++ kernel-power-2.6.28.new/arch/arm/mach-omap2/smartreflex.c   2012-01-06 20:56:55.000000000 +0000
143 @@ -37,6 +37,7 @@
144  #include "prm.h"
145  #include "smartreflex.h"
146  #include "prm-regbits-34xx.h"
147 +#include "omap3-opp.h"
148  
149  /*
150   * VP_TRANXDONE_TIMEOUT: maximum microseconds to wait for the VP to
151 @@ -73,6 +74,23 @@
152   */
153  #define SR_DISABLE_MAX_ATTEMPTS 4
154  
155 +#define ACCURACY               100
156 +#define NDELTA_3430            (3.0 * ACCURACY)
157 +#define PDELTA_3430            (2.6 * ACCURACY)
158 +
159 +/* Since factory calibrated Efuse values lead to very high SR calculated voltages
160 + * adjust them with a constant
161 + */
162 +#define SR_NVALUE_ADJUST_LOWOPP   -150000 /* For 125 and 250 MHz */
163 +#define SR_NVALUE_ADJUST_HIGHOPP  -125000 /* For 500+ MHz */
164 +
165 +/* Boost voltage with the bellow value(in uV) when DSP frequency is >430 MHz and 
166 + * twice that value when DSP frequency is > 520 Mhz
167 + */
168 +#define SR_NVALUE_DSP_MAX_ADJUST 100000
169 +
170 +static atomic_t sr_vdd1_dsp_boost_coeff;
171 +
172  struct omap_sr {
173         int             srid;
174         int             is_sr_reset;
175 @@ -82,6 +100,7 @@
176         u32             req_opp_no;
177         u32             opp1_nvalue, opp2_nvalue, opp3_nvalue, opp4_nvalue;
178         u32             opp5_nvalue;
179 +       u32             opp6_nvalue, opp7_nvalue, opp8_nvalue, opp9_nvalue;
180         u32             senp_mod, senn_mod;
181         void __iomem    *srbase_addr;
182         void __iomem    *vpbase_addr;
183 @@ -101,6 +120,7 @@
184  
185         reg_val = __raw_readl(SR_REGADDR(offset));
186         reg_val &= ~mask;
187 +
188         reg_val |= value;
189  
190         __raw_writel(reg_val, SR_REGADDR(offset));
191 @@ -211,26 +231,173 @@
192         }
193  }
194  
195 +static u32 calculate_opp_nadj(u32 opp_value, u32 delta_n)
196 +{
197 +       u32 sen_ngain_fuse, sen_nrn_fuse;
198 +
199 +       sen_ngain_fuse = (opp_value & 0x000F0000) >> 0x10;
200 +       sen_nrn_fuse = (opp_value & 0x000000FF);
201 +
202 +       return ((1 << (sen_ngain_fuse + 8)) / sen_nrn_fuse) + delta_n;
203 +}
204 +
205 +static u32 calculate_opp_padj(u32 opp_value, u32 delta_p)
206 +{
207 +       u32 sen_pgain_fuse, sen_prn_fuse;
208 +
209 +       sen_pgain_fuse = (opp_value & 0x000F00000) >> 0x14;
210 +       sen_prn_fuse = (opp_value & 0x0000FF00) >> 8;
211 +
212 +       return ((1 << (sen_pgain_fuse + 8)) / sen_prn_fuse) + delta_p;
213 +}
214 +
215 +static u32 get_padj_for_freq(u32 opp0fuse,u32 opp1fuse, u32 freq)
216 +{
217 +       u32 padj_0=calculate_opp_padj(opp0fuse,0);
218 +       u32 padj_1=calculate_opp_padj(opp1fuse,0);
219 +       u32 p_slope_a=(1000*(padj_1-padj_0))/(250-125);
220 +       u32 p_slope_b=1000*(padj_1-p_slope_a*250/1000);
221 +
222 +       return (u32)(p_slope_a*freq+p_slope_b)/1000;
223 +}
224 +
225 +static u32 get_nadj_for_freq(u32 opp0fuse,u32 opp1fuse, u32 freq)
226 +{
227 +       u32 nadj_0=calculate_opp_nadj(opp0fuse,0);
228 +       u32 nadj_1=calculate_opp_nadj(opp1fuse,0);
229 +       u32 n_slope_a=(1000*(nadj_1-nadj_0))/(250-125);
230 +       u32 n_slope_b=1000*(nadj_1-n_slope_a*250/1000);
231 +
232 +       return (u32)(n_slope_a*freq+n_slope_b)/1000;
233 +}
234 +
235 +/**
236 + * recalc_with_margin() - helper to add margin to reciprocal and gain
237 + * @uv:                voltage in uVolts to add.
238 + * @soc_delta: SoC specific delta base
239 + * @reci:      Reciprocal for the sensor
240 + * @gain:      Gain for the sensor
241 + *
242 + * The algorithm computes an adjustment required to meet the delta voltage
243 + * to be added to a given sensor's reciprocal and gain. It then does a
244 + * search for maximum gain for valid reciprocal value. This forms the
245 + * new reciprocal and gain which incorporates the additional voltage
246 + * requested.
247 + *
248 + * IMPORTANT: since it is not possible to ascertain the actual voltage from
249 + * ntarget value, the additional voltage will be accurate upto 1 additional
250 + * pmic step. The algorithm is optimized to adjust to higher end rather than
251 + * less than requested additional voltage as it could be unsafe to run at
252 + * voltage lower than requested level.
253 + *
254 + * Example: if the PMIC step size is 12.5 and requested margin in 25mV(2 PMIC
255 + * steps). the actual voltage achieved can be original V achieved + 25mV upto
256 + * original V + 37.5mV(3 steps) - depending on where V was achieved.
257 + */
258 +static __init int recalc_with_margin(long uv, int soc_delta, unsigned int *reci,
259 +               unsigned int *gain)
260 +{
261 +       int r = 0, g = 0;
262 +       int nadj = 0;
263 +
264 +       nadj = ((1 << (*gain + 8)) * ACCURACY) / (*reci) +
265 +               soc_delta * uv / 1000;
266 +
267 +       /* Linear search for the best reciprocal */
268 +       for (g = 15; g >= 0; g--) {
269 +               r = ((1 << (g + 8)) * ACCURACY) / nadj;
270 +               if (r < 256) {
271 +                       *reci = r;
272 +                       *gain = g;
273 +                       return 0;
274 +               }
275 +       }
276 +       /* Dont modify the input, just return error */
277 +       return -EINVAL;
278 +}
279 +
280 +/**
281 + * sr_ntarget_add_margin() - Modify h/w ntarget to add a s/w margin
282 + * @vdata:     voltage data for the OPP to be modified with ntarget populated
283 + * @add_uv:    voltate to add to nTarget in uVolts
284 + *
285 + * Once the sr_device_init is complete and nTargets are populated, using this
286 + * function nTarget read from h/w efuse and stored in vdata is modified to add
287 + * a platform(board) specific additional voltage margin. Based on analysis,
288 + * we might need different margins to be added per vdata.
289 + */
290 +int __init sr_ntarget_add_margin(u32 old_ntarget, ulong add_uv)
291 +{
292 +       u32 temp_senp_gain, temp_senp_reciprocal;
293 +       u32 temp_senn_gain, temp_senn_reciprocal;
294 +       int soc_p_delta, soc_n_delta;
295 +       int r;
296 +
297 +       temp_senp_gain = (old_ntarget & 0x00F00000) >> 20;
298 +       temp_senn_gain = (old_ntarget & 0x000F0000) >> 16;
299 +       temp_senp_reciprocal = (old_ntarget & 0x0000FF00) >> 8;
300 +       temp_senn_reciprocal = old_ntarget & 0x000000FF;
301 +
302 +       soc_p_delta = PDELTA_3430;
303 +       soc_n_delta = NDELTA_3430;
304 +
305 +       r = recalc_with_margin(add_uv, soc_n_delta,
306 +                       &temp_senn_reciprocal, &temp_senn_gain);
307 +       if (r) {
308 +               pr_err("%s: unable to add %ld uV to ntarget 0x%08x\n",
309 +                       __func__, add_uv, old_ntarget);
310 +               return r;
311 +       }
312 +       r = recalc_with_margin(add_uv, soc_p_delta,
313 +                       &temp_senp_reciprocal, &temp_senp_gain);
314 +       if (r) {
315 +           pr_err("%s: unable to add %ld uV to ntarget 0x%08x\n",
316 +                       __func__, add_uv, old_ntarget);
317 +               return r;
318 +       }
319 +
320 +       /* Populate the new modified nTarget */
321 +       return (temp_senp_gain << 20) | (temp_senn_gain << 16) |
322 +                       (temp_senp_reciprocal << 8) | temp_senn_reciprocal;
323 +
324 +}
325 +
326 +static u32 calculate_freq_efuse_value(u32 opp0efuse,u32 opp1efuse,u32 freq)
327 +{
328 +       u32 sen_nrn, sen_ngain, sen_prn, sen_pgain;
329 +       u32 opp0efuse_adj = sr_ntarget_add_margin(opp0efuse,freq>S250M?SR_NVALUE_ADJUST_HIGHOPP:SR_NVALUE_ADJUST_LOWOPP);
330 +       u32 opp1efuse_adj = sr_ntarget_add_margin(opp1efuse,freq>S250M?SR_NVALUE_ADJUST_HIGHOPP:SR_NVALUE_ADJUST_LOWOPP);
331 +
332 +       freq/=1000000;
333 +       cal_reciprocal(get_padj_for_freq(opp0efuse_adj,opp1efuse_adj,freq), &sen_pgain, &sen_prn);
334 +       cal_reciprocal(get_nadj_for_freq(opp0efuse_adj,opp1efuse_adj,freq), &sen_ngain, &sen_nrn);
335 +
336 +       return (sen_pgain << 0x14) | (sen_ngain << 0x10)
337 +       | (sen_prn << 0x08) | (sen_nrn);
338 +}
339 +
340  static void sr_set_efuse_nvalues(struct omap_sr *sr)
341  {
342         if (sr->srid == SR1) {
343 +               u32 opp0efuse = omap_ctrl_readl(OMAP343X_CONTROL_FUSE_OPP1_VDD1);
344 +               u32 opp1efuse = omap_ctrl_readl(OMAP343X_CONTROL_FUSE_OPP2_VDD1);
345 +               
346                 sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
347                                         OMAP343X_SR1_SENNENABLE_MASK) >>
348                                         OMAP343X_SR1_SENNENABLE_SHIFT;
349                 sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
350                                         OMAP343X_SR1_SENPENABLE_MASK) >>
351                                         OMAP343X_SR1_SENPENABLE_SHIFT;
352 -
353 -               sr->opp5_nvalue = omap_ctrl_readl(
354 -                                       OMAP343X_CONTROL_FUSE_OPP5_VDD1);
355 -               sr->opp4_nvalue = omap_ctrl_readl(
356 -                                       OMAP343X_CONTROL_FUSE_OPP4_VDD1);
357 -               sr->opp3_nvalue = omap_ctrl_readl(
358 -                                       OMAP343X_CONTROL_FUSE_OPP3_VDD1);
359 -               sr->opp2_nvalue = omap_ctrl_readl(
360 -                                       OMAP343X_CONTROL_FUSE_OPP2_VDD1);
361 -               sr->opp1_nvalue = omap_ctrl_readl(
362 -                                       OMAP343X_CONTROL_FUSE_OPP1_VDD1);
363 +               
364 +               sr->opp1_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S125M);
365 +               sr->opp2_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S250M);
366 +               sr->opp3_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S500M);
367 +               sr->opp4_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S550M);
368 +               sr->opp5_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S600M);
369 +               sr->opp6_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S720M);
370 +               sr->opp7_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S805M);
371 +               sr->opp8_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S850M);
372 +               sr->opp9_nvalue = calculate_freq_efuse_value(opp0efuse,opp1efuse,S900M);
373         } else if (sr->srid == SR2) {
374                 sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
375                                         OMAP343X_SR2_SENNENABLE_MASK) >>
376 @@ -262,6 +429,14 @@
377                 sr->opp3_nvalue = cal_test_nvalue(0x85b + 0x200, 0x655 + 0x200);
378                 sr->opp2_nvalue = cal_test_nvalue(0x506 + 0x1a0, 0x3be + 0x1a0);
379                 sr->opp1_nvalue = cal_test_nvalue(0x373 + 0x100, 0x28c + 0x100);
380 +               sr->opp6_nvalue = calculate_freq_efuse_value(sr->opp1_nvalue,sr->opp2_nvalue,
381 +                                                            mpu_opps[VDD1_OPP6].rate/1000000);
382 +               sr->opp7_nvalue = calculate_freq_efuse_value(sr->opp1_nvalue,sr->opp2_nvalue,
383 +                                                            mpu_opps[VDD1_OPP7].rate/1000000);
384 +               sr->opp8_nvalue = calculate_freq_efuse_value(sr->opp1_nvalue,sr->opp2_nvalue,
385 +                                                            mpu_opps[VDD1_OPP8].rate/1000000);
386 +               sr->opp9_nvalue = calculate_freq_efuse_value(sr->opp1_nvalue,sr->opp2_nvalue,
387 +                                                            mpu_opps[VDD1_OPP9].rate/1000000);
388         } else if (sr->srid == SR2) {
389                 sr->senp_mod = 0x03;
390                 sr->senn_mod = 0x03;
391 @@ -426,7 +601,7 @@
392         sr->is_sr_reset = 0;
393  }
394  
395 -static int sr_reset_voltage(int srid)
396 +static int sr_reset_voltage(int srid,u32 curr_opp_no)
397  {
398         u32 target_opp_no, vsel = 0;
399         u32 reg_addr = 0;
400 @@ -443,6 +618,14 @@
401                 reg_addr = R_VDD1_SR_CONTROL;
402                 prm_vp1_voltage = prm_read_mod_reg(OMAP3430_GR_MOD,
403                                                 OMAP3_PRM_VP1_VOLTAGE_OFFSET);
404 +               /* Store current calibrated voltage to be used next time preventing
405 +                * overvoltage when calibration cycle  starts. if cur_opp_no is 0 don't
406 +                * store current voltage, we've been called from sram_idle().
407 +                * Just in case add 2 to it, so we can start a little higher next time
408 +                */
409 +               if(curr_opp_no)
410 +                       mpu_opps[curr_opp_no].vsel = min((u32)mpu_opps[curr_opp_no].vsel,
411 +                                                         prm_vp1_voltage+2);
412                 t2_smps_steps = abs(vsel - prm_vp1_voltage);
413                 errorgain = (target_opp_no > SR_MAX_LOW_OPP) ?
414                         PRM_VP1_CONFIG_ERRORGAIN_HIGHOPP :
415 @@ -507,13 +690,24 @@
416  {
417         u32 nvalue_reciprocal, v;
418         u8 errminlimit;
419 -
420         BUG_ON(!(mpu_opps && l3_opps));
421 -
422 +
423         sr->req_opp_no = target_opp_no;
424  
425         if (sr->srid == SR1) {
426 -               switch (min(target_opp_no-1,5)) {
427 +               switch (min(target_opp_no,(u32)PRCM_NO_VDD1_OPPS)) {
428 +               case 9:
429 +                       nvalue_reciprocal = sr->opp9_nvalue;
430 +                       break;
431 +               case 8:
432 +                       nvalue_reciprocal = sr->opp8_nvalue;
433 +                       break;
434 +               case 7:
435 +                       nvalue_reciprocal = sr->opp7_nvalue;
436 +                       break;
437 +               case 6:
438 +                       nvalue_reciprocal = sr->opp6_nvalue;
439 +                       break;
440                 case 5:
441                         nvalue_reciprocal = sr->opp5_nvalue;
442                         break;
443 @@ -531,9 +725,24 @@
444                         nvalue_reciprocal = sr->opp1_nvalue;
445                         break;
446                 default:
447 -                       nvalue_reciprocal = sr->opp3_nvalue;
448 +                       nvalue_reciprocal = sr->opp9_nvalue;
449                         break;
450                 }
451 +               /* give more juice when DSP is active and overclocked */
452 +               if(omap_pm_dsp_get_min_opp() > VDD1_OPP1 && dsp_opps[target_opp_no].rate > S430M)
453 +               {
454 +                       /* DSP is active and overclocked, boost voltage based on overclocking percent
455 +                          and target OPP
456 +                        */
457 +                       u32 dsp_volt_boost = ((dsp_opps[target_opp_no].rate-S430M)/1000000) *
458 +                                             atomic_read(&sr_vdd1_dsp_boost_coeff) *
459 +                                             (VDD1_OPP9-target_opp_no);
460 +                       dsp_volt_boost = dsp_volt_boost > SR_NVALUE_DSP_MAX_ADJUST ? SR_NVALUE_DSP_MAX_ADJUST : dsp_volt_boost;
461 +                       nvalue_reciprocal = sr_ntarget_add_margin(nvalue_reciprocal,dsp_volt_boost);
462 +                       mpu_opps[target_opp_no].vsel += (dsp_volt_boost/12500);
463 +                       mpu_opps[target_opp_no].vsel = mpu_opps[target_opp_no].vsel > (PRM_VP1_VLIMITTO_VDDMAX >> 24) ?
464 +                               PRM_VP1_VLIMITTO_VDDMAX >> 24 : mpu_opps[target_opp_no].vsel;
465 +               }
466         } else {
467                 switch (target_opp_no) {
468                 case 3:
469 @@ -556,7 +765,6 @@
470                                                                 target_opp_no);
471                 return SR_FALSE;
472         }
473 -
474         sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
475  
476         /* Enable the interrupt */
477 @@ -772,7 +980,7 @@
478  }
479  EXPORT_SYMBOL(sr_start_vddautocomap);
480  
481 -int sr_stop_vddautocomap(int srid)
482 +int sr_stop_vddautocomap(int srid,u32 cur_opp_no)
483  {
484         struct omap_sr *sr = NULL;
485  
486 @@ -789,7 +997,7 @@
487                 sr_clk_disable(sr);
488                 sr->is_autocomp_active = 0;
489                 /* Reset the volatage for current OPP */
490 -               sr_reset_voltage(srid);
491 +               sr_reset_voltage(srid,cur_opp_no);
492                 return SR_TRUE;
493         } else
494                 return SR_FALSE;
495 @@ -823,7 +1031,7 @@
496         }
497  }
498  
499 -void disable_smartreflex(int srid)
500 +void disable_smartreflex(int srid,u32 cur_opp_no)
501  {
502         struct omap_sr *sr = NULL;
503  
504 @@ -843,7 +1051,7 @@
505                         /* Disable SR clk */
506                         sr_clk_disable(sr);
507                         /* Reset the volatage for current OPP */
508 -                       sr_reset_voltage(srid);
509 +                       sr_reset_voltage(srid,cur_opp_no);
510                 }
511         }
512  }
513 @@ -953,22 +1161,22 @@
514                                         const char *buf, size_t n)
515  {
516         unsigned short value;
517 -
518 +       u32 current_vdd1opp_no;
519         if (sscanf(buf, "%hu", &value) != 1 || (value > 1)) {
520                 printk(KERN_ERR "sr_vdd1_autocomp: Invalid value\n");
521                 return -EINVAL;
522         }
523  
524         mutex_lock(&dvfs_mutex);
525 +       current_vdd1opp_no = resource_get_level("vdd1_opp");
526 +       if (IS_ERR_VALUE(current_vdd1opp_no)) {
527 +               mutex_unlock(&dvfs_mutex);
528 +               return -ENODEV;
529 +       }
530  
531         if (value == 0) {
532 -               sr_stop_vddautocomap(SR1);
533 +               sr_stop_vddautocomap(SR1,current_vdd1opp_no);
534         } else {
535 -               u32 current_vdd1opp_no = resource_get_level("vdd1_opp");
536 -               if (IS_ERR_VALUE(current_vdd1opp_no)) {
537 -                       mutex_unlock(&dvfs_mutex);
538 -                       return -ENODEV;
539 -               }
540                 sr_start_vddautocomap(SR1, current_vdd1opp_no);
541         }
542  
543 @@ -1008,9 +1216,13 @@
544         mutex_lock(&dvfs_mutex);
545  
546         current_vdd2opp_no = resource_get_level("vdd2_opp");
547 +       if (IS_ERR_VALUE(current_vdd2opp_no)) {
548 +               mutex_unlock(&dvfs_mutex);
549 +               return -ENODEV;
550 +       }
551  
552         if (value == 0)
553 -               sr_stop_vddautocomap(SR2);
554 +               sr_stop_vddautocomap(SR2, current_vdd2opp_no);
555         else
556                 sr_start_vddautocomap(SR2, current_vdd2opp_no);
557  
558 @@ -1028,30 +1240,128 @@
559         .store = omap_sr_vdd2_autocomp_store,
560  };
561  
562 -static ssize_t omap_sr_opp1_efuse_show(struct kobject *kobj,
563 +static ssize_t omap_sr_efuse_vdd1_show(struct kobject *kobj,
564                                         struct kobj_attribute *attr,
565                                         char *buf)
566  {
567 -       return sprintf(buf, "%08x\n%08x\n%08x\n%08x\n%08x\n", sr1.opp1_nvalue,
568 +       return sprintf(buf, "%08x\n%08x\n%08x\n%08x\n%08x\n%08x\n%08x\n%08x\n%08x\n",
569 +                                                       sr1.opp1_nvalue,
570                                                         sr1.opp2_nvalue,
571                                                         sr1.opp3_nvalue,
572                                                         sr1.opp4_nvalue,
573 -                                                       sr1.opp5_nvalue);
574 +                                                       sr1.opp5_nvalue,
575 +                                                       sr1.opp6_nvalue,
576 +                                                       sr1.opp7_nvalue,
577 +                                                       sr1.opp8_nvalue,
578 +                                                       sr1.opp9_nvalue
579 +                      );
580  }
581  
582 -static struct kobj_attribute sr_efuse = {
583 +static struct kobj_attribute sr_efuse_vdd1 = {
584         .attr = {
585 -       .name = "Efuse",
586 +       .name = "efuse_vdd1",
587         .mode = 0444,
588         },
589 -       .show = omap_sr_opp1_efuse_show,
590 +       .show = omap_sr_efuse_vdd1_show,
591 +};
592 +
593 +static ssize_t omap_sr_vdd1_voltage_show(struct kobject *kobj,
594 +                                       struct kobj_attribute *attr,
595 +                                       char *buf)
596 +{
597 +       u32 prm_vp1_voltage;
598 +       mutex_lock(&dvfs_mutex);
599 +       prm_vp1_voltage = prm_read_mod_reg(OMAP3430_GR_MOD,
600 +                                          OMAP3_PRM_VP1_VOLTAGE_OFFSET);
601 +       mutex_unlock(&dvfs_mutex);
602 +       return sprintf(buf,"%u\n",prm_vp1_voltage);
603 +}
604 +
605 +static struct kobj_attribute sr_vdd1_voltage = {
606 +       .attr = {
607 +       .name = "sr_vdd1_voltage",
608 +       .mode = 0444,
609 +       },
610 +       .show = omap_sr_vdd1_voltage_show,
611 +};
612 +
613 +static ssize_t omap_sr_efuse_vdd2_show(struct kobject *kobj,
614 +                                       struct kobj_attribute *attr,
615 +                                       char *buf)
616 +{
617 +       return sprintf(buf, "%08x\n%08x\n%08x\n",       sr2.opp1_nvalue,
618 +                                                       sr2.opp2_nvalue,
619 +                                                       sr2.opp3_nvalue
620 +                      );
621 +}
622 +
623 +static struct kobj_attribute sr_efuse_vdd2 = {
624 +       .attr = {
625 +       .name = "efuse_vdd2",
626 +       .mode = 0444,
627 +       },
628 +       .show = omap_sr_efuse_vdd2_show,
629 +};
630 +
631 +static ssize_t omap_sr_vdd2_voltage_show(struct kobject *kobj,
632 +                                       struct kobj_attribute *attr,
633 +                                       char *buf)
634 +{
635 +       u32 prm_vp2_voltage;
636 +       mutex_lock(&dvfs_mutex);
637 +       prm_vp2_voltage = prm_read_mod_reg(OMAP3430_GR_MOD,
638 +                                          OMAP3_PRM_VP2_VOLTAGE_OFFSET);
639 +       mutex_unlock(&dvfs_mutex);
640 +       return sprintf(buf,"%u\n",prm_vp2_voltage);
641 +}
642 +
643 +static struct kobj_attribute sr_vdd2_voltage = {
644 +       .attr = {
645 +       .name = "sr_vdd2_voltage",
646 +       .mode = 0444,
647 +       },
648 +       .show = omap_sr_vdd2_voltage_show,
649 +};
650 +
651 +static ssize_t omap_sr_vdd1_dsp_boost_show(struct kobject *kobj,
652 +                                       struct kobj_attribute *attr,
653 +                                       char *buf)
654 +{
655 +       return sprintf(buf,"%u\n",atomic_read(&sr_vdd1_dsp_boost_coeff));
656 +}
657 +
658 +static ssize_t omap_sr_vdd1_dsp_boost_store(struct kobject *kobj,
659 +                                       struct kobj_attribute *attr,
660 +                                       const char *buf, size_t n)
661 +{
662 +       u32 value;
663 +
664 +       if (sscanf(buf, "%u", &value) != 1 || (value > 250)) {
665 +               printk(KERN_ERR "sr_vdd1_dsp_boost: Invalid value\n");
666 +               return -EINVAL;
667 +       }
668 +       atomic_set(&sr_vdd1_dsp_boost_coeff,value);
669 +
670 +       return n;
671 +}
672 +
673 +static struct kobj_attribute sr_vdd1_dsp_boost = {
674 +       .attr = {
675 +       .name = __stringify(sr_vdd1_dsp_boost),
676 +       .mode = 0644,
677 +       },
678 +       .show = omap_sr_vdd1_dsp_boost_show,
679 +       .store = omap_sr_vdd1_dsp_boost_store,
680  };
681  
682  static int __init omap3_sr_init(void)
683  {
684         int ret = 0;
685         u8 RdReg;
686 -
687 +
688 +       /* Set default dsp boost value */
689 +       atomic_set(&sr_vdd1_dsp_boost_coeff,125);
690 +
691         /* Enable SR on T2 */
692         ret = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &RdReg,
693                                         R_DCDC_GLOBAL_CFG);
694 @@ -1084,9 +1394,25 @@
695         if (ret)
696                 printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
697  
698 -       ret = sysfs_create_file(power_kobj, &sr_efuse.attr);
699 +       ret = sysfs_create_file(power_kobj, &sr_efuse_vdd1.attr);
700 +       if (ret)
701 +               printk(KERN_ERR "sysfs_create_file failed for VDD1 efuse data: %d\n", ret);
702 +
703 +       ret = sysfs_create_file(power_kobj, &sr_vdd1_voltage.attr);
704 +       if (ret)
705 +               printk(KERN_ERR "sysfs_create_file failed for VDD1 voltage data: %d\n", ret);
706 +
707 +       ret = sysfs_create_file(power_kobj, &sr_efuse_vdd2.attr);
708 +       if (ret)
709 +               printk(KERN_ERR "sysfs_create_file failed for VDD2 efuse data: %d\n", ret);
710 +
711 +       ret = sysfs_create_file(power_kobj, &sr_vdd2_voltage.attr);
712 +       if (ret)
713 +               printk(KERN_ERR "sysfs_create_file failed for VDD2 voltage data: %d\n", ret);
714 +
715 +       ret = sysfs_create_file(power_kobj, &sr_vdd1_dsp_boost.attr);
716         if (ret)
717 -               printk(KERN_ERR "sysfs_create_file failed for OPP data: %d\n", ret);
718 +               printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
719  
720         return 0;
721  }
722 diff -urN kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.h kernel-power-2.6.28.new/arch/arm/mach-omap2/smartreflex.h
723 --- kernel-power-2.6.28/arch/arm/mach-omap2/smartreflex.h       2012-01-07 13:49:16.543132598 +0000
724 +++ kernel-power-2.6.28.new/arch/arm/mach-omap2/smartreflex.h   2011-12-31 12:54:23.820044299 +0000
725 @@ -63,7 +63,7 @@
726  
727  /* PRM_VP1_VSTEPMAX */
728  #define PRM_VP1_VSTEPMAX_SMPSWAITTIMEMAX       (0x01F4 << 8)
729 -#define PRM_VP1_VSTEPMAX_VSTEPMAX              (0x04 << 0)
730 +#define PRM_VP1_VSTEPMAX_VSTEPMAX              (0x01 << 0)
731  
732  /* PRM_VP1_VLIMITTO */
733  #define PRM_VP1_VLIMITTO_VDDMAX                (0x3C << 24)
734 @@ -240,7 +240,15 @@
735                                         ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x4))
736  #define PRCM_VDD1_OPP5         (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
737                                         ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x5))
738 -#define PRCM_NO_VDD1_OPPS      5
739 +#define PRCM_VDD1_OPP6         (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
740 +                                       ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x6))
741 +#define PRCM_VDD1_OPP7         (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
742 +                                       ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x7))
743 +#define PRCM_VDD1_OPP8         (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
744 +                                       ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x8))
745 +#define PRCM_VDD1_OPP9         (OMAP(AT_3430_ES2) | OTHER_ID_TYPE(ID_OPP) | \
746 +                                       ID_VDD(PRCM_VDD1) | ID_OPP_NO(0x9))
747 +#define PRCM_NO_VDD1_OPPS      VDD1_OPP9
748  
749  
750  /* VDD2 OPPs */
751 @@ -254,7 +262,7 @@
752  /* XXX: end remove/move */
753  
754  /* SR_MAX_LOW_OPP: the highest of the "low OPPs", 1 and 2. */
755 -#define SR_MAX_LOW_OPP         3
756 +#define SR_MAX_LOW_OPP         VDD1_OPP2
757  
758  /* XXX: find more appropriate place for these once DVFS is in place */
759  extern u32 current_vdd1_opp;
760 @@ -273,10 +281,10 @@
761   */
762  #ifdef CONFIG_OMAP_SMARTREFLEX
763  void enable_smartreflex(int srid);
764 -void disable_smartreflex(int srid);
765 +void disable_smartreflex(int srid,u32 cur_opp_no);
766  int sr_voltagescale_vcbypass(u32 t_opp, u32 c_opp, u8 t_vsel, u8 c_vsel);
767  void sr_start_vddautocomap(int srid, u32 target_opp_no);
768 -int sr_stop_vddautocomap(int srid);
769 +int sr_stop_vddautocomap(int srid,u32 cur_opp_no);
770  #else
771  static inline void enable_smartreflex(int srid) {}
772  static inline void disable_smartreflex(int srid) {}
773 diff -urN kernel-power-2.6.28/arch/arm/plat-omap/include/mach/omap34xx.h kernel-power-2.6.28.new/arch/arm/plat-omap/include/mach/omap34xx.h
774 --- kernel-power-2.6.28/arch/arm/plat-omap/include/mach/omap34xx.h      2012-01-07 13:49:16.503856035 +0000
775 +++ kernel-power-2.6.28.new/arch/arm/plat-omap/include/mach/omap34xx.h  2011-12-31 12:54:23.820044299 +0000
776 @@ -107,6 +107,14 @@
777  #define VDD1_OPP3      0x3
778  #define VDD1_OPP4      0x4
779  #define VDD1_OPP5      0x5
780 +#define VDD1_OPP6      0x6
781 +#define VDD1_OPP7      0x7
782 +#define VDD1_OPP8      0x8
783 +#define VDD1_OPP9      0x9
784 +#define VDD1_OPP10     0xA
785 +#define VDD1_OPP11     0xB
786 +#define VDD1_OPP12     0xC
787 +#define VDD1_OPP13     0xD
788  
789  /* VDD2 OPPS */
790  #define VDD2_OPP1      0x1
791 @@ -114,8 +122,7 @@
792  #define VDD2_OPP3      0x3
793  
794  #define MIN_VDD1_OPP   VDD1_OPP1
795 -/*#define MAX_VDD1_OPP VDD1_OPP5*/
796 -#define MAX_VDD1_OPP   15
797 +#define MAX_VDD1_OPP   VDD1_OPP13
798  #define MIN_VDD2_OPP   VDD2_OPP1
799  #define MAX_VDD2_OPP   VDD2_OPP3
800  
801 diff -urN kernel-power-2.6.28/arch/arm/plat-omap/include/mach/omap-pm.h kernel-power-2.6.28.new/arch/arm/plat-omap/include/mach/omap-pm.h
802 --- kernel-power-2.6.28/arch/arm/plat-omap/include/mach/omap-pm.h       2012-01-07 13:49:16.487184834 +0000
803 +++ kernel-power-2.6.28.new/arch/arm/plat-omap/include/mach/omap-pm.h   2012-01-06 07:35:45.000000000 +0000
804 @@ -280,6 +280,17 @@
805  #else
806  void omap_pm_dsp_set_min_opp(u8 opp_id);
807  #endif
808 +
809 +/**
810 + * omap_pm_dsp_get_min_opp - return desired minimum OPP ID from DSP Bridge
811 + *
812 + * Get a minimum OPP ID for the DSP.
813 + */
814 +#ifdef CONFIG_OMAP_PM_NONE
815 +static inline u8 omap_pm_dsp_get_min_opp(void) { }
816 +#else
817 +u8 omap_pm_dsp_get_min_opp(void);
818 +#endif
819  
820  /**
821   * omap_pm_dsp_get_opp - report the current DSP OPP ID
822 diff -urN kernel-power-2.6.28/arch/arm/plat-omap/omap-pm-srf.c kernel-power-2.6.28.new/arch/arm/plat-omap/omap-pm-srf.c
823 --- kernel-power-2.6.28/arch/arm/plat-omap/omap-pm-srf.c        2012-01-07 13:49:16.470963471 +0000
824 +++ kernel-power-2.6.28.new/arch/arm/plat-omap/omap-pm-srf.c    2012-01-07 13:45:44.000000000 +0000
825 @@ -36,6 +36,20 @@
826  #define LAT_RES_POSTAMBLE "_latency"
827  #define MAX_LATENCY_RES_NAME 30
828  
829 +atomic_t dsp_min_opp;
830 +/*
831 + * Smartreflex module enable/disable interface.
832 + * NOTE: if smartreflex is not enabled from sysfs, these functions will not
833 + * do anything.
834 + */
835 +#ifdef CONFIG_OMAP_SMARTREFLEX
836 +void sr_start_vddautocomap(int srid, u32 target_opp_no);
837 +int sr_stop_vddautocomap(int srid,u32 cur_opp_no);
838 +/* SR Modules */
839 +#define SR1            1
840 +#define SR2            2
841 +#endif
842 +
843  /**
844   * get_lat_res_name - gets the latency resource name given a power domain name
845   * @pwrdm_name: Name of the power domain.
846 @@ -205,13 +219,29 @@
847  
848  void omap_pm_dsp_set_min_opp(u8 opp_id)
849  {
850 +       u8 curr_dsp_min_opp;
851 +       pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id);
852         if (opp_id == 0) {
853                 WARN_ON(1);
854                 return;
855         }
856  
857 -       pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id);
858 -
859 +       curr_dsp_min_opp = omap_pm_dsp_get_min_opp();
860 +       atomic_set(&dsp_min_opp,opp_id);
861 +#ifdef CONFIG_OMAP_SMARTREFLEX
862 +       if(curr_dsp_min_opp == VDD1_OPP1 || opp_id == VDD1_OPP1)
863 +       {
864 +               /* DSP is about to be enabled/disabled, restart SR,
865 +                * so DSP voltage boost to be applied or removed.
866 +                * This is needed in case current OPP has DSP overclocking frequency
867 +                */
868 +               u8 curr_opp = omap_pm_dsp_get_opp();
869 +
870 +               if(sr_stop_vddautocomap(SR1 , curr_opp))
871 +                       sr_start_vddautocomap(SR1 , curr_opp);
872 +
873 +       }
874 +#endif
875         /*
876          * For now pass a dummy_dev struct for SRF to identify the caller.
877          * Maybe its good to have DSP pass this as an argument
878 @@ -221,6 +251,12 @@
879  }
880  EXPORT_SYMBOL(omap_pm_dsp_set_min_opp);
881  
882 +u8 omap_pm_dsp_get_min_opp(void)
883 +{
884 +       return atomic_read(&dsp_min_opp);
885 +}
886 +EXPORT_SYMBOL(omap_pm_dsp_get_min_opp);
887 +
888  u8 omap_pm_dsp_get_opp(void)
889  {
890         pr_debug("OMAP PM: DSP requests current DSP OPP ID\n");
891 @@ -341,6 +377,7 @@
892         mpu_opps = mpu_opp_table;
893         dsp_opps = dsp_opp_table;
894         l3_opps = l3_opp_table;
895 +       atomic_set(&dsp_min_opp,VDD1_OPP1);
896         return 0;
897  }
898