id.c 17.5 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 * linux/arch/arm/mach-omap2/id.c
 *
 * OMAP2 CPU identification code
 *
 * Copyright (C) 2005 Nokia Corporation
 * Written by Tony Lindgren <tony@atomide.com>
 *
9
 * Copyright (C) 2009-11 Texas Instruments
10 11
 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
 *
12 13 14 15 16 17 18 19
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
20
#include <linux/io.h>
21
#include <linux/random.h>
22 23 24 25 26
#include <linux/slab.h>

#ifdef CONFIG_SOC_BUS
#include <linux/sys_soc.h>
#endif
27

28
#include <asm/cputype.h>
29

30
#include "common.h"
31

T
Tony Lindgren 已提交
32
#include "id.h"
33

34
#include "soc.h"
35 36
#include "control.h"

37 38 39
#define OMAP4_SILICON_TYPE_STANDARD		0x01
#define OMAP4_SILICON_TYPE_PERFORMANCE		0x02

40 41
#define OMAP_SOC_MAX_NAME_LENGTH		16

42
static unsigned int omap_revision;
43 44
static char soc_name[OMAP_SOC_MAX_NAME_LENGTH];
static char soc_rev[OMAP_SOC_MAX_NAME_LENGTH];
45
u32 omap_features;
46 47 48

unsigned int omap_rev(void)
{
49
	WARN_ON_ONCE(!omap_revision || omap_revision == -1);
50 51 52
	return omap_revision;
}
EXPORT_SYMBOL(omap_rev);
53

54 55
int omap_type(void)
{
56 57 58 59
	static u32 val = OMAP2_DEVICETYPE_MASK;

	if (val < OMAP2_DEVICETYPE_MASK)
		return val;
60

61
	if (soc_is_omap24xx()) {
62
		val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
63
	} else if (soc_is_ti81xx()) {
T
Tony Lindgren 已提交
64
		val = omap_ctrl_readl(TI81XX_CONTROL_STATUS);
A
Afzal Mohammed 已提交
65
	} else if (soc_is_am33xx() || soc_is_am43xx()) {
66
		val = omap_ctrl_readl(AM33XX_CONTROL_STATUS);
67
	} else if (soc_is_omap34xx()) {
68
		val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
69
	} else if (soc_is_omap44xx()) {
70
		val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS);
71
	} else if (soc_is_omap54xx() || soc_is_dra7xx()) {
72 73 74 75
		val = omap_ctrl_readl(OMAP5XXX_CONTROL_STATUS);
		val &= OMAP5_DEVICETYPE_MASK;
		val >>= 6;
		goto out;
76
	} else {
77 78 79 80 81 82 83 84 85 86 87 88 89
		pr_err("Cannot detect omap type!\n");
		goto out;
	}

	val &= OMAP2_DEVICETYPE_MASK;
	val >>= 8;

out:
	return val;
}
EXPORT_SYMBOL(omap_type);


T
Tony Lindgren 已提交
90
/*----------------------------------------------------------------------------*/
91

T
Tony Lindgren 已提交
92 93 94 95 96
#define OMAP_TAP_IDCODE		0x0204
#define OMAP_TAP_DIE_ID_0	0x0218
#define OMAP_TAP_DIE_ID_1	0x021C
#define OMAP_TAP_DIE_ID_2	0x0220
#define OMAP_TAP_DIE_ID_3	0x0224
97

98 99 100 101 102
#define OMAP_TAP_DIE_ID_44XX_0	0x0200
#define OMAP_TAP_DIE_ID_44XX_1	0x0208
#define OMAP_TAP_DIE_ID_44XX_2	0x020c
#define OMAP_TAP_DIE_ID_44XX_3	0x0210

103
#define read_tap_reg(reg)	readl_relaxed(tap_base  + (reg))
104

T
Tony Lindgren 已提交
105 106 107
struct omap_id {
	u16	hawkeye;	/* Silicon type (Hawkeye id) */
	u8	dev;		/* Device type from production_id reg */
108
	u32	type;		/* Combined type id copied to omap_revision */
T
Tony Lindgren 已提交
109
};
110

