Commit 8d78a20015f0929b4bf3a2bae12fd040b2230ea7
1 parent
ae25144ed1
Exists in
v3.2_SMARCT335xPSP_04.06.00.11
and in
3 other branches
ARM: OMAP: AM33XX: Add OPP table for PG2.1 AM335x
Add OPP table for MPU voltage domain. Changes from PG2.0: 1. The Operating voltage for Nitro Mode is 1.35V 2. PG 2.1 SoC has a new efuse sma register which describes the device's ARM maximum frequency capabilities and package type. Upon parsing this register, the supported maximum frequency is obtained. Note: If this register is not populated (mpu max freq field is 0), then we revert back to PG 2.0 OPP list. Signed-off-by: Hebbar Gururaja <gururaja.hebbar@ti.com>
Showing 1 changed file with 102 additions and 4 deletions Side-by-side Diff
arch/arm/mach-omap2/opp3xxx_data.c
... | ... | @@ -18,6 +18,7 @@ |
18 | 18 | * GNU General Public License for more details. |
19 | 19 | */ |
20 | 20 | #include <linux/module.h> |
21 | +#include <linux/io.h> | |
21 | 22 | |
22 | 23 | #include <plat/cpu.h> |
23 | 24 | |
24 | 25 | |
... | ... | @@ -197,12 +198,56 @@ |
197 | 198 | AM33XX_ES2_0_VDD_MPU_OPPNITRO_UV), |
198 | 199 | }; |
199 | 200 | |
201 | +#define AM33XX_ES2_1_VDD_MPU_OPP50_UV 950000 | |
202 | +#define AM33XX_ES2_1_VDD_MPU_OPP100_UV 1100000 | |
203 | +#define AM33XX_ES2_1_VDD_MPU_OPPTURBO_UV 1260000 | |
204 | +#define AM33XX_ES2_1_VDD_MPU_OPPNITRO_UV 1350000 | |
205 | + | |
206 | +#define OPP_50_INDEX 0 | |
207 | +#define OPP_100_INDEX 1 | |
208 | +#define OPP_TURBO_INDEX 2 | |
209 | +#define OPP_NITRO_INDEX 3 | |
210 | + | |
211 | + | |
212 | +/* From AM335x TRM, SPRUH73H, Section 9.3.50 */ | |
213 | +#define AM33XX_EFUSE_SMA_OFFSET 0x7fc | |
214 | + | |
215 | +/* | |
216 | + * Bits [12:0] are OPP Disabled bits, | |
217 | + * 1 = OPP is disabled and not available, | |
218 | + * 0 = OPP available. | |
219 | + */ | |
220 | +#define MAX_FREQ_MASK 0x1fff | |
221 | +#define MAX_FREQ_SHFT 0 | |
222 | + | |
223 | +#define OPP_50_300MHZ_BIT (0x1 << 4) | |
224 | +#define OPP_100_300MHZ_BIT (0x1 << 5) | |
225 | +#define OPP_100_600MHZ_BIT (0x1 << 6) | |
226 | +#define OPP_TURBO_800MHZ_BIT (0x1 << 8) | |
227 | +#define OPP_NITRO_1GHZ_BIT (0x1 << 9) | |
228 | + | |
229 | +static struct omap_opp_def __initdata am33xx_es2_1_opp_list[] = { | |
230 | + /* MPU OPP1 - OPP50 */ | |
231 | + OPP_INITIALIZER("mpu", false, 300000000, | |
232 | + AM33XX_ES2_1_VDD_MPU_OPP50_UV), | |
233 | + /* MPU OPP2 - OPP100 */ | |
234 | + OPP_INITIALIZER("mpu", false, 600000000, | |
235 | + AM33XX_ES2_1_VDD_MPU_OPP100_UV), | |
236 | + /* MPU OPP3 - OPPTurbo */ | |
237 | + OPP_INITIALIZER("mpu", false, 800000000, | |
238 | + AM33XX_ES2_1_VDD_MPU_OPPTURBO_UV), | |
239 | + /* MPU OPP4 - OPPNitro */ | |
240 | + OPP_INITIALIZER("mpu", false, 1000000000, | |
241 | + AM33XX_ES2_1_VDD_MPU_OPPNITRO_UV), | |
242 | +}; | |
243 | + | |
200 | 244 | /** |
201 | 245 | * omap3_opp_init() - initialize omap3 opp table |
202 | 246 | */ |
203 | 247 | int __init omap3_opp_init(void) |
204 | 248 | { |
205 | 249 | int r = -ENODEV; |
250 | + u32 rev, val, max_freq; | |
206 | 251 | |
207 | 252 | if (!cpu_is_omap34xx()) |
208 | 253 | return r; |
209 | 254 | |
210 | 255 | |
211 | 256 | |
... | ... | @@ -211,16 +256,69 @@ |
211 | 256 | r = omap_init_opp_table(omap36xx_opp_def_list, |
212 | 257 | ARRAY_SIZE(omap36xx_opp_def_list)); |
213 | 258 | else if (cpu_is_am33xx()) { |
214 | - if (omap_rev() == AM335X_REV_ES1_0) | |
259 | + rev = omap_rev(); | |
260 | + switch (rev) { | |
261 | + case AM335X_REV_ES1_0: | |
215 | 262 | r = omap_init_opp_table(am33xx_es1_0_opp_def_list, |
216 | 263 | ARRAY_SIZE(am33xx_es1_0_opp_def_list)); |
217 | - else | |
264 | + break; | |
265 | + | |
266 | + case AM335X_REV_ES2_1: | |
267 | + /* | |
268 | + * First read efuse sma reg to detect package type and | |
269 | + * supported frequency | |
270 | + */ | |
271 | + val = | |
272 | + readl(AM33XX_CTRL_REGADDR(AM33XX_EFUSE_SMA_OFFSET)); | |
273 | + | |
274 | + if (!(val & MAX_FREQ_MASK)) { | |
275 | + /* | |
276 | + * if mpu max freq is not populated, fall back to | |
277 | + * PG 2.0 OPP settings. | |
278 | + */ | |
279 | + r = | |
280 | + omap_init_opp_table(am33xx_es2_0_opp_def_list, | |
281 | + ARRAY_SIZE(am33xx_es2_0_opp_def_list)); | |
282 | + break; | |
283 | + } | |
284 | + | |
285 | + /* | |
286 | + * 1 = OPP is disabled and not available, | |
287 | + * 0 = OPP available. | |
288 | + */ | |
289 | + max_freq = (~val & MAX_FREQ_MASK); | |
290 | + | |
291 | + if (max_freq & OPP_50_300MHZ_BIT) | |
292 | + am33xx_es2_1_opp_list[OPP_50_INDEX]. | |
293 | + default_available = true; | |
294 | + | |
295 | + if ((max_freq & OPP_100_300MHZ_BIT) || | |
296 | + (max_freq & OPP_100_600MHZ_BIT)) | |
297 | + am33xx_es2_1_opp_list[OPP_100_INDEX]. | |
298 | + default_available = true; | |
299 | + | |
300 | + if (max_freq & OPP_TURBO_800MHZ_BIT) | |
301 | + am33xx_es2_1_opp_list[OPP_TURBO_INDEX]. | |
302 | + default_available = true; | |
303 | + | |
304 | + if (max_freq & OPP_NITRO_1GHZ_BIT) | |
305 | + am33xx_es2_1_opp_list[OPP_NITRO_INDEX]. | |
306 | + default_available = true; | |
307 | + | |
308 | + r = omap_init_opp_table(am33xx_es2_1_opp_list, | |
309 | + ARRAY_SIZE(am33xx_es2_1_opp_list)); | |
310 | + break; | |
311 | + | |
312 | + case AM335X_REV_ES2_0: | |
313 | + /* FALLTHROUGH */ | |
314 | + default: | |
218 | 315 | r = omap_init_opp_table(am33xx_es2_0_opp_def_list, |
219 | 316 | ARRAY_SIZE(am33xx_es2_0_opp_def_list)); |
220 | - } | |
221 | - else | |
317 | + } | |
318 | + } else { | |
222 | 319 | r = omap_init_opp_table(omap34xx_opp_def_list, |
223 | 320 | ARRAY_SIZE(omap34xx_opp_def_list)); |
321 | + } | |
224 | 322 | |
225 | 323 | return r; |
226 | 324 | } |