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 default: 348 /* Unknown default to latest silicon rev as default */ 349 omap_revision = OMAP3630_REV_ES1_2; 350 *cpu_rev = "1.2"; 351 pr_warn("Warning: unknown chip type; assuming OMAP3630ES1.2\n"); 352 } 353 } 354 355 static void __init omap4_check_revision(void) 356 { 357 u32 idcode; 358 u16 hawkeye; 359 u8 rev; 360 361 /* 362 * The IC rev detection is done with hawkeye and rev. 363 * Note that rev does not map directly to defined processor 364 * revision numbers as ES1.0 uses value 0. 365 */ 366 idcode = read_tap_reg(OMAP_TAP_IDCODE); 367 hawkeye = (idcode >> 12) & 0xffff; 368 rev = (idcode >> 28) & 0xf; 369 370 /* 371 * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0 372 * Use ARM register to detect the correct ES version 373 */ 374 if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) { 375 idcode = read_cpuid(CPUID_ID); 376 rev = (idcode & 0xf) - 1; 377 } 378 379 switch (hawkeye) { 380 case 0xb852: 381 switch (rev) { 382 case 0: 383 omap_revision = OMAP4430_REV_ES1_0; 384 break; 385 case 1: 386 default: 387 omap_revision = OMAP4430_REV_ES2_0; 388 } 389 break; 390 case 0xb95c: 391 switch (rev) { 392 case 3: 393 omap_revision = OMAP4430_REV_ES2_1; 394 break; 395 case 4: 396 omap_revision = OMAP4430_REV_ES2_2; 397 break; 398 case 6: 399 default: 400 omap_revision = OMAP4430_REV_ES2_3; 401 } 402 break; 403 case 0xb94e: 404 switch (rev) { 405 case 0: 406 default: 407 omap_revision = OMAP4460_REV_ES1_0; 408 break; 409 } 410 break; 411 case 0xb975: 412 switch (rev) { 413 case 0: 414 default: 415 omap_revision = OMAP4470_REV_ES1_0; 416 break; 417 } 418 break; 419 default: 420 /* Unknown default to latest silicon rev as default */ 421 omap_revision = OMAP4430_REV_ES2_3; 422 } 423 424 pr_info("OMAP%04x ES%d.%d\n", omap_rev() >> 16, 425 ((omap_rev() >> 12) & 0xf), ((omap_rev() >> 8) & 0xf)); 426 } 427 428 #define OMAP3_SHOW_FEATURE(feat) \ 429 if (omap3_has_ ##feat()) \ 430 printk(#feat" "); 431 432 static void __init omap3_cpuinfo(const char *cpu_rev) 433 { 434 const char *cpu_name; 435 436 /* 437 * OMAP3430 and OMAP3530 are assumed to be same. 438 * 439 * OMAP3525, OMAP3515 and OMAP3503 can be detected only based 440 * on available features. Upon detection, update the CPU id 441 * and CPU class bits. 442 */ 443 if (cpu_is_omap3630()) { 444 cpu_name = "OMAP3630"; 445 } else if (cpu_is_omap3517()) { 446 /* AM35xx devices */ 447 cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505"; 448 } else if (cpu_is_ti816x()) { 449 cpu_name = "TI816X"; 450 } else if (cpu_is_am335x()) { 451 cpu_name = "AM335X"; 452 } else if (omap3_has_iva() && omap3_has_sgx()) { 453 /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ 454 cpu_name = "OMAP3430/3530"; 455 } else if (omap3_has_iva()) { 456 cpu_name = "OMAP3525"; 457 } else if (omap3_has_sgx()) { 458 cpu_name = "OMAP3515"; 459 } else { 460 cpu_name = "OMAP3503"; 461 } 462 463 /* Print verbose information */ 464 pr_info("%s ES%s (", cpu_name, cpu_rev); 465 466 OMAP3_SHOW_FEATURE(l2cache); 467 OMAP3_SHOW_FEATURE(iva); 468 OMAP3_SHOW_FEATURE(sgx); 469 OMAP3_SHOW_FEATURE(neon); 470 OMAP3_SHOW_FEATURE(isp); 471 OMAP3_SHOW_FEATURE(192mhz_clk); 472 473 printk(")\n"); 474 } 475 476 /* 477 * Try to detect the exact revision of the omap we're running on 478 */ 479 void __init omap2_check_revision(void) 480 { 481 const char *cpu_rev; 482 483 /* 484 * At this point we have an idea about the processor revision set 485 * earlier with omap2_set_globals_tap(). 486 */ 487 if (cpu_is_omap24xx()) { 488 omap24xx_check_revision(); 489 } else if (cpu_is_omap34xx()) { 490 omap3_check_revision(&cpu_rev); 491 492 /* TI81XX doesn't have feature register */ 493 if (!cpu_is_ti81xx()) 494 omap3_check_features(); 495 else 496 ti81xx_check_features(); 497 498 omap3_cpuinfo(cpu_rev); 499 return; 500 } else if (cpu_is_omap44xx()) { 501 omap4_check_revision(); 502 omap4_check_features(); 503 return; 504 } else { 505 pr_err("OMAP revision unknown, please fix!\n"); 506 } 507 } 508 509 /* 510 * Set up things for map_io and processor detection later on. Gets called 511 * pretty much first thing from board init. For multi-omap, this gets 512 * cpu_is_omapxxxx() working accurately enough for map_io. Then we'll try to 513 * detect the exact revision later on in omap2_detect_revision() once map_io 514 * is done. 515 */ 516 void __init omap2_set_globals_tap(struct omap_globals *omap2_globals) 517 { 518 omap_revision = omap2_globals->class; 519 tap_base = omap2_globals->tap; 520 521 if (cpu_is_omap34xx()) 522 tap_prod_id = 0x0210; 523 else 524 tap_prod_id = 0x0208; 525 } 526