T
Tony Lindgren 已提交
111 112 113 114 115 116 117 118 119
/* Register values to detect the OMAP version */
static struct omap_id omap_ids[] __initdata = {
	{ .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200024 },
	{ .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201024 },
	{ .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202024 },
	{ .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220024 },
	{ .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230024 },
	{ .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300024 },
};
120

T
Tony Lindgren 已提交
121 122
static void __iomem *tap_base;
static u16 tap_prod_id;
123

124 125
void omap_get_die_id(struct omap_die_id *odi)
{
126
	if (soc_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) {
127 128 129 130 131 132 133
		odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_0);
		odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_1);
		odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_2);
		odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_3);

		return;
	}
134 135 136 137 138 139
	odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_0);
	odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_1);
	odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_2);
	odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3);
}

140 141 142 143 144 145 146 147 148 149 150
static int __init omap_feed_randpool(void)
{
	struct omap_die_id odi;

	/* Throw the die ID into the entropy pool at boot */
	omap_get_die_id(&odi);
	add_device_randomness(&odi, sizeof(odi));
	return 0;
}
omap_device_initcall(omap_feed_randpool);

151
void __init omap2xxx_check_revision(void)
152 153
{
	int i, j;
T
Tony Lindgren 已提交
154
	u32 idcode, prod_id;
155
	u16 hawkeye;
T
Tony Lindgren 已提交
156
	u8  dev_type, rev;
157
	struct omap_die_id odi;
158 159

	idcode = read_tap_reg(OMAP_TAP_IDCODE);
160
	prod_id = read_tap_reg(tap_prod_id);
161 162 163
	hawkeye = (idcode >> 12) & 0xffff;
	rev = (idcode >> 28) & 0x0f;
	dev_type = (prod_id >> 16) & 0x0f;
164
	omap_get_die_id(&odi);
165

166 167
	pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
		 idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
168
	pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", odi.id_0);
169
	pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
170 171 172
		 odi.id_1, (odi.id_1 >> 28) & 0xf);
	pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", odi.id_2);
	pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", odi.id_3);
173 174 175
	pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
		 prod_id, dev_type);

176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
	/* Check hawkeye ids */
	for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
		if (hawkeye == omap_ids[i].hawkeye)
			break;
	}

	if (i == ARRAY_SIZE(omap_ids)) {
		printk(KERN_ERR "Unknown OMAP CPU id\n");
		return;
	}

	for (j = i; j < ARRAY_SIZE(omap_ids); j++) {
		if (dev_type == omap_ids[j].dev)
			break;
	}

	if (j == ARRAY_SIZE(omap_ids)) {
P
Paul Walmsley 已提交
193 194
		pr_err("Unknown OMAP device type. Handling it as OMAP%04x\n",
		       omap_ids[i].type >> 16);
195 196 197
		j = i;
	}

198 199 200 201
	sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
	sprintf(soc_rev, "ES%x", (omap_rev() >> 12) & 0xf);

	pr_info("%s", soc_name);
202
	if ((omap_rev() >> 8) & 0x0f)
203
		pr_info("%s", soc_rev);
204
	pr_info("\n");
T
Tony Lindgren 已提交
205 206
}

