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 #include <linux/slab.h> 22 23 #ifdef CONFIG_SOC_BUS 24 #include <linux/sys_soc.h> 25 #endif 26 27 #include <asm/cputype.h> 28 29 #include "common.h" 30 31 #include "id.h" 32 33 #include "soc.h" 34 #include "control.h" 35 36 #define OMAP4_SILICON_TYPE_STANDARD 0x01 37 #define OMAP4_SILICON_TYPE_PERFORMANCE 0x02 38 39 #define OMAP_SOC_MAX_NAME_LENGTH 16 40 41 static unsigned int omap_revision; 42 static char soc_name[OMAP_SOC_MAX_NAME_LENGTH]; 43 static char soc_rev[OMAP_SOC_MAX_NAME_LENGTH]; 44 u32 omap_features; 45 46 unsigned int omap_rev(void) 47 { 48 return omap_revision; 49 } 50 EXPORT_SYMBOL(omap_rev); 51 52 int omap_type(void) 53 { 54 u32 val = 0; 55 56 if (cpu_is_omap24xx()) { 57 val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS); 58 } else if (soc_is_am33xx()) { 59 val = omap_ctrl_readl(AM33XX_CONTROL_STATUS); 60 } else if (cpu_is_omap34xx()) { 61 val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS); 62 } else if (cpu_is_omap44xx()) { 63 val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS); 64 } else if (soc_is_omap54xx()) { 65 val = omap_ctrl_readl(OMAP5XXX_CONTROL_STATUS); 66 val &= OMAP5_DEVICETYPE_MASK; 67 val >>= 6; 68 goto out; 69 } else { 70 pr_err("Cannot detect omap type!\n"); 71 goto out; 72 } 73 74 val &= OMAP2_DEVICETYPE_MASK; 75 val >>= 8; 76 77 out: 78 return val; 79 } 80 EXPORT_SYMBOL(omap_type); 81 82 83 /*----------------------------------------------------------------------------*/ 84 85 #define OMAP_TAP_IDCODE 0x0204 86 #define OMAP_TAP_DIE_ID_0 0x0218 87 #define OMAP_TAP_DIE_ID_1 0x021C 88 #define OMAP_TAP_DIE_ID_2 0x0220 89 #define OMAP_TAP_DIE_ID_3 0x0224 90 91 #define OMAP_TAP_DIE_ID_44XX_0 0x0200 92 #define OMAP_TAP_DIE_ID_44XX_1 0x0208 93 #define OMAP_TAP_DIE_ID_44XX_2 0x020c 94 #define OMAP_TAP_DIE_ID_44XX_3 0x0210 95 96 #define read_tap_reg(reg) __raw_readl(tap_base + (reg)) 97 98 struct omap_id { 99 u16 hawkeye; /* Silicon type (Hawkeye id) */ 100 u8 dev; /* Device type from production_id reg */ 101 u32 type; /* Combined type id copied to omap_revision */ 102 }; 103 104 /* Register values to detect the OMAP version */ 105 static struct omap_id omap_ids[] __initdata = { 106 { .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200024 }, 107 { .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201024 }, 108 { .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202024 }, 109 { .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220024 }, 110 { .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230024 }, 111 { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300024 }, 112 }; 113 114 static void __iomem *tap_base; 115 static u16 tap_prod_id; 116 117 void omap_get_die_id(struct omap_die_id *odi) 118 { 119 if (cpu_is_omap44xx() || soc_is_omap54xx()) { 120 odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_0); 121 odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_1); 122 odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_2); 123 odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_3); 124 125 return; 126 } 127 odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_0); 128 odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_1); 129 odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_2); 130 odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3); 131 } 132 133 void __init omap2xxx_check_revision(void) 134 { 135 int i, j; 136 u32 idcode, prod_id; 137 u16 hawkeye; 138 u8 dev_type, rev; 139 struct omap_die_id odi; 140 141 idcode = read_tap_reg(OMAP_TAP_IDCODE); 142 prod_id = read_tap_reg(tap_prod_id); 143 hawkeye = (idcode >> 12) & 0xffff; 144 rev = (idcode >> 28) & 0x0f; 145 dev_type = (prod_id >> 16) & 0x0f; 146 omap_get_die_id(&odi); 147 148 pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n", 149 idcode, rev, hawkeye, (idcode >> 1) & 0x7ff); 150 pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", odi.id_0); 151 pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n", 152 odi.id_1, (odi.id_1 >> 28) & 0xf); 153 pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", odi.id_2); 154 pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", odi.id_3); 155 pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n", 156 prod_id, dev_type); 157 158 /* Check hawkeye ids */ 159 for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { 160 if (hawkeye == omap_ids[i].hawkeye) 161 break; 162 } 163 164 if (i == ARRAY_SIZE(omap_ids)) { 165 printk(KERN_ERR "Unknown OMAP CPU id\n"); 166 return; 167 } 168 169 for (j = i; j < ARRAY_SIZE(omap_ids); j++) { 170 if (dev_type == omap_ids[j].dev) 171 break; 172 } 173 174 if (j == ARRAY_SIZE(omap_ids)) { 175 pr_err("Unknown OMAP device type. Handling it as OMAP%04x\n", 176 omap_ids[i].type >> 16); 177 j = i; 178 } 179 180 sprintf(soc_name, "OMAP%04x", omap_rev() >> 16); 181 sprintf(soc_rev, "ES%x", (omap_rev() >> 12) & 0xf); 182 183 pr_info("%s", soc_name); 184 if ((omap_rev() >> 8) & 0x0f) 185 pr_info("%s", soc_rev); 186 pr_info("\n"); 187 } 188 189 #define OMAP3_SHOW_FEATURE(feat) \ 190 if (omap3_has_ ##feat()) \ 191 printk(#feat" "); 192 193 static void __init omap3_cpuinfo(void) 194 { 195 const char *cpu_name; 196 197 /* 198 * OMAP3430 and OMAP3530 are assumed to be same. 199 * 200 * OMAP3525, OMAP3515 and OMAP3503 can be detected only based 201 * on available features. Upon detection, update the CPU id 202 * and CPU class bits. 203 */ 204 if (cpu_is_omap3630()) { 205 cpu_name = "OMAP3630"; 206 } else if (soc_is_am35xx()) { 207 cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505"; 208 } else if (cpu_is_ti816x()) { 209 cpu_name = "TI816X"; 210 } else if (soc_is_am335x()) { 211 cpu_name = "AM335X"; 212 } else if (cpu_is_ti814x()) { 213 cpu_name = "TI814X"; 214 } else if (omap3_has_iva() && omap3_has_sgx()) { 215 /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ 216 cpu_name = "OMAP3430/3530"; 217 } else if (omap3_has_iva()) { 218 cpu_name = "OMAP3525"; 219 } else if (omap3_has_sgx()) { 220 cpu_name = "OMAP3515"; 221 } else { 222 cpu_name = "OMAP3503"; 223 } 224 225 sprintf(soc_name, "%s", cpu_name); 226 227 /* Print verbose information */ 228 pr_info("%s %s (", soc_name, soc_rev); 229 230 OMAP3_SHOW_FEATURE(l2cache); 231 OMAP3_SHOW_FEATURE(iva); 232 OMAP3_SHOW_FEATURE(sgx); 233 OMAP3_SHOW_FEATURE(neon); 234 OMAP3_SHOW_FEATURE(isp); 235 OMAP3_SHOW_FEATURE(192mhz_clk); 236 237 printk(")\n"); 238 } 239 240 #define OMAP3_CHECK_FEATURE(status,feat) \ 241 if (((status & OMAP3_ ##feat## _MASK) \ 242 >> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { \ 243 omap_features |= OMAP3_HAS_ ##feat; \ 244 } 245 246 void __init omap3xxx_check_features(void) 247 { 248 u32 status; 249 250 omap_features = 0; 251 252 status = omap_ctrl_readl(OMAP3_CONTROL_OMAP_STATUS); 253 254 OMAP3_CHECK_FEATURE(status, L2CACHE); 255 OMAP3_CHECK_FEATURE(status, IVA); 256 OMAP3_CHECK_FEATURE(status, SGX); 257 OMAP3_CHECK_FEATURE(status, NEON); 258 OMAP3_CHECK_FEATURE(status, ISP); 259 if (cpu_is_omap3630()) 260 omap_features |= OMAP3_HAS_192MHZ_CLK; 261 if (cpu_is_omap3430() || cpu_is_omap3630()) 262 omap_features |= OMAP3_HAS_IO_WAKEUP; 263 if (cpu_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 || 264 omap_rev() == OMAP3430_REV_ES3_1_2) 265 omap_features |= OMAP3_HAS_IO_CHAIN_CTRL; 266 267 omap_features |= OMAP3_HAS_SDRC; 268 269 /* 270 * am35x fixups: 271 * - The am35x Chip ID register has bits 12, 7:5, and 3:2 marked as 272 * reserved and therefore return 0 when read. Unfortunately, 273 * OMAP3_CHECK_FEATURE() will interpret some of those zeroes to 274 * mean that a feature is present even though it isn't so clear 275 * the incorrectly set feature bits. 276 */ 277 if (soc_is_am35xx()) 278 omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP); 279 280 /* 281 * TODO: Get additional info (where applicable) 282 * e.g. Size of L2 cache. 283 */ 284 285 omap3_cpuinfo(); 286 } 287 288 void __init omap4xxx_check_features(void) 289 { 290 u32 si_type; 291 292 si_type = 293 (read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1) >> 16) & 0x03; 294 295 if (si_type == OMAP4_SILICON_TYPE_PERFORMANCE) 296 omap_features = OMAP4_HAS_PERF_SILICON; 297 } 298 299 void __init ti81xx_check_features(void) 300 { 301 omap_features = OMAP3_HAS_NEON; 302 omap3_cpuinfo(); 303 } 304 305 void __init omap3xxx_check_revision(void) 306 { 307 const char *cpu_rev; 308 u32 cpuid, idcode; 309 u16 hawkeye; 310 u8 rev; 311 312 /* 313 * We cannot access revision registers on ES1.0. 314 * If the processor type is Cortex-A8 and the revision is 0x0 315 * it means its Cortex r0p0 which is 3430 ES1.0. 316 */ 317 cpuid = read_cpuid(CPUID_ID); 318 if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) { 319 omap_revision = OMAP3430_REV_ES1_0; 320 cpu_rev = "1.0"; 321 return; 322 } 323 324 /* 325 * Detection for 34xx ES2.0 and above can be done with just 326 * hawkeye and rev. See TRM 1.5.2 Device Identification. 327 * Note that rev does not map directly to our defined processor 328 * revision numbers as ES1.0 uses value 0. 329 */ 330 idcode = read_tap_reg(OMAP_TAP_IDCODE); 331 hawkeye = (idcode >> 12) & 0xffff; 332 rev = (idcode >> 28) & 0xff; 333 334 switch (hawkeye) { 335 case 0xb7ae: 336 /* Handle 34xx/35xx devices */ 337 switch (rev) { 338 case 0: /* Take care of early samples */ 339 case 1: 340 omap_revision = OMAP3430_REV_ES2_0; 341 cpu_rev = "2.0"; 342 break; 343 case 2: 344 omap_revision = OMAP3430_REV_ES2_1; 345 cpu_rev = "2.1"; 346 break; 347 case 3: 348 omap_revision = OMAP3430_REV_ES3_0; 349 cpu_rev = "3.0"; 350 break; 351 case 4: 352 omap_revision = OMAP3430_REV_ES3_1; 353 cpu_rev = "3.1"; 354 break; 355 case 7: 356 /* FALLTHROUGH */ 357 default: 358 /* Use the latest known revision as default */ 359 omap_revision = OMAP3430_REV_ES3_1_2; 360 cpu_rev = "3.1.2"; 361 } 362 break; 363 case 0xb868: 364 /* 365 * Handle OMAP/AM 3505/3517 devices 366 * 367 * Set the device to be OMAP3517 here. Actual device 368 * is identified later based on the features. 369 */ 370 switch (rev) { 371 case 0: 372 omap_revision = AM35XX_REV_ES1_0; 373 cpu_rev = "1.0"; 374 break; 375 case 1: 376 /* FALLTHROUGH */ 377 default: 378 omap_revision = AM35XX_REV_ES1_1; 379 cpu_rev = "1.1"; 380 } 381 break; 382 case 0xb891: 383 /* Handle 36xx devices */ 384 385 switch(rev) { 386 case 0: /* Take care of early samples */ 387 omap_revision = OMAP3630_REV_ES1_0; 388 cpu_rev = "1.0"; 389 break; 390 case 1: 391 omap_revision = OMAP3630_REV_ES1_1; 392 cpu_rev = "1.1"; 393 break; 394 case 2: 395 /* FALLTHROUGH */ 396 default: 397 omap_revision = OMAP3630_REV_ES1_2; 398 cpu_rev = "1.2"; 399 } 400 break; 401 case 0xb81e: 402 switch (rev) { 403 case 0: 404 omap_revision = TI8168_REV_ES1_0; 405 cpu_rev = "1.0"; 406 break; 407 case 1: 408 /* FALLTHROUGH */ 409 default: 410 omap_revision = TI8168_REV_ES1_1; 411 cpu_rev = "1.1"; 412 break; 413 } 414 break; 415 case 0xb944: 416 switch (rev) { 417 case 0: 418 omap_revision = AM335X_REV_ES1_0; 419 cpu_rev = "1.0"; 420 break; 421 case 1: 422 /* FALLTHROUGH */ 423 default: 424 omap_revision = AM335X_REV_ES2_0; 425 cpu_rev = "2.0"; 426 break; 427 } 428 break; 429 case 0xb8f2: 430 switch (rev) { 431 case 0: 432 /* FALLTHROUGH */ 433 case 1: 434 omap_revision = TI8148_REV_ES1_0; 435 cpu_rev = "1.0"; 436 break; 437 case 2: 438 omap_revision = TI8148_REV_ES2_0; 439 cpu_rev = "2.0"; 440 break; 441 case 3: 442 /* FALLTHROUGH */ 443 default: 444 omap_revision = TI8148_REV_ES2_1; 445 cpu_rev = "2.1"; 446 break; 447 } 448 break; 449 default: 450 /* Unknown default to latest silicon rev as default */ 451 omap_revision = OMAP3630_REV_ES1_2; 452 cpu_rev = "1.2"; 453 pr_warn("Warning: unknown chip type; assuming OMAP3630ES1.2\n"); 454 } 455 sprintf(soc_rev, "ES%s", cpu_rev); 456 } 457 458 void __init omap4xxx_check_revision(void) 459 { 460 u32 idcode; 461 u16 hawkeye; 462 u8 rev; 463 464 /* 465 * The IC rev detection is done with hawkeye and rev. 466 * Note that rev does not map directly to defined processor 467 * revision numbers as ES1.0 uses value 0. 468 */ 469 idcode = read_tap_reg(OMAP_TAP_IDCODE); 470 hawkeye = (idcode >> 12) & 0xffff; 471 rev = (idcode >> 28) & 0xf; 472 473 /* 474 * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0 475 * Use ARM register to detect the correct ES version 476 */ 477 if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) { 478 idcode = read_cpuid(CPUID_ID); 479 rev = (idcode & 0xf) - 1; 480 } 481 482 switch (hawkeye) { 483 case 0xb852: 484 switch (rev) { 485 case 0: 486 omap_revision = OMAP4430_REV_ES1_0; 487 break; 488 case 1: 489 default: 490 omap_revision = OMAP4430_REV_ES2_0; 491 } 492 break; 493 case 0xb95c: 494 switch (rev) { 495 case 3: 496 omap_revision = OMAP4430_REV_ES2_1; 497 break; 498 case 4: 499 omap_revision = OMAP4430_REV_ES2_2; 500 break; 501 case 6: 502 default: 503 omap_revision = OMAP4430_REV_ES2_3; 504 } 505 break; 506 case 0xb94e: 507 switch (rev) { 508 case 0: 509 omap_revision = OMAP4460_REV_ES1_0; 510 break; 511 case 2: 512 default: 513 omap_revision = OMAP4460_REV_ES1_1; 514 break; 515 } 516 break; 517 case 0xb975: 518 switch (rev) { 519 case 0: 520 default: 521 omap_revision = OMAP4470_REV_ES1_0; 522 break; 523 } 524 break; 525 default: 526 /* Unknown default to latest silicon rev as default */ 527 omap_revision = OMAP4430_REV_ES2_3; 528 } 529 530 sprintf(soc_name, "OMAP%04x", omap_rev() >> 16); 531 sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf, 532 (omap_rev() >> 8) & 0xf); 533 pr_info("%s %s\n", soc_name, soc_rev); 534 } 535 536 void __init omap5xxx_check_revision(void) 537 { 538 u32 idcode; 539 u16 hawkeye; 540 u8 rev; 541 542 idcode = read_tap_reg(OMAP_TAP_IDCODE); 543 hawkeye = (idcode >> 12) & 0xffff; 544 rev = (idcode >> 28) & 0xff; 545 switch (hawkeye) { 546 case 0xb942: 547 switch (rev) { 548 case 0: 549 default: 550 omap_revision = OMAP5430_REV_ES1_0; 551 } 552 break; 553 554 case 0xb998: 555 switch (rev) { 556 case 0: 557 default: 558 omap_revision = OMAP5432_REV_ES1_0; 559 } 560 break; 561 562 default: 563 /* Unknown default to latest silicon rev as default*/ 564 omap_revision = OMAP5430_REV_ES1_0; 565 } 566 567 sprintf(soc_name, "OMAP%04x", omap_rev() >> 16); 568 sprintf(soc_rev, "ES%d.0", (omap_rev() >> 12) & 0xf); 569 570 pr_info("%s %s\n", soc_name, soc_rev); 571 } 572 573 /* 574 * Set up things for map_io and processor detection later on. Gets called 575 * pretty much first thing from board init. For multi-omap, this gets 576 * cpu_is_omapxxxx() working accurately enough for map_io. Then we'll try to 577 * detect the exact revision later on in omap2_detect_revision() once map_io 578 * is done. 579 */ 580 void __init omap2_set_globals_tap(u32 class, void __iomem *tap) 581 { 582 omap_revision = class; 583 tap_base = tap; 584 585 /* XXX What is this intended to do? */ 586 if (cpu_is_omap34xx()) 587 tap_prod_id = 0x0210; 588 else 589 tap_prod_id = 0x0208; 590 } 591 592 #ifdef CONFIG_SOC_BUS 593 594 static const char const *omap_types[] = { 595 [OMAP2_DEVICE_TYPE_TEST] = "TST", 596 [OMAP2_DEVICE_TYPE_EMU] = "EMU", 597 [OMAP2_DEVICE_TYPE_SEC] = "HS", 598 [OMAP2_DEVICE_TYPE_GP] = "GP", 599 [OMAP2_DEVICE_TYPE_BAD] = "BAD", 600 }; 601 602 static const char * __init omap_get_family(void) 603 { 604 if (cpu_is_omap24xx()) 605 return kasprintf(GFP_KERNEL, "OMAP2"); 606 else if (cpu_is_omap34xx()) 607 return kasprintf(GFP_KERNEL, "OMAP3"); 608 else if (cpu_is_omap44xx()) 609 return kasprintf(GFP_KERNEL, "OMAP4"); 610 else if (soc_is_omap54xx()) 611 return kasprintf(GFP_KERNEL, "OMAP5"); 612 else 613 return kasprintf(GFP_KERNEL, "Unknown"); 614 } 615 616 static ssize_t omap_get_type(struct device *dev, 617 struct device_attribute *attr, 618 char *buf) 619 { 620 return sprintf(buf, "%s\n", omap_types[omap_type()]); 621 } 622 623 static struct device_attribute omap_soc_attr = 624 __ATTR(type, S_IRUGO, omap_get_type, NULL); 625 626 void __init omap_soc_device_init(void) 627 { 628 struct device *parent; 629 struct soc_device *soc_dev; 630 struct soc_device_attribute *soc_dev_attr; 631 632 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); 633 if (!soc_dev_attr) 634 return; 635 636 soc_dev_attr->machine = soc_name; 637 soc_dev_attr->family = omap_get_family(); 638 soc_dev_attr->revision = soc_rev; 639 640 soc_dev = soc_device_register(soc_dev_attr); 641 if (IS_ERR_OR_NULL(soc_dev)) { 642 kfree(soc_dev_attr); 643 return; 644 } 645 646 parent = soc_device_to_device(soc_dev); 647 if (!IS_ERR_OR_NULL(parent)) 648 device_create_file(parent, &omap_soc_attr); 649 } 650 #endif /* CONFIG_SOC_BUS */ 651