1 From bf679a27766de623815d820431e1049326f7cac1 Mon Sep 17 00:00:00 2001
2 From: Ranjith Lohithakshan <ranjithl@ti.com>
3 Date: Fri, 9 Jul 2010 15:55:41 +0530
4 Subject: [PATCH 3/9] OMAP3: PM: Introduce Smartreflex support on OMAP3630/DM3730
6 OMAP3630 has a newer version of Smartreflex IP called Smartreflex2. There are
7 new register additions and bit definition differences in this version of the IP.
8 This patch introduces the Class3 driver support for Smartreflex2 on OMAP3630.
10 Smartreflex2 has the following registers added
11 IRQ_EOI, IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR
13 And following register offsets are different from Smartreflex1
16 Signed-off-by: Ranjith Lohithakshan <ranjithl@ti.com>
18 arch/arm/mach-omap2/smartreflex.c | 190 +++++++++++++++++++----------
19 arch/arm/mach-omap2/smartreflex.h | 16 +++
20 arch/arm/plat-omap/include/plat/control.h | 13 ++
21 3 files changed, 157 insertions(+), 62 deletions(-)
23 diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
24 index fd34af2..fdd9540 100644
25 --- a/arch/arm/mach-omap2/smartreflex.c
26 +++ b/arch/arm/mach-omap2/smartreflex.c
27 @@ -99,18 +99,26 @@ static int sr_clk_enable(struct omap_sr *sr)
31 - /* set fclk- active , iclk- idle */
32 - sr_modify_reg(sr, ERRCONFIG, SR_CLKACTIVITY_MASK,
33 - SR_CLKACTIVITY_IOFF_FON);
34 + if (cpu_is_omap3630())
35 + sr_modify_reg(sr, ERRCONFIG_36XX, SR_IDLEMODE_MASK,
38 + /* set fclk- active , iclk- idle */
39 + sr_modify_reg(sr, ERRCONFIG, SR_CLKACTIVITY_MASK,
40 + SR_CLKACTIVITY_IOFF_FON);
45 static void sr_clk_disable(struct omap_sr *sr)
47 - /* set fclk, iclk- idle */
48 - sr_modify_reg(sr, ERRCONFIG, SR_CLKACTIVITY_MASK,
49 - SR_CLKACTIVITY_IOFF_FOFF);
50 + if (cpu_is_omap3630())
51 + sr_modify_reg(sr, ERRCONFIG_36XX, SR_IDLEMODE_MASK,
54 + /* set fclk, iclk- idle */
55 + sr_modify_reg(sr, ERRCONFIG, SR_CLKACTIVITY_MASK,
56 + SR_CLKACTIVITY_IOFF_FOFF);
60 @@ -285,39 +293,55 @@ static u32 swcalc_opp6_nvalue(void)
61 static void sr_set_efuse_nvalues(struct omap_sr *sr)
63 if (sr->srid == SR1) {
64 - sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
65 - OMAP343X_SR1_SENNENABLE_MASK) >>
66 - OMAP343X_SR1_SENNENABLE_SHIFT;
67 - sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
68 - OMAP343X_SR1_SENPENABLE_MASK) >>
69 - OMAP343X_SR1_SENPENABLE_SHIFT;
71 - sr->opp6_nvalue = swcalc_opp6_nvalue();
72 - sr->opp5_nvalue = omap_ctrl_readl(
73 - OMAP343X_CONTROL_FUSE_OPP5_VDD1);
74 - sr->opp4_nvalue = omap_ctrl_readl(
75 - OMAP343X_CONTROL_FUSE_OPP4_VDD1);
76 - sr->opp3_nvalue = omap_ctrl_readl(
77 - OMAP343X_CONTROL_FUSE_OPP3_VDD1);
78 - sr->opp2_nvalue = omap_ctrl_readl(
79 - OMAP343X_CONTROL_FUSE_OPP2_VDD1);
80 - sr->opp1_nvalue = omap_ctrl_readl(
81 - OMAP343X_CONTROL_FUSE_OPP1_VDD1);
82 + if (cpu_is_omap3630()) {
83 + sr->senn_mod = sr->senp_mod = 0x1;
85 + sr->opp4_nvalue = omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP4_VDD1);
86 + sr->opp3_nvalue = omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP3_VDD1);
87 + sr->opp2_nvalue = omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP2_VDD1);
88 + sr->opp1_nvalue = omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP1_VDD1);
90 + sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
91 + OMAP343X_SR1_SENNENABLE_MASK) >>
92 + OMAP343X_SR1_SENNENABLE_SHIFT;
93 + sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
94 + OMAP343X_SR1_SENPENABLE_MASK) >>
95 + OMAP343X_SR1_SENPENABLE_SHIFT;
97 + sr->opp6_nvalue = swcalc_opp6_nvalue();
98 + sr->opp5_nvalue = omap_ctrl_readl(
99 + OMAP343X_CONTROL_FUSE_OPP5_VDD1);
100 + sr->opp4_nvalue = omap_ctrl_readl(
101 + OMAP343X_CONTROL_FUSE_OPP4_VDD1);
102 + sr->opp3_nvalue = omap_ctrl_readl(
103 + OMAP343X_CONTROL_FUSE_OPP3_VDD1);
104 + sr->opp2_nvalue = omap_ctrl_readl(
105 + OMAP343X_CONTROL_FUSE_OPP2_VDD1);
106 + sr->opp1_nvalue = omap_ctrl_readl(
107 + OMAP343X_CONTROL_FUSE_OPP1_VDD1);
109 } else if (sr->srid == SR2) {
110 - sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
111 - OMAP343X_SR2_SENNENABLE_MASK) >>
112 - OMAP343X_SR2_SENNENABLE_SHIFT;
114 - sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
115 - OMAP343X_SR2_SENPENABLE_MASK) >>
116 - OMAP343X_SR2_SENPENABLE_SHIFT;
118 - sr->opp3_nvalue = omap_ctrl_readl(
119 - OMAP343X_CONTROL_FUSE_OPP3_VDD2);
120 - sr->opp2_nvalue = omap_ctrl_readl(
121 - OMAP343X_CONTROL_FUSE_OPP2_VDD2);
122 - sr->opp1_nvalue = omap_ctrl_readl(
123 - OMAP343X_CONTROL_FUSE_OPP1_VDD2);
124 + if (cpu_is_omap3630()) {
125 + sr->senn_mod = sr->senp_mod = 0x1;
127 + sr->opp1_nvalue = omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP1_VDD2);
128 + sr->opp2_nvalue = omap_ctrl_readl(OMAP36XX_CONTROL_FUSE_OPP2_VDD2);
130 + sr->senn_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
131 + OMAP343X_SR2_SENNENABLE_MASK) >>
132 + OMAP343X_SR2_SENNENABLE_SHIFT;
134 + sr->senp_mod = (omap_ctrl_readl(OMAP343X_CONTROL_FUSE_SR) &
135 + OMAP343X_SR2_SENPENABLE_MASK) >>
136 + OMAP343X_SR2_SENPENABLE_SHIFT;
138 + sr->opp3_nvalue = omap_ctrl_readl(
139 + OMAP343X_CONTROL_FUSE_OPP3_VDD2);
140 + sr->opp2_nvalue = omap_ctrl_readl(
141 + OMAP343X_CONTROL_FUSE_OPP2_VDD2);
142 + sr->opp1_nvalue = omap_ctrl_readl(
143 + OMAP343X_CONTROL_FUSE_OPP1_VDD2);
148 @@ -325,22 +349,42 @@ static void sr_set_efuse_nvalues(struct omap_sr *sr)
149 static void sr_set_testing_nvalues(struct omap_sr *sr)
151 if (sr->srid == SR1) {
152 - sr->senp_mod = 0x03; /* SenN-M5 enabled */
153 - sr->senn_mod = 0x03;
155 - /* calculate nvalues for each opp */
156 - sr->opp5_nvalue = cal_test_nvalue(0xacd + 0x330, 0x848 + 0x330);
157 - sr->opp4_nvalue = cal_test_nvalue(0x964 + 0x2a0, 0x727 + 0x2a0);
158 - sr->opp3_nvalue = cal_test_nvalue(0x85b + 0x200, 0x655 + 0x200);
159 - sr->opp2_nvalue = cal_test_nvalue(0x506 + 0x1a0, 0x3be + 0x1a0);
160 - sr->opp1_nvalue = cal_test_nvalue(0x373 + 0x100, 0x28c + 0x100);
161 + if (cpu_is_omap3630()) {
162 + sr->senp_mod = 0x1;
163 + sr->senn_mod = 0x1;
165 + /* calculate nvalues for each opp */
166 + sr->opp1_nvalue = cal_test_nvalue(581, 489);
167 + sr->opp2_nvalue = cal_test_nvalue(1072, 910);
168 + sr->opp3_nvalue = cal_test_nvalue(1405, 1200);
169 + sr->opp4_nvalue = cal_test_nvalue(1842, 1580);
170 + sr->opp5_nvalue = cal_test_nvalue(1842, 1580);
172 + sr->senp_mod = 0x03; /* SenN-M5 enabled */
173 + sr->senn_mod = 0x03;
175 + /* calculate nvalues for each opp */
176 + sr->opp5_nvalue = cal_test_nvalue(0xacd + 0x330, 0x848 + 0x330);
177 + sr->opp4_nvalue = cal_test_nvalue(0x964 + 0x2a0, 0x727 + 0x2a0);
178 + sr->opp3_nvalue = cal_test_nvalue(0x85b + 0x200, 0x655 + 0x200);
179 + sr->opp2_nvalue = cal_test_nvalue(0x506 + 0x1a0, 0x3be + 0x1a0);
180 + sr->opp1_nvalue = cal_test_nvalue(0x373 + 0x100, 0x28c + 0x100);
182 } else if (sr->srid == SR2) {
183 - sr->senp_mod = 0x03;
184 - sr->senn_mod = 0x03;
186 - sr->opp3_nvalue = cal_test_nvalue(0x76f + 0x200, 0x579 + 0x200);
187 - sr->opp2_nvalue = cal_test_nvalue(0x4f5 + 0x1c0, 0x390 + 0x1c0);
188 - sr->opp1_nvalue = cal_test_nvalue(0x359, 0x25d);
189 + if (cpu_is_omap3630()) {
190 + sr->senp_mod = 0x1;
191 + sr->senn_mod = 0x1;
193 + sr->opp1_nvalue = cal_test_nvalue(556, 468);
194 + sr->opp2_nvalue = cal_test_nvalue(1099, 933);
196 + sr->senp_mod = 0x03;
197 + sr->senn_mod = 0x03;
199 + sr->opp3_nvalue = cal_test_nvalue(0x76f + 0x200, 0x579 + 0x200);
200 + sr->opp2_nvalue = cal_test_nvalue(0x4f5 + 0x1c0, 0x390 + 0x1c0);
201 + sr->opp1_nvalue = cal_test_nvalue(0x359, 0x25d);
206 @@ -487,6 +531,17 @@ static void sr_configure(struct omap_sr *sr)
209 u32 senp_en , senn_en;
210 + u32 senp_en_shift, senn_en_shift, err_config;
212 + if (cpu_is_omap3630()) {
213 + senp_en_shift = SRCONFIG_SENPENABLE_SHIFT_36XX;
214 + senn_en_shift = SRCONFIG_SENNENABLE_SHIFT_36XX;
215 + err_config = ERRCONFIG_36XX;
217 + senp_en_shift = SRCONFIG_SENPENABLE_SHIFT;
218 + senn_en_shift = SRCONFIG_SENNENABLE_SHIFT;
219 + err_config = ERRCONFIG;
222 if (sr->clk_length == 0)
223 sr_set_clk_length(sr);
224 @@ -498,15 +553,15 @@ static void sr_configure(struct omap_sr *sr)
225 (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
226 SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
227 SRCONFIG_MINMAXAVG_EN |
228 - (senn_en << SRCONFIG_SENNENABLE_SHIFT) |
229 - (senp_en << SRCONFIG_SENPENABLE_SHIFT) |
230 + (senn_en << senn_en_shift) |
231 + (senp_en << senp_en_shift) |
234 sr_write_reg(sr, SRCONFIG, sr_config);
235 sr_write_reg(sr, AVGWEIGHT, SR1_AVGWEIGHT_SENPAVGWEIGHT |
236 SR1_AVGWEIGHT_SENNAVGWEIGHT);
238 - sr_modify_reg(sr, ERRCONFIG, (SR_ERRWEIGHT_MASK |
239 + sr_modify_reg(sr, err_config, (SR_ERRWEIGHT_MASK |
240 SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
241 (SR1_ERRWEIGHT | SR1_ERRMAXLIMIT | SR1_ERRMINLIMIT));
243 @@ -515,14 +570,14 @@ static void sr_configure(struct omap_sr *sr)
244 (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
245 SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN |
246 SRCONFIG_MINMAXAVG_EN |
247 - (senn_en << SRCONFIG_SENNENABLE_SHIFT) |
248 - (senp_en << SRCONFIG_SENPENABLE_SHIFT) |
249 + (senn_en << senn_en_shift) |
250 + (senp_en << senp_en_shift) |
253 sr_write_reg(sr, SRCONFIG, sr_config);
254 sr_write_reg(sr, AVGWEIGHT, SR2_AVGWEIGHT_SENPAVGWEIGHT |
255 SR2_AVGWEIGHT_SENNAVGWEIGHT);
256 - sr_modify_reg(sr, ERRCONFIG, (SR_ERRWEIGHT_MASK |
257 + sr_modify_reg(sr, err_config, (SR_ERRWEIGHT_MASK |
258 SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
259 (SR2_ERRWEIGHT | SR2_ERRMAXLIMIT | SR2_ERRMINLIMIT));
261 @@ -604,6 +659,7 @@ static int sr_reset_voltage(int srid)
262 static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
264 u32 nvalue_reciprocal, v;
265 + u32 inten, intst, err_config;
267 if (!(mpu_opps && l3_opps)) {
268 pr_notice("VSEL values not found\n");
269 @@ -662,9 +718,19 @@ static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
270 sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
272 /* Enable the interrupt */
273 - sr_modify_reg(sr, ERRCONFIG,
274 - (ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST),
275 - (ERRCONFIG_VPBOUNDINTEN | ERRCONFIG_VPBOUNDINTST));
276 + if (cpu_is_omap3630()) {
277 + inten = ERRCONFIG_VPBOUNDINTEN_36XX;
278 + intst = ERRCONFIG_VPBOUNDINTST_36XX;
279 + err_config = ERRCONFIG_36XX;
281 + inten = ERRCONFIG_VPBOUNDINTEN;
282 + intst = ERRCONFIG_VPBOUNDINTST;
283 + err_config = ERRCONFIG;
286 + sr_modify_reg(sr, err_config,
290 if (sr->srid == SR1) {
291 /* set/latch init voltage */
292 diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
293 index 2a0e823..f20406b 100644
294 --- a/arch/arm/mach-omap2/smartreflex.h
295 +++ b/arch/arm/mach-omap2/smartreflex.h
297 #define SENERROR 0x20
298 #define ERRCONFIG 0x24
300 +#define SENERROR_36XX 0x34
301 +#define ERRCONFIG_36XX 0x38
307 #define SRCONFIG_SENNENABLE_SHIFT 5
308 #define SRCONFIG_SENPENABLE_SHIFT 3
310 +#define SRCONFIG_SENNENABLE_SHIFT_36XX 1
311 +#define SRCONFIG_SENPENABLE_SHIFT_36XX 0
313 #define SRCONFIG_SRENABLE BIT(11)
314 #define SRCONFIG_SENENABLE BIT(10)
315 #define SRCONFIG_ERRGEN_EN BIT(9)
317 #define SR_CLKACTIVITY_IOFF_FOFF (0x00 << 20)
318 #define SR_CLKACTIVITY_IOFF_FON (0x02 << 20)
320 +/* IDLEMODE SETTINGS for OMAP3630 */
321 +#define SR_IDLEMODE_MASK (0x3 << 24)
322 +#define SR_FORCE_IDLE 0x0
323 +#define SR_NO_IDLE 0x1
324 +#define SR_SMART_IDLE 0x2
325 +#define SR_SMART_IDLE_WKUP 0x3
327 #define ERRCONFIG_VPBOUNDINTEN BIT(31)
328 #define ERRCONFIG_VPBOUNDINTST BIT(30)
330 +#define ERRCONFIG_VPBOUNDINTEN_36XX BIT(23)
331 +#define ERRCONFIG_VPBOUNDINTST_36XX BIT(22)
333 #define SR1_ERRWEIGHT (0x07 << 16)
334 #define SR1_ERRMAXLIMIT (0x02 << 8)
335 #define SR1_ERRMINLIMIT (0xFA << 0)
336 diff --git a/arch/arm/plat-omap/include/plat/control.h b/arch/arm/plat-omap/include/plat/control.h
337 index 20f5c98..68100d6 100644
338 --- a/arch/arm/plat-omap/include/plat/control.h
339 +++ b/arch/arm/plat-omap/include/plat/control.h
341 #define OMAP343X_SCRATCHPAD (OMAP343X_CTRL_BASE + 0x910)
342 #define OMAP343X_SCRATCHPAD_ROM_OFFSET 0x19C
344 +/* OMAP36XX CONTROL FUSE */
346 +#define OMAP36XX_CONTROL_FUSE_OPP1_VDD1 (OMAP2_CONTROL_GENERAL + 0x0114)
347 +#define OMAP36XX_CONTROL_FUSE_OPP2_VDD1 (OMAP2_CONTROL_GENERAL + 0x0118)
348 +#define OMAP36XX_CONTROL_FUSE_OPP3_VDD1 (OMAP2_CONTROL_GENERAL + 0x0120)
349 +#define OMAP36XX_CONTROL_FUSE_OPP4_VDD1 (OMAP2_CONTROL_GENERAL + 0x0110)
350 +#define OMAP36XX_CONTROL_FUSE_OPP5_VDD1 (OMAP2_CONTROL_GENERAL + 0x0108)
352 +#define OMAP36XX_CONTROL_FUSE_OPP1_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128)
353 +#define OMAP36XX_CONTROL_FUSE_OPP2_VDD2 (OMAP2_CONTROL_GENERAL + 0x012c)
355 +#define OMAP36XX_CONTROL_FUSE_SR (OMAP2_CONTROL_GENERAL + 0x0130)
358 * Product ID register