diff options
author | Franklin S. Cooper Jr <fcooper@ti.com> | 2013-06-27 10:57:32 -0500 |
---|---|---|
committer | Denys Dmytriyenko <denys@ti.com> | 2013-07-02 11:59:19 -0400 |
commit | 5f945012c9705a23a3eb9a2827807e3c3ed263a1 (patch) | |
tree | e7d2685835499382b4db85a1b29844f27430d20f | |
parent | 29719b15eededd6a3f9b985d1fa2304d3aa9de77 (diff) | |
download | meta-ti-5f945012c9705a23a3eb9a2827807e3c3ed263a1.tar.gz |
linux-am335x-psp: Add patch to enable SR on PG 2.x boards.
* Add patch that enables Smart Reflex on new PG 2.x boards.
Signed-off-by: Franklin S. Cooper Jr <fcooper@ti.com>
Signed-off-by: Denys Dmytriyenko <denys@ti.com>
-rw-r--r-- | recipes-kernel/linux/linux-am335x-psp-3.2/0001-Smartreflex-support-for-ES-2.x-and-suspend-resume.patch | 1928 | ||||
-rw-r--r-- | recipes-kernel/linux/linux-am335x-psp_3.2.bb | 3 |
2 files changed, 1930 insertions, 1 deletions
diff --git a/recipes-kernel/linux/linux-am335x-psp-3.2/0001-Smartreflex-support-for-ES-2.x-and-suspend-resume.patch b/recipes-kernel/linux/linux-am335x-psp-3.2/0001-Smartreflex-support-for-ES-2.x-and-suspend-resume.patch new file mode 100644 index 00000000..bc2b5c7a --- /dev/null +++ b/recipes-kernel/linux/linux-am335x-psp-3.2/0001-Smartreflex-support-for-ES-2.x-and-suspend-resume.patch | |||
@@ -0,0 +1,1928 @@ | |||
1 | From 4866616f13b397a07c06a45a34d050c1b4539e10 Mon Sep 17 00:00:00 2001 | ||
2 | From: Greg Guyotte <gguyotte@ti.com> | ||
3 | Date: Tue, 28 May 2013 20:45:07 -0500 | ||
4 | Subject: [PATCH] Smartreflex support for ES 2.x and suspend resume | ||
5 | |||
6 | This change adds support for ES 2.x to the SmartReflex driver. | ||
7 | It also adds suspend/resume handlers which resolves an identified | ||
8 | problem. The voltage calculation has been improved in order | ||
9 | to settle more quickly and accurately to the target voltage. | ||
10 | |||
11 | Signed-off-by: Greg Guyotte <gguyotte@ti.com> | ||
12 | --- | ||
13 | arch/arm/mach-omap2/am33xx-smartreflex-class2.c | 852 +++++++++++++---------- | ||
14 | arch/arm/mach-omap2/devices.c | 483 +++++++------ | ||
15 | arch/arm/plat-omap/include/plat/smartreflex.h | 72 +- | ||
16 | 3 files changed, 812 insertions(+), 595 deletions(-) | ||
17 | |||
18 | diff --git a/arch/arm/mach-omap2/am33xx-smartreflex-class2.c b/arch/arm/mach-omap2/am33xx-smartreflex-class2.c | ||
19 | index 6a66e68..4d750d4 100644 | ||
20 | --- a/arch/arm/mach-omap2/am33xx-smartreflex-class2.c | ||
21 | +++ b/arch/arm/mach-omap2/am33xx-smartreflex-class2.c | ||
22 | @@ -28,6 +28,7 @@ | ||
23 | #include <linux/regulator/consumer.h> | ||
24 | #include <linux/cpufreq.h> | ||
25 | #include <linux/opp.h> | ||
26 | +#include <linux/pm.h> | ||
27 | |||
28 | #include <plat/common.h> | ||
29 | #include <plat/smartreflex.h> | ||
30 | @@ -37,6 +38,9 @@ | ||
31 | |||
32 | #define CLK_NAME_LEN 40 | ||
33 | |||
34 | +/* Global reference used for suspend/resume only */ | ||
35 | +static struct am33xx_sr *global_sr_info; | ||
36 | + | ||
37 | static inline void sr_write_reg(struct am33xx_sr *sr, int offset, u32 value, | ||
38 | u32 srid) | ||
39 | { | ||
40 | @@ -60,63 +64,68 @@ static inline u32 sr_read_reg(struct am33xx_sr *sr, int offset, u32 srid) | ||
41 | return readl(sr->sen[srid].base + offset); | ||
42 | } | ||
43 | |||
44 | -static void cal_reciprocal(u32 sensor, u32 *sengain, u32 *rnsen) { | ||
45 | - u32 gn, rn, mul; | ||
46 | - | ||
47 | - for (gn = 0; gn < GAIN_MAXLIMIT; gn++) { | ||
48 | - mul = 1 << (gn + 8); | ||
49 | - rn = mul / sensor; | ||
50 | - if (rn < R_MAXLIMIT) { | ||
51 | - *sengain = gn; | ||
52 | - *rnsen = rn; | ||
53 | - } | ||
54 | - } | ||
55 | +static void cal_reciprocal(u32 sensor, u32 *sengain, u32 *rnsen) | ||
56 | +{ | ||
57 | + u32 gn, rn, mul; | ||
58 | + | ||
59 | + for (gn = 0; gn < GAIN_MAXLIMIT; gn++) { | ||
60 | + mul = 1 << (gn + 8); | ||
61 | + rn = mul / sensor; | ||
62 | + if (rn < R_MAXLIMIT) { | ||
63 | + *sengain = gn; | ||
64 | + *rnsen = rn; | ||
65 | + } | ||
66 | + } | ||
67 | } | ||
68 | |||
69 | -static u32 cal_test_nvalue(u32 sennval, u32 senpval) { | ||
70 | - u32 senpgain=0, senngain=0; | ||
71 | - u32 rnsenp=0, rnsenn=0; | ||
72 | +static u32 cal_test_nvalue(u32 sennval, u32 senpval) | ||
73 | +{ | ||
74 | + u32 senpgain = 0, senngain = 0; | ||
75 | + u32 rnsenp = 0, rnsenn = 0; | ||
76 | |||
77 | - /* Calculating the gain and reciprocal of the SenN and SenP values */ | ||
78 | - cal_reciprocal(senpval, &senpgain, &rnsenp); | ||
79 | - cal_reciprocal(sennval, &senngain, &rnsenn); | ||
80 | + /* Calculating the gain and reciprocal of the SenN and SenP values */ | ||
81 | + cal_reciprocal(senpval, &senpgain, &rnsenp); | ||
82 | + cal_reciprocal(sennval, &senngain, &rnsenn); | ||
83 | |||
84 | - return (senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) | | ||
85 | - (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) | | ||
86 | - (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) | | ||
87 | - (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT); | ||
88 | + return (senpgain << NVALUERECIPROCAL_SENPGAIN_SHIFT) | | ||
89 | + (senngain << NVALUERECIPROCAL_SENNGAIN_SHIFT) | | ||
90 | + (rnsenp << NVALUERECIPROCAL_RNSENP_SHIFT) | | ||
91 | + (rnsenn << NVALUERECIPROCAL_RNSENN_SHIFT); | ||
92 | } | ||
93 | |||
94 | +/* margin is defined similar to the SenVal register. | ||
95 | + SenP margin is 31:16 bits | ||
96 | + SenN margin is 15:00 bits | ||
97 | +*/ | ||
98 | static unsigned int sr_adjust_efuse_nvalue(unsigned int opp_no, | ||
99 | - unsigned int orig_opp_nvalue, | ||
100 | - unsigned int mv_delta) { | ||
101 | - unsigned int new_opp_nvalue; | ||
102 | - unsigned int senp_gain, senn_gain, rnsenp, rnsenn, pnt_delta, nnt_delta; | ||
103 | - unsigned int new_senn, new_senp, senn, senp; | ||
104 | + unsigned int orig_opp_nvalue, | ||
105 | + unsigned int margin) { | ||
106 | + unsigned int new_opp_nvalue, senp_gain, senn_gain, rnsenp, rnsenn; | ||
107 | + unsigned int pnt_delta, nnt_delta, new_senn, new_senp, senn, senp; | ||
108 | |||
109 | - /* calculate SenN and SenP from the efuse value */ | ||
110 | - senp_gain = ((orig_opp_nvalue >> 20) & 0xf); | ||
111 | - senn_gain = ((orig_opp_nvalue >> 16) & 0xf); | ||
112 | - rnsenp = ((orig_opp_nvalue >> 8) & 0xff); | ||
113 | - rnsenn = (orig_opp_nvalue & 0xff); | ||
114 | + /* calculate SenN and SenP from the efuse value */ | ||
115 | + senp_gain = ((orig_opp_nvalue >> 20) & 0xf); | ||
116 | + senn_gain = ((orig_opp_nvalue >> 16) & 0xf); | ||
117 | + rnsenp = ((orig_opp_nvalue >> 8) & 0xff); | ||
118 | + rnsenn = (orig_opp_nvalue & 0xff); | ||
119 | |||
120 | - senp = ((1<<(senp_gain+8))/(rnsenp)); | ||
121 | - senn = ((1<<(senn_gain+8))/(rnsenn)); | ||
122 | + senp = ((1<<(senp_gain+8))/(rnsenp)); | ||
123 | + senn = ((1<<(senn_gain+8))/(rnsenn)); | ||
124 | |||
125 | - /* calculate the voltage delta */ | ||
126 | - pnt_delta = (26 * mv_delta)/10; | ||
127 | - nnt_delta = (3 * mv_delta); | ||
128 | + /* calculate the voltage delta */ | ||
129 | + pnt_delta = (margin >> 16) & 0xffff; | ||
130 | + nnt_delta = margin & 0xffff; | ||
131 | |||
132 | - /* now lets add the voltage delta to the sensor values */ | ||
133 | - new_senn = senn + nnt_delta; | ||
134 | - new_senp = senp + pnt_delta; | ||
135 | + /* now lets add the voltage delta to the sensor values */ | ||
136 | + new_senn = senn + nnt_delta; | ||
137 | + new_senp = senp + pnt_delta; | ||
138 | |||
139 | - new_opp_nvalue = cal_test_nvalue(new_senn, new_senp); | ||
140 | + new_opp_nvalue = cal_test_nvalue(new_senn, new_senp); | ||
141 | |||
142 | - printk("Compensating OPP%d for %dmV Orig nvalue:0x%x New nvalue:0x%x \n", | ||
143 | - opp_no, mv_delta, orig_opp_nvalue, new_opp_nvalue); | ||
144 | + printk(KERN_DEBUG "Compensating OPP%d: Orig nvalue:0x%x New nvalue:0x%x\n", | ||
145 | + opp_no, orig_opp_nvalue, new_opp_nvalue); | ||
146 | |||
147 | - return new_opp_nvalue; | ||
148 | + return new_opp_nvalue; | ||
149 | } | ||
150 | |||
151 | /* irq_sr_reenable - Re-enable SR interrupts (triggered by delayed work queue) | ||
152 | @@ -128,55 +137,104 @@ static unsigned int sr_adjust_efuse_nvalue(unsigned int opp_no, | ||
153 | */ | ||
154 | static void irq_sr_reenable(struct work_struct *work) | ||
155 | { | ||
156 | - u32 srid; | ||
157 | + u32 srid; | ||
158 | struct am33xx_sr_sensor *sens; | ||
159 | - struct am33xx_sr *sr; | ||
160 | + struct am33xx_sr *sr; | ||
161 | |||
162 | - sens = container_of((void *)work, struct am33xx_sr_sensor, | ||
163 | - work_reenable); | ||
164 | + sens = container_of((void *)work, struct am33xx_sr_sensor, | ||
165 | + work_reenable); | ||
166 | |||
167 | - srid = sens->sr_id; | ||
168 | + srid = sens->sr_id; | ||
169 | |||
170 | - sr = container_of((void *)sens, struct am33xx_sr, sen[srid]); | ||
171 | + sr = container_of((void *)sens, struct am33xx_sr, sen[srid]); | ||
172 | |||
173 | - dev_dbg(&sr->pdev->dev, "%s: SR %d\n", __func__, srid); | ||
174 | + dev_dbg(&sr->pdev->dev, "%s: SR %d\n", __func__, srid); | ||
175 | |||
176 | - /* Must clear IRQ status */ | ||
177 | - sens->irq_status = 0; | ||
178 | + /* Must clear IRQ status */ | ||
179 | + sens->irq_status = 0; | ||
180 | |||
181 | - /* Re-enable the interrupt */ | ||
182 | + /* moved from initial irq handler to solve problem of extra | ||
183 | + interrupts (Clear bounds interrupt) */ | ||
184 | + sr_modify_reg(sr, IRQSTATUS, IRQSTATUS_MCBOUNDSINT, | ||
185 | + IRQSTATUS_MCBOUNDSINT, srid); | ||
186 | + | ||
187 | + /* Re-enable the interrupt */ | ||
188 | sr_modify_reg(sr, IRQENABLE_SET, IRQENABLE_MCUBOUNDSINT, | ||
189 | IRQENABLE_MCUBOUNDSINT, srid); | ||
190 | - | ||
191 | - /* Restart the module after voltage set */ | ||
192 | - sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, | ||
193 | - SRCONFIG_SRENABLE, srid); | ||
194 | } | ||
195 | |||
196 | /* get_errvolt - get error voltage from SR error register | ||
197 | * @sr: contains SR driver data | ||
198 | * @srid: contains the srid, indicates which SR moduel lswe are using | ||
199 | + * @curr_volt: current voltage for domain (in microvolts) | ||
200 | + * @reset: set to 1 to reset the internal state machine | ||
201 | * | ||
202 | - * Read the error from SENSOR error register and then convert | ||
203 | + * Reads the error from SENSOR error register and then convert | ||
204 | * to voltage delta, return value is the voltage delta in micro | ||
205 | * volt. | ||
206 | */ | ||
207 | -static int get_errvolt(struct am33xx_sr *sr, s32 srid) | ||
208 | +static int get_errvolt(struct am33xx_sr *sr, int srid, int curr_volt, | ||
209 | + int reset) | ||
210 | { | ||
211 | - struct am33xx_sr_sensor *sens; | ||
212 | - int senerror_reg; | ||
213 | - s32 uvoltage; | ||
214 | - s8 terror; | ||
215 | + struct am33xx_sr_sensor *sens; | ||
216 | + int senerror_reg, gain; | ||
217 | + s32 uvoltage = 0; | ||
218 | + s8 avg_error; | ||
219 | |||
220 | - sens = &sr->sen[srid]; | ||
221 | + sens = &sr->sen[srid]; | ||
222 | |||
223 | + /* used when OPP changes to reset the state machine */ | ||
224 | + if (reset > 0) { | ||
225 | + sens->state = 0; | ||
226 | + return 0; | ||
227 | + } | ||
228 | + | ||
229 | + /* Read the AvgError */ | ||
230 | senerror_reg = sr_read_reg(sr, SENERROR_V2, srid); | ||
231 | senerror_reg = (senerror_reg & 0x0000FF00); | ||
232 | - terror = (s8)(senerror_reg >> 8); | ||
233 | + avg_error = (s8)(senerror_reg >> 8); | ||
234 | + | ||
235 | + switch (sens->state) { | ||
236 | + case 0: /* save the current voltage and AvgError for state 1 */ | ||
237 | + sens->saved_volt = curr_volt; | ||
238 | + sens->avg_error_nom = avg_error; | ||
239 | + | ||
240 | + /* calculate -5% voltage (spec vmin) */ | ||
241 | + uvoltage = -(curr_volt * 5) / 100; | ||
242 | + | ||
243 | + sens->state = 1; | ||
244 | + break; | ||
245 | + case 1: /* guard against divide by zero (should not happen) */ | ||
246 | + if (sens->avg_error_nom == avg_error) { | ||
247 | + dev_err(&sr->pdev->dev, | ||
248 | + "%s: SR %d: Same AvgError for 2 different voltages\n", | ||
249 | + __func__, srid); | ||
250 | + sens->state = 0; | ||
251 | + break; | ||
252 | + } | ||
253 | |||
254 | - /* math defined in SR functional spec */ | ||
255 | - uvoltage = ((terror) * sr->uvoltage_step_size) >> 7; | ||
256 | - uvoltage = uvoltage * sens->opp_data[sens->curr_opp].e2v_gain; | ||
257 | + /* calculate what the gain should be based on slope */ | ||
258 | + gain = abs(sens->saved_volt - curr_volt) / | ||
259 | + abs(sens->avg_error_nom - avg_error); | ||
260 | + uvoltage = gain * avg_error; | ||
261 | + | ||
262 | + dev_dbg(&sr->pdev->dev, | ||
263 | + "SR %d: State 1 calculated %duV gain, vmin = %d\n", | ||
264 | + srid, gain, curr_volt + uvoltage); | ||
265 | + | ||
266 | + /* store computed gain for state 2 */ | ||
267 | + sens->opp_data[sens->curr_opp].e2v_gain = (gain / 100); | ||
268 | + sens->state = 2; | ||
269 | + break; | ||
270 | + case 2: /* remain in this state to converge to final voltage */ | ||
271 | + uvoltage = (avg_error * sr->uvoltage_step_size) >> 7; | ||
272 | + uvoltage = uvoltage * sens->opp_data[sens->curr_opp].e2v_gain; | ||
273 | + break; | ||
274 | + default: | ||
275 | + dev_err(&sr->pdev->dev, | ||
276 | + "%s: SR %d: Invalid state for get_errvolt\n", | ||
277 | + __func__, srid); | ||
278 | + } | ||
279 | |||
280 | return uvoltage; | ||
281 | } | ||
282 | @@ -204,48 +262,46 @@ static void set_voltage(struct work_struct *work) | ||
283 | |||
284 | sr = container_of((void *)work, struct am33xx_sr, work); | ||
285 | |||
286 | - for (i = 0; i < sr->no_of_sens; i++) { | ||
287 | - if (sr->sen[i].irq_status != 1) | ||
288 | - continue; | ||
289 | + for (i = 0; i < sr->no_of_sens; i++) { | ||
290 | + if (sr->sen[i].irq_status != 1) | ||
291 | + continue; | ||
292 | |||
293 | - /* Get the current voltage from PMIC */ | ||
294 | - prev_volt = regulator_get_voltage(sr->sen[i].reg); | ||
295 | + /* Get the current voltage from PMIC */ | ||
296 | + prev_volt = regulator_get_voltage(sr->sen[i].reg); | ||
297 | |||
298 | - if (prev_volt < 0) { | ||
299 | - dev_err(&sr->pdev->dev, | ||
300 | - "%s: SR %d: regulator_get_voltage error %d\n", | ||
301 | - __func__, i, prev_volt); | ||
302 | + if (prev_volt < 0) { | ||
303 | + dev_err(&sr->pdev->dev, | ||
304 | + "%s: SR %d: regulator_get_voltage error %d\n", | ||
305 | + __func__, i, prev_volt); | ||
306 | |||
307 | - goto reenable; | ||
308 | - } | ||
309 | + goto reenable; | ||
310 | + } | ||
311 | |||
312 | - delta_v = get_errvolt(sr, i); | ||
313 | - new_volt = prev_volt + delta_v; | ||
314 | + delta_v = get_errvolt(sr, i, prev_volt, 0); | ||
315 | + new_volt = prev_volt + delta_v; | ||
316 | |||
317 | - /* this is the primary output for debugging SR activity */ | ||
318 | - dev_dbg(&sr->pdev->dev, | ||
319 | - "%s: SR %d: prev volt=%d, delta_v=%d, req_volt=%d\n", | ||
320 | - __func__, i, prev_volt, delta_v, new_volt); | ||
321 | + if (delta_v != 0) { | ||
322 | + ret = regulator_set_voltage(sr->sen[i].reg, new_volt, | ||
323 | + new_volt + sr->uvoltage_step_size); | ||
324 | |||
325 | - /* Clear the counter, SR module disable */ | ||
326 | - sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, | ||
327 | - ~SRCONFIG_SRENABLE, i); | ||
328 | + if (ret < 0) | ||
329 | + dev_err(&sr->pdev->dev, | ||
330 | + "%s: regulator_set_voltage failed! (err %d)\n", | ||
331 | + __func__, ret); | ||
332 | + } | ||
333 | |||
334 | - if (delta_v != 0) { | ||
335 | - ret = regulator_set_voltage(sr->sen[i].reg, new_volt, | ||
336 | - new_volt + sr->uvoltage_step_size); | ||
337 | + /* this is the primary output for debugging SR activity */ | ||
338 | + printk(KERN_DEBUG "SR %d: curr=%d, delta_v=%d, calc=%d, act=%d, gain=%02x\n", | ||
339 | + i, prev_volt, delta_v, new_volt, | ||
340 | + regulator_get_voltage(sr->sen[i].reg), | ||
341 | + sr->sen[i].opp_data[sr->sen[i].curr_opp].e2v_gain); | ||
342 | |||
343 | - if (ret < 0) | ||
344 | - dev_err(&sr->pdev->dev, | ||
345 | - "%s: regulator_set_voltage failed! (err %d)\n", | ||
346 | - __func__, ret); | ||
347 | - } | ||
348 | reenable: | ||
349 | - /* allow time for voltage to settle before re-enabling SR | ||
350 | - module and interrupt */ | ||
351 | - schedule_delayed_work(&sr->sen[i].work_reenable, | ||
352 | - msecs_to_jiffies(sr->irq_delay)); | ||
353 | - } | ||
354 | + /* allow time for voltage to settle before re-enabling SR | ||
355 | + module and interrupt */ | ||
356 | + schedule_delayed_work(&sr->sen[i].work_reenable, | ||
357 | + msecs_to_jiffies(sr->irq_delay)); | ||
358 | + } | ||
359 | } | ||
360 | |||
361 | /* sr_class2_irq - sr irq handling | ||
362 | @@ -267,32 +323,28 @@ reenable: | ||
363 | static irqreturn_t sr_class2_irq(int irq, void *data) | ||
364 | { | ||
365 | u32 srid; | ||
366 | - struct am33xx_sr *sr; | ||
367 | - struct am33xx_sr_sensor *sr_sensor = (struct am33xx_sr_sensor *)data; | ||
368 | + struct am33xx_sr *sr; | ||
369 | + struct am33xx_sr_sensor *sr_sensor = (struct am33xx_sr_sensor *)data; | ||
370 | |||
371 | - srid = sr_sensor->sr_id; | ||
372 | + srid = sr_sensor->sr_id; | ||
373 | |||
374 | - sr = container_of(data, struct am33xx_sr, sen[srid]); | ||
375 | + sr = container_of(data, struct am33xx_sr, sen[srid]); | ||
376 | |||
377 | sr->sen[srid].irq_status = 1; | ||
378 | |||
379 | - /* Clear MCUBounds Interrupt */ | ||
380 | - sr_modify_reg(sr, IRQSTATUS, IRQSTATUS_MCBOUNDSINT, | ||
381 | - IRQSTATUS_MCBOUNDSINT, srid); | ||
382 | - | ||
383 | /* Disable the interrupt and re-enable in set_voltage() */ | ||
384 | sr_modify_reg(sr, IRQENABLE_CLR, IRQENABLE_MCUBOUNDSINT, | ||
385 | IRQENABLE_MCUBOUNDSINT, srid); | ||
386 | |||
387 | - /* Causes set_voltage() to get called at a later time. Set_voltage() | ||
388 | - will check the irq_status flags to determine which SR needs to | ||
389 | - be serviced. This was previously done with schedule_work, but | ||
390 | - I observed a crash in set_voltage() when changing OPPs on weak | ||
391 | - silicon, which may have been related to insufficient voltage | ||
392 | - settling time for OPP change. This additional delay avoids the | ||
393 | - crash. */ | ||
394 | - schedule_delayed_work(&sr->work, | ||
395 | - msecs_to_jiffies(250)); | ||
396 | + /* Causes set_voltage() to get called at a later time. Set_voltage() | ||
397 | + will check the irq_status flags to determine which SR needs to | ||
398 | + be serviced. This was previously done with schedule_work, but | ||
399 | + I observed a crash in set_voltage() when changing OPPs on weak | ||
400 | + silicon, which may have been related to insufficient voltage | ||
401 | + settling time for OPP change. This additional delay avoids the | ||
402 | + crash. */ | ||
403 | + schedule_delayed_work(&sr->work, | ||
404 | + msecs_to_jiffies(250)); | ||
405 | |||
406 | return IRQ_HANDLED; | ||
407 | } | ||
408 | @@ -317,31 +369,31 @@ static int sr_clk_disable(struct am33xx_sr *sr, u32 srid) | ||
409 | |||
410 | static inline int sr_set_nvalues(struct am33xx_sr *sr, u32 srid) | ||
411 | { | ||
412 | - int i; | ||
413 | - struct am33xx_sr_sensor *sens = &sr->sen[srid]; | ||
414 | + int i; | ||
415 | + struct am33xx_sr_sensor *sens = &sr->sen[srid]; | ||
416 | |||
417 | - for (i = 0; i < sens->no_of_opps; i++) { | ||
418 | - /* Read nTarget value form EFUSE register*/ | ||
419 | - sens->opp_data[i].nvalue = readl(AM33XX_CTRL_REGADDR | ||
420 | + for (i = 0; i < sens->no_of_opps; i++) { | ||
421 | + /* Read nTarget value form EFUSE register*/ | ||
422 | + sens->opp_data[i].nvalue = readl(AM33XX_CTRL_REGADDR | ||
423 | (sens->opp_data[i].efuse_offs)) & 0xFFFFFF; | ||
424 | |||
425 | - /* validate nTarget value */ | ||
426 | - if (sens->opp_data[i].nvalue == 0) | ||
427 | - return -EINVAL; | ||
428 | + /* validate nTarget value */ | ||
429 | + if (sens->opp_data[i].nvalue == 0) | ||
430 | + return -EINVAL; | ||
431 | |||
432 | - /* adjust nTarget based on margin in mv */ | ||
433 | - sens->opp_data[i].adj_nvalue = sr_adjust_efuse_nvalue(i, | ||
434 | - sens->opp_data[i].nvalue, | ||
435 | - sens->opp_data[i].margin); | ||
436 | + /* adjust nTarget based on margin in mv */ | ||
437 | + sens->opp_data[i].adj_nvalue = sr_adjust_efuse_nvalue(i, | ||
438 | + sens->opp_data[i].nvalue, | ||
439 | + sens->opp_data[i].margin); | ||
440 | |||
441 | - dev_dbg(&sr->pdev->dev, | ||
442 | - "NValueReciprocal value (from efuse) = %08x\n", | ||
443 | - sens->opp_data[i].nvalue); | ||
444 | + dev_dbg(&sr->pdev->dev, | ||
445 | + "NValueReciprocal value (from efuse) = %08x\n", | ||
446 | + sens->opp_data[i].nvalue); | ||
447 | |||
448 | - dev_dbg(&sr->pdev->dev, | ||
449 | - "Adjusted NValueReciprocal value = %08x\n", | ||
450 | - sens->opp_data[i].adj_nvalue); | ||
451 | - } | ||
452 | + dev_dbg(&sr->pdev->dev, | ||
453 | + "Adjusted NValueReciprocal value = %08x\n", | ||
454 | + sens->opp_data[i].adj_nvalue); | ||
455 | + } | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | @@ -354,7 +406,7 @@ static inline int sr_set_nvalues(struct am33xx_sr *sr, u32 srid) | ||
460 | */ | ||
461 | static void sr_configure(struct am33xx_sr *sr, u32 srid) | ||
462 | { | ||
463 | - struct am33xx_sr_sensor *sens = &sr->sen[srid]; | ||
464 | + struct am33xx_sr_sensor *sens = &sr->sen[srid]; | ||
465 | |||
466 | /* Configuring the SR module with clock length, enabling the | ||
467 | * error generator, enable SR module, enable individual N and P | ||
468 | @@ -370,11 +422,11 @@ static void sr_configure(struct am33xx_sr *sr, u32 srid) | ||
469 | sr_modify_reg(sr, ERRCONFIG_V2, (SR_ERRWEIGHT_MASK | | ||
470 | SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK), | ||
471 | ((sens->opp_data[sens->curr_opp].err_weight << | ||
472 | - ERRCONFIG_ERRWEIGHT_SHIFT) | | ||
473 | + ERRCONFIG_ERRWEIGHT_SHIFT) | | ||
474 | (sens->opp_data[sens->curr_opp].err_maxlimit << | ||
475 | - ERRCONFIG_ERRMAXLIMIT_SHIFT) | | ||
476 | + ERRCONFIG_ERRMAXLIMIT_SHIFT) | | ||
477 | (sens->opp_data[sens->curr_opp].err_minlimit << | ||
478 | - ERRCONFIG_ERRMINLIMIT_SHIFT)), | ||
479 | + ERRCONFIG_ERRMINLIMIT_SHIFT)), | ||
480 | srid); | ||
481 | } | ||
482 | |||
483 | @@ -387,9 +439,14 @@ static void sr_configure(struct am33xx_sr *sr, u32 srid) | ||
484 | */ | ||
485 | static void sr_enable(struct am33xx_sr *sr, u32 srid) | ||
486 | { | ||
487 | - struct am33xx_sr_sensor *sens; | ||
488 | + struct am33xx_sr_sensor *sens; | ||
489 | + | ||
490 | + if (sr->is_suspended) { | ||
491 | + dev_dbg(&sr->pdev->dev, "%s: in suspended state\n", __func__); | ||
492 | + return; | ||
493 | + } | ||
494 | |||
495 | - sens = &sr->sen[srid]; | ||
496 | + sens = &sr->sen[srid]; | ||
497 | |||
498 | /* Check if SR is already enabled. If yes do nothing */ | ||
499 | if (sr_read_reg(sr, SRCONFIG, srid) & SRCONFIG_SRENABLE) | ||
500 | @@ -397,11 +454,11 @@ static void sr_enable(struct am33xx_sr *sr, u32 srid) | ||
501 | |||
502 | if (sens->opp_data[sens->curr_opp].nvalue == 0) | ||
503 | dev_err(&sr->pdev->dev, | ||
504 | - "%s: OPP doesn't support SmartReflex\n", __func__); | ||
505 | + "%s: OPP doesn't support SmartReflex\n", __func__); | ||
506 | |||
507 | /* Writing the nReciprocal value to the register */ | ||
508 | sr_write_reg(sr, NVALUERECIPROCAL, | ||
509 | - sens->opp_data[sens->curr_opp].adj_nvalue, srid); | ||
510 | + sens->opp_data[sens->curr_opp].adj_nvalue, srid); | ||
511 | |||
512 | /* Enable the interrupt */ | ||
513 | sr_modify_reg(sr, IRQENABLE_SET, IRQENABLE_MCUBOUNDSINT, | ||
514 | @@ -420,6 +477,11 @@ static void sr_enable(struct am33xx_sr *sr, u32 srid) | ||
515 | */ | ||
516 | static void sr_disable(struct am33xx_sr *sr, u32 srid) | ||
517 | { | ||
518 | + if (sr->is_suspended) { | ||
519 | + dev_dbg(&sr->pdev->dev, "%s: in suspended state\n", __func__); | ||
520 | + return; | ||
521 | + } | ||
522 | + | ||
523 | /* Disable the interrupt */ | ||
524 | sr_modify_reg(sr, IRQENABLE_CLR, IRQENABLE_MCUBOUNDSINT, | ||
525 | IRQENABLE_MCUBOUNDSINT, srid); | ||
526 | @@ -440,31 +502,31 @@ static void sr_start_vddautocomp(struct am33xx_sr *sr) | ||
527 | int i; | ||
528 | |||
529 | if ((sr->sen[SR_CORE].opp_data[0].nvalue == 0) || | ||
530 | - (sr->sen[SR_MPU].opp_data[0].nvalue == 0)) { | ||
531 | + (sr->sen[SR_MPU].opp_data[0].nvalue == 0)) { | ||
532 | dev_err(&sr->pdev->dev, "SR module not enabled, nTarget" | ||
533 | " values are not found\n"); | ||
534 | return; | ||
535 | } | ||
536 | |||
537 | - if (sr->autocomp_active == 1) { | ||
538 | + if (sr->autocomp_active) { | ||
539 | dev_warn(&sr->pdev->dev, "SR VDD autocomp already active\n"); | ||
540 | return; | ||
541 | } | ||
542 | |||
543 | for (i = 0; i < sr->no_of_sens; i++) { | ||
544 | - /* Read current regulator value and voltage */ | ||
545 | - sr->sen[i].init_volt_mv = regulator_get_voltage(sr->sen[i].reg); | ||
546 | + /* Read current regulator value and voltage */ | ||
547 | + sr->sen[i].init_volt_mv = regulator_get_voltage(sr->sen[i].reg); | ||
548 | |||
549 | - dev_dbg(&sr->pdev->dev, "%s: regulator %d, init_volt = %d\n", | ||
550 | - __func__, i, sr->sen[i].init_volt_mv); | ||
551 | + dev_dbg(&sr->pdev->dev, "%s: regulator %d, init_volt = %d\n", | ||
552 | + __func__, i, sr->sen[i].init_volt_mv); | ||
553 | |||
554 | if (sr_clk_enable(sr, i)) | ||
555 | - return; | ||
556 | + return; | ||
557 | sr_configure(sr, i); | ||
558 | sr_enable(sr, i); | ||
559 | } | ||
560 | |||
561 | - sr->autocomp_active = 1; | ||
562 | + sr->autocomp_active = true; | ||
563 | } | ||
564 | |||
565 | /* sr_stop_vddautocomp - Stop VDD auto compensation | ||
566 | @@ -477,22 +539,22 @@ static void sr_stop_vddautocomp(struct am33xx_sr *sr) | ||
567 | { | ||
568 | int i; | ||
569 | |||
570 | - if (sr->autocomp_active == 0) { | ||
571 | + if (!sr->autocomp_active) { | ||
572 | dev_warn(&sr->pdev->dev, "SR VDD autocomp is not active\n"); | ||
573 | return; | ||
574 | } | ||
575 | |||
576 | - /* cancel bottom half interrupt handlers that haven't run yet */ | ||
577 | + /* cancel bottom half interrupt handlers that haven't run yet */ | ||
578 | cancel_delayed_work_sync(&sr->work); | ||
579 | |||
580 | for (i = 0; i < sr->no_of_sens; i++) { | ||
581 | - /* cancel any outstanding SR IRQ re-enables on work queue */ | ||
582 | - cancel_delayed_work_sync(&sr->sen[i].work_reenable); | ||
583 | + /* cancel any outstanding SR IRQ re-enables on work queue */ | ||
584 | + cancel_delayed_work_sync(&sr->sen[i].work_reenable); | ||
585 | sr_disable(sr, i); | ||
586 | sr_clk_disable(sr, i); | ||
587 | } | ||
588 | |||
589 | - sr->autocomp_active = 0; | ||
590 | + sr->autocomp_active = false; | ||
591 | } | ||
592 | |||
593 | /* am33xx_sr_autocomp_show - Store user input value and stop SR | ||
594 | @@ -513,7 +575,8 @@ static int am33xx_sr_autocomp_show(void *data, u64 *val) | ||
595 | |||
596 | static int am33xx_sr_margin_show(void *data, u64 *val) | ||
597 | { | ||
598 | - struct am33xx_sr_opp_data *sr_opp_data = (struct am33xx_sr_opp_data *)data; | ||
599 | + struct am33xx_sr_opp_data *sr_opp_data = | ||
600 | + (struct am33xx_sr_opp_data *)data; | ||
601 | |||
602 | *val = (u64) sr_opp_data->margin; | ||
603 | |||
604 | @@ -522,35 +585,35 @@ static int am33xx_sr_margin_show(void *data, u64 *val) | ||
605 | |||
606 | static int am33xx_sr_margin_update(void *data, u64 val) | ||
607 | { | ||
608 | - struct am33xx_sr_opp_data *sr_opp_data = | ||
609 | - (struct am33xx_sr_opp_data *)data; | ||
610 | - struct am33xx_sr_sensor *sr_sensor; | ||
611 | - struct am33xx_sr *sr_info; | ||
612 | + struct am33xx_sr_opp_data *sr_opp_data = | ||
613 | + (struct am33xx_sr_opp_data *)data; | ||
614 | + struct am33xx_sr_sensor *sr_sensor; | ||
615 | + struct am33xx_sr *sr_info; | ||
616 | |||
617 | - /* work back to the sr_info pointer */ | ||
618 | - sr_sensor = container_of((void *)sr_opp_data, struct am33xx_sr_sensor, | ||
619 | - opp_data[sr_opp_data->opp_id]); | ||
620 | + /* work back to the sr_info pointer */ | ||
621 | + sr_sensor = container_of((void *)sr_opp_data, struct am33xx_sr_sensor, | ||
622 | + opp_data[sr_opp_data->opp_id]); | ||
623 | |||
624 | - sr_info = container_of((void *)sr_sensor, struct am33xx_sr, | ||
625 | - sen[sr_sensor->sr_id]); | ||
626 | + sr_info = container_of((void *)sr_sensor, struct am33xx_sr, | ||
627 | + sen[sr_sensor->sr_id]); | ||
628 | |||
629 | - /* store the value of margin */ | ||
630 | - sr_opp_data->margin = (s32)val; | ||
631 | + /* store the value of margin */ | ||
632 | + sr_opp_data->margin = (s32)val; | ||
633 | |||
634 | - dev_warn(&sr_info->pdev->dev, "%s: new margin=%d, srid=%d, opp=%d\n", | ||
635 | - __func__, sr_opp_data->margin, sr_sensor->sr_id, | ||
636 | - sr_opp_data->opp_id); | ||
637 | + dev_warn(&sr_info->pdev->dev, "%s: new margin=%d, srid=%d, opp=%d\n", | ||
638 | + __func__, sr_opp_data->margin, sr_sensor->sr_id, | ||
639 | + sr_opp_data->opp_id); | ||
640 | |||
641 | - /* updata ntarget values based upon new margin */ | ||
642 | - if (sr_set_nvalues(sr_info, sr_sensor->sr_id) == -EINVAL) | ||
643 | - dev_err(&sr_info->pdev->dev, | ||
644 | - "%s: Zero NValue read from EFUSE\n", __func__); | ||
645 | + /* updata ntarget values based upon new margin */ | ||
646 | + if (sr_set_nvalues(sr_info, sr_sensor->sr_id) == -EINVAL) | ||
647 | + dev_err(&sr_info->pdev->dev, | ||
648 | + "%s: Zero NValue read from EFUSE\n", __func__); | ||
649 | |||
650 | - /* restart SmartReflex to adapt to new values */ | ||
651 | - sr_stop_vddautocomp(sr_info); | ||
652 | - sr_start_vddautocomp(sr_info); | ||
653 | + /* restart SmartReflex to adapt to new values */ | ||
654 | + sr_stop_vddautocomp(sr_info); | ||
655 | + sr_start_vddautocomp(sr_info); | ||
656 | |||
657 | - return 0; | ||
658 | + return 0; | ||
659 | } | ||
660 | |||
661 | /* am33xx_sr_autocomp_store - Store user input and start SR | ||
662 | @@ -564,21 +627,25 @@ static int am33xx_sr_autocomp_store(void *data, u64 val) | ||
663 | { | ||
664 | struct am33xx_sr *sr_info = (struct am33xx_sr *) data; | ||
665 | |||
666 | + if (sr_info->is_suspended) { | ||
667 | + pr_warning("%s: in suspended state\n", __func__); | ||
668 | + return -EBUSY; | ||
669 | + } | ||
670 | + | ||
671 | /* Sanity check */ | ||
672 | if (val && (val != 1)) { | ||
673 | dev_warn(&sr_info->pdev->dev, "%s: Invalid argument %llu\n", | ||
674 | - __func__, val); | ||
675 | + __func__, val); | ||
676 | return -EINVAL; | ||
677 | } | ||
678 | |||
679 | if (!val) { | ||
680 | - sr_info->disabled_by_user = 1; | ||
681 | + sr_info->disabled_by_user = true; | ||
682 | sr_stop_vddautocomp(sr_info); | ||
683 | - } | ||
684 | - else { | ||
685 | - sr_info->disabled_by_user = 0; | ||
686 | + } else { | ||
687 | + sr_info->disabled_by_user = false; | ||
688 | sr_start_vddautocomp(sr_info); | ||
689 | - } | ||
690 | + } | ||
691 | |||
692 | return 0; | ||
693 | } | ||
694 | @@ -618,7 +685,7 @@ DEFINE_SIMPLE_ATTRIBUTE(margin_fops, am33xx_sr_margin_show, | ||
695 | */ | ||
696 | static int sr_debugfs_entries(struct am33xx_sr *sr_info) | ||
697 | { | ||
698 | - struct am33xx_sr_sensor *sens; | ||
699 | + struct am33xx_sr_sensor *sens; | ||
700 | struct dentry *dbg_dir, *sen_dir, *opp_dir; | ||
701 | int i, j; | ||
702 | |||
703 | @@ -629,13 +696,13 @@ static int sr_debugfs_entries(struct am33xx_sr *sr_info) | ||
704 | return PTR_ERR(dbg_dir); | ||
705 | } | ||
706 | |||
707 | - (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUGO, dbg_dir, | ||
708 | + (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, dbg_dir, | ||
709 | (void *)sr_info, &sr_fops); | ||
710 | - (void) debugfs_create_u32("interrupt_delay", S_IRUGO | S_IWUGO, | ||
711 | + (void) debugfs_create_u32("interrupt_delay", S_IRUGO | S_IWUSR, | ||
712 | dbg_dir, &sr_info->irq_delay); | ||
713 | |||
714 | for (i = 0; i < sr_info->no_of_sens; i++) { | ||
715 | - sens = &sr_info->sen[i]; | ||
716 | + sens = &sr_info->sen[i]; | ||
717 | sen_dir = debugfs_create_dir(sens->name, dbg_dir); | ||
718 | if (IS_ERR(sen_dir)) { | ||
719 | dev_err(&sr_info->pdev->dev, "%s: Unable to create" | ||
720 | @@ -643,37 +710,37 @@ static int sr_debugfs_entries(struct am33xx_sr *sr_info) | ||
721 | return PTR_ERR(sen_dir); | ||
722 | } | ||
723 | |||
724 | - (void)debugfs_create_u32("initial_voltage", S_IRUGO, sen_dir, | ||
725 | + (void)debugfs_create_u32("initial_voltage", S_IRUGO, sen_dir, | ||
726 | &sens->init_volt_mv); | ||
727 | - (void)debugfs_create_file("current_voltage", S_IRUGO, sen_dir, | ||
728 | + (void)debugfs_create_file("current_voltage", S_IRUGO, sen_dir, | ||
729 | (void *)sens, &curr_volt_fops); | ||
730 | |||
731 | - for (j = 0; j < sr_info->sen[i].no_of_opps; j++) { | ||
732 | - char tmp[20]; | ||
733 | - | ||
734 | - sprintf(&tmp[0], "opp%d", j); | ||
735 | - opp_dir = debugfs_create_dir(tmp, sen_dir); | ||
736 | - if (IS_ERR(opp_dir)) { | ||
737 | - dev_err(&sr_info->pdev->dev, | ||
738 | - "%s: Unable to create debugfs directory\n", | ||
739 | - __func__); | ||
740 | - return PTR_ERR(opp_dir); | ||
741 | - } | ||
742 | - | ||
743 | - (void)debugfs_create_file("margin", S_IRUGO | S_IWUGO, | ||
744 | - opp_dir, (void *)&sens->opp_data[j], | ||
745 | - &margin_fops); | ||
746 | - (void)debugfs_create_x32("err2voltgain", | ||
747 | - S_IRUGO | S_IWUGO, | ||
748 | - opp_dir, | ||
749 | - &sens->opp_data[j].e2v_gain); | ||
750 | - (void)debugfs_create_x32("nvalue", S_IRUGO, | ||
751 | - opp_dir, | ||
752 | - &sens->opp_data[j].nvalue); | ||
753 | - (void)debugfs_create_x32("adj_nvalue", S_IRUGO, | ||
754 | - opp_dir, | ||
755 | - &sens->opp_data[j].adj_nvalue); | ||
756 | - } | ||
757 | + for (j = 0; j < sr_info->sen[i].no_of_opps; j++) { | ||
758 | + char tmp[20]; | ||
759 | + | ||
760 | + sprintf(&tmp[0], "opp%d", j); | ||
761 | + opp_dir = debugfs_create_dir(tmp, sen_dir); | ||
762 | + if (IS_ERR(opp_dir)) { | ||
763 | + dev_err(&sr_info->pdev->dev, | ||
764 | + "%s: Unable to create debugfs directory\n", | ||
765 | + __func__); | ||
766 | + return PTR_ERR(opp_dir); | ||
767 | + } | ||
768 | + | ||
769 | + (void)debugfs_create_file("margin", S_IRUGO | S_IWUSR, | ||
770 | + opp_dir, (void *)&sens->opp_data[j], | ||
771 | + &margin_fops); | ||
772 | + (void)debugfs_create_x32("err2voltgain", | ||
773 | + S_IRUGO | S_IWUSR, | ||
774 | + opp_dir, | ||
775 | + &sens->opp_data[j].e2v_gain); | ||
776 | + (void)debugfs_create_x32("nvalue", S_IRUGO, | ||
777 | + opp_dir, | ||
778 | + &sens->opp_data[j].nvalue); | ||
779 | + (void)debugfs_create_x32("adj_nvalue", S_IRUGO, | ||
780 | + opp_dir, | ||
781 | + &sens->opp_data[j].adj_nvalue); | ||
782 | + } | ||
783 | } | ||
784 | return 0; | ||
785 | } | ||
786 | @@ -688,51 +755,64 @@ static int sr_debugfs_entries(struct am33xx_sr *sr_info) | ||
787 | |||
788 | /* Find and return current OPP. This should change to use system APIs, | ||
789 | but voltdm is not currently populated, and opp APIs are also not working. */ | ||
790 | -static int get_current_opp(struct am33xx_sr *sr, u32 srid, u32 freq) { | ||
791 | - int i; | ||
792 | +static int get_current_opp(struct am33xx_sr *sr, u32 srid, u32 freq) | ||
793 | +{ | ||
794 | + int i; | ||
795 | |||
796 | - for (i = 0; i < sr->sen[srid].no_of_opps; i++) { | ||
797 | - if (sr->sen[srid].opp_data[i].frequency == freq) | ||
798 | - return i; | ||
799 | - } | ||
800 | + for (i = 0; i < sr->sen[srid].no_of_opps; i++) { | ||
801 | + if (sr->sen[srid].opp_data[i].frequency == freq) | ||
802 | + return i; | ||
803 | + } | ||
804 | |||
805 | - return -EINVAL; | ||
806 | + return -EINVAL; | ||
807 | } | ||
808 | |||
809 | static int am33xx_sr_cpufreq_transition(struct notifier_block *nb, | ||
810 | unsigned long val, void *data) | ||
811 | { | ||
812 | - struct am33xx_sr *sr; | ||
813 | - struct cpufreq_freqs *cpu; | ||
814 | + struct am33xx_sr *sr; | ||
815 | + struct cpufreq_freqs *cpu; | ||
816 | |||
817 | sr = container_of(nb, struct am33xx_sr, freq_transition); | ||
818 | |||
819 | - /* We are required to disable SR while OPP change is occurring */ | ||
820 | + /* We are required to disable SR while OPP change is occurring */ | ||
821 | if (val == CPUFREQ_PRECHANGE) { | ||
822 | - dev_dbg(&sr->pdev->dev, "%s: prechange\n", __func__); | ||
823 | - sr_stop_vddautocomp(sr); | ||
824 | + dev_dbg(&sr->pdev->dev, "%s: prechange\n", __func__); | ||
825 | + | ||
826 | + printk(KERN_DEBUG "%s: prechange\n", __func__); | ||
827 | + | ||
828 | + sr_stop_vddautocomp(sr); | ||
829 | + | ||
830 | } else if (val == CPUFREQ_POSTCHANGE) { | ||
831 | - cpu = (struct cpufreq_freqs *)data; | ||
832 | - dev_dbg(&sr->pdev->dev, | ||
833 | - "%s: postchange, cpu=%d, old=%d, new=%d\n", | ||
834 | - __func__, cpu->cpu, cpu->old, cpu->new); | ||
835 | - | ||
836 | - /* update current OPP */ | ||
837 | - sr->sen[SR_MPU].curr_opp = get_current_opp(sr, SR_MPU, | ||
838 | - cpu->new*1000); | ||
839 | - if (sr->sen[SR_MPU].curr_opp == -EINVAL) { | ||
840 | - dev_err(&sr->pdev->dev, "%s: cannot determine opp\n", | ||
841 | - __func__); | ||
842 | - return -EINVAL; | ||
843 | - } | ||
844 | - | ||
845 | - dev_dbg(&sr->pdev->dev, "%s: postchange, new opp=%d\n", | ||
846 | - __func__, sr->sen[SR_MPU].curr_opp); | ||
847 | - | ||
848 | - /* this handles the case when the user has disabled SR via | ||
849 | - debugfs, therefore we do not want to enable SR */ | ||
850 | - if (sr->disabled_by_user == 0) | ||
851 | - sr_start_vddautocomp(sr); | ||
852 | + cpu = (struct cpufreq_freqs *)data; | ||
853 | + dev_dbg(&sr->pdev->dev, | ||
854 | + "%s: postchange, cpu=%d, old=%d, new=%d\n", | ||
855 | + __func__, cpu->cpu, cpu->old, cpu->new); | ||
856 | + | ||
857 | + printk(KERN_DEBUG "%s: postchange\n", __func__); | ||
858 | + | ||
859 | + /* update current OPP */ | ||
860 | + sr->sen[SR_MPU].curr_opp = get_current_opp(sr, SR_MPU, | ||
861 | + cpu->new*1000); | ||
862 | + if (sr->sen[SR_MPU].curr_opp == -EINVAL) { | ||
863 | + dev_err(&sr->pdev->dev, "%s: cannot determine opp\n", | ||
864 | + __func__); | ||
865 | + return -EINVAL; | ||
866 | + } | ||
867 | + | ||
868 | + dev_dbg(&sr->pdev->dev, "%s: postchange, new opp=%d\n", | ||
869 | + __func__, sr->sen[SR_MPU].curr_opp); | ||
870 | + | ||
871 | + /* reset the voltage calculation algorithm for MPU */ | ||
872 | + get_errvolt(sr, SR_MPU, 0, 1); | ||
873 | + | ||
874 | + /* this handles the case when the user has disabled SR via | ||
875 | + debugfs, therefore we do not want to enable SR */ | ||
876 | + if (sr->disabled_by_user == false) { | ||
877 | + printk(KERN_DEBUG "%s: postchange, new opp=%d\n", | ||
878 | + __func__, sr->sen[SR_MPU].curr_opp); | ||
879 | + sr_start_vddautocomp(sr); | ||
880 | + } | ||
881 | } | ||
882 | |||
883 | return 0; | ||
884 | @@ -740,7 +820,7 @@ static int am33xx_sr_cpufreq_transition(struct notifier_block *nb, | ||
885 | |||
886 | static inline int am33xx_sr_cpufreq_register(struct am33xx_sr *sr) | ||
887 | { | ||
888 | - sr->freq_transition.notifier_call = am33xx_sr_cpufreq_transition; | ||
889 | + sr->freq_transition.notifier_call = am33xx_sr_cpufreq_transition; | ||
890 | |||
891 | return cpufreq_register_notifier(&sr->freq_transition, | ||
892 | CPUFREQ_TRANSITION_NOTIFIER); | ||
893 | @@ -754,6 +834,67 @@ static inline void am33xx_sr_cpufreq_deregister(struct am33xx_sr *sr) | ||
894 | |||
895 | #endif | ||
896 | |||
897 | +static void print_die_id(void) | ||
898 | +{ | ||
899 | + writel(0xF47765F2, AM33XX_CTRL_REGADDR(0x1828)); | ||
900 | + writel(0x703E6C3D, AM33XX_CTRL_REGADDR(0x1844)); | ||
901 | + writel(0x3724C7D6, AM33XX_CTRL_REGADDR(0x182C)); | ||
902 | + writel(0x7A733E49, AM33XX_CTRL_REGADDR(0x184C)); | ||
903 | + | ||
904 | + printk(KERN_DEBUG "DIEID: %08x %08x %08x %08x\n", | ||
905 | + readl(AM33XX_CTRL_REGADDR(0x183C)), | ||
906 | + readl(AM33XX_CTRL_REGADDR(0x1848)), | ||
907 | + readl(AM33XX_CTRL_REGADDR(0x1824)), | ||
908 | + readl(AM33XX_CTRL_REGADDR(0x1850))); | ||
909 | + | ||
910 | + printk(KERN_DEBUG "EFUSE SMA register val = %08x\n", | ||
911 | + readl(AM33XX_CTRL_REGADDR(0x7fc))); | ||
912 | +} | ||
913 | + | ||
914 | +static int am33xx_sr_suspend(struct device *dev) | ||
915 | +{ | ||
916 | + if (global_sr_info == NULL) | ||
917 | + return -EINVAL; | ||
918 | + | ||
919 | + /* if we are already disabled or suspended, do nothing */ | ||
920 | + if (global_sr_info->disabled_by_user) | ||
921 | + return 0; | ||
922 | + | ||
923 | + if (global_sr_info->is_suspended) | ||
924 | + return 0; | ||
925 | + | ||
926 | +#ifdef CONFIG_CPU_FREQ | ||
927 | + am33xx_sr_cpufreq_deregister(global_sr_info); | ||
928 | +#endif | ||
929 | + sr_stop_vddautocomp(global_sr_info); | ||
930 | + global_sr_info->is_suspended = true; | ||
931 | + | ||
932 | + return 0; | ||
933 | +} | ||
934 | + | ||
935 | +static int am33xx_sr_resume(struct device *dev) | ||
936 | +{ | ||
937 | + if (global_sr_info == NULL) | ||
938 | + return -EINVAL; | ||
939 | + | ||
940 | + /* ensure we don't enable SR if it was disabled before suspend */ | ||
941 | + if (global_sr_info->disabled_by_user) | ||
942 | + return 0; | ||
943 | + | ||
944 | + if (!global_sr_info->is_suspended) | ||
945 | + return 0; | ||
946 | + | ||
947 | + global_sr_info->is_suspended = false; | ||
948 | + sr_start_vddautocomp(global_sr_info); | ||
949 | + | ||
950 | +#ifdef CONFIG_CPU_FREQ | ||
951 | + if (am33xx_sr_cpufreq_register(global_sr_info)) { | ||
952 | + printk(KERN_ERR "failed to register cpufreq\n"); | ||
953 | + } | ||
954 | +#endif | ||
955 | + return 0; | ||
956 | +} | ||
957 | + | ||
958 | static int __init am33xx_sr_probe(struct platform_device *pdev) | ||
959 | { | ||
960 | struct am33xx_sr *sr_info; | ||
961 | @@ -761,13 +902,9 @@ static int __init am33xx_sr_probe(struct platform_device *pdev) | ||
962 | struct resource *res[MAX_SENSORS]; | ||
963 | int irq; | ||
964 | int ret; | ||
965 | - int i,j; | ||
966 | + int i, j; | ||
967 | |||
968 | - if (omap_rev() != AM335X_REV_ES1_0) { | ||
969 | - dev_err(&pdev->dev, "%s: Smartreflex requires ES 1.0\n", | ||
970 | - __func__); | ||
971 | - return -EINVAL; | ||
972 | - } | ||
973 | + print_die_id(); | ||
974 | |||
975 | sr_info = kzalloc(sizeof(struct am33xx_sr), GFP_KERNEL); | ||
976 | if (!sr_info) { | ||
977 | @@ -776,6 +913,8 @@ static int __init am33xx_sr_probe(struct platform_device *pdev) | ||
978 | return -ENOMEM; | ||
979 | } | ||
980 | |||
981 | + global_sr_info = sr_info; | ||
982 | + | ||
983 | pdata = pdev->dev.platform_data; | ||
984 | if (!pdata) { | ||
985 | dev_err(&pdev->dev, "%s: platform data missing\n", __func__); | ||
986 | @@ -787,77 +926,77 @@ static int __init am33xx_sr_probe(struct platform_device *pdev) | ||
987 | sr_info->sen[SR_CORE].name = "smartreflex0"; | ||
988 | sr_info->sen[SR_MPU].name = "smartreflex1"; | ||
989 | sr_info->ip_type = pdata->ip_type; | ||
990 | - sr_info->irq_delay = pdata->irq_delay; | ||
991 | - sr_info->no_of_sens = pdata->no_of_sens; | ||
992 | - sr_info->no_of_vds = pdata->no_of_vds; | ||
993 | + sr_info->irq_delay = pdata->irq_delay; | ||
994 | + sr_info->no_of_sens = pdata->no_of_sens; | ||
995 | + sr_info->no_of_vds = pdata->no_of_vds; | ||
996 | sr_info->uvoltage_step_size = pdata->vstep_size_uv; | ||
997 | sr_info->autocomp_active = false; | ||
998 | - sr_info->disabled_by_user = false; | ||
999 | + sr_info->disabled_by_user = false; | ||
1000 | |||
1001 | for (i = 0; i < sr_info->no_of_sens; i++) { | ||
1002 | - u32 curr_freq=0; | ||
1003 | - | ||
1004 | - sr_info->sen[i].reg_name = pdata->vd_name[i]; | ||
1005 | - | ||
1006 | - /* this should be determined from voltdm or opp layer, but | ||
1007 | - those approaches are not working */ | ||
1008 | - sr_info->sen[i].no_of_opps = pdata->sr_sdata[i].no_of_opps; | ||
1009 | - sr_info->sen[i].sr_id = i; | ||
1010 | - | ||
1011 | - /* Reading per OPP Values */ | ||
1012 | - for (j = 0; j < sr_info->sen[i].no_of_opps; j++) { | ||
1013 | - sr_info->sen[i].opp_data[j].efuse_offs = | ||
1014 | - pdata->sr_sdata[i].sr_opp_data[j].efuse_offs; | ||
1015 | - sr_info->sen[i].opp_data[j].e2v_gain = | ||
1016 | - pdata->sr_sdata[i].sr_opp_data[j].e2v_gain; | ||
1017 | - sr_info->sen[i].opp_data[j].err_weight = | ||
1018 | - pdata->sr_sdata[i].sr_opp_data[j].err_weight; | ||
1019 | - sr_info->sen[i].opp_data[j].err_minlimit = | ||
1020 | - pdata->sr_sdata[i].sr_opp_data[j].err_minlimit; | ||
1021 | - sr_info->sen[i].opp_data[j].err_maxlimit = | ||
1022 | - pdata->sr_sdata[i].sr_opp_data[j].err_maxlimit; | ||
1023 | - sr_info->sen[i].opp_data[j].margin = | ||
1024 | - pdata->sr_sdata[i].sr_opp_data[j].margin; | ||
1025 | - sr_info->sen[i].opp_data[j].nominal_volt = | ||
1026 | - pdata->sr_sdata[i].sr_opp_data[j].nominal_volt; | ||
1027 | - sr_info->sen[i].opp_data[j].frequency = | ||
1028 | - pdata->sr_sdata[i].sr_opp_data[j].frequency; | ||
1029 | - sr_info->sen[i].opp_data[j].opp_id = j; | ||
1030 | - } | ||
1031 | - | ||
1032 | - if (i == SR_MPU) { | ||
1033 | - /* hardcoded CPU NR */ | ||
1034 | - curr_freq = cpufreq_get(0); | ||
1035 | - | ||
1036 | - /* update current OPP */ | ||
1037 | - sr_info->sen[i].curr_opp = get_current_opp(sr_info, i, | ||
1038 | - curr_freq*1000); | ||
1039 | - if (sr_info->sen[i].curr_opp == -EINVAL) { | ||
1040 | - dev_err(&sr_info->pdev->dev, | ||
1041 | - "%s: cannot determine opp\n",__func__); | ||
1042 | - ret = -EINVAL; | ||
1043 | - goto err_free_sr_info; | ||
1044 | - } | ||
1045 | - } else { | ||
1046 | - sr_info->sen[i].curr_opp = | ||
1047 | - pdata->sr_sdata[i].default_opp; | ||
1048 | - } | ||
1049 | - | ||
1050 | - dev_dbg(&pdev->dev, | ||
1051 | - "%s: SR%d, curr_opp=%d, no_of_opps=%d, step_size=%d\n", | ||
1052 | - __func__, i, sr_info->sen[i].curr_opp, | ||
1053 | - sr_info->sen[i].no_of_opps, | ||
1054 | - sr_info->uvoltage_step_size); | ||
1055 | - | ||
1056 | - ret = sr_set_nvalues(sr_info, i); | ||
1057 | - if (ret == -EINVAL) { | ||
1058 | - dev_err(&sr_info->pdev->dev, | ||
1059 | - "%s: Zero NValue read from EFUSE\n", __func__); | ||
1060 | - goto err_free_sr_info; | ||
1061 | - } | ||
1062 | - | ||
1063 | - INIT_DELAYED_WORK(&sr_info->sen[i].work_reenable, | ||
1064 | - irq_sr_reenable); | ||
1065 | + u32 curr_freq = 0; | ||
1066 | + | ||
1067 | + sr_info->sen[i].reg_name = pdata->vd_name[i]; | ||
1068 | + | ||
1069 | + /* this should be determined from voltdm or opp layer, but | ||
1070 | + those approaches are not working */ | ||
1071 | + sr_info->sen[i].no_of_opps = pdata->sr_sdata[i].no_of_opps; | ||
1072 | + sr_info->sen[i].sr_id = i; | ||
1073 | + | ||
1074 | + /* Reading per OPP Values */ | ||
1075 | + for (j = 0; j < sr_info->sen[i].no_of_opps; j++) { | ||
1076 | + sr_info->sen[i].opp_data[j].efuse_offs = | ||
1077 | + pdata->sr_sdata[i].sr_opp_data[j].efuse_offs; | ||
1078 | + sr_info->sen[i].opp_data[j].e2v_gain = | ||
1079 | + pdata->sr_sdata[i].sr_opp_data[j].e2v_gain; | ||
1080 | + sr_info->sen[i].opp_data[j].err_weight = | ||
1081 | + pdata->sr_sdata[i].sr_opp_data[j].err_weight; | ||
1082 | + sr_info->sen[i].opp_data[j].err_minlimit = | ||
1083 | + pdata->sr_sdata[i].sr_opp_data[j].err_minlimit; | ||
1084 | + sr_info->sen[i].opp_data[j].err_maxlimit = | ||
1085 | + pdata->sr_sdata[i].sr_opp_data[j].err_maxlimit; | ||
1086 | + sr_info->sen[i].opp_data[j].margin = | ||
1087 | + pdata->sr_sdata[i].sr_opp_data[j].margin; | ||
1088 | + sr_info->sen[i].opp_data[j].nominal_volt = | ||
1089 | + pdata->sr_sdata[i].sr_opp_data[j].nominal_volt; | ||
1090 | + sr_info->sen[i].opp_data[j].frequency = | ||
1091 | + pdata->sr_sdata[i].sr_opp_data[j].frequency; | ||
1092 | + sr_info->sen[i].opp_data[j].opp_id = j; | ||
1093 | + } | ||
1094 | + | ||
1095 | + if (i == SR_MPU) { | ||
1096 | + /* hardcoded CPU NR */ | ||
1097 | + curr_freq = cpufreq_get(0); | ||
1098 | + | ||
1099 | + /* update current OPP */ | ||
1100 | + sr_info->sen[i].curr_opp = get_current_opp(sr_info, i, | ||
1101 | + curr_freq*1000); | ||
1102 | + if (sr_info->sen[i].curr_opp == -EINVAL) { | ||
1103 | + dev_err(&sr_info->pdev->dev, | ||
1104 | + "%s: cannot determine opp\n", __func__); | ||
1105 | + ret = -EINVAL; | ||
1106 | + goto err_free_sr_info; | ||
1107 | + } | ||
1108 | + } else { | ||
1109 | + sr_info->sen[i].curr_opp = | ||
1110 | + pdata->sr_sdata[i].default_opp; | ||
1111 | + } | ||
1112 | + | ||
1113 | + dev_dbg(&pdev->dev, | ||
1114 | + "%s: SR%d, curr_opp=%d, no_of_opps=%d, step_size=%d\n", | ||
1115 | + __func__, i, sr_info->sen[i].curr_opp, | ||
1116 | + sr_info->sen[i].no_of_opps, | ||
1117 | + sr_info->uvoltage_step_size); | ||
1118 | + | ||
1119 | + ret = sr_set_nvalues(sr_info, i); | ||
1120 | + if (ret == -EINVAL) { | ||
1121 | + dev_err(&sr_info->pdev->dev, | ||
1122 | + "%s: Zero NValue read from EFUSE\n", __func__); | ||
1123 | + goto err_free_sr_info; | ||
1124 | + } | ||
1125 | + | ||
1126 | + INIT_DELAYED_WORK(&sr_info->sen[i].work_reenable, | ||
1127 | + irq_sr_reenable); | ||
1128 | |||
1129 | sr_info->res_name[i] = kzalloc(CLK_NAME_LEN + 1, GFP_KERNEL); | ||
1130 | |||
1131 | @@ -907,7 +1046,7 @@ static int __init am33xx_sr_probe(struct platform_device *pdev) | ||
1132 | |||
1133 | ret = request_irq(sr_info->sen[i].irq, sr_class2_irq, | ||
1134 | IRQF_DISABLED, sr_info->sen[i].name, | ||
1135 | - (void *)&sr_info->sen[i]); | ||
1136 | + (void *)&sr_info->sen[i]); | ||
1137 | if (ret) { | ||
1138 | dev_err(&pdev->dev, "%s: Could not install SR ISR\n", | ||
1139 | __func__); | ||
1140 | @@ -917,22 +1056,22 @@ static int __init am33xx_sr_probe(struct platform_device *pdev) | ||
1141 | sr_info->sen[i].senn_en = pdata->sr_sdata[i].senn_mod; | ||
1142 | sr_info->sen[i].senp_en = pdata->sr_sdata[i].senp_mod; | ||
1143 | |||
1144 | - sr_info->sen[i].reg = | ||
1145 | - regulator_get(NULL, sr_info->sen[i].reg_name); | ||
1146 | - if (IS_ERR(sr_info->sen[i].reg)) { | ||
1147 | - ret = -EINVAL; | ||
1148 | - goto err_free_irq; | ||
1149 | - } | ||
1150 | + sr_info->sen[i].reg = | ||
1151 | + regulator_get(NULL, sr_info->sen[i].reg_name); | ||
1152 | + if (IS_ERR(sr_info->sen[i].reg)) { | ||
1153 | + ret = -EINVAL; | ||
1154 | + goto err_free_irq; | ||
1155 | + } | ||
1156 | |||
1157 | - /* Read current regulator value and voltage */ | ||
1158 | - sr_info->sen[i].init_volt_mv = | ||
1159 | - regulator_get_voltage(sr_info->sen[i].reg); | ||
1160 | + /* Read current regulator value and voltage */ | ||
1161 | + sr_info->sen[i].init_volt_mv = | ||
1162 | + regulator_get_voltage(sr_info->sen[i].reg); | ||
1163 | |||
1164 | - dev_dbg(&pdev->dev, "%s: regulator %d, init_volt = %d\n", | ||
1165 | - __func__, i, sr_info->sen[i].init_volt_mv); | ||
1166 | + dev_dbg(&pdev->dev, "%s: regulator %d, init_volt = %d\n", | ||
1167 | + __func__, i, sr_info->sen[i].init_volt_mv); | ||
1168 | } /* for() */ | ||
1169 | |||
1170 | - /* set_voltage() will be used as the bottom half IRQ handler */ | ||
1171 | + /* set_voltage() will be used as the bottom half IRQ handler */ | ||
1172 | INIT_DELAYED_WORK(&sr_info->work, set_voltage); | ||
1173 | |||
1174 | #ifdef CONFIG_CPU_FREQ | ||
1175 | @@ -943,22 +1082,24 @@ static int __init am33xx_sr_probe(struct platform_device *pdev) | ||
1176 | } | ||
1177 | #endif | ||
1178 | |||
1179 | +#ifdef CONFIG_DEBUG_FS | ||
1180 | /* debugfs entries */ | ||
1181 | ret = sr_debugfs_entries(sr_info); | ||
1182 | if (ret) | ||
1183 | dev_warn(&pdev->dev, "%s: Debugfs entries are not created\n", | ||
1184 | __func__); | ||
1185 | +#endif | ||
1186 | |||
1187 | platform_set_drvdata(pdev, sr_info); | ||
1188 | |||
1189 | dev_info(&pdev->dev, "%s: Driver initialized\n", __func__); | ||
1190 | |||
1191 | - /* disabled_by_user used to ensure SR doesn't come on via CPUFREQ | ||
1192 | - scaling if user has disabled SR via debugfs on enable_on_init */ | ||
1193 | + /* disabled_by_user used to ensure SR doesn't come on via CPUFREQ | ||
1194 | + scaling if user has disabled SR via debugfs on enable_on_init */ | ||
1195 | if (pdata->enable_on_init) | ||
1196 | sr_start_vddautocomp(sr_info); | ||
1197 | - else | ||
1198 | - sr_info->disabled_by_user = 1; | ||
1199 | + else | ||
1200 | + sr_info->disabled_by_user = true; | ||
1201 | |||
1202 | return ret; | ||
1203 | |||
1204 | @@ -967,8 +1108,8 @@ static int __init am33xx_sr_probe(struct platform_device *pdev) | ||
1205 | #endif | ||
1206 | |||
1207 | err_reg_put: | ||
1208 | - i--; /* back up i by one to walk back through the for loop */ | ||
1209 | - regulator_put(sr_info->sen[i].reg); | ||
1210 | + i--; /* back up i by one to walk back through the for loop */ | ||
1211 | + regulator_put(sr_info->sen[i].reg); | ||
1212 | err_free_irq: | ||
1213 | free_irq(sr_info->sen[i].irq, (void *)sr_info); | ||
1214 | err_put_clock: | ||
1215 | @@ -978,11 +1119,10 @@ err_unmap: | ||
1216 | err_release_mem: | ||
1217 | release_mem_region(res[i]->start, resource_size(res[i])); | ||
1218 | err_free_mem: | ||
1219 | - kfree(sr_info->res_name[i]); | ||
1220 | - /* unwind back through the for loop */ | ||
1221 | - if (i != 0) { | ||
1222 | - goto err_reg_put; | ||
1223 | - } | ||
1224 | + kfree(sr_info->res_name[i]); | ||
1225 | + /* unwind back through the for loop */ | ||
1226 | + if (i != 0) | ||
1227 | + goto err_reg_put; | ||
1228 | |||
1229 | err_free_sr_info: | ||
1230 | kfree(sr_info); | ||
1231 | @@ -1010,27 +1150,31 @@ static int __devexit am33xx_sr_remove(struct platform_device *pdev) | ||
1232 | #endif | ||
1233 | |||
1234 | for (i = 0; i < sr_info->no_of_sens; i++) { | ||
1235 | - regulator_put(sr_info->sen[i].reg); | ||
1236 | - irq = platform_get_irq_byname(pdev, sr_info->sen[i].name); | ||
1237 | + regulator_put(sr_info->sen[i].reg); | ||
1238 | + irq = platform_get_irq_byname(pdev, sr_info->sen[i].name); | ||
1239 | free_irq(irq, (void *)sr_info); | ||
1240 | clk_put(sr_info->sen[i].fck); | ||
1241 | iounmap(sr_info->sen[i].base); | ||
1242 | res[i] = platform_get_resource_byname(pdev, | ||
1243 | IORESOURCE_MEM, sr_info->sen[i].name); | ||
1244 | release_mem_region(res[i]->start, resource_size(res[i])); | ||
1245 | - kfree(sr_info->res_name[i]); | ||
1246 | + kfree(sr_info->res_name[i]); | ||
1247 | } | ||
1248 | |||
1249 | kfree(sr_info); | ||
1250 | |||
1251 | - dev_info(&pdev->dev, "%s: SR has been removed\n", __func__); | ||
1252 | + dev_info(&pdev->dev, "%s: SR has been removed\n", __func__); | ||
1253 | return 0; | ||
1254 | } | ||
1255 | |||
1256 | +static SIMPLE_DEV_PM_OPS(am33xx_sr_dev_pm_ops, am33xx_sr_suspend, | ||
1257 | + am33xx_sr_resume); | ||
1258 | + | ||
1259 | static struct platform_driver smartreflex_driver = { | ||
1260 | .driver = { | ||
1261 | .name = "smartreflex", | ||
1262 | .owner = THIS_MODULE, | ||
1263 | + .pm = &am33xx_sr_dev_pm_ops, | ||
1264 | }, | ||
1265 | .remove = am33xx_sr_remove, | ||
1266 | }; | ||
1267 | diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c | ||
1268 | index b524b47..8081818 100644 | ||
1269 | --- a/arch/arm/mach-omap2/devices.c | ||
1270 | +++ b/arch/arm/mach-omap2/devices.c | ||
1271 | @@ -1231,244 +1231,313 @@ static struct platform_device am335x_sgx = { | ||
1272 | /* The values below are based upon silicon characterization data. | ||
1273 | * Each OPP and sensor combination potentially has different values. | ||
1274 | * The values of ERR2VOLT_GAIN and ERR_MIN_LIMIT also change based on | ||
1275 | - * the PMIC step size. Values have been given to cover the AM335 EVM | ||
1276 | + * the PMIC step size. Values have been given to cover the AM335 EVM | ||
1277 | * (12.5mV step) and the Beaglebone (25mV step). If the step | ||
1278 | * size changes, you should update these values, and don't forget to | ||
1279 | * change the step size in the platform data structure, am33xx_sr_pdata. | ||
1280 | */ | ||
1281 | |||
1282 | -#define AM33XX_SR0_OPP50_CNTRL_OFFSET 0x07B8 | ||
1283 | -#define AM33XX_SR0_OPP50_EVM_ERR2VOLT_GAIN 0xC | ||
1284 | -#define AM33XX_SR0_OPP50_EVM_ERR_MIN_LIMIT 0xF5 | ||
1285 | -#define AM33XX_SR0_OPP50_BB_ERR2VOLT_GAIN 0x6 | ||
1286 | -#define AM33XX_SR0_OPP50_BB_ERR_MIN_LIMIT 0xEA | ||
1287 | -#define AM33XX_SR0_OPP50_ERR_MAX_LIMIT 0x2 | ||
1288 | -#define AM33XX_SR0_OPP50_ERR_WEIGHT 0x4 | ||
1289 | -#define AM33XX_SR0_OPP50_MARGIN 0 | ||
1290 | - | ||
1291 | -#define AM33XX_SR0_OPP100_CNTRL_OFFSET 0x07BC | ||
1292 | -#define AM33XX_SR0_OPP100_EVM_ERR2VOLT_GAIN 0x12 | ||
1293 | -#define AM33XX_SR0_OPP100_EVM_ERR_MIN_LIMIT 0xF8 | ||
1294 | -#define AM33XX_SR0_OPP100_BB_ERR2VOLT_GAIN 0x9 | ||
1295 | -#define AM33XX_SR0_OPP100_BB_ERR_MIN_LIMIT 0xF1 | ||
1296 | -#define AM33XX_SR0_OPP100_ERR_MAX_LIMIT 0x2 | ||
1297 | -#define AM33XX_SR0_OPP100_ERR_WEIGHT 0x4 | ||
1298 | -#define AM33XX_SR0_OPP100_MARGIN 0 | ||
1299 | - | ||
1300 | -#define AM33XX_SR1_OPP50_CNTRL_OFFSET 0x0770 | ||
1301 | -#define AM33XX_SR1_OPP50_EVM_ERR2VOLT_GAIN 0x5 | ||
1302 | -#define AM33XX_SR1_OPP50_EVM_ERR_MIN_LIMIT 0xE6 | ||
1303 | -#define AM33XX_SR1_OPP50_BB_ERR2VOLT_GAIN 0x2 | ||
1304 | -#define AM33XX_SR1_OPP50_BB_ERR_MIN_LIMIT 0xC0 | ||
1305 | -#define AM33XX_SR1_OPP50_ERR_MAX_LIMIT 0x2 | ||
1306 | -#define AM33XX_SR1_OPP50_ERR_WEIGHT 0x4 | ||
1307 | -#define AM33XX_SR1_OPP50_MARGIN 0 | ||
1308 | - | ||
1309 | -#define AM33XX_SR1_OPP100_CNTRL_OFFSET 0x0774 | ||
1310 | -#define AM33XX_SR1_OPP100_EVM_ERR2VOLT_GAIN 0x8 | ||
1311 | -#define AM33XX_SR1_OPP100_EVM_ERR_MIN_LIMIT 0xF0 | ||
1312 | -#define AM33XX_SR1_OPP100_BB_ERR2VOLT_GAIN 0x4 | ||
1313 | -#define AM33XX_SR1_OPP100_BB_ERR_MIN_LIMIT 0xDF | ||
1314 | -#define AM33XX_SR1_OPP100_ERR_MAX_LIMIT 0x2 | ||
1315 | -#define AM33XX_SR1_OPP100_ERR_WEIGHT 0x4 | ||
1316 | -#define AM33XX_SR1_OPP100_MARGIN 0 | ||
1317 | - | ||
1318 | -#define AM33XX_SR1_OPP120_CNTRL_OFFSET 0x0778 | ||
1319 | -#define AM33XX_SR1_OPP120_EVM_ERR2VOLT_GAIN 0xB | ||
1320 | -#define AM33XX_SR1_OPP120_EVM_ERR_MIN_LIMIT 0xF4 | ||
1321 | -#define AM33XX_SR1_OPP120_BB_ERR2VOLT_GAIN 0x5 | ||
1322 | -#define AM33XX_SR1_OPP120_BB_ERR_MIN_LIMIT 0xE6 | ||
1323 | -#define AM33XX_SR1_OPP120_ERR_MAX_LIMIT 0x2 | ||
1324 | -#define AM33XX_SR1_OPP120_ERR_WEIGHT 0x4 | ||
1325 | -#define AM33XX_SR1_OPP120_MARGIN 0 | ||
1326 | - | ||
1327 | -#define AM33XX_SR1_OPPTURBO_CNTRL_OFFSET 0x077C | ||
1328 | -#define AM33XX_SR1_OPPTURBO_EVM_ERR2VOLT_GAIN 0xC | ||
1329 | -#define AM33XX_SR1_OPPTURBO_EVM_ERR_MIN_LIMIT 0xF5 | ||
1330 | -#define AM33XX_SR1_OPPTURBO_BB_ERR2VOLT_GAIN 0x6 | ||
1331 | -#define AM33XX_SR1_OPPTURBO_BB_ERR_MIN_LIMIT 0xEA | ||
1332 | -#define AM33XX_SR1_OPPTURBO_ERR_MAX_LIMIT 0x2 | ||
1333 | -#define AM33XX_SR1_OPPTURBO_ERR_WEIGHT 0x4 | ||
1334 | -#define AM33XX_SR1_OPPTURBO_MARGIN 0 | ||
1335 | +#define AM33XX_SR0_OPP50_CNTRL_OFFSET 0x07B8 | ||
1336 | +#define AM33XX_SR0_OPP50_EVM_ERR_MIN_LIMIT 0xF0 | ||
1337 | +#define AM33XX_SR0_OPP50_BB_ERR_MIN_LIMIT 0xEA | ||
1338 | +#define AM33XX_SR0_OPP50_ERR_MAX_LIMIT 0x2 | ||
1339 | +#define AM33XX_SR0_OPP50_ERR_WEIGHT 0x4 | ||
1340 | +#define AM33XX_SR0_OPP50_MARGIN 0 | ||
1341 | + | ||
1342 | +#define AM33XX_SR0_OPP100_CNTRL_OFFSET 0x07BC | ||
1343 | +#define AM33XX_SR0_OPP100_EVM_ERR_MIN_LIMIT 0xF0 | ||
1344 | +#define AM33XX_SR0_OPP100_BB_ERR_MIN_LIMIT 0xF1 | ||
1345 | +#define AM33XX_SR0_OPP100_ERR_MAX_LIMIT 0x2 | ||
1346 | +#define AM33XX_SR0_OPP100_ERR_WEIGHT 0x4 | ||
1347 | +#define AM33XX_SR0_OPP100_MARGIN 0 | ||
1348 | + | ||
1349 | +#define AM33XX_SR1_OPP50_CNTRL_OFFSET 0x0770 | ||
1350 | +#define AM33XX_SR1_OPP50_EVM_ERR_MIN_LIMIT 0xFA | ||
1351 | +#define AM33XX_SR1_OPP50_BB_ERR_MIN_LIMIT 0xC0 | ||
1352 | +#define AM33XX_SR1_OPP50_ERR_MAX_LIMIT 0x2 | ||
1353 | +#define AM33XX_SR1_OPP50_ERR_WEIGHT 0x4 | ||
1354 | +#define AM33XX_SR1_OPP50_MARGIN 0 | ||
1355 | + | ||
1356 | +#define AM33XX_SR1_OPP100_CNTRL_OFFSET 0x0774 | ||
1357 | +#define AM33XX_SR1_OPP100_EVM_ERR_MIN_LIMIT 0xFB | ||
1358 | +#define AM33XX_SR1_OPP100_BB_ERR_MIN_LIMIT 0xDF | ||
1359 | +#define AM33XX_SR1_OPP100_ERR_MAX_LIMIT 0x2 | ||
1360 | +#define AM33XX_SR1_OPP100_ERR_WEIGHT 0x4 | ||
1361 | +#define AM33XX_SR1_OPP100_MARGIN 0 | ||
1362 | + | ||
1363 | +#define AM33XX_SR1_OPP120_CNTRL_OFFSET 0x0778 | ||
1364 | +#define AM33XX_SR1_OPP120_EVM_ERR_MIN_LIMIT 0xFC | ||
1365 | +#define AM33XX_SR1_OPP120_BB_ERR_MIN_LIMIT 0xE6 | ||
1366 | +#define AM33XX_SR1_OPP120_ERR_MAX_LIMIT 0x2 | ||
1367 | +#define AM33XX_SR1_OPP120_ERR_WEIGHT 0x7 | ||
1368 | +#define AM33XX_SR1_OPP120_MARGIN 0 | ||
1369 | + | ||
1370 | +#define AM33XX_SR1_OPPTURBO_CNTRL_OFFSET 0x077C | ||
1371 | +#define AM33XX_SR1_OPPTURBO_EVM_ERR_MIN_LIMIT 0xFD | ||
1372 | +#define AM33XX_SR1_OPPTURBO_BB_ERR_MIN_LIMIT 0xEA | ||
1373 | +#define AM33XX_SR1_OPPTURBO_ERR_MAX_LIMIT 0x2 | ||
1374 | +#define AM33XX_SR1_OPPTURBO_ERR_WEIGHT 0x7 | ||
1375 | +#define AM33XX_SR1_OPPTURBO_MARGIN 0 | ||
1376 | + | ||
1377 | +/* bits 31:16 = SenP margin; bit 15:0 = SenN margin */ | ||
1378 | + | ||
1379 | +#define AM33XX_SR1_OPPNITRO_MARGIN 0x018B019A | ||
1380 | |||
1381 | /* the voltages and frequencies should probably be defined in opp3xxx_data.c. | ||
1382 | Once SR is integrated to the mainline driver, and voltdm is working | ||
1383 | correctly in AM335x, these can be removed. */ | ||
1384 | -#define AM33XX_VDD_MPU_OPP50_UV 950000 | ||
1385 | -#define AM33XX_VDD_MPU_OPP100_UV 1100000 | ||
1386 | -#define AM33XX_VDD_MPU_OPP120_UV 1200000 | ||
1387 | -#define AM33XX_VDD_MPU_OPPTURBO_UV 1260000 | ||
1388 | -#define AM33XX_VDD_CORE_OPP50_UV 950000 | ||
1389 | -#define AM33XX_VDD_CORE_OPP100_UV 1100000 | ||
1390 | - | ||
1391 | -#define AM33XX_VDD_MPU_OPP50_FREQ 275000000 | ||
1392 | -#define AM33XX_VDD_MPU_OPP100_FREQ 500000000 | ||
1393 | -#define AM33XX_VDD_MPU_OPP120_FREQ 600000000 | ||
1394 | -#define AM33XX_VDD_MPU_OPPTURBO_FREQ 720000000 | ||
1395 | +#define AM33XX_VDD_MPU_OPP50_UV 950000 | ||
1396 | +#define AM33XX_VDD_MPU_OPP100_UV 1100000 | ||
1397 | +#define AM33XX_VDD_MPU_OPP120_UV 1200000 | ||
1398 | +#define AM33XX_VDD_MPU_OPPTURBO_UV 1260000 | ||
1399 | +#define AM33XX_VDD_CORE_OPP50_UV 950000 | ||
1400 | +#define AM33XX_VDD_CORE_OPP100_UV 1100000 | ||
1401 | + | ||
1402 | +#define AM33XX_VDD_MPU_OPP50_FREQ 275000000 | ||
1403 | +#define AM33XX_VDD_MPU_OPP100_FREQ 500000000 | ||
1404 | +#define AM33XX_VDD_MPU_OPP120_FREQ 600000000 | ||
1405 | +#define AM33XX_VDD_MPU_OPPTURBO_FREQ 720000000 | ||
1406 | + | ||
1407 | +#define AM33XX_ES2_0_VDD_MPU_OPP50_UV 950000 | ||
1408 | +#define AM33XX_ES2_0_VDD_MPU_OPP100_UV 1100000 | ||
1409 | +#define AM33XX_ES2_0_VDD_MPU_OPP120_UV 1200000 | ||
1410 | +#define AM33XX_ES2_0_VDD_MPU_OPPTURBO_UV 1260000 | ||
1411 | +#define AM33XX_ES2_0_VDD_MPU_OPPNITRO_UV 1320000 | ||
1412 | + | ||
1413 | +#define AM33XX_ES2_0_VDD_MPU_OPP50_FREQ 300000000 | ||
1414 | +#define AM33XX_ES2_0_VDD_MPU_OPP100_FREQ 600000000 | ||
1415 | +#define AM33XX_ES2_0_VDD_MPU_OPP120_FREQ 720000000 | ||
1416 | +#define AM33XX_ES2_0_VDD_MPU_OPPTURBO_FREQ 800000000 | ||
1417 | +#define AM33XX_ES2_0_VDD_MPU_OPPNITRO_FREQ 1000000000 | ||
1418 | + | ||
1419 | +static struct am33xx_sr_opp_data sr1_opp_data_2_0[] = { | ||
1420 | + { | ||
1421 | + .efuse_offs = AM33XX_SR1_OPP50_CNTRL_OFFSET, | ||
1422 | + .e2v_gain = 0, | ||
1423 | + .err_minlimit = AM33XX_SR1_OPP50_EVM_ERR_MIN_LIMIT, | ||
1424 | + .err_maxlimit = AM33XX_SR1_OPP50_ERR_MAX_LIMIT, | ||
1425 | + .err_weight = AM33XX_SR1_OPP50_ERR_WEIGHT, | ||
1426 | + .margin = AM33XX_SR1_OPP50_MARGIN, | ||
1427 | + .nominal_volt = AM33XX_ES2_0_VDD_MPU_OPP50_UV, | ||
1428 | + .frequency = AM33XX_ES2_0_VDD_MPU_OPP50_FREQ, | ||
1429 | + }, | ||
1430 | + { | ||
1431 | + .efuse_offs = AM33XX_SR1_OPP100_CNTRL_OFFSET, | ||
1432 | + .e2v_gain = 0, | ||
1433 | + .err_minlimit = AM33XX_SR1_OPP100_EVM_ERR_MIN_LIMIT, | ||
1434 | + .err_maxlimit = AM33XX_SR1_OPP100_ERR_MAX_LIMIT, | ||
1435 | + .err_weight = AM33XX_SR1_OPP100_ERR_WEIGHT, | ||
1436 | + .margin = AM33XX_SR1_OPP100_MARGIN, | ||
1437 | + .nominal_volt = AM33XX_ES2_0_VDD_MPU_OPP100_UV, | ||
1438 | + .frequency = AM33XX_ES2_0_VDD_MPU_OPP100_FREQ, | ||
1439 | + }, | ||
1440 | + { | ||
1441 | + .efuse_offs = AM33XX_SR1_OPP120_CNTRL_OFFSET, | ||
1442 | + .e2v_gain = 0, | ||
1443 | + .err_minlimit = AM33XX_SR1_OPP120_EVM_ERR_MIN_LIMIT, | ||
1444 | + .err_maxlimit = AM33XX_SR1_OPP120_ERR_MAX_LIMIT, | ||
1445 | + .err_weight = AM33XX_SR1_OPP120_ERR_WEIGHT, | ||
1446 | + .margin = AM33XX_SR1_OPP120_MARGIN, | ||
1447 | + .nominal_volt = AM33XX_ES2_0_VDD_MPU_OPP120_UV, | ||
1448 | + .frequency = AM33XX_ES2_0_VDD_MPU_OPP120_FREQ, | ||
1449 | + }, | ||
1450 | + { | ||
1451 | + .efuse_offs = AM33XX_SR1_OPPTURBO_CNTRL_OFFSET, | ||
1452 | + .e2v_gain = 0, | ||
1453 | + .err_minlimit = AM33XX_SR1_OPPTURBO_EVM_ERR_MIN_LIMIT, | ||
1454 | + .err_maxlimit = AM33XX_SR1_OPPTURBO_ERR_MAX_LIMIT, | ||
1455 | + .err_weight = AM33XX_SR1_OPPTURBO_ERR_WEIGHT, | ||
1456 | + .margin = AM33XX_SR1_OPPTURBO_MARGIN, | ||
1457 | + .nominal_volt = AM33XX_ES2_0_VDD_MPU_OPPTURBO_UV, | ||
1458 | + .frequency = AM33XX_ES2_0_VDD_MPU_OPPTURBO_FREQ, | ||
1459 | + }, | ||
1460 | + { | ||
1461 | + /* NITRO can use the TURBO data, except for margin */ | ||
1462 | + .efuse_offs = AM33XX_SR1_OPPTURBO_CNTRL_OFFSET, | ||
1463 | + .e2v_gain = 0, | ||
1464 | + .err_minlimit = AM33XX_SR1_OPPTURBO_EVM_ERR_MIN_LIMIT, | ||
1465 | + .err_maxlimit = AM33XX_SR1_OPPTURBO_ERR_MAX_LIMIT, | ||
1466 | + .err_weight = AM33XX_SR1_OPPTURBO_ERR_WEIGHT, | ||
1467 | + .margin = AM33XX_SR1_OPPNITRO_MARGIN, | ||
1468 | + .nominal_volt = AM33XX_ES2_0_VDD_MPU_OPPNITRO_UV, | ||
1469 | + .frequency = AM33XX_ES2_0_VDD_MPU_OPPNITRO_FREQ, | ||
1470 | + }, | ||
1471 | +}; | ||
1472 | |||
1473 | static struct am33xx_sr_opp_data sr1_opp_data[] = { | ||
1474 | - { | ||
1475 | - .efuse_offs = AM33XX_SR1_OPP50_CNTRL_OFFSET, | ||
1476 | - .e2v_gain = AM33XX_SR1_OPP50_EVM_ERR2VOLT_GAIN, | ||
1477 | - .err_minlimit = AM33XX_SR1_OPP50_EVM_ERR_MIN_LIMIT, | ||
1478 | - .err_maxlimit = AM33XX_SR1_OPP50_ERR_MAX_LIMIT, | ||
1479 | - .err_weight = AM33XX_SR1_OPP50_ERR_WEIGHT, | ||
1480 | - .margin = AM33XX_SR1_OPP50_MARGIN, | ||
1481 | - .nominal_volt = AM33XX_VDD_MPU_OPP50_UV, | ||
1482 | - .frequency = AM33XX_VDD_MPU_OPP50_FREQ, | ||
1483 | - }, | ||
1484 | - { | ||
1485 | - .efuse_offs = AM33XX_SR1_OPP100_CNTRL_OFFSET, | ||
1486 | - .e2v_gain = AM33XX_SR1_OPP100_EVM_ERR2VOLT_GAIN, | ||
1487 | - .err_minlimit = AM33XX_SR1_OPP100_EVM_ERR_MIN_LIMIT, | ||
1488 | - .err_maxlimit = AM33XX_SR1_OPP100_ERR_MAX_LIMIT, | ||
1489 | - .err_weight = AM33XX_SR1_OPP100_ERR_WEIGHT, | ||
1490 | - .margin = AM33XX_SR1_OPP100_MARGIN, | ||
1491 | - .nominal_volt = AM33XX_VDD_MPU_OPP100_UV, | ||
1492 | - .frequency = AM33XX_VDD_MPU_OPP100_FREQ, | ||
1493 | - }, | ||
1494 | - { | ||
1495 | - .efuse_offs = AM33XX_SR1_OPP120_CNTRL_OFFSET, | ||
1496 | - .e2v_gain = AM33XX_SR1_OPP120_EVM_ERR2VOLT_GAIN, | ||
1497 | - .err_minlimit = AM33XX_SR1_OPP120_EVM_ERR_MIN_LIMIT, | ||
1498 | - .err_maxlimit = AM33XX_SR1_OPP120_ERR_MAX_LIMIT, | ||
1499 | - .err_weight = AM33XX_SR1_OPP120_ERR_WEIGHT, | ||
1500 | - .margin = AM33XX_SR1_OPP120_MARGIN, | ||
1501 | - .nominal_volt = AM33XX_VDD_MPU_OPP120_UV, | ||
1502 | - .frequency = AM33XX_VDD_MPU_OPP120_FREQ, | ||
1503 | - }, | ||
1504 | - { | ||
1505 | - .efuse_offs = AM33XX_SR1_OPPTURBO_CNTRL_OFFSET, | ||
1506 | - .e2v_gain = AM33XX_SR1_OPPTURBO_EVM_ERR2VOLT_GAIN, | ||
1507 | - .err_minlimit = AM33XX_SR1_OPPTURBO_EVM_ERR_MIN_LIMIT, | ||
1508 | - .err_maxlimit = AM33XX_SR1_OPPTURBO_ERR_MAX_LIMIT, | ||
1509 | - .err_weight = AM33XX_SR1_OPPTURBO_ERR_WEIGHT, | ||
1510 | - .margin = AM33XX_SR1_OPPTURBO_MARGIN, | ||
1511 | - .nominal_volt = AM33XX_VDD_MPU_OPPTURBO_UV, | ||
1512 | - .frequency = AM33XX_VDD_MPU_OPPTURBO_FREQ, | ||
1513 | - }, | ||
1514 | + { | ||
1515 | + .efuse_offs = AM33XX_SR1_OPP50_CNTRL_OFFSET, | ||
1516 | + .e2v_gain = 0, | ||
1517 | + .err_minlimit = AM33XX_SR1_OPP50_EVM_ERR_MIN_LIMIT, | ||
1518 | + .err_maxlimit = AM33XX_SR1_OPP50_ERR_MAX_LIMIT, | ||
1519 | + .err_weight = AM33XX_SR1_OPP50_ERR_WEIGHT, | ||
1520 | + .margin = AM33XX_SR1_OPP50_MARGIN, | ||
1521 | + .nominal_volt = AM33XX_VDD_MPU_OPP50_UV, | ||
1522 | + .frequency = AM33XX_VDD_MPU_OPP50_FREQ, | ||
1523 | + }, | ||
1524 | + { | ||
1525 | + .efuse_offs = AM33XX_SR1_OPP100_CNTRL_OFFSET, | ||
1526 | + .e2v_gain = 0, | ||
1527 | + .err_minlimit = AM33XX_SR1_OPP100_EVM_ERR_MIN_LIMIT, | ||
1528 | + .err_maxlimit = AM33XX_SR1_OPP100_ERR_MAX_LIMIT, | ||
1529 | + .err_weight = AM33XX_SR1_OPP100_ERR_WEIGHT, | ||
1530 | + .margin = AM33XX_SR1_OPP100_MARGIN, | ||
1531 | + .nominal_volt = AM33XX_VDD_MPU_OPP100_UV, | ||
1532 | + .frequency = AM33XX_VDD_MPU_OPP100_FREQ, | ||
1533 | + }, | ||
1534 | + { | ||
1535 | + .efuse_offs = AM33XX_SR1_OPP120_CNTRL_OFFSET, | ||
1536 | + .e2v_gain = 0, | ||
1537 | + .err_minlimit = AM33XX_SR1_OPP120_EVM_ERR_MIN_LIMIT, | ||
1538 | + .err_maxlimit = AM33XX_SR1_OPP120_ERR_MAX_LIMIT, | ||
1539 | + .err_weight = AM33XX_SR1_OPP120_ERR_WEIGHT, | ||
1540 | + .margin = AM33XX_SR1_OPP120_MARGIN, | ||
1541 | + .nominal_volt = AM33XX_VDD_MPU_OPP120_UV, | ||
1542 | + .frequency = AM33XX_VDD_MPU_OPP120_FREQ, | ||
1543 | + }, | ||
1544 | + { | ||
1545 | + .efuse_offs = AM33XX_SR1_OPPTURBO_CNTRL_OFFSET, | ||
1546 | + .e2v_gain = 0, | ||
1547 | + .err_minlimit = AM33XX_SR1_OPPTURBO_EVM_ERR_MIN_LIMIT, | ||
1548 | + .err_maxlimit = AM33XX_SR1_OPPTURBO_ERR_MAX_LIMIT, | ||
1549 | + .err_weight = AM33XX_SR1_OPPTURBO_ERR_WEIGHT, | ||
1550 | + .margin = AM33XX_SR1_OPPTURBO_MARGIN, | ||
1551 | + .nominal_volt = AM33XX_VDD_MPU_OPPTURBO_UV, | ||
1552 | + .frequency = AM33XX_VDD_MPU_OPPTURBO_FREQ, | ||
1553 | + }, | ||
1554 | }; | ||
1555 | |||
1556 | static struct am33xx_sr_opp_data sr0_opp_data[] = { | ||
1557 | - { | ||
1558 | - .efuse_offs = AM33XX_SR0_OPP50_CNTRL_OFFSET, | ||
1559 | - .e2v_gain = AM33XX_SR0_OPP50_EVM_ERR2VOLT_GAIN, | ||
1560 | - .err_minlimit = AM33XX_SR0_OPP50_EVM_ERR_MIN_LIMIT, | ||
1561 | - .err_maxlimit = AM33XX_SR0_OPP50_ERR_MAX_LIMIT, | ||
1562 | - .err_weight = AM33XX_SR0_OPP50_ERR_WEIGHT, | ||
1563 | - .margin = AM33XX_SR0_OPP50_MARGIN, | ||
1564 | - .nominal_volt = AM33XX_VDD_CORE_OPP50_UV, | ||
1565 | - }, | ||
1566 | - { | ||
1567 | - .efuse_offs = AM33XX_SR0_OPP100_CNTRL_OFFSET, | ||
1568 | - .e2v_gain = AM33XX_SR0_OPP100_EVM_ERR2VOLT_GAIN, | ||
1569 | - .err_minlimit = AM33XX_SR0_OPP100_EVM_ERR_MIN_LIMIT, | ||
1570 | - .err_maxlimit = AM33XX_SR0_OPP100_ERR_MAX_LIMIT, | ||
1571 | - .err_weight = AM33XX_SR0_OPP100_ERR_WEIGHT, | ||
1572 | - .margin = AM33XX_SR0_OPP100_MARGIN, | ||
1573 | - .nominal_volt = AM33XX_VDD_CORE_OPP100_UV, | ||
1574 | - }, | ||
1575 | + { | ||
1576 | + .efuse_offs = AM33XX_SR0_OPP50_CNTRL_OFFSET, | ||
1577 | + .e2v_gain = 0, | ||
1578 | + .err_minlimit = AM33XX_SR0_OPP50_EVM_ERR_MIN_LIMIT, | ||
1579 | + .err_maxlimit = AM33XX_SR0_OPP50_ERR_MAX_LIMIT, | ||
1580 | + .err_weight = AM33XX_SR0_OPP50_ERR_WEIGHT, | ||
1581 | + .margin = AM33XX_SR0_OPP50_MARGIN, | ||
1582 | + .nominal_volt = AM33XX_VDD_CORE_OPP50_UV, | ||
1583 | + }, | ||
1584 | + { | ||
1585 | + .efuse_offs = AM33XX_SR0_OPP100_CNTRL_OFFSET, | ||
1586 | + .e2v_gain = 0, | ||
1587 | + .err_minlimit = AM33XX_SR0_OPP100_EVM_ERR_MIN_LIMIT, | ||
1588 | + .err_maxlimit = AM33XX_SR0_OPP100_ERR_MAX_LIMIT, | ||
1589 | + .err_weight = AM33XX_SR0_OPP100_ERR_WEIGHT, | ||
1590 | + .margin = AM33XX_SR0_OPP100_MARGIN, | ||
1591 | + .nominal_volt = AM33XX_VDD_CORE_OPP100_UV, | ||
1592 | + }, | ||
1593 | +}; | ||
1594 | + | ||
1595 | +static struct am33xx_sr_sdata sr_sensor_data_2_0[] = { | ||
1596 | + { | ||
1597 | + .sr_opp_data = sr0_opp_data, | ||
1598 | + /* note that OPP50 is NOT used in Linux kernel for AM335x */ | ||
1599 | + .no_of_opps = 0x2, | ||
1600 | + .default_opp = 0x1, | ||
1601 | + .senn_mod = 0x1, | ||
1602 | + .senp_mod = 0x1, | ||
1603 | + }, | ||
1604 | + { | ||
1605 | + .sr_opp_data = sr1_opp_data_2_0, | ||
1606 | + /* the opp data below should be determined | ||
1607 | + dynamically during SR probe */ | ||
1608 | + .no_of_opps = 0x5, | ||
1609 | + .default_opp = 0x3, | ||
1610 | + .senn_mod = 0x1, | ||
1611 | + .senp_mod = 0x1, | ||
1612 | + }, | ||
1613 | }; | ||
1614 | |||
1615 | static struct am33xx_sr_sdata sr_sensor_data[] = { | ||
1616 | - { | ||
1617 | - .sr_opp_data = sr0_opp_data, | ||
1618 | - /* note that OPP50 is NOT used in Linux kernel for AM335x */ | ||
1619 | - .no_of_opps = 0x2, | ||
1620 | - .default_opp = 0x1, | ||
1621 | - .senn_mod = 0x1, | ||
1622 | - .senp_mod = 0x1, | ||
1623 | - }, | ||
1624 | - { | ||
1625 | - .sr_opp_data = sr1_opp_data, | ||
1626 | - /* the opp data below should be determined | ||
1627 | - dynamically during SR probe */ | ||
1628 | - .no_of_opps = 0x4, | ||
1629 | - .default_opp = 0x3, | ||
1630 | - .senn_mod = 0x1, | ||
1631 | - .senp_mod = 0x1, | ||
1632 | - }, | ||
1633 | + { | ||
1634 | + .sr_opp_data = sr0_opp_data, | ||
1635 | + /* note that OPP50 is NOT used in Linux kernel for AM335x */ | ||
1636 | + .no_of_opps = 0x2, | ||
1637 | + .default_opp = 0x1, | ||
1638 | + .senn_mod = 0x1, | ||
1639 | + .senp_mod = 0x1, | ||
1640 | + }, | ||
1641 | + { | ||
1642 | + .sr_opp_data = sr1_opp_data, | ||
1643 | + /* the opp data below should be determined | ||
1644 | + dynamically during SR probe */ | ||
1645 | + .no_of_opps = 0x4, | ||
1646 | + .default_opp = 0x3, | ||
1647 | + .senn_mod = 0x1, | ||
1648 | + .senp_mod = 0x1, | ||
1649 | + }, | ||
1650 | }; | ||
1651 | |||
1652 | static struct am33xx_sr_platform_data am33xx_sr_pdata = { | ||
1653 | - .vd_name[0] = "vdd_core", | ||
1654 | - .vd_name[1] = "vdd_mpu", | ||
1655 | - .ip_type = 2, | ||
1656 | - .irq_delay = 1000, | ||
1657 | - .no_of_vds = 2, | ||
1658 | - .no_of_sens = ARRAY_SIZE(sr_sensor_data), | ||
1659 | - .vstep_size_uv = 12500, | ||
1660 | - .enable_on_init = true, | ||
1661 | - .sr_sdata = sr_sensor_data, | ||
1662 | + .vd_name[0] = "vdd_core", | ||
1663 | + .vd_name[1] = "vdd_mpu", | ||
1664 | + .ip_type = 2, | ||
1665 | + .irq_delay = 1000, | ||
1666 | + .no_of_vds = 2, | ||
1667 | + .no_of_sens = ARRAY_SIZE(sr_sensor_data), | ||
1668 | + .vstep_size_uv = 12500, | ||
1669 | + .enable_on_init = true, | ||
1670 | + .sr_sdata = sr_sensor_data, | ||
1671 | }; | ||
1672 | |||
1673 | static struct resource am33xx_sr_resources[] = { | ||
1674 | - { | ||
1675 | - .name = "smartreflex0", | ||
1676 | - .start = AM33XX_SR0_BASE, | ||
1677 | - .end = AM33XX_SR0_BASE + SZ_4K - 1, | ||
1678 | - .flags = IORESOURCE_MEM, | ||
1679 | - }, | ||
1680 | - { | ||
1681 | - .name = "smartreflex0", | ||
1682 | - .start = AM33XX_IRQ_SMARTREFLEX0, | ||
1683 | - .end = AM33XX_IRQ_SMARTREFLEX0, | ||
1684 | - .flags = IORESOURCE_IRQ, | ||
1685 | - }, | ||
1686 | - { | ||
1687 | - .name = "smartreflex1", | ||
1688 | - .start = AM33XX_SR1_BASE, | ||
1689 | - .end = AM33XX_SR1_BASE + SZ_4K - 1, | ||
1690 | - .flags = IORESOURCE_MEM, | ||
1691 | - }, | ||
1692 | - { | ||
1693 | - .name = "smartreflex1", | ||
1694 | - .start = AM33XX_IRQ_SMARTREFLEX1, | ||
1695 | - .end = AM33XX_IRQ_SMARTREFLEX1, | ||
1696 | - .flags = IORESOURCE_IRQ, | ||
1697 | - }, | ||
1698 | + { | ||
1699 | + .name = "smartreflex0", | ||
1700 | + .start = AM33XX_SR0_BASE, | ||
1701 | + .end = AM33XX_SR0_BASE + SZ_4K - 1, | ||
1702 | + .flags = IORESOURCE_MEM, | ||
1703 | + }, | ||
1704 | + { | ||
1705 | + .name = "smartreflex0", | ||
1706 | + .start = AM33XX_IRQ_SMARTREFLEX0, | ||
1707 | + .end = AM33XX_IRQ_SMARTREFLEX0, | ||
1708 | + .flags = IORESOURCE_IRQ, | ||
1709 | + }, | ||
1710 | + { | ||
1711 | + .name = "smartreflex1", | ||
1712 | + .start = AM33XX_SR1_BASE, | ||
1713 | + .end = AM33XX_SR1_BASE + SZ_4K - 1, | ||
1714 | + .flags = IORESOURCE_MEM, | ||
1715 | + }, | ||
1716 | + { | ||
1717 | + .name = "smartreflex1", | ||
1718 | + .start = AM33XX_IRQ_SMARTREFLEX1, | ||
1719 | + .end = AM33XX_IRQ_SMARTREFLEX1, | ||
1720 | + .flags = IORESOURCE_IRQ, | ||
1721 | + }, | ||
1722 | }; | ||
1723 | |||
1724 | /* VCORE for SR regulator init */ | ||
1725 | static struct platform_device am33xx_sr_device = { | ||
1726 | - .name = "smartreflex", | ||
1727 | - .id = -1, | ||
1728 | - .num_resources = ARRAY_SIZE(am33xx_sr_resources), | ||
1729 | - .resource = am33xx_sr_resources, | ||
1730 | - .dev = { | ||
1731 | - .platform_data = &am33xx_sr_pdata, | ||
1732 | - }, | ||
1733 | + .name = "smartreflex", | ||
1734 | + .id = -1, | ||
1735 | + .num_resources = ARRAY_SIZE(am33xx_sr_resources), | ||
1736 | + .resource = am33xx_sr_resources, | ||
1737 | + .dev = { | ||
1738 | + .platform_data = &am33xx_sr_pdata, | ||
1739 | + }, | ||
1740 | }; | ||
1741 | |||
1742 | void __init am33xx_sr_init(void) | ||
1743 | { | ||
1744 | - /* For beaglebone, update voltage step size and related parameters | ||
1745 | - appropriately. All other AM33XX platforms are good with the | ||
1746 | - structure defaults as initialized above. */ | ||
1747 | - if ((am33xx_evmid == BEAGLE_BONE_OLD) || | ||
1748 | - (am33xx_evmid == BEAGLE_BONE_A3)) { | ||
1749 | - printk(KERN_ERR "address of pdata = %08x\n", (u32)&am33xx_sr_pdata); | ||
1750 | - am33xx_sr_pdata.vstep_size_uv = 25000; | ||
1751 | - /* CORE */ | ||
1752 | - sr0_opp_data[0].e2v_gain = AM33XX_SR0_OPP50_BB_ERR2VOLT_GAIN; | ||
1753 | - sr0_opp_data[0].err_minlimit = AM33XX_SR0_OPP50_BB_ERR_MIN_LIMIT; | ||
1754 | - sr0_opp_data[1].e2v_gain = AM33XX_SR0_OPP100_BB_ERR2VOLT_GAIN; | ||
1755 | - sr0_opp_data[1].err_minlimit = AM33XX_SR0_OPP100_BB_ERR_MIN_LIMIT; | ||
1756 | - /* MPU */ | ||
1757 | - sr1_opp_data[0].e2v_gain = AM33XX_SR1_OPP50_BB_ERR2VOLT_GAIN; | ||
1758 | - sr1_opp_data[0].err_minlimit = AM33XX_SR1_OPP50_BB_ERR_MIN_LIMIT; | ||
1759 | - sr1_opp_data[1].e2v_gain = AM33XX_SR1_OPP100_BB_ERR2VOLT_GAIN; | ||
1760 | - sr1_opp_data[1].err_minlimit = AM33XX_SR1_OPP100_BB_ERR_MIN_LIMIT; | ||
1761 | - sr1_opp_data[2].e2v_gain = AM33XX_SR1_OPP120_BB_ERR2VOLT_GAIN; | ||
1762 | - sr1_opp_data[2].err_minlimit = AM33XX_SR1_OPP120_BB_ERR_MIN_LIMIT; | ||
1763 | - sr1_opp_data[3].e2v_gain = AM33XX_SR1_OPPTURBO_BB_ERR2VOLT_GAIN; | ||
1764 | - sr1_opp_data[3].err_minlimit = AM33XX_SR1_OPPTURBO_BB_ERR_MIN_LIMIT; | ||
1765 | - } | ||
1766 | - | ||
1767 | - if (platform_device_register(&am33xx_sr_device)) | ||
1768 | - printk(KERN_ERR "failed to register am33xx_sr device\n"); | ||
1769 | - else | ||
1770 | - printk(KERN_INFO "registered am33xx_sr device\n"); | ||
1771 | + if (omap_rev() != AM335X_REV_ES1_0) | ||
1772 | + am33xx_sr_pdata.sr_sdata = sr_sensor_data_2_0; | ||
1773 | + | ||
1774 | + /* For beaglebone, update voltage step size and related parameters | ||
1775 | + appropriately. All other AM33XX platforms are good with the | ||
1776 | + structure defaults as initialized above. */ | ||
1777 | + if ((am33xx_evmid == BEAGLE_BONE_OLD) || | ||
1778 | + (am33xx_evmid == BEAGLE_BONE_A3)) { | ||
1779 | + printk(KERN_ERR "address of pdata = %08x\n", | ||
1780 | + (u32)&am33xx_sr_pdata); | ||
1781 | + | ||
1782 | + am33xx_sr_pdata.vstep_size_uv = 25000; | ||
1783 | + } | ||
1784 | + | ||
1785 | + if (platform_device_register(&am33xx_sr_device)) | ||
1786 | + printk(KERN_ERR "failed to register am33xx_sr device\n"); | ||
1787 | + else | ||
1788 | + printk(KERN_INFO "registered am33xx_sr device\n"); | ||
1789 | } | ||
1790 | #else | ||
1791 | inline void am33xx_sr_init(void) {} | ||
1792 | diff --git a/arch/arm/plat-omap/include/plat/smartreflex.h b/arch/arm/plat-omap/include/plat/smartreflex.h | ||
1793 | index 76c1ff7..d837755 100644 | ||
1794 | --- a/arch/arm/plat-omap/include/plat/smartreflex.h | ||
1795 | +++ b/arch/arm/plat-omap/include/plat/smartreflex.h | ||
1796 | @@ -238,14 +238,14 @@ int sr_register_class(struct omap_sr_class_data *class_data); | ||
1797 | |||
1798 | #ifdef CONFIG_AM33XX_SMARTREFLEX | ||
1799 | |||
1800 | -#define SR_CORE (0) | ||
1801 | -#define SR_MPU (1) | ||
1802 | +#define SR_CORE (0) | ||
1803 | +#define SR_MPU (1) | ||
1804 | #define SRCLKLENGTH_125MHZ_SYSCLK (0x78 << 12) | ||
1805 | -#define GAIN_MAXLIMIT (16) | ||
1806 | -#define R_MAXLIMIT (256) | ||
1807 | -#define MAX_SENSORS 2 | ||
1808 | +#define GAIN_MAXLIMIT (16) | ||
1809 | +#define R_MAXLIMIT (256) | ||
1810 | +#define MAX_SENSORS (2) | ||
1811 | /* GG: eventually this should be determined at runtime */ | ||
1812 | -#define AM33XX_OPP_COUNT 4 | ||
1813 | +#define AM33XX_OPP_COUNT (5) | ||
1814 | |||
1815 | /** | ||
1816 | * struct am33xx_sr_opp_data - Smartreflex data per OPP | ||
1817 | @@ -264,17 +264,17 @@ int sr_register_class(struct omap_sr_class_data *class_data); | ||
1818 | */ | ||
1819 | struct am33xx_sr_opp_data { | ||
1820 | u32 efuse_offs; | ||
1821 | - u32 nvalue; | ||
1822 | - u32 adj_nvalue; | ||
1823 | + u32 nvalue; | ||
1824 | + u32 adj_nvalue; | ||
1825 | s32 e2v_gain; | ||
1826 | u32 err_weight; | ||
1827 | u32 err_minlimit; | ||
1828 | u32 err_maxlimit; | ||
1829 | - s32 margin; | ||
1830 | - u32 nominal_volt; /* nominal_volt and frequency may be removed | ||
1831 | - once am33xx voltdm layer works */ | ||
1832 | - u32 frequency; | ||
1833 | - u32 opp_id; | ||
1834 | + s32 margin; | ||
1835 | + u32 nominal_volt; /* nominal_volt and frequency may be removed | ||
1836 | + once am33xx voltdm layer works */ | ||
1837 | + u32 frequency; | ||
1838 | + u32 opp_id; | ||
1839 | }; | ||
1840 | |||
1841 | /** | ||
1842 | @@ -290,50 +290,54 @@ struct am33xx_sr_opp_data { | ||
1843 | */ | ||
1844 | struct am33xx_sr_sdata { | ||
1845 | struct am33xx_sr_opp_data *sr_opp_data; | ||
1846 | - u32 no_of_opps; | ||
1847 | - u32 default_opp; | ||
1848 | + u32 no_of_opps; | ||
1849 | + u32 default_opp; | ||
1850 | u32 senn_mod; | ||
1851 | u32 senp_mod; | ||
1852 | }; | ||
1853 | |||
1854 | struct am33xx_sr_sensor { | ||
1855 | - u32 sr_id; | ||
1856 | + u32 sr_id; | ||
1857 | u32 irq; | ||
1858 | u32 irq_status; | ||
1859 | u32 senn_en; | ||
1860 | u32 senp_en; | ||
1861 | char *name; | ||
1862 | - char *reg_name; | ||
1863 | + char *reg_name; | ||
1864 | void __iomem *base; | ||
1865 | - int init_volt_mv; | ||
1866 | - int curr_opp; | ||
1867 | - u32 no_of_opps; | ||
1868 | - struct delayed_work work_reenable; | ||
1869 | - struct regulator *reg; | ||
1870 | - struct am33xx_sr_opp_data opp_data[AM33XX_OPP_COUNT]; | ||
1871 | + int init_volt_mv; | ||
1872 | + int curr_opp; | ||
1873 | + u32 no_of_opps; | ||
1874 | + int state; | ||
1875 | + s8 avg_error_nom; | ||
1876 | + int saved_volt; | ||
1877 | + struct delayed_work work_reenable; | ||
1878 | + struct regulator *reg; | ||
1879 | + struct am33xx_sr_opp_data opp_data[AM33XX_OPP_COUNT]; | ||
1880 | struct clk *fck; | ||
1881 | - struct voltagedomain *voltdm; | ||
1882 | - struct omap_volt_data *volt_data; | ||
1883 | + struct voltagedomain *voltdm; | ||
1884 | + struct omap_volt_data *volt_data; | ||
1885 | }; | ||
1886 | |||
1887 | struct am33xx_sr { | ||
1888 | - u32 autocomp_active; | ||
1889 | + bool autocomp_active; | ||
1890 | + bool is_suspended; | ||
1891 | u32 sens_per_vd; | ||
1892 | - u32 no_of_sens; | ||
1893 | - u32 no_of_vds; | ||
1894 | + u32 no_of_sens; | ||
1895 | + u32 no_of_vds; | ||
1896 | u32 ip_type; | ||
1897 | - u32 irq_delay; | ||
1898 | - u32 disabled_by_user; | ||
1899 | + u32 irq_delay; | ||
1900 | + bool disabled_by_user; | ||
1901 | int uvoltage_step_size; | ||
1902 | - char *res_name[MAX_SENSORS]; | ||
1903 | + char *res_name[MAX_SENSORS]; | ||
1904 | #ifdef CONFIG_CPU_FREQ | ||
1905 | struct notifier_block freq_transition; | ||
1906 | #endif | ||
1907 | - /*struct work_struct work;*/ | ||
1908 | - struct delayed_work work; | ||
1909 | + struct delayed_work work; | ||
1910 | struct sr_platform_data *sr_data; | ||
1911 | struct am33xx_sr_sensor sen[MAX_SENSORS]; | ||
1912 | struct platform_device *pdev; | ||
1913 | + struct list_head node; | ||
1914 | }; | ||
1915 | |||
1916 | /** | ||
1917 | @@ -354,7 +358,7 @@ struct am33xx_sr_platform_data { | ||
1918 | struct am33xx_sr_sdata *sr_sdata; | ||
1919 | char *vd_name[2]; | ||
1920 | u32 ip_type; | ||
1921 | - u32 irq_delay; | ||
1922 | + u32 irq_delay; | ||
1923 | u32 no_of_vds; | ||
1924 | u32 no_of_sens; | ||
1925 | u32 vstep_size_uv; | ||
1926 | -- | ||
1927 | 1.7.9.5 | ||
1928 | |||
diff --git a/recipes-kernel/linux/linux-am335x-psp_3.2.bb b/recipes-kernel/linux/linux-am335x-psp_3.2.bb index 7fd69353..958bba5a 100644 --- a/recipes-kernel/linux/linux-am335x-psp_3.2.bb +++ b/recipes-kernel/linux/linux-am335x-psp_3.2.bb | |||
@@ -15,7 +15,7 @@ DEPENDS += "am33x-cm3" | |||
15 | KERNEL_IMAGETYPE = "uImage" | 15 | KERNEL_IMAGETYPE = "uImage" |
16 | 16 | ||
17 | # The main PR is now using MACHINE_KERNEL_PR, for ti33x see conf/machine/include/ti33x.inc | 17 | # The main PR is now using MACHINE_KERNEL_PR, for ti33x see conf/machine/include/ti33x.inc |
18 | MACHINE_KERNEL_PR_append = "e+gitr${SRCPV}" | 18 | MACHINE_KERNEL_PR_append = "f+gitr${SRCPV}" |
19 | 19 | ||
20 | BRANCH = "v3.2-staging" | 20 | BRANCH = "v3.2-staging" |
21 | 21 | ||
@@ -68,6 +68,7 @@ PATCHES += "file://0001-am33x-Add-memory-addresses-for-crypto-modules.patch \ | |||
68 | PATCHES += "file://0001-am33xx-Add-SmartReflex-support.patch \ | 68 | PATCHES += "file://0001-am33xx-Add-SmartReflex-support.patch \ |
69 | file://0002-am33xx-Enable-CONFIG_AM33XX_SMARTREFLEX.patch \ | 69 | file://0002-am33xx-Enable-CONFIG_AM33XX_SMARTREFLEX.patch \ |
70 | file://0002-Smartreflex-limited-to-ES-1.0.patch \ | 70 | file://0002-Smartreflex-limited-to-ES-1.0.patch \ |
71 | file://0001-Smartreflex-support-for-ES-2.x-and-suspend-resume.patch \ | ||
71 | " | 72 | " |
72 | 73 | ||
73 | # Add a patch to the omap-serial driver to allow suspend/resume during | 74 | # Add a patch to the omap-serial driver to allow suspend/resume during |