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 * 9 * Copyright (C) 2009-11 Texas Instruments 10 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> 11 * 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 17 #include <linux/module.h> 18 #include <linux/kernel.h> 19 #include <linux/init.h> 20 #include <linux/io.h> 21 22 #include <asm/cputype.h> 23 24 #include "common.h" 25 #include <plat/cpu.h> 26 27 #include <mach/id.h> 28 29 #include "control.h" 30 31 static unsigned int omap_revision; 32 33 u32 omap_features; 34 35 unsigned int omap_rev(void) 36 { 37 return omap_revision; 38 } 39 EXPORT_SYMBOL(omap_rev); 40 41 int omap_type(void) 42 { 43 u32 val = 0; 44 45 if (cpu_is_omap24xx()) { 46 val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS); 47 } else if (cpu_is_omap34xx()) { 48 val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS); 49 } else if (cpu_is_omap44xx()) { 50 val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS); 51 } else { 52 pr_err("Cannot detect omap type!\n"); 53 goto out; 54 } 55 56 val &= OMAP2_DEVICETYPE_MASK; 57 val >>= 8; 58 59 out: 60 return val; 61 } 62 EXPORT_SYMBOL(omap_type); 63 64 65 /*----------------------------------------------------------------------------*/ 66 67 #define OMAP_TAP_IDCODE 0x0204 68 #define OMAP_TAP_DIE_ID_0 0x0218 69 #define OMAP_TAP_DIE_ID_1 0x021C 70 #define OMAP_TAP_DIE_ID_2 0x0220 71 #define OMAP_TAP_DIE_ID_3 0x0224 72 73 #define OMAP_TAP_DIE_ID_44XX_0 0x0200 74 #define OMAP_TAP_DIE_ID_44XX_1 0x0208 75 #define OMAP_TAP_DIE_ID_44XX_2 0x020c 76 #define OMAP_TAP_DIE_ID_44XX_3 0x0210 77 78 #define read_tap_reg(reg) __raw_readl(tap_base + (reg)) 79 80 struct omap_id { 81 u16 hawkeye; /* Silicon type (Hawkeye id) */ 82 u8 dev; /* Device type from production_id reg */ 83 u32 type; /* Combined type id copied to omap_revision */ 84 }; 85 86 /* Register values to detect the OMAP version */ 87 static struct omap_id omap_ids[] __initdata = { 88 { .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200024 }, 89 { .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201024 }, 90 { .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202024 }, 91 { .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220024 }, 92 { .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230024 }, 93 { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300024 }, 94 }; 95 96 static void __iomem *tap_base; 97 static u16 tap_prod_id; 98 99 void omap_get_die_id(struct omap_die_id *odi) 100 { 101 if (cpu_is_omap44xx()) { 102 odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_0); 103 odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_1); 104 odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_2); 105 odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_3); 106 107 return; 108 } 109 odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_0); 110 odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_1); 111 odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_2); 112 odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3); 113 } 114 115 static void __init omap24xx_check_revision(void) 116 { 117 int i, j; 118 u32 idcode, prod_id; 119 u16 hawkeye; 120 u8 dev_type, rev; 121 struct omap_die_id odi; 122 123 idcode = read_tap_reg(OMAP_TAP_IDCODE); 124 prod_id = read_tap_reg(tap_prod_id); 125 hawkeye = (idcode >> 12) & 0xffff; 126 rev = (idcode >> 28) & 0x0f; 127 dev_type = (prod_id >> 16) & 0x0f; 128 omap_get_die_id(&odi); 129 130 pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n", 131 idcode, rev, hawkeye, (idcode >> 1) & 0x7ff); 132 pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", odi.id_0); 133 pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n", 134 odi.id_1, (odi.id_1 >> 28) & 0xf); 135 pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", odi.id_2); 136 pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", odi.id_3); 137 pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n", 138 prod_id, dev_type); 139 140 /* Check hawkeye ids */ 141 for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { 142 if (hawkeye == omap_ids[i].hawkeye) 143 break; 144 } 145 146 if (i == ARRAY_SIZE(omap_ids)) { 147 printk(KERN_ERR "Unknown OMAP CPU id\n"); 148 return; 149 } 150 151 for (j = i; j < ARRAY_SIZE(omap_ids); j++) { 152 if (dev_type == omap_ids[j].dev) 153 break; 154 } 155 156 if (j == ARRAY_SIZE(omap_ids)) { 157 printk(KERN_ERR "Unknown OMAP device type. " 158 "Handling it as OMAP%04x\n", 159 omap_ids[i].type >> 16); 160 j = i; 161 } 162 163 pr_info("OMAP%04x", omap_rev() >> 16); 164 if ((omap_rev() >> 8) & 0x0f) 165 pr_info("ES%x", (omap_rev() >> 12) & 0xf); 166 pr_info("\n"); 167 } 168 169 #define OMAP3_CHECK_FEATURE(status,feat) \ 170 if (((status & OMAP3_ ##feat## _MASK) \ 171 >> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { \ 172 omap_features |= OMAP3_HAS_ ##feat; \ 173 } 174 175 static void __init omap3_check_features(void) 176 { 177 u32 status; 178 179 omap_features = 0; 180 181 status = omap_ctrl_readl(OMAP3_CONTROL_OMAP_STATUS); 182 183 OMAP3_CHECK_FEATURE(status, L2CACHE); 184 OMAP3_CHECK_FEATURE(status, IVA); 185 OMAP3_CHECK_FEATURE(status, SGX); 186 OMAP3_CHECK_FEATURE(status, NEON); 187 OMAP3_CHECK_FEATURE(status, ISP); 188 if (cpu_is_omap3630()) 189 omap_features |= OMAP3_HAS_192MHZ_CLK; 190 if (cpu_is_omap3430() || cpu_is_omap3630()) 191 omap_features |= OMAP3_HAS_IO_WAKEUP; 192 if (cpu_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 || 193 omap_rev() == OMAP3430_REV_ES3_1_2) 194 omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; 195 196 omap_features |= OMAP3_HAS_SDRC; 197 198 /* 199 * TODO: Get additional info (where applicable) 200 * e.g. Size of L2 cache. 201 */ 202 } 203 204 static void __init omap4_check_features(void) 205 { 206 u32 si_type; 207 208 if (cpu_is_omap443x()) 209 omap_features |= OMAP4_HAS_MPU_1GHZ; 210 211 212 if (cpu_is_omap446x()) { 213 si_type = 214 read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1); 215 switch ((si_type & (3 << 16)) >> 16) { 216 case 2: 217 /* High performance device */ 218 omap_features |= OMAP4_HAS_MPU_1_5GHZ; 219 break; 220 case 1: 221 default: 222 /* Standard device */ 223 omap_features |= OMAP4_HAS_MPU_1_2GHZ; 224 break; 225 } 226 } 227 } 228 229 static void __init ti81xx_check_features(void) 230 { 231 omap_features = OMAP3_HAS_NEON; 232 } 233 234 static void __init omap3_check_revision(const char **cpu_rev) 235 { 236 u32 cpuid, idcode; 237 u16 hawkeye; 238 u8 rev; 239 240 /* 241 * We cannot access revision registers on ES1.0. 242 * If the processor type is Cortex-A8 and the revision is 0x0 243 * it means its Cortex r0p0 which is 3430 ES1.0. 244 */ 245 cpuid = read_cpuid(CPUID_ID); 246 if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) { 247 omap_revision = OMAP3430_REV_ES1_0; 248 *cpu_rev = "1.0"; 249 return; 250 } 251 252 /* 253 * Detection for 34xx ES2.0 and above can be done with just 254 * hawkeye and rev. See TRM 1.5.2 Device Identification. 255 * Note that rev does not map directly to our defined processor 256 * revision numbers as ES1.0 uses value 0. 257 */ 258 idcode = read_tap_reg(OMAP_TAP_IDCODE); 259 hawkeye = (idcode >> 12) & 0xffff; 260 rev = (idcode >> 28) & 0xff; 261 262 switch (hawkeye) { 263 case 0xb7ae: 264 /* Handle 34xx/35xx devices */ 265 switch (rev) { 266 case 0: /* Take care of early samples */ 267 case 1: 268 omap_revision = OMAP3430_REV_ES2_0; 269 *cpu_rev = "2.0"; 270 break; 271 case 2: 272 omap_revision = OMAP3430_REV_ES2_1; 273 *cpu_rev = "2.1"; 274 break; 275 case 3: 276 omap_revision = OMAP3430_REV_ES3_0; 277 *cpu_rev = "3.0"; 278 break; 279 case 4: 280 omap_revision = OMAP3430_REV_ES3_1; 281 *cpu_rev = "3.1"; 282 break; 283 case 7: 284 /* FALLTHROUGH */ 285 default: 286 /* Use the latest known revision as default */ 287 omap_revision = OMAP3430_REV_ES3_1_2; 288 *cpu_rev = "3.1.2"; 289 } 290 break; 291 case 0xb868: 292 /* 293 * Handle OMAP/AM 3505/3517 devices 294 * 295 * Set the device to be OMAP3517 here. Actual device 296 * is identified later based on the features. 297 */ 298 switch (rev) { 299 case 0: 300 omap_revision = OMAP3517_REV_ES1_0; 301 *cpu_rev = "1.0"; 302 break; 303 case 1: 304 /* FALLTHROUGH */ 305 default: 306 omap_revision = OMAP3517_REV_ES1_1; 307 *cpu_rev = "1.1"; 308 } 309 break; 310 case 0xb891: 311 /* Handle 36xx devices */ 312 313 switch(rev) { 314 case 0: /* Take care of early samples */ 315 omap_revision = OMAP3630_REV_ES1_0; 316 *cpu_rev = "1.0"; 317 break; 318 case 1: 319 omap_revision = OMAP3630_REV_ES1_1; 320 *cpu_rev = "1.1"; 321 break; 322 case 2: 323 /* FALLTHROUGH */ 324 default: 325 omap_revision = OMAP3630_REV_ES1_2; 326 *cpu_rev = "1.2"; 327 } 328 break; 329 case 0xb81e: 330 switch (rev) { 331 case 0: 332 omap_revision = TI8168_REV_ES1_0; 333 *cpu_rev = "1.0"; 334 break; 335 case 1: 336 /* FALLTHROUGH */ 337 default: 338 omap_revision = TI8168_REV_ES1_1; 339 *cpu_rev = "1.1"; 340 break; 341 } 342 break; 343 case 0xb944: 344 omap_revision = AM335X_REV_ES1_0; 345 *cpu_rev = "1.0"; 346 break; 347 case 0xb8f2: 348 switch (rev) { 349 case 0: 350 /* FALLTHROUGH */ 351 case 1: 352 omap_revision = TI8148_REV_ES1_0; 353 *cpu_rev = "1.0"; 354 break; 355 case 2: 356 omap_revision = TI8148_REV_ES2_0; 357 *cpu_rev = "2.0"; 358 break; 359 case 3: 360 /* FALLTHROUGH */ 361 default: 362 omap_revision = TI8148_REV_ES2_1; 363 *cpu_rev = "2.1"; 364 break; 365 } 366 break; 367 default: 368 /* Unknown default to latest silicon rev as default */ 369 omap_revision = OMAP3630_REV_ES1_2; 370 *cpu_rev = "1.2"; 371 pr_warn("Warning: unknown chip type; assuming OMAP3630ES1.2\n"); 372 } 373 } 374 375 static void __init omap4_check_revision(void) 376 { 377 u32 idcode; 378 u16 hawkeye; 379 u8 rev; 380 381 /* 382 * The IC rev detection is done with hawkeye and rev. 383 * Note that rev does not map directly to defined processor 384 * revision numbers as ES1.0 uses value 0. 385 */ 386 idcode = read_tap_reg(OMAP_TAP_IDCODE); 387 hawkeye = (idcode >> 12) & 0xffff; 388 rev = (idcode >> 28) & 0xf; 389 390 /* 391 * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0 392 * Use ARM register to detect the correct ES version 393 */ 394 if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) { 395 idcode = read_cpuid(CPUID_ID); 396 rev = (idcode & 0xf) - 1; 397 } 398 399 switch (hawkeye) { 400 case 0xb852: 401 switch (rev) { 402 case 0: 403 omap_revision = OMAP4430_REV_ES1_0; 404 break; 405 case 1: 406 default: 407 omap_revision = OMAP4430_REV_ES2_0; 408 } 409 break; 410 case 0xb95c: 411 switch (rev) { 412 case 3: 413 omap_revision = OMAP4430_REV_ES2_1; 414 break; 415 case 4: 416 omap_revision = OMAP4430_REV_ES2_2; 417 break; 418 case 6: 419 default: 420 omap_revision = OMAP4430_REV_ES2_3; 421 } 422 break; 423 case 0xb94e: 424 switch (rev) { 425 case 0: 426 default: 427 omap_revision = OMAP4460_REV_ES1_0; 428 break; 429 } 430 break; 431 case 0xb975: 432 switch (rev) { 433 case 0: 434 default: 435 omap_revision = OMAP4470_REV_ES1_0; 436 break; 437 } 438 break; 439 default: 440 /* Unknown default to latest silicon rev as default */ 441 omap_revision = OMAP4430_REV_ES2_3; 442 } 443 444 pr_info("OMAP%04x ES%d.%d\n", omap_rev() >> 16, 445 ((omap_rev() >> 12) & 0xf), ((omap_rev() >> 8) & 0xf)); 446 } 447 448 #define OMAP3_SHOW_FEATURE(feat) \ 449 if (omap3_has_ ##feat()) \ 450 printk(#feat" "); 451 452 static void __init omap3_cpuinfo(const char *cpu_rev) 453 { 454 const char *cpu_name; 455 456 /* 457 * OMAP3430 and OMAP3530 are assumed to be same. 458 * 459 * OMAP3525, OMAP3515 and OMAP3503 can be detected only based 460 * on available features. Upon detection, update the CPU id 461 * and CPU class bits. 462 */ 463 if (cpu_is_omap3630()) { 464 cpu_name = "OMAP3630"; 465 } else if (cpu_is_omap3517()) { 466 /* AM35xx devices */ 467 cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505"; 468 } else if (cpu_is_ti816x()) { 469 cpu_name = "TI816X"; 470 } else if (cpu_is_am335x()) { 471 cpu_name = "AM335X"; 472 } else if (cpu_is_ti814x()) { 473 cpu_name = "TI814X"; 474 } else if (omap3_has_iva() && omap3_has_sgx()) { 475 /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ 476 cpu_name = "OMAP3430/3530"; 477 } else if (omap3_has_iva()) { 478 cpu_name = "OMAP3525"; 479 } else if (omap3_has_sgx()) { 480 cpu_name = "OMAP3515"; 481 } else { 482 cpu_name = "OMAP3503"; 483 } 484 485 /* Print verbose information */ 486 pr_info("%s ES%s (", cpu_name, cpu_rev); 487 488 OMAP3_SHOW_FEATURE(l2cache); 489 OMAP3_SHOW_FEATURE(iva); 490 OMAP3_SHOW_FEATURE(sgx); 491 OMAP3_SHOW_FEATURE(neon); 492 OMAP3_SHOW_FEATURE(isp); 493 OMAP3_SHOW_FEATURE(192mhz_clk); 494 495 printk(")\n"); 496 } 497 498 /* 499 * Try to detect the exact revision of the omap we're running on 500 */ 501 void __init omap2_check_revision(void) 502 { 503 const char *cpu_rev; 504 505 /* 506 * At this point we have an idea about the processor revision set 507 * earlier with omap2_set_globals_tap(). 508 */ 509 if (cpu_is_omap24xx()) { 510 omap24xx_check_revision(); 511 } else if (cpu_is_omap34xx()) { 512 omap3_check_revision(&cpu_rev); 513 514 /* TI81XX doesn't have feature register */ 515 if (!cpu_is_ti81xx()) 516 omap3_check_features(); 517 else 518 ti81xx_check_features(); 519 520 omap3_cpuinfo(cpu_rev); 521 return; 522 } else if (cpu_is_omap44xx()) { 523 omap4_check_revision(); 524 omap4_check_features(); 525 return; 526 } else { 527 pr_err("OMAP revision unknown, please fix!\n"); 528 } 529 } 530 531 /* 532 * Set up things for map_io and processor detection later on. Gets called 533 * pretty much first thing from board init. For multi-omap, this gets 534 * cpu_is_omapxxxx() working accurately enough for map_io. Then we'll try to 535 * detect the exact revision later on in omap2_detect_revision() once map_io 536 * is done. 537 */ 538 void __init omap2_set_globals_tap(struct omap_globals *omap2_globals) 539 { 540 omap_revision = omap2_globals->class; 541 tap_base = omap2_globals->tap; 542 543 if (cpu_is_omap34xx()) 544 tap_prod_id = 0x0210; 545 else 546 tap_prod_id = 0x0208; 547 } 548