207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
#define OMAP3_SHOW_FEATURE(feat)		\
	if (omap3_has_ ##feat())		\
		printk(#feat" ");

static void __init omap3_cpuinfo(void)
{
	const char *cpu_name;

	/*
	 * OMAP3430 and OMAP3530 are assumed to be same.
	 *
	 * OMAP3525, OMAP3515 and OMAP3503 can be detected only based
	 * on available features. Upon detection, update the CPU id
	 * and CPU class bits.
	 */
222
	if (soc_is_omap3630()) {
223
		cpu_name = "OMAP3630";
224
	} else if (soc_is_am35xx()) {
225
		cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
226
	} else if (soc_is_ti816x()) {
227
		cpu_name = "TI816X";
228
	} else if (soc_is_am335x()) {
229
		cpu_name =  "AM335X";
230 231
	} else if (soc_is_am437x()) {
		cpu_name =  "AM437x";
232
	} else if (soc_is_ti814x()) {
233 234 235 236 237 238 239 240 241 242 243 244
		cpu_name = "TI814X";
	} else if (omap3_has_iva() && omap3_has_sgx()) {
		/* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
		cpu_name = "OMAP3430/3530";
	} else if (omap3_has_iva()) {
		cpu_name = "OMAP3525";
	} else if (omap3_has_sgx()) {
		cpu_name = "OMAP3515";
	} else {
		cpu_name = "OMAP3503";
	}

245 246
	sprintf(soc_name, "%s", cpu_name);

247
	/* Print verbose information */
248
	pr_info("%s %s (", soc_name, soc_rev);
249 250 251 252 253 254 255 256 257 258 259

	OMAP3_SHOW_FEATURE(l2cache);
	OMAP3_SHOW_FEATURE(iva);
	OMAP3_SHOW_FEATURE(sgx);
	OMAP3_SHOW_FEATURE(neon);
	OMAP3_SHOW_FEATURE(isp);
	OMAP3_SHOW_FEATURE(192mhz_clk);

	printk(")\n");
}

260 261 262
#define OMAP3_CHECK_FEATURE(status,feat)				\
	if (((status & OMAP3_ ##feat## _MASK) 				\
		>> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { 	\
263
		omap_features |= OMAP3_HAS_ ##feat;			\
264 265
	}

266
void __init omap3xxx_check_features(void)
267 268 269
{
	u32 status;

270
	omap_features = 0;
271 272 273 274 275 276 277 278

	status = omap_ctrl_readl(OMAP3_CONTROL_OMAP_STATUS);

	OMAP3_CHECK_FEATURE(status, L2CACHE);
	OMAP3_CHECK_FEATURE(status, IVA);
	OMAP3_CHECK_FEATURE(status, SGX);
	OMAP3_CHECK_FEATURE(status, NEON);
	OMAP3_CHECK_FEATURE(status, ISP);
279
	if (soc_is_omap3630())
280
		omap_features |= OMAP3_HAS_192MHZ_CLK;
281
	if (soc_is_omap3430() || soc_is_omap3630())
282
		omap_features |= OMAP3_HAS_IO_WAKEUP;
283
	if (soc_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 ||
284 285
	    omap_rev() == OMAP3430_REV_ES3_1_2)
		omap_features |= OMAP3_HAS_IO_CHAIN_CTRL;
286

287
	omap_features |= OMAP3_HAS_SDRC;
288

289 290 291 292 293 294 295 296 297 298 299
	/*
	 * am35x fixups:
	 * - The am35x Chip ID register has bits 12, 7:5, and 3:2 marked as
	 *   reserved and therefore return 0 when read.  Unfortunately,
	 *   OMAP3_CHECK_FEATURE() will interpret some of those zeroes to
	 *   mean that a feature is present even though it isn't so clear
	 *   the incorrectly set feature bits.
	 */
	if (soc_is_am35xx())
		omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP);

300 301 302 303
	/*
	 * TODO: Get additional info (where applicable)
	 *       e.g. Size of L2 cache.
	 */
304 305

	omap3_cpuinfo();
306 307
}

308
void __init omap4xxx_check_features(void)
309 310 311
{
	u32 si_type;

312 313
	si_type =
	(read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1) >> 16) & 0x03;
314

315 316
	if (si_type == OMAP4_SILICON_TYPE_PERFORMANCE)
		omap_features = OMAP4_HAS_PERF_SILICON;
317 318
}

319
void __init ti81xx_check_features(void)
320
{
321
	omap_features = OMAP3_HAS_NEON;
322
	omap3_cpuinfo();
323 324
}

325 326 327 328 329 330 331 332 333 334 335 336 337
void __init am33xx_check_features(void)
{
	u32 status;

	omap_features = OMAP3_HAS_NEON;

	status = omap_ctrl_readl(AM33XX_DEV_FEATURE);
	if (status & AM33XX_SGX_MASK)
		omap_features |= OMAP3_HAS_SGX;

	omap3_cpuinfo();
}

338
void __init omap3xxx_check_revision(void)
T
Tony Lindgren 已提交
339
{
340
	const char *cpu_rev;
T
Tony Lindgren 已提交
341 342 343 344 345 346 347 348 349
	u32 cpuid, idcode;
	u16 hawkeye;
	u8 rev;

	/*
	 * We cannot access revision registers on ES1.0.
	 * If the processor type is Cortex-A8 and the revision is 0x0
	 * it means its Cortex r0p0 which is 3430 ES1.0.
	 */
350
	cpuid = read_cpuid_id();
T
Tony Lindgren 已提交
351
	if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) {
352
		omap_revision = OMAP3430_REV_ES1_0;
353
		cpu_rev = "1.0";
354
		return;
T
Tony Lindgren 已提交
355 356 357 358 359 360 361 362 363 364 365
	}

	/*
	 * Detection for 34xx ES2.0 and above can be done with just
	 * hawkeye and rev. See TRM 1.5.2 Device Identification.
	 * Note that rev does not map directly to our defined processor
	 * revision numbers as ES1.0 uses value 0.
	 */
	idcode = read_tap_reg(OMAP_TAP_IDCODE);
	hawkeye = (idcode >> 12) & 0xffff;
	rev = (idcode >> 28) & 0xff;
366

N
Nishanth Menon 已提交
367 368 369
	switch (hawkeye) {
	case 0xb7ae:
		/* Handle 34xx/35xx devices */
T
Tony Lindgren 已提交
370
		switch (rev) {
371 372
		case 0: /* Take care of early samples */
		case 1:
373
			omap_revision = OMAP3430_REV_ES2_0;
374
			cpu_rev = "2.0";
T
Tony Lindgren 已提交
375 376
			break;
		case 2:
377
			omap_revision = OMAP3430_REV_ES2_1;
378
			cpu_rev = "2.1";
T
Tony Lindgren 已提交
379 380
			break;
		case 3:
381
			omap_revision = OMAP3430_REV_ES3_0;
382
			cpu_rev = "3.0";
T
Tony Lindgren 已提交
383
			break;
384
		case 4:
T
Tony Lindgren 已提交
385
			omap_revision = OMAP3430_REV_ES3_1;
386
			cpu_rev = "3.1";
T
Tony Lindgren 已提交
387 388
			break;
		case 7:
389
		/* FALLTHROUGH */
T
Tony Lindgren 已提交
390 391
		default:
			/* Use the latest known revision as default */
T
Tony Lindgren 已提交
392
			omap_revision = OMAP3430_REV_ES3_1_2;
393
			cpu_rev = "3.1.2";
T
Tony Lindgren 已提交
394
		}
N
Nishanth Menon 已提交
395
		break;
396
	case 0xb868:
397 398
		/*
		 * Handle OMAP/AM 3505/3517 devices
399
		 *
400
		 * Set the device to be OMAP3517 here. Actual device
401 402
		 * is identified later based on the features.
		 */
403 404
		switch (rev) {
		case 0:
405
			omap_revision = AM35XX_REV_ES1_0;
406
			cpu_rev = "1.0";
407 408 409 410
			break;
		case 1:
		/* FALLTHROUGH */
		default:
411
			omap_revision = AM35XX_REV_ES1_1;
412
			cpu_rev = "1.1";
413
		}
414
		break;
415
	case 0xb891:
416 417 418 419 420
		/* Handle 36xx devices */

		switch(rev) {
		case 0: /* Take care of early samples */
			omap_revision = OMAP3630_REV_ES1_0;
421
			cpu_rev = "1.0";
422 423 424
			break;
		case 1:
			omap_revision = OMAP3630_REV_ES1_1;
425
			cpu_rev = "1.1";
426 427
			break;
		case 2:
428
		/* FALLTHROUGH */
429
		default:
430
			omap_revision = OMAP3630_REV_ES1_2;
431
			cpu_rev = "1.2";
432
		}
433
		break;
434 435 436 437
	case 0xb81e:
		switch (rev) {
		case 0:
			omap_revision = TI8168_REV_ES1_0;
438
			cpu_rev = "1.0";
439 440
			break;
		case 1:
441
			omap_revision = TI8168_REV_ES1_1;
442
			cpu_rev = "1.1";
443
			break;
444 445 446 447 448 449 450 451 452
		case 2:
			omap_revision = TI8168_REV_ES2_0;
			cpu_rev = "2.0";
			break;
		case 3:
			/* FALLTHROUGH */
		default:
			omap_revision = TI8168_REV_ES2_1;
			cpu_rev = "2.1";
453 454
		}
		break;
455
	case 0xb944:
456 457 458 459 460 461 462 463 464
		switch (rev) {
		case 0:
			omap_revision = AM335X_REV_ES1_0;
			cpu_rev = "1.0";
			break;
		case 1:
			omap_revision = AM335X_REV_ES2_0;
			cpu_rev = "2.0";
			break;
465 466 467 468 469 470
		case 2:
		/* FALLTHROUGH */
		default:
			omap_revision = AM335X_REV_ES2_1;
			cpu_rev = "2.1";
			break;
471
		}
472
		break;
473
	case 0xb98c:
474 475 476 477 478 479 480 481 482
		switch (rev) {
		case 0:
			omap_revision = AM437X_REV_ES1_0;
			cpu_rev = "1.0";
			break;
		case 1:
			omap_revision = AM437X_REV_ES1_1;
			cpu_rev = "1.1";
			break;
483 484 485 486 487 488
		case 2:
		/* FALLTHROUGH */
		default:
			omap_revision = AM437X_REV_ES1_2;
			cpu_rev = "1.2";
			break;
489
		}
490
		break;
491
	case 0xb8f2:
492
	case 0xb968:
493 494 495 496 497
		switch (rev) {
		case 0:
		/* FALLTHROUGH */
		case 1:
			omap_revision = TI8148_REV_ES1_0;
498
			cpu_rev = "1.0";
499 500 501
			break;
		case 2:
			omap_revision = TI8148_REV_ES2_0;
502
			cpu_rev = "2.0";
503 504 505 506 507
			break;
		case 3:
		/* FALLTHROUGH */
		default:
			omap_revision = TI8148_REV_ES2_1;
508
			cpu_rev = "2.1";
509 510
			break;
		}
511
		break;
N
Nishanth Menon 已提交
512
	default:
513
		/* Unknown default to latest silicon rev as default */
514
		omap_revision = OMAP3630_REV_ES1_2;
515
		cpu_rev = "1.2";
516 517
		pr_warn("Warning: unknown chip type: hawkeye %04x, assuming OMAP3630ES1.2\n",
			hawkeye);
T
Tony Lindgren 已提交
518
	}
519
	sprintf(soc_rev, "ES%s", cpu_rev);
520 521
}

522
void __init omap4xxx_check_revision(void)
S
Santosh Shilimkar 已提交
523 524 525 526 527 528 529 530 531 532 533 534
{
	u32 idcode;
	u16 hawkeye;
	u8 rev;

	/*
	 * The IC rev detection is done with hawkeye and rev.
	 * Note that rev does not map directly to defined processor
	 * revision numbers as ES1.0 uses value 0.
	 */
	idcode = read_tap_reg(OMAP_TAP_IDCODE);
	hawkeye = (idcode >> 12) & 0xffff;
535
	rev = (idcode >> 28) & 0xf;
S
Santosh Shilimkar 已提交
536

537
	/*
538
	 * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0
539 540
	 * Use ARM register to detect the correct ES version
	 */
541
	if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) {
542
		idcode = read_cpuid_id();
543 544 545 546 547 548 549 550 551 552
		rev = (idcode & 0xf) - 1;
	}

	switch (hawkeye) {
	case 0xb852:
		switch (rev) {
		case 0:
			omap_revision = OMAP4430_REV_ES1_0;
			break;
		case 1:
553
		default:
554
			omap_revision = OMAP4430_REV_ES2_0;
555 556 557 558 559 560
		}
		break;
	case 0xb95c:
		switch (rev) {
		case 3:
			omap_revision = OMAP4430_REV_ES2_1;
561
			break;
562 563
		case 4:
			omap_revision = OMAP4430_REV_ES2_2;
564 565 566 567
			break;
		case 6:
		default:
			omap_revision = OMAP4430_REV_ES2_3;
568 569
		}
		break;
570 571 572 573 574
	case 0xb94e:
		switch (rev) {
		case 0:
			omap_revision = OMAP4460_REV_ES1_0;
			break;
575 576 577 578
		case 2:
		default:
			omap_revision = OMAP4460_REV_ES1_1;
			break;
579 580
		}
		break;
581 582 583 584 585 586 587 588
	case 0xb975:
		switch (rev) {
		case 0:
		default:
			omap_revision = OMAP4470_REV_ES1_0;
			break;
		}
		break;
589
	default:
590
		/* Unknown default to latest silicon rev as default */
591
		omap_revision = OMAP4430_REV_ES2_3;
S
Santosh Shilimkar 已提交
592 593
	}

594 595 596 597
	sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
	sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf,
						(omap_rev() >> 8) & 0xf);
	pr_info("%s %s\n", soc_name, soc_rev);
S
Santosh Shilimkar 已提交
598 599
}

600 601 602 603 604 605 606 607 608 609 610 611 612
void __init omap5xxx_check_revision(void)
{
	u32 idcode;
	u16 hawkeye;
	u8 rev;

	idcode = read_tap_reg(OMAP_TAP_IDCODE);
	hawkeye = (idcode >> 12) & 0xffff;
	rev = (idcode >> 28) & 0xff;
	switch (hawkeye) {
	case 0xb942:
		switch (rev) {
		case 0:
613 614
			/* No support for ES1.0 Test chip */
			BUG();
615 616 617
		case 1:
		default:
			omap_revision = OMAP5430_REV_ES2_0;
618 619 620 621 622 623
		}
		break;

	case 0xb998:
		switch (rev) {
		case 0:
624 625
			/* No support for ES1.0 Test chip */
			BUG();
626 627 628
		case 1:
		default:
			omap_revision = OMAP5432_REV_ES2_0;
629 630 631 632 633
		}
		break;

	default:
		/* Unknown default to latest silicon rev as default*/
634
		omap_revision = OMAP5430_REV_ES2_0;
635 636
	}

637 638 639 640
	sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
	sprintf(soc_rev, "ES%d.0", (omap_rev() >> 12) & 0xf);

	pr_info("%s %s\n", soc_name, soc_rev);
641 642
}

643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659
void __init dra7xxx_check_revision(void)
{
	u32 idcode;
	u16 hawkeye;
	u8 rev;

	idcode = read_tap_reg(OMAP_TAP_IDCODE);
	hawkeye = (idcode >> 12) & 0xffff;
	rev = (idcode >> 28) & 0xff;
	switch (hawkeye) {
	case 0xb990:
		switch (rev) {
		case 0:
			omap_revision = DRA752_REV_ES1_0;
			break;
		case 1:
			omap_revision = DRA752_REV_ES1_1;
660 661 662 663 664
			break;
		case 2:
		default:
			omap_revision = DRA752_REV_ES2_0;
			break;
665 666 667
		}
		break;

668 669 670 671 672 673 674 675 676 677 678 679
	case 0xb9bc:
		switch (rev) {
		case 0:
			omap_revision = DRA722_REV_ES1_0;
			break;
		default:
			/* If we have no new revisions */
			omap_revision = DRA722_REV_ES1_0;
			break;
		}
		break;

680 681
	default:
		/* Unknown default to latest silicon rev as default*/
682
		pr_warn("%s: unknown idcode=0x%08x (hawkeye=0x%08x,rev=0x%x)\n",
683
			__func__, idcode, hawkeye, rev);
684
		omap_revision = DRA752_REV_ES2_0;
685 686 687 688 689 690 691 692 693
	}

	sprintf(soc_name, "DRA%03x", omap_rev() >> 16);
	sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf,
		(omap_rev() >> 8) & 0xf);

	pr_info("%s %s\n", soc_name, soc_rev);
}

