Commit | Line | Data |
---|---|---|
1dbae815 TL |
1 | /* |
2 | * linux/arch/arm/mach-omap2/id.c | |
3 | * | |
4 | * OMAP2 CPU identification code | |
5 | * | |
6 | * Copyright (C) 2005 Nokia Corporation | |
7 | * Written by Tony Lindgren <tony@atomide.com> | |
8 | * | |
e49c4d27 | 9 | * Copyright (C) 2009-11 Texas Instruments |
44169075 SS |
10 | * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> |
11 | * | |
1dbae815 TL |
12 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License version 2 as | |
14 | * published by the Free Software Foundation. | |
15 | */ | |
16 | ||
1dbae815 TL |
17 | #include <linux/module.h> |
18 | #include <linux/kernel.h> | |
19 | #include <linux/init.h> | |
fced80c7 | 20 | #include <linux/io.h> |
1dbae815 | 21 | |
0ba8b9b2 | 22 | #include <asm/cputype.h> |
1dbae815 | 23 | |
4e65331c | 24 | #include "common.h" |
72d0f1c3 | 25 | |
4952af43 | 26 | #include "id.h" |
2e130fc3 | 27 | |
dbc04161 | 28 | #include "soc.h" |
4814ced5 PW |
29 | #include "control.h" |
30 | ||
42a1cc9c IK |
31 | #define OMAP4_SILICON_TYPE_STANDARD 0x01 |
32 | #define OMAP4_SILICON_TYPE_PERFORMANCE 0x02 | |
33 | ||
f9d41eef RB |
34 | #define OMAP_SOC_MAX_NAME_LENGTH 16 |
35 | ||
84a34344 | 36 | static unsigned int omap_revision; |
f9d41eef RB |
37 | static char soc_name[OMAP_SOC_MAX_NAME_LENGTH]; |
38 | static char soc_rev[OMAP_SOC_MAX_NAME_LENGTH]; | |
cc0170b2 | 39 | u32 omap_features; |
84a34344 LL |
40 | |
41 | unsigned int omap_rev(void) | |
42 | { | |
43 | return omap_revision; | |
44 | } | |
45 | EXPORT_SYMBOL(omap_rev); | |
097c584c | 46 | |
8e25ad96 KH |
47 | int omap_type(void) |
48 | { | |
49 | u32 val = 0; | |
50 | ||
edeae658 | 51 | if (cpu_is_omap24xx()) { |
8e25ad96 | 52 | val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS); |
971b8a9c | 53 | } else if (soc_is_am33xx()) { |
fb3cfb1f | 54 | val = omap_ctrl_readl(AM33XX_CONTROL_STATUS); |
edeae658 | 55 | } else if (cpu_is_omap34xx()) { |
8e25ad96 | 56 | val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS); |
737daa03 | 57 | } else if (cpu_is_omap44xx()) { |
dcf5ef3f | 58 | val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS); |
b13e80a8 S |
59 | } else if (soc_is_omap54xx()) { |
60 | val = omap_ctrl_readl(OMAP5XXX_CONTROL_STATUS); | |
61 | val &= OMAP5_DEVICETYPE_MASK; | |
62 | val >>= 6; | |
63 | goto out; | |
edeae658 | 64 | } else { |
8e25ad96 KH |
65 | pr_err("Cannot detect omap type!\n"); |
66 | goto out; | |
67 | } | |
68 | ||
69 | val &= OMAP2_DEVICETYPE_MASK; | |
70 | val >>= 8; | |
71 | ||
72 | out: | |
73 | return val; | |
74 | } | |
75 | EXPORT_SYMBOL(omap_type); | |
76 | ||
77 | ||
a8823143 | 78 | /*----------------------------------------------------------------------------*/ |
097c584c | 79 | |
a8823143 TL |
80 | #define OMAP_TAP_IDCODE 0x0204 |
81 | #define OMAP_TAP_DIE_ID_0 0x0218 | |
82 | #define OMAP_TAP_DIE_ID_1 0x021C | |
83 | #define OMAP_TAP_DIE_ID_2 0x0220 | |
84 | #define OMAP_TAP_DIE_ID_3 0x0224 | |
097c584c | 85 | |
b235e007 AG |
86 | #define OMAP_TAP_DIE_ID_44XX_0 0x0200 |
87 | #define OMAP_TAP_DIE_ID_44XX_1 0x0208 | |
88 | #define OMAP_TAP_DIE_ID_44XX_2 0x020c | |
89 | #define OMAP_TAP_DIE_ID_44XX_3 0x0210 | |
90 | ||
a8823143 | 91 | #define read_tap_reg(reg) __raw_readl(tap_base + (reg)) |
097c584c | 92 | |
a8823143 TL |
93 | struct omap_id { |
94 | u16 hawkeye; /* Silicon type (Hawkeye id) */ | |
95 | u8 dev; /* Device type from production_id reg */ | |
84a34344 | 96 | u32 type; /* Combined type id copied to omap_revision */ |
a8823143 | 97 | }; |
097c584c | 98 | |
a8823143 TL |
99 | /* Register values to detect the OMAP version */ |
100 | static struct omap_id omap_ids[] __initdata = { | |
101 | { .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200024 }, | |
102 | { .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201024 }, | |
103 | { .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202024 }, | |
104 | { .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220024 }, | |
105 | { .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230024 }, | |
106 | { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300024 }, | |
107 | }; | |
097c584c | 108 | |
a8823143 TL |
109 | static void __iomem *tap_base; |
110 | static u16 tap_prod_id; | |
1dbae815 | 111 | |
2e130fc3 KRC |
112 | void omap_get_die_id(struct omap_die_id *odi) |
113 | { | |
b13e80a8 | 114 | if (cpu_is_omap44xx() || soc_is_omap54xx()) { |
b235e007 AG |
115 | odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_0); |
116 | odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_1); | |
117 | odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_2); | |
118 | odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_3); | |
119 | ||
120 | return; | |
121 | } | |
2e130fc3 KRC |
122 | odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_0); |
123 | odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_1); | |
124 | odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_2); | |
125 | odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3); | |
126 | } | |
127 | ||
4de34f35 | 128 | void __init omap2xxx_check_revision(void) |
1dbae815 TL |
129 | { |
130 | int i, j; | |
a8823143 | 131 | u32 idcode, prod_id; |
1dbae815 | 132 | u16 hawkeye; |
a8823143 | 133 | u8 dev_type, rev; |
c46732bb | 134 | struct omap_die_id odi; |
1dbae815 TL |
135 | |
136 | idcode = read_tap_reg(OMAP_TAP_IDCODE); | |
0e564848 | 137 | prod_id = read_tap_reg(tap_prod_id); |
1dbae815 TL |
138 | hawkeye = (idcode >> 12) & 0xffff; |
139 | rev = (idcode >> 28) & 0x0f; | |
140 | dev_type = (prod_id >> 16) & 0x0f; | |
c46732bb | 141 | omap_get_die_id(&odi); |
1dbae815 | 142 | |
097c584c PW |
143 | pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n", |
144 | idcode, rev, hawkeye, (idcode >> 1) & 0x7ff); | |
c46732bb | 145 | pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", odi.id_0); |
097c584c | 146 | pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n", |
c46732bb KRC |
147 | odi.id_1, (odi.id_1 >> 28) & 0xf); |
148 | pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", odi.id_2); | |
149 | pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", odi.id_3); | |
097c584c PW |
150 | pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n", |
151 | prod_id, dev_type); | |
152 | ||
1dbae815 TL |
153 | /* Check hawkeye ids */ |
154 | for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { | |
155 | if (hawkeye == omap_ids[i].hawkeye) | |
156 | break; | |
157 | } | |
158 | ||
159 | if (i == ARRAY_SIZE(omap_ids)) { | |
160 | printk(KERN_ERR "Unknown OMAP CPU id\n"); | |
161 | return; | |
162 | } | |
163 | ||
164 | for (j = i; j < ARRAY_SIZE(omap_ids); j++) { | |
165 | if (dev_type == omap_ids[j].dev) | |
166 | break; | |
167 | } | |
168 | ||
169 | if (j == ARRAY_SIZE(omap_ids)) { | |
7852ec05 PW |
170 | pr_err("Unknown OMAP device type. Handling it as OMAP%04x\n", |
171 | omap_ids[i].type >> 16); | |
1dbae815 TL |
172 | j = i; |
173 | } | |
1dbae815 | 174 | |
f9d41eef RB |
175 | sprintf(soc_name, "OMAP%04x", omap_rev() >> 16); |
176 | sprintf(soc_rev, "ES%x", (omap_rev() >> 12) & 0xf); | |
177 | ||
178 | pr_info("%s", soc_name); | |
84a34344 | 179 | if ((omap_rev() >> 8) & 0x0f) |
f9d41eef | 180 | pr_info("%s", soc_rev); |
097c584c | 181 | pr_info("\n"); |
a8823143 TL |
182 | } |
183 | ||
50a01e64 VH |
184 | #define OMAP3_SHOW_FEATURE(feat) \ |
185 | if (omap3_has_ ##feat()) \ | |
186 | printk(#feat" "); | |
187 | ||
188 | static void __init omap3_cpuinfo(void) | |
189 | { | |
190 | const char *cpu_name; | |
191 | ||
192 | /* | |
193 | * OMAP3430 and OMAP3530 are assumed to be same. | |
194 | * | |
195 | * OMAP3525, OMAP3515 and OMAP3503 can be detected only based | |
196 | * on available features. Upon detection, update the CPU id | |
197 | * and CPU class bits. | |
198 | */ | |
199 | if (cpu_is_omap3630()) { | |
200 | cpu_name = "OMAP3630"; | |
68a88b98 | 201 | } else if (soc_is_am35xx()) { |
50a01e64 VH |
202 | cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505"; |
203 | } else if (cpu_is_ti816x()) { | |
204 | cpu_name = "TI816X"; | |
971b8a9c | 205 | } else if (soc_is_am335x()) { |
50a01e64 VH |
206 | cpu_name = "AM335X"; |
207 | } else if (cpu_is_ti814x()) { | |
208 | cpu_name = "TI814X"; | |
209 | } else if (omap3_has_iva() && omap3_has_sgx()) { | |
210 | /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ | |
211 | cpu_name = "OMAP3430/3530"; | |
212 | } else if (omap3_has_iva()) { | |
213 | cpu_name = "OMAP3525"; | |
214 | } else if (omap3_has_sgx()) { | |
215 | cpu_name = "OMAP3515"; | |
216 | } else { | |
217 | cpu_name = "OMAP3503"; | |
218 | } | |
219 | ||
f9d41eef RB |
220 | sprintf(soc_name, "%s", cpu_name); |
221 | ||
50a01e64 | 222 | /* Print verbose information */ |
f9d41eef | 223 | pr_info("%s %s (", soc_name, soc_rev); |
50a01e64 VH |
224 | |
225 | OMAP3_SHOW_FEATURE(l2cache); | |
226 | OMAP3_SHOW_FEATURE(iva); | |
227 | OMAP3_SHOW_FEATURE(sgx); | |
228 | OMAP3_SHOW_FEATURE(neon); | |
229 | OMAP3_SHOW_FEATURE(isp); | |
230 | OMAP3_SHOW_FEATURE(192mhz_clk); | |
231 | ||
232 | printk(")\n"); | |
233 | } | |
234 | ||
8384ce07 SP |
235 | #define OMAP3_CHECK_FEATURE(status,feat) \ |
236 | if (((status & OMAP3_ ##feat## _MASK) \ | |
237 | >> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { \ | |
cc0170b2 | 238 | omap_features |= OMAP3_HAS_ ##feat; \ |
8384ce07 SP |
239 | } |
240 | ||
4de34f35 | 241 | void __init omap3xxx_check_features(void) |
8384ce07 SP |
242 | { |
243 | u32 status; | |
244 | ||
cc0170b2 | 245 | omap_features = 0; |
8384ce07 SP |
246 | |
247 | status = omap_ctrl_readl(OMAP3_CONTROL_OMAP_STATUS); | |
248 | ||
249 | OMAP3_CHECK_FEATURE(status, L2CACHE); | |
250 | OMAP3_CHECK_FEATURE(status, IVA); | |
251 | OMAP3_CHECK_FEATURE(status, SGX); | |
252 | OMAP3_CHECK_FEATURE(status, NEON); | |
253 | OMAP3_CHECK_FEATURE(status, ISP); | |
7356f0b2 | 254 | if (cpu_is_omap3630()) |
cc0170b2 | 255 | omap_features |= OMAP3_HAS_192MHZ_CLK; |
b02b9172 | 256 | if (cpu_is_omap3430() || cpu_is_omap3630()) |
cc0170b2 | 257 | omap_features |= OMAP3_HAS_IO_WAKEUP; |
b02b9172 PW |
258 | if (cpu_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 || |
259 | omap_rev() == OMAP3430_REV_ES3_1_2) | |
260 | omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; | |
8384ce07 | 261 | |
cc0170b2 | 262 | omap_features |= OMAP3_HAS_SDRC; |
01001712 | 263 | |
1ce02996 MG |
264 | /* |
265 | * am35x fixups: | |
266 | * - The am35x Chip ID register has bits 12, 7:5, and 3:2 marked as | |
267 | * reserved and therefore return 0 when read. Unfortunately, | |
268 | * OMAP3_CHECK_FEATURE() will interpret some of those zeroes to | |
269 | * mean that a feature is present even though it isn't so clear | |
270 | * the incorrectly set feature bits. | |
271 | */ | |
272 | if (soc_is_am35xx()) | |
273 | omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP); | |
274 | ||
8384ce07 SP |
275 | /* |
276 | * TODO: Get additional info (where applicable) | |
277 | * e.g. Size of L2 cache. | |
278 | */ | |
4de34f35 VH |
279 | |
280 | omap3_cpuinfo(); | |
8384ce07 SP |
281 | } |
282 | ||
4de34f35 | 283 | void __init omap4xxx_check_features(void) |
cc0170b2 A |
284 | { |
285 | u32 si_type; | |
286 | ||
42a1cc9c IK |
287 | si_type = |
288 | (read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1) >> 16) & 0x03; | |
cc0170b2 | 289 | |
42a1cc9c IK |
290 | if (si_type == OMAP4_SILICON_TYPE_PERFORMANCE) |
291 | omap_features = OMAP4_HAS_PERF_SILICON; | |
cc0170b2 A |
292 | } |
293 | ||
4de34f35 | 294 | void __init ti81xx_check_features(void) |
01001712 | 295 | { |
cc0170b2 | 296 | omap_features = OMAP3_HAS_NEON; |
4de34f35 | 297 | omap3_cpuinfo(); |
01001712 HP |
298 | } |
299 | ||
4de34f35 | 300 | void __init omap3xxx_check_revision(void) |
a8823143 | 301 | { |
f9d41eef | 302 | const char *cpu_rev; |
a8823143 TL |
303 | u32 cpuid, idcode; |
304 | u16 hawkeye; | |
305 | u8 rev; | |
a8823143 TL |
306 | |
307 | /* | |
308 | * We cannot access revision registers on ES1.0. | |
309 | * If the processor type is Cortex-A8 and the revision is 0x0 | |
310 | * it means its Cortex r0p0 which is 3430 ES1.0. | |
311 | */ | |
312 | cpuid = read_cpuid(CPUID_ID); | |
313 | if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) { | |
84a34344 | 314 | omap_revision = OMAP3430_REV_ES1_0; |
50a01e64 | 315 | cpu_rev = "1.0"; |
048f4bd7 | 316 | return; |
a8823143 TL |
317 | } |
318 | ||
319 | /* | |
320 | * Detection for 34xx ES2.0 and above can be done with just | |
321 | * hawkeye and rev. See TRM 1.5.2 Device Identification. | |
322 | * Note that rev does not map directly to our defined processor | |
323 | * revision numbers as ES1.0 uses value 0. | |
324 | */ | |
325 | idcode = read_tap_reg(OMAP_TAP_IDCODE); | |
326 | hawkeye = (idcode >> 12) & 0xffff; | |
327 | rev = (idcode >> 28) & 0xff; | |
097c584c | 328 | |
2456a10f NM |
329 | switch (hawkeye) { |
330 | case 0xb7ae: | |
331 | /* Handle 34xx/35xx devices */ | |
a8823143 | 332 | switch (rev) { |
048f4bd7 SP |
333 | case 0: /* Take care of early samples */ |
334 | case 1: | |
84a34344 | 335 | omap_revision = OMAP3430_REV_ES2_0; |
50a01e64 | 336 | cpu_rev = "2.0"; |
a8823143 TL |
337 | break; |
338 | case 2: | |
84a34344 | 339 | omap_revision = OMAP3430_REV_ES2_1; |
50a01e64 | 340 | cpu_rev = "2.1"; |
a8823143 TL |
341 | break; |
342 | case 3: | |
84a34344 | 343 | omap_revision = OMAP3430_REV_ES3_0; |
50a01e64 | 344 | cpu_rev = "3.0"; |
a8823143 | 345 | break; |
187e688d | 346 | case 4: |
e9acb9b6 | 347 | omap_revision = OMAP3430_REV_ES3_1; |
50a01e64 | 348 | cpu_rev = "3.1"; |
e9acb9b6 TL |
349 | break; |
350 | case 7: | |
edeae658 | 351 | /* FALLTHROUGH */ |
a8823143 TL |
352 | default: |
353 | /* Use the latest known revision as default */ | |
e9acb9b6 | 354 | omap_revision = OMAP3430_REV_ES3_1_2; |
50a01e64 | 355 | cpu_rev = "3.1.2"; |
a8823143 | 356 | } |
2456a10f | 357 | break; |
4cac6018 | 358 | case 0xb868: |
1f1b0353 PW |
359 | /* |
360 | * Handle OMAP/AM 3505/3517 devices | |
4cac6018 | 361 | * |
1f1b0353 | 362 | * Set the device to be OMAP3517 here. Actual device |
4cac6018 SP |
363 | * is identified later based on the features. |
364 | */ | |
9ed2ba7a PW |
365 | switch (rev) { |
366 | case 0: | |
68a88b98 | 367 | omap_revision = AM35XX_REV_ES1_0; |
50a01e64 | 368 | cpu_rev = "1.0"; |
9ed2ba7a PW |
369 | break; |
370 | case 1: | |
371 | /* FALLTHROUGH */ | |
372 | default: | |
68a88b98 | 373 | omap_revision = AM35XX_REV_ES1_1; |
50a01e64 | 374 | cpu_rev = "1.1"; |
9ed2ba7a | 375 | } |
4cac6018 | 376 | break; |
edeae658 | 377 | case 0xb891: |
b0a1a6ce | 378 | /* Handle 36xx devices */ |
b0a1a6ce AG |
379 | |
380 | switch(rev) { | |
381 | case 0: /* Take care of early samples */ | |
382 | omap_revision = OMAP3630_REV_ES1_0; | |
50a01e64 | 383 | cpu_rev = "1.0"; |
b0a1a6ce AG |
384 | break; |
385 | case 1: | |
386 | omap_revision = OMAP3630_REV_ES1_1; | |
50a01e64 | 387 | cpu_rev = "1.1"; |
b0a1a6ce AG |
388 | break; |
389 | case 2: | |
51ec811a | 390 | /* FALLTHROUGH */ |
b0a1a6ce | 391 | default: |
51ec811a | 392 | omap_revision = OMAP3630_REV_ES1_2; |
50a01e64 | 393 | cpu_rev = "1.2"; |
b0a1a6ce | 394 | } |
77c0870c | 395 | break; |
01001712 | 396 | case 0xb81e: |
01001712 HP |
397 | switch (rev) { |
398 | case 0: | |
399 | omap_revision = TI8168_REV_ES1_0; | |
50a01e64 | 400 | cpu_rev = "1.0"; |
01001712 HP |
401 | break; |
402 | case 1: | |
51ec811a | 403 | /* FALLTHROUGH */ |
01001712 | 404 | default: |
51ec811a | 405 | omap_revision = TI8168_REV_ES1_1; |
50a01e64 | 406 | cpu_rev = "1.1"; |
3b32b7d6 | 407 | break; |
01001712 HP |
408 | } |
409 | break; | |
1e6cb146 | 410 | case 0xb944: |
5af044f4 AC |
411 | switch (rev) { |
412 | case 0: | |
413 | omap_revision = AM335X_REV_ES1_0; | |
414 | cpu_rev = "1.0"; | |
415 | break; | |
416 | case 1: | |
417 | /* FALLTHROUGH */ | |
418 | default: | |
419 | omap_revision = AM335X_REV_ES2_0; | |
420 | cpu_rev = "2.0"; | |
421 | break; | |
422 | } | |
c2d13554 | 423 | break; |
4390f5b2 HP |
424 | case 0xb8f2: |
425 | switch (rev) { | |
426 | case 0: | |
427 | /* FALLTHROUGH */ | |
428 | case 1: | |
429 | omap_revision = TI8148_REV_ES1_0; | |
50a01e64 | 430 | cpu_rev = "1.0"; |
4390f5b2 HP |
431 | break; |
432 | case 2: | |
433 | omap_revision = TI8148_REV_ES2_0; | |
50a01e64 | 434 | cpu_rev = "2.0"; |
4390f5b2 HP |
435 | break; |
436 | case 3: | |
437 | /* FALLTHROUGH */ | |
438 | default: | |
439 | omap_revision = TI8148_REV_ES2_1; | |
50a01e64 | 440 | cpu_rev = "2.1"; |
4390f5b2 HP |
441 | break; |
442 | } | |
1e6cb146 | 443 | break; |
2456a10f | 444 | default: |
51ec811a | 445 | /* Unknown default to latest silicon rev as default */ |
3b32b7d6 | 446 | omap_revision = OMAP3630_REV_ES1_2; |
50a01e64 | 447 | cpu_rev = "1.2"; |
51ec811a | 448 | pr_warn("Warning: unknown chip type; assuming OMAP3630ES1.2\n"); |
a8823143 | 449 | } |
f9d41eef | 450 | sprintf(soc_rev, "ES%s", cpu_rev); |
1dbae815 TL |
451 | } |
452 | ||
4de34f35 | 453 | void __init omap4xxx_check_revision(void) |
b570e0ec SS |
454 | { |
455 | u32 idcode; | |
456 | u16 hawkeye; | |
457 | u8 rev; | |
b570e0ec SS |
458 | |
459 | /* | |
460 | * The IC rev detection is done with hawkeye and rev. | |
461 | * Note that rev does not map directly to defined processor | |
462 | * revision numbers as ES1.0 uses value 0. | |
463 | */ | |
464 | idcode = read_tap_reg(OMAP_TAP_IDCODE); | |
465 | hawkeye = (idcode >> 12) & 0xffff; | |
e49c4d27 | 466 | rev = (idcode >> 28) & 0xf; |
b570e0ec | 467 | |
ed6be0ba | 468 | /* |
fa54dccd | 469 | * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0 |
ed6be0ba SS |
470 | * Use ARM register to detect the correct ES version |
471 | */ | |
ec023e46 | 472 | if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) { |
ed6be0ba SS |
473 | idcode = read_cpuid(CPUID_ID); |
474 | rev = (idcode & 0xf) - 1; | |
475 | } | |
476 | ||
477 | switch (hawkeye) { | |
478 | case 0xb852: | |
479 | switch (rev) { | |
480 | case 0: | |
481 | omap_revision = OMAP4430_REV_ES1_0; | |
ed6be0ba SS |
482 | break; |
483 | case 1: | |
e49c4d27 | 484 | default: |
ed6be0ba | 485 | omap_revision = OMAP4430_REV_ES2_0; |
e49c4d27 NK |
486 | } |
487 | break; | |
488 | case 0xb95c: | |
489 | switch (rev) { | |
490 | case 3: | |
491 | omap_revision = OMAP4430_REV_ES2_1; | |
ed6be0ba | 492 | break; |
e49c4d27 | 493 | case 4: |
e49c4d27 | 494 | omap_revision = OMAP4430_REV_ES2_2; |
55035c15 DA |
495 | break; |
496 | case 6: | |
497 | default: | |
498 | omap_revision = OMAP4430_REV_ES2_3; | |
e49c4d27 NK |
499 | } |
500 | break; | |
fa54dccd A |
501 | case 0xb94e: |
502 | switch (rev) { | |
503 | case 0: | |
fa54dccd | 504 | omap_revision = OMAP4460_REV_ES1_0; |
fa54dccd | 505 | break; |
33ee0db5 CL |
506 | case 2: |
507 | default: | |
508 | omap_revision = OMAP4460_REV_ES1_1; | |
509 | break; | |
fa54dccd A |
510 | } |
511 | break; | |
ec023e46 LI |
512 | case 0xb975: |
513 | switch (rev) { | |
514 | case 0: | |
515 | default: | |
516 | omap_revision = OMAP4470_REV_ES1_0; | |
517 | break; | |
518 | } | |
519 | break; | |
ed6be0ba | 520 | default: |
e49c4d27 | 521 | /* Unknown default to latest silicon rev as default */ |
55035c15 | 522 | omap_revision = OMAP4430_REV_ES2_3; |
b570e0ec SS |
523 | } |
524 | ||
f9d41eef RB |
525 | sprintf(soc_name, "OMAP%04x", omap_rev() >> 16); |
526 | sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf, | |
527 | (omap_rev() >> 8) & 0xf); | |
528 | pr_info("%s %s\n", soc_name, soc_rev); | |
b570e0ec SS |
529 | } |
530 | ||
b13e80a8 S |
531 | void __init omap5xxx_check_revision(void) |
532 | { | |
533 | u32 idcode; | |
534 | u16 hawkeye; | |
535 | u8 rev; | |
536 | ||
537 | idcode = read_tap_reg(OMAP_TAP_IDCODE); | |
538 | hawkeye = (idcode >> 12) & 0xffff; | |
539 | rev = (idcode >> 28) & 0xff; | |
540 | switch (hawkeye) { | |
541 | case 0xb942: | |
542 | switch (rev) { | |
543 | case 0: | |
544 | default: | |
545 | omap_revision = OMAP5430_REV_ES1_0; | |
546 | } | |
547 | break; | |
548 | ||
549 | case 0xb998: | |
550 | switch (rev) { | |
551 | case 0: | |
552 | default: | |
553 | omap_revision = OMAP5432_REV_ES1_0; | |
554 | } | |
555 | break; | |
556 | ||
557 | default: | |
558 | /* Unknown default to latest silicon rev as default*/ | |
559 | omap_revision = OMAP5430_REV_ES1_0; | |
560 | } | |
561 | ||
f9d41eef RB |
562 | sprintf(soc_name, "OMAP%04x", omap_rev() >> 16); |
563 | sprintf(soc_rev, "ES%d.0", (omap_rev() >> 12) & 0xf); | |
564 | ||
565 | pr_info("%s %s\n", soc_name, soc_rev); | |
b13e80a8 S |
566 | } |
567 | ||
a8823143 TL |
568 | /* |
569 | * Set up things for map_io and processor detection later on. Gets called | |
570 | * pretty much first thing from board init. For multi-omap, this gets | |
571 | * cpu_is_omapxxxx() working accurately enough for map_io. Then we'll try to | |
572 | * detect the exact revision later on in omap2_detect_revision() once map_io | |
573 | * is done. | |
574 | */ | |
b6a4226c | 575 | void __init omap2_set_globals_tap(u32 class, void __iomem *tap) |
0e564848 | 576 | { |
b6a4226c PW |
577 | omap_revision = class; |
578 | tap_base = tap; | |
0e564848 | 579 | |
b6a4226c | 580 | /* XXX What is this intended to do? */ |
a8823143 | 581 | if (cpu_is_omap34xx()) |
0e564848 TL |
582 | tap_prod_id = 0x0210; |
583 | else | |
584 | tap_prod_id = 0x0208; | |
585 | } |