T
Tony Lindgren 已提交
694 695 696 697 698 699 700
/*
 * Set up things for map_io and processor detection later on. Gets called
 * pretty much first thing from board init. For multi-omap, this gets
 * cpu_is_omapxxxx() working accurately enough for map_io. Then we'll try to
 * detect the exact revision later on in omap2_detect_revision() once map_io
 * is done.
 */
701
void __init omap2_set_globals_tap(u32 class, void __iomem *tap)
702
{
703 704
	omap_revision = class;
	tap_base = tap;
705

706
	/* XXX What is this intended to do? */
707
	if (soc_is_omap34xx())
708 709 710 711
		tap_prod_id = 0x0210;
	else
		tap_prod_id = 0x0208;
}
712 713 714

#ifdef CONFIG_SOC_BUS

715
static const char * const omap_types[] = {
716 717 718 719 720 721 722 723 724
	[OMAP2_DEVICE_TYPE_TEST]	= "TST",
	[OMAP2_DEVICE_TYPE_EMU]		= "EMU",
	[OMAP2_DEVICE_TYPE_SEC]		= "HS",
	[OMAP2_DEVICE_TYPE_GP]		= "GP",
	[OMAP2_DEVICE_TYPE_BAD]		= "BAD",
};

static const char * __init omap_get_family(void)
{
725
	if (soc_is_omap24xx())
726
		return kasprintf(GFP_KERNEL, "OMAP2");
727
	else if (soc_is_omap34xx())
728
		return kasprintf(GFP_KERNEL, "OMAP3");
729
	else if (soc_is_omap44xx())
730 731 732
		return kasprintf(GFP_KERNEL, "OMAP4");
	else if (soc_is_omap54xx())
		return kasprintf(GFP_KERNEL, "OMAP5");
733 734
	else if (soc_is_am33xx() || soc_is_am335x())
		return kasprintf(GFP_KERNEL, "AM33xx");
735 736
	else if (soc_is_am43xx())
		return kasprintf(GFP_KERNEL, "AM43xx");
737 738
	else if (soc_is_dra7xx())
		return kasprintf(GFP_KERNEL, "DRA7");
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
	else
		return kasprintf(GFP_KERNEL, "Unknown");
}

static ssize_t omap_get_type(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	return sprintf(buf, "%s\n", omap_types[omap_type()]);
}

static struct device_attribute omap_soc_attr =
	__ATTR(type,  S_IRUGO, omap_get_type,  NULL);

void __init omap_soc_device_init(void)
{
	struct device *parent;
	struct soc_device *soc_dev;
	struct soc_device_attribute *soc_dev_attr;

	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
	if (!soc_dev_attr)
		return;

	soc_dev_attr->machine  = soc_name;
	soc_dev_attr->family   = omap_get_family();
	soc_dev_attr->revision = soc_rev;

	soc_dev = soc_device_register(soc_dev_attr);
768
	if (IS_ERR(soc_dev)) {
769 770 771 772 773
		kfree(soc_dev_attr);
		return;
	}

	parent = soc_device_to_device(soc_dev);
774
	device_create_file(parent, &omap_soc_attr);
775 776
}
#endif /* CONFIG_SOC_BUS */